diff --git a/.ci/README.md b/.ci/README.md
index 60a030b4b658..6d3819f50fc3 100644
--- a/.ci/README.md
+++ b/.ci/README.md
@@ -37,7 +37,21 @@ a) make no changes to any downstream and fail
or
b) atomically update every downstream to a fast-forward state that represents the appropriate HEAD as of the beginning of the run
-It's possible, if we assume the worst, for a job to be cancelled or fail in the middle of pushing downstreams in a transient way. The sorts of failures that happen at scale - lightning strikes a datacenter or some other unlikely misfortune happens. This has a chance to cause a hiccup in the downstream history, but isn't dangerous. If that happens, the sync tags may need to be manually updated to sit at the same commit, just before the commit which needs to be generated. Then, the downstream pusher workflow will need to be restarted.
+#### Something went wrong!
+Don't panic - this is all quite safe. :)
+
+It's possible for a job to be cancelled or fail in the middle of pushing downstreams in a transient way. The sorts of failures that happen at scale - lightning strikes a datacenter or some other unlikely misfortune happens. This has a chance to cause a hiccup in the downstream history, but isn't dangerous. If that happens, the sync tags may need to be manually updated to sit at the same commit, just before the commit which needs to be generated. Then, the downstream pusher workflow will need to be restarted.
+
+Updating the sync tags is done like this:
+First, check their state: `git fetch origin && git rev-parse origin/tpg-sync origin/tpgb-sync origin/ansible-sync origin/inspec-sync origin/tf-oics-sync origin/tf-conv-sync` will list the commits for each of the sync tags.
+If you have changed the name of the `googlecloudplatform/magic-modules` remote from `origin`, substitute that name instead.
+In normal, steady-state operation, these tags will all be identical. When a failure occurs, some of them may be one commit ahead of the others. It is rare for any of them to be 2 or more commits ahead of any other. If they are not all equal, and there is no pusher task currently running, this means you need to reset them by hand. If they are all equal, skip the next step.
+
+Second, find which commit caused the error. This will usually be easy - cloud build lists the commit which triggered a build, so you can probably just use that one. You need to set all the sync tags to the parent of that commit. Say the commit which caused the error is `12345abc`. You can find the parent of that commit with `git rev-parse 12345abc~` (note the `~` suffix). Some of the sync tags are likely set to this value already. For the remainder, simply perform a git push. Assuming that the parent commit is `98765fed`, that would be `git push origin 98765fed:tf-conv-sync`.
+
+If you are unlucky, there may be open PRs - this only happens if the failure occurred during the ~5 second period surrounding the merging of one of the downstreams. Close those PRs before proceeding to the final step.
+
+Click "retry" on the failed job in Cloud Build. Watch the retried job and see if it succeeds - it should! If it does not, the underlying problem may not have been fixed.
## Deploying the pipeline
The code on the PR's branch is used to plan actions - no merge is performed.
@@ -46,8 +60,15 @@ If you are making changes to the containers, your changes will not apply until t
Pausing the pipeline is done in the cloud console, by setting the downstream-builder trigger to disabled. You can find that trigger [here](https://console.cloud.google.com/cloud-build/triggers/edit/f80a7496-b2f4-4980-a706-c5425a52045b?project=graphite-docker-images)
-## Design choices & tradeoffs
-* The downstreams share some setup code in common - especially TPG and TPGB. We violated the DRY principle by writing separate workflows for each repo. In practice, this has substantially reduced the amount of code - the coordination layer above the two repos was larger than the code saved by combining them. We also increase speed, since each Action runs separately.
+
+## Dependency change handbook:
+If someone (often a bot) creates a PR which updates Gemfile or Gemfile.lock, they will not be able to generate diffs. This is because bundler doesn't allow you to run a binary unless your installed gems exactly match the Gemfile.lock, and since we have to run generation before and after the change, there is no possible container that will satisfy all requirements.
+
+The best approach is
+* Build the `downstream-generator` container locally, with the new Gemfile and Gemfile.lock. This will involve hand-modifying the Dockerfile to use the local Gemfile/Gemfile.lock instead of wget from this repo's `master` branch. You don't need to check in those changes.
+* When that container is built, and while nothing else is running in GCB (wait, if you need to), push the container to GCR, and as soon as possible afterwards, merge the dependency-changing PR.
+
+## Historical Note: Design choices & tradeoffs
* The downstream push doesn't wait for checks on its PRs against downstreams. This may inconvenience some existing workflows which rely on the downstream PR checks. This ensures that merge conflicts never come into play, since the downstreams never have dangling PRs, but it requires some up-front work to get those checks into the differ. If a new check is introduced into the downstream Travis, we will need to introduce it into the terraform-tester container.
* The downstream push is disconnected from the output of the differ (but runs the same code). This means that the diff which is approved isn't guaranteed to be applied *exactly*, if for instance magic modules' behavior changes on master between diff generation and downstream push. This is also intended to avoid merge conflicts by, effectively, rebasing each commit on top of master before final generation is done.
* Imagine the following situation: PR A and PR B are opened simultaneously. PR A changes the copyright date in each file to 2020. PR B adds a new resource. PR A is merged seconds before PR B, so they are picked up in the same push-downstream run. The commit from PR B will produce a new file with the 2020 copyright date, even though the diff said 2019, since PR A was merged first.
diff --git a/.ci/acceptance-tests/ansible-integration.sh b/.ci/acceptance-tests/ansible-integration.sh
deleted file mode 100755
index 9940edbc75bd..000000000000
--- a/.ci/acceptance-tests/ansible-integration.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-echo "${SERVICE_ACCOUNT_KEY}" > /tmp/google-account.json
-echo "${ANSIBLE_TEMPLATE}" > /tmp/ansible-template.ini
-
-set -e
-set -x
-
-# Install ansible from source
-git clone https://github.com/ansible/ansible.git
-pushd ansible
-pip install -r requirements.txt
-source hacking/env-setup
-popd
-
-# Clone ansible_collections_google because submodules
-# break collections
-git clone https://github.com/ansible-collections/ansible_collections_google.git
-
-# Build newest modules
-pushd magic-modules-gcp
-bundle install
-bundle exec compiler -a -e ansible -o ../ansible_collections_google
-popd
-
-# Install collection
-pushd ansible_collections_google
-ansible-galaxy collection build .
-ansible-galaxy collection install *.gz
-popd
-
-# Setup Cloud configuration template with variables
-pushd ~/.ansible/collections/ansible_collections/google/cloud
-cp /tmp/ansible-template.ini tests/integration/cloud-config-gcp.ini
-
-# Run ansible
-ansible-test integration -v --allow-unsupported --continue-on-error $(find tests/integration/targets -name "gcp*" -type d -printf "%P ")
diff --git a/.ci/acceptance-tests/ansible-integration.yml b/.ci/acceptance-tests/ansible-integration.yml
deleted file mode 100644
index a8dd4a521e58..000000000000
--- a/.ci/acceptance-tests/ansible-integration.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-platform: linux
-
-inputs:
- - name: magic-modules-gcp
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/ansible
-
-run:
- path: magic-modules-gcp/.ci/acceptance-tests/ansible-integration.sh
diff --git a/.ci/acceptance-tests/inspec-integration.sh b/.ci/acceptance-tests/inspec-integration.sh
deleted file mode 100755
index 806b2a662a91..000000000000
--- a/.ci/acceptance-tests/inspec-integration.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${TERRAFORM_KEY}" > /tmp/google-account.json
-export GCP_PROJECT_NUMBER=${PROJECT_NUMBER}
-export GCP_PROJECT_ID=${PROJECT_NAME}
-export GCP_PROJECT_NAME=${PROJECT_NAME}
-set -x
-
-pushd magic-modules-gcp/build/inspec
-
-# Setup for using current GCP resources
-export GCP_ZONE=europe-west2-a
-export GCP_LOCATION=europe-west2
-
-bundle install
-
-function cleanup {
- cd $INSPEC_DIR
- bundle exec rake test:cleanup_integration_tests
-}
-
-export INSPEC_DIR=${PWD}
-trap cleanup EXIT
-bundle exec rake test:integration
-popd
\ No newline at end of file
diff --git a/.ci/acceptance-tests/inspec-integration.yml b/.ci/acceptance-tests/inspec-integration.yml
deleted file mode 100644
index c948d3e2b601..000000000000
--- a/.ci/acceptance-tests/inspec-integration.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-platform: linux
-
-inputs:
- - name: magic-modules-gcp
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-
-run:
- path: magic-modules-gcp/.ci/acceptance-tests/inspec-integration.sh
diff --git a/.ci/acceptance-tests/inspec-post-approve.sh b/.ci/acceptance-tests/inspec-post-approve.sh
deleted file mode 100755
index 68bece76ca80..000000000000
--- a/.ci/acceptance-tests/inspec-post-approve.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${TERRAFORM_KEY}" > /tmp/google-account.json
-export GCP_PROJECT_NUMBER=${PROJECT_NUMBER}
-export GCP_PROJECT_ID=${PROJECT_NAME}
-export GCP_PROJECT_NAME=${PROJECT_NAME}
-set -x
-
-gcloud auth activate-service-account terraform@graphite-test-sam-chef.iam.gserviceaccount.com --key-file=$GOOGLE_CLOUD_KEYFILE_JSON
-# TODO(slevenick): Check to see if we have already run this
-PR_ID="$(cat ./mm-approved-prs/.git/id)"
-
-# Check if PR_ID folder exists
-set +e
-gsutil ls gs://magic-modules-inspec-bucket/$PR_ID
-if [ $? -ne 0 ]; then
- # Bucket does not exist, so we did not have to record new cassettes to pass the inspec-test step.
- # This means no new cassettes need to be generated after this PR is merged.
- exit 0
-fi
-set -e
-
-pushd mm-approved-prs
-export VCR_MODE=all
-# Running other controls may cause caching issues due to underlying clients caching responses
-rm build/inspec/test/integration/verify/controls/*
-bundle install
-bundle exec compiler -a -e inspec -o "build/inspec/" -v beta
-cp templates/inspec/vcr_config.rb build/inspec
-
-pushd build/inspec
-
-# Setup for using current GCP resources
-export GCP_ZONE=europe-west2-a
-export GCP_LOCATION=europe-west2
-
-bundle install
-
-function cleanup {
- cd $INSPEC_DIR
- bundle exec rake test:cleanup_integration_tests
-}
-
-export INSPEC_DIR=${PWD}
-trap cleanup EXIT
-
-seed=$RANDOM
-bundle exec rake test:init_workspace
-# Seed plan_integration_tests so VCR cassettes work with random resource suffixes
-bundle exec rake test:plan_integration_tests[$seed]
-bundle exec rake test:setup_integration_tests
-bundle exec rake test:run_integration_tests
-bundle exec rake test:cleanup_integration_tests
-
-echo $seed > inspec-cassettes/seed.txt
-
-gsutil -m cp inspec-cassettes/* gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/approved/
-
-popd
\ No newline at end of file
diff --git a/.ci/acceptance-tests/inspec-post-approve.yml b/.ci/acceptance-tests/inspec-post-approve.yml
deleted file mode 100644
index f724216954d4..000000000000
--- a/.ci/acceptance-tests/inspec-post-approve.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-platform: linux
-
-inputs:
- - name: mm-approved-prs
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-
-run:
- path: mm-approved-prs/.ci/acceptance-tests/inspec-post-approve.sh
diff --git a/.ci/acceptance-tests/inspec-post-merge.sh b/.ci/acceptance-tests/inspec-post-merge.sh
deleted file mode 100755
index 57c3bcf6c4a6..000000000000
--- a/.ci/acceptance-tests/inspec-post-merge.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${TERRAFORM_KEY}" > /tmp/google-account.json
-export GCP_PROJECT_NUMBER=${PROJECT_NUMBER}
-export GCP_PROJECT_ID=${PROJECT_NAME}
-export GCP_PROJECT_NAME=${PROJECT_NAME}
-set -x
-
-gcloud auth activate-service-account terraform@graphite-test-sam-chef.iam.gserviceaccount.com --key-file=$GOOGLE_CLOUD_KEYFILE_JSON
-
-PR_ID="$(cat ./mm-approved-prs/.git/id)"
-# Check if PR_ID folder exists in the GS bucket.
-set +e
-gsutil ls gs://magic-modules-inspec-bucket/$PR_ID
-if [ $? -ne 0 ]; then
- # Bucket does not exist, so we did not have to record new cassettes to pass the inspec-test step.
- # This means no new cassettes need to be generated after this PR is merged.
- exit 0
-fi
-set -e
-
-pushd mm-approved-prs
-export VCR_MODE=all
-# Running other controls may cause caching issues due to underlying clients caching responses
-rm build/inspec/test/integration/verify/controls/*
-bundle install
-bundle exec compiler -a -e inspec -o "build/inspec/" -v beta
-cp templates/inspec/vcr_config.rb build/inspec
-
-pushd build/inspec
-
-# Setup for using current GCP resources
-export GCP_ZONE=europe-west2-a
-export GCP_LOCATION=europe-west2
-
-bundle install
-
-function cleanup {
- cd $INSPEC_DIR
- bundle exec rake test:cleanup_integration_tests
-}
-
-export INSPEC_DIR=${PWD}
-trap cleanup EXIT
-
-set +e
-gsutil ls gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/approved
-if [ $? -eq 0 ]; then
- # We have already recorded new cassettes during the inspec-post-merge step
- gsutil -m cp gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/approved/* gs://magic-modules-inspec-bucket/master/inspec-cassettes
-else
- # We need to record new cassettes for this PR
- seed=$RANDOM
- bundle exec rake test:init_workspace
- # Seed plan_integration_tests so VCR cassettes work with random resource suffixes
- bundle exec rake test:plan_integration_tests[$seed]
- bundle exec rake test:setup_integration_tests
- bundle exec rake test:run_integration_tests
- bundle exec rake test:cleanup_integration_tests
-
- echo $seed > inspec-cassettes/seed.txt
- gsutil -m cp inspec-cassettes/* gs://magic-modules-inspec-bucket/master/inspec-cassettes/
-fi
-set -e
-
-# Clean up cassettes for merged PR
-gsutil -m rm -r gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/*
-popd
\ No newline at end of file
diff --git a/.ci/acceptance-tests/inspec-post-merge.yml b/.ci/acceptance-tests/inspec-post-merge.yml
deleted file mode 100644
index 838672508199..000000000000
--- a/.ci/acceptance-tests/inspec-post-merge.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-platform: linux
-
-inputs:
- - name: mm-approved-prs
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-
-run:
- path: mm-approved-prs/.ci/acceptance-tests/inspec-post-merge.sh
diff --git a/.ci/acceptance-tests/inspec-vcr.sh b/.ci/acceptance-tests/inspec-vcr.sh
deleted file mode 100755
index 179f1eb4facc..000000000000
--- a/.ci/acceptance-tests/inspec-vcr.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${TERRAFORM_KEY}" > /tmp/google-account.json
-export GCP_PROJECT_NUMBER=${PROJECT_NUMBER}
-export GCP_PROJECT_ID=${PROJECT_NAME}
-export GCP_PROJECT_NAME=${PROJECT_NAME}
-set -x
-
-gcloud auth activate-service-account terraform@graphite-test-sam-chef.iam.gserviceaccount.com --key-file=$GOOGLE_CLOUD_KEYFILE_JSON
-PR_ID="$(cat ./magic-modules-new-prs/.git/id)"
-
-pushd magic-modules-new-prs
-export VCR_MODE=all
-# Running other controls may cause caching issues due to underlying clients caching responses
-rm build/inspec/test/integration/verify/controls/*
-bundle install
-bundle exec compiler -a -e inspec -o "build/inspec/" -v beta
-cp templates/inspec/vcr_config.rb build/inspec
-
-pushd build/inspec
-
-# Setup for using current GCP resources
-export GCP_ZONE=europe-west2-a
-export GCP_LOCATION=europe-west2
-
-bundle install
-
-function cleanup {
- cd $INSPEC_DIR
- bundle exec rake test:cleanup_integration_tests
-}
-
-export INSPEC_DIR=${PWD}
-trap cleanup EXIT
-
-seed=$RANDOM
-bundle exec rake test:init_workspace
-# Seed plan_integration_tests so VCR cassettes work with random resource suffixes
-bundle exec rake test:plan_integration_tests[$seed]
-bundle exec rake test:setup_integration_tests
-bundle exec rake test:run_integration_tests
-bundle exec rake test:cleanup_integration_tests
-
-echo $seed > inspec-cassettes/seed.txt
-
-gsutil -m cp inspec-cassettes/* gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/
-popd
\ No newline at end of file
diff --git a/.ci/acceptance-tests/inspec-vcr.yml b/.ci/acceptance-tests/inspec-vcr.yml
deleted file mode 100644
index bf7857f481f8..000000000000
--- a/.ci/acceptance-tests/inspec-vcr.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-platform: linux
-
-inputs:
- - name: magic-modules-new-prs
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-
-run:
- path: magic-modules-new-prs/.ci/acceptance-tests/inspec-vcr.sh
diff --git a/.ci/acceptance-tests/terraform-acceptance.sh b/.ci/acceptance-tests/terraform-acceptance.sh
deleted file mode 100755
index 1636d4c1036e..000000000000
--- a/.ci/acceptance-tests/terraform-acceptance.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-set -x
-
-export GOOGLE_CREDENTIALS_FILE="/tmp/google-account.json"
-export GOOGLE_REGION="us-central1"
-export GOOGLE_ZONE="us-central1-a"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${GOOGLE_JSON_ACCOUNT}" > $GOOGLE_CREDENTIALS_FILE
-set -x
-
-# Create GOPATH structure
-mkdir -p "${GOPATH}/src/github.com/terraform-providers"
-ln -s "${PWD}/magic-modules/build/$SHORT_NAME" "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-cd "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-git diff HEAD~ > tmp.diff
-OUTPUT=( $(go run scripts/affectedtests/affectedtests.go -diff tmp.diff) )
-rm tmp.diff
-
-if [ ${#OUTPUT[@]} -eq 0 ]; then
- echo "No tests to run"
-else
- make testacc TEST=./$TEST_DIR TESTARGS="-run=\"$( IFS=$'|'; echo "${OUTPUT[*]}" )\""
-fi
diff --git a/.ci/acceptance-tests/terraform-acceptance.yml b/.ci/acceptance-tests/terraform-acceptance.yml
deleted file mode 100644
index 1077fa53e885..000000000000
--- a/.ci/acceptance-tests/terraform-acceptance.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-platform: linux
-params:
- # Params are set as environment variables when the run part is executed.
- # Here we use (()) notation to indicate that we're using a credhub secret.
- GOOGLE_JSON_ACCOUNT: ((terraform-integration-key))
- GOOGLE_PROJECT: ((terraform-integration-project))
- GOOGLE_ORG: ((terraform-integration-org))
- GOOGLE_BILLING_ACCOUNT: ((terraform-integration-billing-account))
- GOOGLE_PROJECT_NUMBER: ((terraform-integration-project-number))
- TEST_DIR: ""
- PROVIDER_NAME: ""
- SHORT_NAME: ""
- # TODO: GOOGLE_BILLING_ACCOUNT_2
-inputs:
- - name: magic-modules
-image_resource:
- type: docker-image
- source:
- repository: golang
- tag: '1.11'
-run:
- path: magic-modules/.ci/acceptance-tests/terraform-acceptance.sh
diff --git a/.ci/acceptance-tests/terraform-integration.sh b/.ci/acceptance-tests/terraform-integration.sh
deleted file mode 100755
index d22b99869c84..000000000000
--- a/.ci/acceptance-tests/terraform-integration.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-set -x
-
-export GOOGLE_CREDENTIALS_FILE="/tmp/google-account.json"
-export GOOGLE_REGION="us-central1"
-export GOOGLE_ZONE="us-central1-a"
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${GOOGLE_JSON_ACCOUNT}" > $GOOGLE_CREDENTIALS_FILE
-set -x
-
-# Create GOPATH structure
-mkdir -p "${GOPATH}/src/github.com/terraform-providers"
-ln -s "${PWD}/magic-modules-gcp/build/$SHORT_NAME" "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-cd "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-make testacc TEST=./$TEST_DIR
diff --git a/.ci/acceptance-tests/terraform-integration.yml b/.ci/acceptance-tests/terraform-integration.yml
deleted file mode 100644
index 828b5be71ccc..000000000000
--- a/.ci/acceptance-tests/terraform-integration.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-platform: linux
-params:
- # Params are set as environment variables when the run part is executed.
- # Here we use (()) notation to indicate that we're using a credhub secret.
- GOOGLE_JSON_ACCOUNT: ((terraform-integration-key))
- GOOGLE_PROJECT: ((terraform-integration-project))
- GOOGLE_ORG: ((terraform-integration-org))
- GOOGLE_BILLING_ACCOUNT: ((terraform-integration-billing-account))
- GOOGLE_PROJECT_NUMBER: ((terraform-integration-project-number))
- TEST_DIR: ""
- PROVIDER_NAME: ""
- SHORT_NAME: ""
- # TODO: GOOGLE_BILLING_ACCOUNT_2
-inputs:
- - name: magic-modules-gcp
-image_resource:
- type: docker-image
- source:
- repository: golang
- tag: '1.11'
-run:
- path: magic-modules-gcp/.ci/acceptance-tests/terraform-integration.sh
diff --git a/.ci/changelog.tmpl b/.ci/changelog.tmpl
index c35942e2e34d..03b7cea36a27 100644
--- a/.ci/changelog.tmpl
+++ b/.ci/changelog.tmpl
@@ -64,4 +64,4 @@ BUG FIXES:
{{range $bugs | sortAlpha -}}
* {{. }}
{{- end -}}
-{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/.ci/ci.yml.tmpl b/.ci/ci.yml.tmpl
deleted file mode 100644
index dface4b51bac..000000000000
--- a/.ci/ci.yml.tmpl
+++ /dev/null
@@ -1,603 +0,0 @@
-{% import "vars.tmpl" as vars %}
-
-resource_types:
- - name: merged-downstreams
- type: docker-image
- source:
- repository: gcr.io/magic-modules/merged-prs-resource
- tag: '1.1'
-
- - name: git-branch
- type: docker-image
- source:
- repository: gcr.io/magic-modules/concourse-git-resource
- tag: '1.0'
-
- - name: github-pull-request
- type: docker-image
- source:
- repository: gcr.io/magic-modules/concourse-github-pr-resource
- tag: '1.1'
-
-resources:
- - name: magic-modules
- type: git-branch
- source:
- uri: git@github.com:((github-account.username))/magic-modules.git
- private_key: ((repo-key.private_key))
-
- - name: magic-modules-gcp
- type: git-branch
- source:
- uri: git@github.com:GoogleCloudPlatform/magic-modules.git
- private_key: ((repo-key.private_key))
-
- - name: magic-modules-new-external-prs
- type: github-pull-request
- source:
- repo: GoogleCloudPlatform/magic-modules
- private_key: ((repo-key.private_key))
- access_token: ((github-account.password))
- community_only: true
- no_label: community
- base: master
-
- - name: magic-modules-external-prs
- type: github-pull-request
- source:
- repo: GoogleCloudPlatform/magic-modules
- private_key: ((repo-key.private_key))
- access_token: ((github-account.password))
- community_only: true
- base: master
-
- - name: magic-modules-new-prs
- type: github-pull-request
- source:
- repo: GoogleCloudPlatform/magic-modules
- private_key: ((repo-key.private_key))
- access_token: ((github-account.password))
- authorship_restriction: true
- no_label: automerged
- base: master
-
- - name: magic-modules-3.0-prs
- type: github-pull-request
- source:
- repo: GoogleCloudPlatform/magic-modules
- private_key: ((repo-key.private_key))
- access_token: ((github-account.password))
- authorship_restriction: true
- no_label: automerged
- base: 3.0.0
-
-{% for v in vars.terraform_v.itervalues() %}
- - name: {{ v.short_name }}-intermediate
- type: git-branch
- source:
- uri: git@github.com:((github-account.username))/{{ v.provider_name }}.git
- private_key: ((repo-key.private_key))
-{% endfor %}
-
- - name: ansible-intermediate
- type: git-branch
- source:
- uri: git@github.com:((github-account.username))/ansible_collections_google.git
- private_key: ((repo-key.private_key))
-
- - name: inspec-intermediate
- type: git-branch
- source:
- uri: git@github.com:((github-account.username))/inspec-gcp.git
- private_key: ((repo-key.private_key))
-
- - name: mm-approved-prs
- type: github-pull-request
- source:
- repo: GoogleCloudPlatform/magic-modules
- private_key: ((repo-key.private_key))
- access_token: ((github-account.password))
- only_mergeable: true
- require_review_approval: true
- check_dependent_prs: true
- label: downstream-generated
- base: master
-
- - name: merged-prs
- type: merged-downstreams
- check_every: 5m
- source:
- repo: GoogleCloudPlatform/magic-modules
- token: ((github-account.password))
-
-jobs:
- - name: respond-to-community-pr
- plan:
- - get: magic-modules-new-external-prs
- trigger: true
- - get: magic-modules-gcp
- # NOTE: we do NOT run a script from the external PR!
- - task: write-welcome-message
- file: magic-modules-gcp/.ci/magic-modules/welcome-contributor.yml
- - put: magic-modules-external-prs
- params:
- status: pending
- path: magic-modules-new-external-prs
- label: community
- comment: comment/pr_comment
- assignee_file: comment/assignee
- get_params:
- skip_clone: true
-
- - name: authorize-single-rev
- plan:
- - get: magic-modules-external-prs
- trigger: false
- - put: magic-modules-new-prs
- params:
- status: pending
- path: magic-modules-external-prs
- get_params:
- skip_clone: true
-
- - name: mm-3.0-diff
- plan:
- - get: magic-modules
- resource: magic-modules-3.0-prs
- version: every
- trigger: true
- attempts: 2
- params:
- fetch_merge: true
- # This isn't strictly-speaking necessary - we aren't actually
- # pushing this anywhere - but it lets us reuse all the other
- # generation stuff.
- - aggregate:
- # consumes: magic-modules (detached HEAD)
- # produces: magic-modules-branched (new branch, with submodule)
- - task: branch-magic-modules
- file: magic-modules/.ci/magic-modules/branch.yml
- params:
- GH_TOKEN: ((github-account.password))
- CREDS: ((repo-key.private_key))
- ALL_SUBMODULES: {{' '.join(vars.all_submodules)}}
- INCLUDE_PREVIOUS: true
- - put: magic-modules-3.0-prs
- params:
- status: pending
- path: magic-modules
- get_params:
- skip_clone: true
-
- - aggregate:
-{% for k, v in vars.terraform_v.iteritems() %}
- - do:
- # consumes: magic-modules-branched
- # produces: terraform-generated
- - task: diff-{{v.short_name}}
- file: magic-modules-branched/.ci/magic-modules/diff-terraform.yml
- params:
- VERSION: {{k}}
- PROVIDER_NAME: {{v.provider_name}}
- SHORT_NAME: {{v.short_name}}
- GITHUB_ORG: {{v.github_org}}
- OVERRIDE_PROVIDER: {{v.override_provider}}
-
- - put: {{v.short_name}}-intermediate
- params:
- repository: terraform-diff/{{k}}/new
- branch_file: magic-modules-branched/branchname
- force: true
- get_params:
- skip_clone: true
-
- - put: {{v.short_name}}-intermediate
- params:
- repository: terraform-diff/{{k}}/old
- branch_file: magic-modules-previous/branchname
- force: true
- get_params:
- skip_clone: true
-
- - task: test-{{v.short_name}}
- file: magic-modules-branched/.ci/unit-tests/tf-3.yml
- timeout: 30m
- params:
- PROVIDER_NAME: {{v.provider_name}}
- TEST_DIR: {{v.test_dir}}
- SUBDIR: {{k}}
-
-{% endfor %}
-
- on_failure:
- put: magic-modules-3.0-prs
- params:
- status: failure
- context: code-generation
- path: magic-modules-3.0-prs
- get_params:
- skip_clone: true
-
- - task: create-message
- file: magic-modules-branched/.ci/magic-modules/create-diff-message.yml
-
- - put: magic-modules-3.0-prs
- params:
- status: success
- path: magic-modules
- comment: message/message.txt
- get_params:
- skip_clone: true
-
-
-
- - name: mm-generate
- plan:
- - get: magic-modules
- resource: magic-modules-new-prs
- version: every
- trigger: true
- attempts: 2
- params:
- fetch_merge: true
- - aggregate:
- - get: patches
- resource: merged-prs
- # consumes: magic-modules (detached HEAD)
- # produces: magic-modules-branched (new branch, with submodule)
- - task: branch-magic-modules
- file: magic-modules/.ci/magic-modules/branch.yml
- params:
- GH_TOKEN: ((github-account.password))
- CREDS: ((repo-key.private_key))
- ALL_SUBMODULES: {{' '.join(vars.all_submodules)}}
- - put: magic-modules-new-prs
- params:
- status: pending
- path: magic-modules
- get_params:
- skip_clone: true
- - aggregate:
-{% for k, v in vars.terraform_v.iteritems() %}
- - do:
- # consumes: magic-modules-branched
- # produces: terraform-generated
- - task: generate-{{v.short_name}}
- file: magic-modules-branched/.ci/magic-modules/generate-terraform.yml
- params:
- VERSION: {{k}}
- PROVIDER_NAME: {{v.provider_name}}
- SHORT_NAME: {{v.short_name}}
- GITHUB_ORG: {{v.github_org}}
- OVERRIDE_PROVIDER: {{v.override_provider}}
- # Puts 'terraform-generated' into the robot's fork.
- - aggregate:
- - put: {{v.short_name}}-intermediate
- params:
- repository: terraform-generated/{{k}}
- branch_file: magic-modules-branched/branchname
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
-{% endfor %}
- - do:
- # consumes: magic-modules-branched
- # produces: ansible-generated
- - task: generate-ansible
- file: magic-modules-branched/.ci/magic-modules/generate-ansible.yml
- # Puts 'ansible-generated' into the robot's fork.
- - put: ansible-intermediate
- params:
- repository: ansible-generated
- branch_file: magic-modules-branched/branchname
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
- - do:
- # consumes: magic-modules-branched
- # produces: inspec-generated
- - task: generate-inspec
- file: magic-modules-branched/.ci/magic-modules/generate-inspec.yml
- # Puts 'inspec-generated' into the robot's fork.
- - put: inspec-intermediate
- params:
- repository: inspec-generated
- branch_file: magic-modules-branched/branchname
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
- on_failure:
- put: magic-modules-new-prs
- params:
- status: failure
- context: code-generation
- path: magic-modules
- get_params:
- skip_clone: true
-
- # consumes: magic-modules-branched
- # produces: magic-modules-submodules
- - task: point-to-submodules
- file: magic-modules-branched/.ci/magic-modules/point-to-submodules.yml
- params:
- # This needs to match the username for the 'intermediate' resources.
- GH_USERNAME: ((github-account.username))
- CREDS: ((repo-key.private_key))
- TERRAFORM_VERSIONS: "{{','.join(vars.terraform_properties_serialized)}}"
- TERRAFORM_ENABLED: true
- ANSIBLE_ENABLED: true
- INSPEC_ENABLED: true
-
- # Push the magic modules branch that contains the updated submodules.
- - put: magic-modules
- params:
- repository: magic-modules-submodules
- branch_file: magic-modules-branched/branchname
- force: true
- get_params:
- skip_clone: true
-
- - name: terraform-test
- plan:
- - get: magic-modules
- version: every
- trigger: true
- params:
- submodules: [{{','.join(vars.terraform_submodules)}}]
- passed: [mm-generate]
- - aggregate:
-{% for v in vars.terraform_v.itervalues() %}
- - task: test-{{v.short_name}}
- file: magic-modules/.ci/unit-tests/task.yml
- timeout: 30m
- params:
- PROVIDER_NAME: {{v.provider_name}}
- SHORT_NAME: {{v.short_name}}
- TEST_DIR: {{v.test_dir}}
-{% endfor %}
- on_failure:
- do:
- - get: magic-modules-new-prs
- passed: [mm-generate]
- - put: magic-modules-new-prs
- params:
- status: failure
- context: terraform-tests
- path: magic-modules-new-prs
- get_params:
- skip_clone: true
-
- - name: inspec-unit-test
- plan:
- - get: magic-modules-new-prs
- passed: [mm-generate]
- - get: magic-modules
- version: every
- trigger: true
- params:
- submodules: [build/inspec]
- passed: [mm-generate]
- - task: test
- file: magic-modules/.ci/unit-tests/inspec.yml
- timeout: 30m
- params:
- TERRAFORM_KEY: ((terraform-key))
- PROJECT_NAME: ((inspec-project-name))
- PROJECT_NUMBER: ((inspec-project-number))
-
- - name: create-prs
- plan:
- - get: magic-modules
- version: every
- trigger: true
- params:
- submodules: {{vars.all_submodules_yaml_format}}
- passed:
- - mm-generate
- - get: mm-initial-pr
- attempts: 2
- resource: magic-modules-new-prs
- passed: [mm-generate]
- version: every
- # This task either uses the 'hub' cli to create a PR from the generated repo,
- # or, if a PR already exists, it uses 'git branch -f' to update the branch
- # that PR is from to point at the commit generated earlier from this run
- # of the pipeline.
- - task: write-original-branch-name
- file: mm-initial-pr/.ci/magic-modules/write-branch-name.yml
- # This will be a no-op the first time through the pipeline. This pushes the updated
- # branch named "codegen-pr-$MM_PR_NUMBER" to the downstream terraform repo. The
- # first time through the pipeline, that branch is unchanged by the create-prs task,
- # because a new PR has just been created from that branch. The second time through
- # the pipeline (when a PR needs to be updated), this does that updating by pushing
- # the new code to the repository/branch from which a pull request is already open.
- - aggregate:
-{% for v in vars.terraform_v.itervalues() %}
- - put: {{v.short_name}}-intermediate
- params:
- repository: magic-modules/build/{{ v.short_name }}
- branch_file: branchname/original_pr_branch_name
- # Every time a change runs through this pipeline, it will generate a commit with
- # a different hash - the hash includes timestamps. Therefore, even if there's no
- # code diff, this push will update terraform's pending PR on every update to the
- # magic-modules PR. With this 'only_if_diff' feature, if the change to the
- # magic-modules PR does not require an update to the terraform PR, this will
- # not push the update even though the commit hashes are different.
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
-{% endfor %}
- - put: ansible-intermediate
- params:
- repository: magic-modules/build/ansible
- branch_file: branchname/original_pr_branch_name
- # See comment on terraform-intermediate
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
- - put: inspec-intermediate
- params:
- repository: magic-modules/build/inspec
- branch_file: branchname/original_pr_branch_name
- # See comment on terraform-intermediate
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
- - task: create-or-update-pr
- file: magic-modules/.ci/magic-modules/create-pr.yml
- params:
- GITHUB_TOKEN: ((github-account.password))
- # This is what tells us which terraform repo to write PRs against - this
- # is what you change if you want to test this in a non-live environment.
- ANSIBLE_REPO_USER: ansible-collections
- INSPEC_REPO_USER: modular-magician
- TERRAFORM_VERSIONS: "{{','.join(vars.terraform_properties_serialized)}}"
- on_failure:
- put: magic-modules-new-prs
- params:
- status: failure
- context: pr-creation
- path: mm-initial-pr
- get_params:
- skip_clone: true
- - put: magic-modules
- params:
- repository: magic-modules/
- branch_file: branchname/original_pr_branch_name
- only_if_diff: true
- force: true
- get_params:
- skip_clone: true
- # Once everything is done and working, post the updated information to the
- # magic-modules PR.
- - put: magic-modules-new-prs
- params:
- status: success
- label: downstream-generated
- path: mm-initial-pr
- comment: magic-modules-with-comment/pr_comment
- label_file: magic-modules-with-comment/label_file
- get_params:
- skip_clone: true
- # Downstream changelog metadata
- - task: downstream-changelog-metadata
- file: magic-modules-with-comment/.ci/magic-modules/downstream-changelog-metadata.yml
- params:
- GITHUB_TOKEN: ((github-account.password))
- DOWNSTREAM_REPOS: "{{','.join(vars.downstreams_with_changelogs)}}"
- - name: terraform-acceptance-tests
- plan:
- - get: magic-modules
- version: every
- trigger: true
- params:
- submodules: [{{', '.join(vars.terraform_submodules)}}]
- passed: [create-prs]
- - aggregate:
-{% for v in vars.terraform_v.itervalues() %}
- - task: test-{{v.short_name}}
- file: magic-modules/.ci/acceptance-tests/terraform-acceptance.yml
- params:
- PROVIDER_NAME: {{v.provider_name}}
- SHORT_NAME: {{v.short_name}}
- TEST_DIR: {{v.test_dir}}
-{% endfor %}
-
- - name: merge-prs
- plan:
- - get: mm-approved-prs
- attempts: 2
- - task: downstream-changelog-metadata
- file: mm-approved-prs/.ci/magic-modules/downstream-changelog-metadata-mergeprs.yml
- params:
- GITHUB_TOKEN: ((github-account.password))
- DOWNSTREAM_REPOS: "{{','.join(vars.downstreams_with_changelogs)}}"
- - task: ensure-downstreams-merged
- file: mm-approved-prs/.ci/magic-modules/ensure-downstreams-merged.yml
- params:
- GH_TOKEN: ((github-account.password))
- - put: mark-automerged
- resource: mm-approved-prs
- params:
- path: mm-approved-prs
- status: success
- label: automerged
- get_params:
- skip_clone: true
- - task: rebase-and-update
- file: mm-approved-prs/.ci/magic-modules/merge.yml
- params:
- CREDS: ((repo-key.private_key))
- ALL_SUBMODULES: "{{' '.join(vars.all_submodules)}}"
- # TODO(ndmckinley): This will work to update the magic-modules PR *if* the original PR
- # was opened from the magic-modules repository. That's not always going to be
- # true - figure out what to do if, for instance, we can't modify the PR.
- # Update: right now, we just require everyone to push to the GCP repo. That's not
- # been a problem yet.
- - put: magic-modules-gcp
- params:
- repository: mm-output
- branch_file: mm-approved-prs/.git/branch
- force: true
- - put: mark-success
- resource: mm-approved-prs
- params:
- path: mm-output
- status: success
- get_params:
- skip_clone: true
- - put: merge-pr
- resource: mm-approved-prs
- params:
- path: mm-output
- status: success
- merge:
- method: squash
- commit_msg: mm-output/commit_message
- get_params:
- skip_clone: true
-
- - name: inspec-vcr-record
- serial: true
- serial_groups: [inspec-integration]
- plan:
- - get: magic-modules-new-prs
- - task: inspec-vcr
- file: magic-modules-new-prs/.ci/acceptance-tests/inspec-vcr.yml
- params:
- TERRAFORM_KEY: ((terraform-key))
- PROJECT_NAME: ((inspec-project-name))
- PROJECT_NUMBER: ((inspec-project-number))
-
- - name: inspec-post-merge
- serial: true
- serial_groups: [inspec-integration]
- plan:
- - get: mm-approved-prs
- passed: [merge-prs]
- trigger: true
- - task: inspec-post-merge
- file: mm-approved-prs/.ci/acceptance-tests/inspec-post-merge.yml
- params:
- TERRAFORM_KEY: ((terraform-key))
- PROJECT_NAME: ((inspec-project-name))
- PROJECT_NUMBER: ((inspec-project-number))
-
- - name: inspec-post-approve
- serial: true
- serial_groups: [inspec-integration]
- plan:
- - get: mm-approved-prs
- trigger: true
- - task: inspec-post-approve
- file: mm-approved-prs/.ci/acceptance-tests/inspec-post-approve.yml
- params:
- TERRAFORM_KEY: ((terraform-key))
- PROJECT_NAME: ((inspec-project-name))
- PROJECT_NUMBER: ((inspec-project-number))
diff --git a/.ci/containers/contributor-checker/Dockerfile b/.ci/containers/contributor-checker/Dockerfile
new file mode 100644
index 000000000000..9df163f0625c
--- /dev/null
+++ b/.ci/containers/contributor-checker/Dockerfile
@@ -0,0 +1,5 @@
+from alpine
+run apk update
+run apk add git curl jq bash
+add check-contributor.sh /main.sh
+entrypoint ["/main.sh"]
diff --git a/.ci/containers/contributor-checker/check-contributor.sh b/.ci/containers/contributor-checker/check-contributor.sh
new file mode 100755
index 000000000000..728bae3b3ede
--- /dev/null
+++ b/.ci/containers/contributor-checker/check-contributor.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+if [[ -z "$GITHUB_TOKEN" ]]; then
+ echo "Did not provide GITHUB_TOKEN environment variable."
+ exit 1
+fi
+if [[ $# -lt 1 ]]; then
+ echo "Usage: $0 pr-number"
+ exit 1
+fi
+PR_NUMBER=$1
+
+set -x
+
+ASSIGNEE=$(curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/${PR_NUMBER}/requested_reviewers" | jq .users[0].login)
+
+if [[ "$ASSIGNEE" == "null" || -z "$ASSIGNEE" ]] ; then
+ ASSIGNEE=$(curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/${PR_NUMBER}/reviews" | jq .[0].user.login)
+fi
+
+if [[ "$ASSIGNEE" == "null" || -z "$ASSIGNEE" ]] ; then
+ echo "Issue is not assigned."
+else
+ echo "Issue is assigned, not assigning."
+ exit 0
+fi
+
+USER=$(curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/${PR_NUMBER}" | jq .user.login)
+
+# This is where you add users who do not need to have an assignee chosen for
+# them.
+if $(echo $USER | fgrep -wq -e ndmckinley -e danawillow -e megan07 -e paddycarver -e rambleraptor -e SirGitsalot -e slevenick -e c2thorn -e rileykarson); then
+ echo "User is on the list, not assigning."
+ exit 0
+fi
+
+# This is where you add people to the random-assignee rotation. This list
+# might not equal the list above.
+ASSIGNEE=$(shuf -n 1 <(printf "danawillow\nrileykarson\nslevenick\nc2thorn\nndmckinley\nmegan07"))
+
+comment=$(cat << EOF
+Hello! I am a robot who works on Magic Modules PRs.
+
+I have detected that you are a community contributor, so your PR will be assigned to someone with a commit-bit on this repo for initial review.
+
+Thanks for your contribution! A human will be with you soon.
+
+@$ASSIGNEE, please review this PR or find an appropriate assignee.
+EOF
+)
+
+curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ -d "$(jq -r --arg comment "$comment" -n "{body: \$comment}")" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/${PR_NUMBER}/comments"
+curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ -d "$(jq -r --arg assignee "$ASSIGNEE" -n "{reviewers: [\$assignee], team_reviewers: []}")" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/${PR_NUMBER}/requested_reviewers"
diff --git a/.ci/containers/downstream-builder/Dockerfile b/.ci/containers/downstream-builder/Dockerfile
index d5a91fec73ce..143905b57791 100644
--- a/.ci/containers/downstream-builder/Dockerfile
+++ b/.ci/containers/downstream-builder/Dockerfile
@@ -9,8 +9,7 @@ RUN go get github.com/github/hub
RUN ssh-keyscan github.com >> /known_hosts
RUN echo "UserKnownHostsFile /known_hosts" >> /etc/ssh/ssh_config
-ENV GOFLAGS "-mod=vendor"
-ENV GO111MODULE "off"
+ENV GO111MODULE "on"
# Install Ruby from source.
RUN apt-get update
diff --git a/.ci/containers/downstream-builder/generate_downstream.sh b/.ci/containers/downstream-builder/generate_downstream.sh
index 80c3d54247d0..5066d97bb622 100755
--- a/.ci/containers/downstream-builder/generate_downstream.sh
+++ b/.ci/containers/downstream-builder/generate_downstream.sh
@@ -27,7 +27,7 @@ function clone_repo() {
LOCAL_PATH=$GOPATH/src/github.com/terraform-google-modules/docs-examples
elif [ "$REPO" == "ansible" ]; then
UPSTREAM_OWNER=ansible-collections
- GH_REPO=ansible_collections_google
+ GH_REPO=google.cloud
LOCAL_PATH=$PWD/../ansible
elif [ "$REPO" == "inspec" ]; then
UPSTREAM_OWNER=modular-magician
@@ -85,7 +85,8 @@ fi
if [ "$REPO" == "terraform" ]; then
pushd $LOCAL_PATH
- find . -type f -not -wholename "./.git*" -not -wholename "./.changelog*" -not -wholename "./vendor*" -not -name ".travis.yml" -not -name ".golangci.yml" -not -name "CHANGELOG.md" -not -name "GNUmakefile" -not -name "docscheck.sh" -not -name "LICENSE" -not -name "README.md" -not -wholename "./examples*" -not -name "go.mod" -not -name "go.sum" -not -name "staticcheck.conf" -not -name ".go-version" -not -name ".hashibot.hcl" -not -name "tools.go" -exec git rm {} \;
+ find . -type f -not -wholename "./.git*" -not -wholename "./.changelog*" -not -name ".travis.yml" -not -name ".golangci.yml" -not -name "CHANGELOG.md" -not -name "GNUmakefile" -not -name "docscheck.sh" -not -name "LICENSE" -not -name "README.md" -not -wholename "./examples*" -not -name "go.mod" -not -name "go.sum" -not -name "staticcheck.conf" -not -name ".go-version" -not -name ".hashibot.hcl" -not -name "tools.go" -exec git rm {} \;
+ go mod download
popd
fi
@@ -100,6 +101,11 @@ else
fi
pushd $LOCAL_PATH
+
+if [ "$REPO" == "terraform" ]; then
+ make generate
+fi
+
git config --local user.name "Modular Magician"
git config --local user.email "magic-modules@google.com"
git add .
diff --git a/.ci/containers/github-differ/generate_comment.sh b/.ci/containers/github-differ/generate_comment.sh
index af85696f37fa..af56b96c330c 100755
--- a/.ci/containers/github-differ/generate_comment.sh
+++ b/.ci/containers/github-differ/generate_comment.sh
@@ -22,7 +22,7 @@ TFC_SCRATCH_PATH=https://modular-magician:$GITHUB_TOKEN@github.com/modular-magic
TFC_LOCAL_PATH=$PWD/../tfc
TFOICS_SCRATCH_PATH=https://modular-magician:$GITHUB_TOKEN@github.com/modular-magician/docs-examples
TFOICS_LOCAL_PATH=$PWD/../tfoics
-ANSIBLE_SCRATCH_PATH=https://modular-magician:$GITHUB_TOKEN@github.com/modular-magician/ansible_collections_google
+ANSIBLE_SCRATCH_PATH=https://modular-magician:$GITHUB_TOKEN@github.com/modular-magician/google.cloud
ANSIBLE_LOCAL_PATH=$PWD/../ansible
INSPEC_SCRATCH_PATH=https://modular-magician:$GITHUB_TOKEN@github.com/modular-magician/inspec-gcp
INSPEC_LOCAL_PATH=$PWD/../inspec
@@ -59,7 +59,7 @@ pushd $ANSIBLE_LOCAL_PATH
git fetch origin $OLD_BRANCH
if ! git diff --exit-code origin/$OLD_BRANCH origin/$NEW_BRANCH; then
SUMMARY=`git diff origin/$OLD_BRANCH origin/$NEW_BRANCH --shortstat`
- DIFFS="${DIFFS}${NEWLINE}Ansible: [Diff](https://github.com/modular-magician/ansible_collections_google/compare/$OLD_BRANCH..$NEW_BRANCH) ($SUMMARY)"
+ DIFFS="${DIFFS}${NEWLINE}Ansible: [Diff](https://github.com/modular-magician/google.cloud/compare/$OLD_BRANCH..$NEW_BRANCH) ($SUMMARY)"
fi
popd
diff --git a/.ci/containers/go-ruby-python/Dockerfile b/.ci/containers/go-ruby-python/Dockerfile
deleted file mode 100644
index e71de141ca87..000000000000
--- a/.ci/containers/go-ruby-python/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM gcr.io/magic-modules/go-ruby:1.13.8-2.6.0-v2
-
-# Install python & python libraries.
-RUN apt-get update
-RUN apt-get install -y git
-RUN apt-get install -y rsync
-RUN apt-get install -y build-essential libbz2-dev libssl-dev libreadline-dev \
- libffi-dev libsqlite3-dev tk-dev
-RUN apt-get install -y libpng-dev libfreetype6-dev
-RUN apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
- libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
- xz-utils tk-dev libffi-dev liblzma-dev python-openssl
-RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
-ENV PATH="/root/.pyenv/bin:${PATH}"
-RUN eval "$(pyenv init -)"
-RUN eval "$(pyenv virtualenv-init -)"
-RUN pyenv install 3.6.8
-RUN pyenv install 2.7.13
-RUN pyenv rehash
-ENV PATH="/root/.pyenv/shims:${PATH}"
-RUN pyenv global 2.7.13 3.6.8
-RUN pip install beautifulsoup4 mistune
-RUN pip3 install black
-ENV LC_ALL=C.UTF-8
-ENV LANG=C.UTF-8
diff --git a/.ci/containers/go-ruby/Dockerfile b/.ci/containers/go-ruby/Dockerfile
deleted file mode 100644
index d458ed98c8ff..000000000000
--- a/.ci/containers/go-ruby/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-from golang:1.13-stretch as resource
-
-SHELL ["/bin/bash", "-c"]
-
-RUN go get golang.org/x/tools/cmd/goimports
-
-# Set up Github SSH cloning.
-RUN ssh-keyscan github.com >> /known_hosts
-RUN echo "UserKnownHostsFile /known_hosts" >> /etc/ssh/ssh_config
-
-ENV GOFLAGS "-mod=vendor"
-
-# Install Ruby from source.
-RUN apt-get update
-RUN apt-get install -y bzip2 libssl-dev libreadline-dev zlib1g-dev
-RUN git clone https://github.com/rbenv/rbenv.git /rbenv
-ENV PATH /rbenv/bin:/root/.rbenv/shims:$PATH
-
-ENV RUBY_VERSION 2.6.0
-ENV RUBYGEMS_VERSION 3.0.2
-ENV BUNDLER_VERSION 1.17.0
-
-RUN /rbenv/bin/rbenv init || true
-RUN eval "$(rbenv init -)"
-RUN mkdir -p "$(rbenv root)"/plugins
-RUN git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
-
-RUN rbenv install $RUBY_VERSION
-RUN rbenv global 2.6.0
-RUN rbenv rehash
-
-RUN gem update --system "$RUBYGEMS_VERSION"
-RUN gem install bundler --version "$BUNDLER_VERSION" --force
-
-ADD Gemfile Gemfile
-ADD Gemfile.lock Gemfile.lock
-RUN bundle install
-RUN rbenv rehash
diff --git a/.ci/containers/go-ruby/Gemfile b/.ci/containers/go-ruby/Gemfile
deleted file mode 100644
index 62dae70bdfb0..000000000000
--- a/.ci/containers/go-ruby/Gemfile
+++ /dev/null
@@ -1,15 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'activesupport'
-gem 'binding_of_caller'
-gem 'rake'
-
-group :test do
- gem 'mocha', '~> 1.3.0'
- gem 'rspec'
- gem 'rubocop', '>= 0.77.0'
-end
-
-group :pr_script do
- gem 'octokit'
-end
diff --git a/.ci/containers/go-ruby/Gemfile.lock b/.ci/containers/go-ruby/Gemfile.lock
deleted file mode 100644
index 59cb6be3aa0c..000000000000
--- a/.ci/containers/go-ruby/Gemfile.lock
+++ /dev/null
@@ -1,77 +0,0 @@
-GEM
- remote: https://rubygems.org/
- specs:
- activesupport (5.2.3)
- concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- addressable (2.5.2)
- public_suffix (>= 2.0.2, < 4.0)
- ast (2.4.0)
- binding_of_caller (0.8.0)
- debug_inspector (>= 0.0.1)
- concurrent-ruby (1.1.5)
- debug_inspector (0.0.3)
- diff-lcs (1.3)
- faraday (0.15.4)
- multipart-post (>= 1.2, < 3)
- i18n (1.6.0)
- concurrent-ruby (~> 1.0)
- jaro_winkler (1.5.4)
- metaclass (0.0.4)
- minitest (5.11.3)
- mocha (1.3.0)
- metaclass (~> 0.0.1)
- multipart-post (2.0.0)
- octokit (4.13.0)
- sawyer (~> 0.8.0, >= 0.5.3)
- parallel (1.19.1)
- parser (2.6.5.0)
- ast (~> 2.4.0)
- public_suffix (3.0.3)
- rainbow (3.0.0)
- rake (12.3.3)
- rspec (3.8.0)
- rspec-core (~> 3.8.0)
- rspec-expectations (~> 3.8.0)
- rspec-mocks (~> 3.8.0)
- rspec-core (3.8.0)
- rspec-support (~> 3.8.0)
- rspec-expectations (3.8.1)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-mocks (3.8.0)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-support (3.8.0)
- rubocop (0.77.0)
- jaro_winkler (~> 1.5.1)
- parallel (~> 1.10)
- parser (>= 2.6)
- rainbow (>= 2.2.2, < 4.0)
- ruby-progressbar (~> 1.7)
- unicode-display_width (>= 1.4.0, < 1.7)
- ruby-progressbar (1.10.1)
- sawyer (0.8.1)
- addressable (>= 2.3.5, < 2.6)
- faraday (~> 0.8, < 1.0)
- thread_safe (0.3.6)
- tzinfo (1.2.5)
- thread_safe (~> 0.1)
- unicode-display_width (1.6.0)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- activesupport
- binding_of_caller
- mocha (~> 1.3.0)
- octokit
- rake
- rspec
- rubocop (>= 0.77.0)
-
-BUNDLED WITH
- 1.17.2
diff --git a/.ci/containers/hub/Dockerfile b/.ci/containers/hub/Dockerfile
deleted file mode 100644
index 6b126b0ef11c..000000000000
--- a/.ci/containers/hub/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-from gcr.io/magic-modules/go-ruby-python:1.11.5-2.6.0-2.7-v6
-
-RUN apt-get update
-RUN apt-get install -y ca-certificates
-RUN apt-get install -y jq
-RUN go get github.com/github/hub
diff --git a/.ci/containers/merged-prs-resource/Dockerfile b/.ci/containers/merged-prs-resource/Dockerfile
deleted file mode 100644
index 70052b9ed26c..000000000000
--- a/.ci/containers/merged-prs-resource/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM gcr.io/magic-modules/python
-ADD get_downstream_prs.py /opt/resource/get_downstream_prs.py
-ADD in.py /opt/resource/in
-ADD check.py /opt/resource/check
diff --git a/.ci/containers/merged-prs-resource/check.py b/.ci/containers/merged-prs-resource/check.py
deleted file mode 100755
index 32e4c2ec9429..000000000000
--- a/.ci/containers/merged-prs-resource/check.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /usr/local/bin/python
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from absl import app
-import json
-import collections
-import sys
-import get_downstream_prs
-import re
-import itertools
-import operator
-from github import Github
-
-def main(argv):
- in_json = json.load(sys.stdin)
- out_version = {}
- g = Github(in_json['source']['token'])
- open_pulls = g.get_repo(in_json['source']['repo']).get_pulls(state='open')
- # For each open pull request, get all the dependencies.
- depends = itertools.chain.from_iterable(
- [get_downstream_prs.get_github_dependencies(g, open_pull.number)
- for open_pull in open_pulls])
- # for each dependency, generate a tuple - (repo, pr_number)
- parsed_dependencies = [re.match(r'https://github.com/([\w-]+/[\w-]+)/pull/(\d+)', d).groups()
- for d in depends]
- parsed_dependencies.sort(key=operator.itemgetter(0))
- # group those dependencies by repo - e.g. [("terraform-provider-google", ["123", "456"]), ...]
- for r, pulls in itertools.groupby(parsed_dependencies, key=operator.itemgetter(0)):
- repo = g.get_repo(r)
- out_version[r] = []
- for pull in pulls:
- # check whether the PR is merged - if it is, add it to the version.
- pr = repo.get_pull(int(pull[1]))
- if pr.is_merged():
- out_version[r].append(pull[1])
- for k, v in out_version.iteritems():
- out_version[k] = ','.join(v)
- print(json.dumps([out_version]))
- # version dict:
- # {
- # "terraform-providers/terraform-provider-google": "1514,1931",
- # "terraform-providers/terraform-provider-google-beta": "121,220",
- # "modular-magician/ansible": "",
- # }
-
-if __name__ == '__main__':
- app.run(main)
-
diff --git a/.ci/containers/merged-prs-resource/get_downstream_prs.py b/.ci/containers/merged-prs-resource/get_downstream_prs.py
deleted file mode 100644
index d183323efd3f..000000000000
--- a/.ci/containers/merged-prs-resource/get_downstream_prs.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-import functools
-import os
-import re
-import sys
-from github import Github
-
-def append_github_dependencies_to_list(lst, comment_body):
- list_of_urls = re.findall(r'^depends: (https://github.com/.*)', comment_body, re.MULTILINE)
- return lst + list_of_urls
-
-def get_github_dependencies(g, pr_number):
- pull_request = g.get_repo('GoogleCloudPlatform/magic-modules').get_pull(pr_number)
- comment_bodies = [c.body for c in pull_request.get_issue_comments()]
- # "reduce" is "foldl" - apply this function to the result of the previous function and
- # the next value in the iterable.
- return functools.reduce(append_github_dependencies_to_list, comment_bodies, [])
-
-if __name__ == '__main__':
- g = Github(os.environ.get('GH_TOKEN'))
- assert len(sys.argv) == 2
- for downstream_pr in get_github_dependencies(g, int(sys.argv[1])):
- print downstream_pr
diff --git a/.ci/containers/merged-prs-resource/in.py b/.ci/containers/merged-prs-resource/in.py
deleted file mode 100755
index 9696a24ddd61..000000000000
--- a/.ci/containers/merged-prs-resource/in.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#! /usr/local/bin/python
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from absl import app
-import json
-import sys
-import os
-from github import Github
-import urllib
-
-def main(argv):
- in_json = json.load(sys.stdin)
- g = Github(in_json['source']['token'])
- version = in_json.get('version', {})
- for repo_name, pr_numbers in version.iteritems():
- repo = g.get_repo(repo_name)
- if not pr_numbers: continue
- for pr_number in pr_numbers.split(','):
- download_location = os.path.join(argv[1], repo_name, pr_number + '.patch')
- if not os.path.exists(os.path.dirname(download_location)):
- os.makedirs(os.path.dirname(download_location))
- pr = repo.get_pull(int(pr_number))
- urllib.urlretrieve(pr.patch_url, download_location)
- print(json.dumps({"version": version}))
-
-if __name__ == '__main__':
- app.run(main)
diff --git a/.ci/containers/python/Dockerfile b/.ci/containers/python/Dockerfile
deleted file mode 100644
index 47e9a6222079..000000000000
--- a/.ci/containers/python/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-from python:2.7-stretch
-
-run pip install pygithub
-run pip install absl-py
-run pip install autopep8
-run pip install beautifulsoup4 mistune
-
-# Set up Github SSH cloning.
-RUN ssh-keyscan github.com >> /known_hosts
-RUN echo "UserKnownHostsFile /known_hosts" >> /etc/ssh/ssh_config
diff --git a/.ci/containers/terraform-gcloud-inspec/Dockerfile b/.ci/containers/terraform-gcloud-inspec/Dockerfile
deleted file mode 100644
index 7a74876cf0c3..000000000000
--- a/.ci/containers/terraform-gcloud-inspec/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM gcr.io/magic-modules/go-ruby-python:1.11.5-2.6.0-2.7-v6
-
-RUN apt-get install unzip
-RUN curl https://releases.hashicorp.com/terraform/0.12.16/terraform_0.12.16_linux_amd64.zip > terraform_0.12.16_linux_amd64.zip
-RUN unzip terraform_0.12.16_linux_amd64.zip -d /usr/bin
-# Install google cloud sdk
-RUN echo "deb http://packages.cloud.google.com/apt cloud-sdk-stretch main" >> /etc/apt/sources.list.d/google-cloud-sdk.list
-RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
-RUN apt-get update && apt-get install google-cloud-sdk -y
-
-ADD Gemfile Gemfile
-RUN bundle install
diff --git a/.ci/containers/terraform-gcloud-inspec/Gemfile b/.ci/containers/terraform-gcloud-inspec/Gemfile
deleted file mode 100644
index ca69894908b5..000000000000
--- a/.ci/containers/terraform-gcloud-inspec/Gemfile
+++ /dev/null
@@ -1,17 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'bundle'
-gem 'google-api-client'
-gem 'google-cloud'
-gem 'googleauth'
-gem 'inifile'
-gem 'inspec-bin'
-gem 'rubocop', '>= 0.77.0'
-
-group :development do
- gem 'github_changelog_generator'
- gem 'pry-coolline'
- gem 'rake'
- gem 'vcr'
- gem 'webmock'
-end
\ No newline at end of file
diff --git a/.ci/containers/terraform-vcr-tester/Dockerfile b/.ci/containers/terraform-vcr-tester/Dockerfile
new file mode 100644
index 000000000000..1f50d1666fd9
--- /dev/null
+++ b/.ci/containers/terraform-vcr-tester/Dockerfile
@@ -0,0 +1,9 @@
+FROM alpine
+
+RUN apk add --no-cache bash
+RUN apk add --no-cache curl
+RUN apk add --no-cache jq
+
+ADD teamcityparams.xml /teamcityparams.xml
+ADD vcr_test_terraform.sh /vcr_test_terraform.sh
+ENTRYPOINT ["/vcr_test_terraform.sh"]
diff --git a/.ci/containers/terraform-vcr-tester/teamcityparams.xml b/.ci/containers/terraform-vcr-tester/teamcityparams.xml
new file mode 100644
index 000000000000..0b6415b3f913
--- /dev/null
+++ b/.ci/containers/terraform-vcr-tester/teamcityparams.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+ Magician triggered PR
+
\ No newline at end of file
diff --git a/.ci/containers/terraform-vcr-tester/vcr_test_terraform.sh b/.ci/containers/terraform-vcr-tester/vcr_test_terraform.sh
new file mode 100755
index 000000000000..a74e16f77d25
--- /dev/null
+++ b/.ci/containers/terraform-vcr-tester/vcr_test_terraform.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+set -e
+
+PR_NUMBER=$1
+
+sed -i 's/{{PR_NUMBER}}/'"$PR_NUMBER"'/g' /teamcityparams.xml
+curl --header "Accept: application/json" --header "Authorization: Bearer $TEAMCITY_TOKEN" https://ci-oss.hashicorp.engineering/app/rest/buildQueue --request POST --header "Content-Type:application/xml" --data-binary @/teamcityparams.xml -o build.json
+
+# Dont crash here if the curl failed due to authorization
+# TODO(slevenick): remove this once this all is stable
+set +e
+URL=echo $(cat build.json | jq .webUrl)
+ret=$?
+if [ $ret -ne 0 ]; then
+ echo "Auth failed"
+else
+ comment="I have triggered VCR tests based on this PR's diffs. See the results here: $URL"
+
+ curl -H "Authorization: token ${GITHUB_TOKEN}" \
+ -d "$(jq -r --arg comment "$comment" -n "{body: \$comment}")" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/${PR_NUMBER}/comments"
+fi
\ No newline at end of file
diff --git a/.ci/containers/vcr-cassette-merger/Dockerfile b/.ci/containers/vcr-cassette-merger/Dockerfile
new file mode 100644
index 000000000000..83cfea1d3ef9
--- /dev/null
+++ b/.ci/containers/vcr-cassette-merger/Dockerfile
@@ -0,0 +1,8 @@
+from gcr.io/google.com/cloudsdktool/cloud-sdk:alpine as resource
+
+RUN apk add --no-cache bash
+RUN apk add --no-cache curl
+RUN apk add --no-cache jq
+
+ADD vcr_merge.sh /vcr_merge.sh
+ENTRYPOINT ["/vcr_merge.sh"]
diff --git a/.ci/containers/vcr-cassette-merger/vcr_merge.sh b/.ci/containers/vcr-cassette-merger/vcr_merge.sh
new file mode 100755
index 000000000000..e0077864f5c4
--- /dev/null
+++ b/.ci/containers/vcr-cassette-merger/vcr_merge.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+REFERENCE=$1
+
+PR_NUMBER=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
+ "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls?state=closed&base=master&sort=updated&direction=desc" | \
+ jq -r ".[] | if .merge_commit_sha == \"$REFERENCE\" then .number else empty end")
+
+set +e
+gsutil ls gs://vcr-$GOOGLE_PROJECT/auto-pr-$PR_NUMBER/fixtures/
+if [ $? -eq 0 ]; then
+ # We have recorded new cassettes for this branch
+ gsutil -m cp gs://vcr-$GOOGLE_PROJECT/refs/heads/auto-pr-$PR_NUMBER/fixtures/* gs://vcr-$GOOGLE_PROJECT/fixtures/
+ gsutil -m rm -r gs://vcr-$GOOGLE_PROJECT/refs/heads/auto-pr-$PR_NUMBER/
+fi
+set -e
diff --git a/.ci/gcb-generate-diffs.yml b/.ci/gcb-generate-diffs.yml
index b071f5171e3d..6e5e35c32106 100644
--- a/.ci/gcb-generate-diffs.yml
+++ b/.ci/gcb-generate-diffs.yml
@@ -1,5 +1,10 @@
---
steps:
+ - name: 'gcr.io/graphite-docker-images/contributor-checker'
+ secretEnv: ["GITHUB_TOKEN"]
+ args:
+ - $_PR_NUMBER
+
# The GCB / GH integration doesn't satisfy our use case perfectly.
# It doesn't check out the merge commit, and it doesn't check out the repo
# itself - it only gives us the actual code, not the repo. So we need
@@ -174,30 +179,45 @@ steps:
args:
- $_PR_NUMBER
- - name: 'gcr.io/graphite-docker-images/changelog-checker'
+ - name: 'gcr.io/graphite-docker-images/terraform-tester'
+ id: tpgb-test
secretEnv: ["GITHUB_TOKEN"]
waitFor: ["diff"]
args:
+ - 'beta'
- $_PR_NUMBER
- name: 'gcr.io/graphite-docker-images/terraform-tester'
+ id: tpg-test
secretEnv: ["GITHUB_TOKEN"]
waitFor: ["diff"]
args:
- - 'beta'
+ - 'ga'
- $_PR_NUMBER
- - name: 'gcr.io/graphite-docker-images/terraform-tester'
- secretEnv: ["GITHUB_TOKEN"]
+ - name: 'gcr.io/graphite-docker-images/terraform-vcr-tester'
+ id: tpg-vcr-test
+ secretEnv: ["TEAMCITY_TOKEN", "GITHUB_TOKEN"]
waitFor: ["diff"]
+ timeout: 1800s
args:
- - 'ga'
- $_PR_NUMBER
+ - name: 'gcr.io/graphite-docker-images/changelog-checker'
+ secretEnv: ["GITHUB_TOKEN"]
+ waitFor: ["tpg-test", "tpgb-test"]
+ args:
+ - $_PR_NUMBER
+
+# Long timeout to enable waiting on VCR test
+timeout: 2400s
options:
machineType: 'N1_HIGHCPU_32'
secrets:
- kmsKeyName: projects/graphite-docker-images/locations/global/keyRings/token-keyring/cryptoKeys/github-token
secretEnv:
- GITHUB_TOKEN: CiQADkR4NnCVXo1OLSWFuPX7eSiifaOfQVzSYmKi2jZdVbKlfYMSUQBfF82vNAgpvSVyhzM8JsQaP6Oky0SAdoR5fPED5cU3qxsCB9wArmdGcgQoRzP7S6jEWHRcvxv/xauznjkJQMWCORzcbUbk6T7k80bdo2mpqw==
+ GITHUB_TOKEN: CiQADkR4Nt6nHLI52Kc1W55OwpLdc4vjBfVR0SGQNzm6VSVj9lUSUQBfF82vVhn43A1jNYOv8ScoWgrZONwNrUabHfGjkvl+IZxcii0JlOVUawbscs4OJga0eitNNlagAOruLs6C926X20ZZPqWtH97ui6CKNvxgkQ==
+ - kmsKeyName: projects/graphite-docker-images/locations/global/keyRings/token-keyring/cryptoKeys/teamcity-token
+ secretEnv:
+ TEAMCITY_TOKEN: CiQAth83aSgKrb5ASI5XwE+yv62KbNtNG+O9gKXJzoflm65H7fESkwEASc1NF0oM3pHb5cUBAHcXZqFjEJrF4eGowPycUpKDmEncuQQSkm8v+dswSNXTXnX2C/reLpw9uGTw7G+K1kqA0sVrzYG3sTdDf/IcS//uloAerUff2wVIlV5rxV357PMkBl5dGyybnKMybgrXGl+CcW9PDLAwqfELWrr5zTSHy799dAhJZi1Wb5KbImmvvU5Z46g=
diff --git a/.ci/gcb-push-downstream.yml b/.ci/gcb-push-downstream.yml
index 6d870a1865b4..6d76c3197ed2 100644
--- a/.ci/gcb-push-downstream.yml
+++ b/.ci/gcb-push-downstream.yml
@@ -192,6 +192,12 @@ steps:
- -c
- git push https://modular-magician:$$GITHUB_TOKEN@github.com/GoogleCloudPlatform/magic-modules $COMMIT_SHA:inspec-sync
+ - name: 'gcr.io/graphite-docker-images/vcr-cassette-merger'
+ secretEnv: ["GITHUB_TOKEN", "GOOGLE_PROJECT"]
+ waitFor: ["tpg-push"]
+ args:
+ - $COMMIT_SHA
+
# set extremely long 1 day timeout, in order to ensure that any jams / backlogs can be cleared.
timeout: 86400s
options:
@@ -201,4 +207,7 @@ options:
secrets:
- kmsKeyName: projects/graphite-docker-images/locations/global/keyRings/token-keyring/cryptoKeys/github-token
secretEnv:
- GITHUB_TOKEN: CiQADkR4NnCVXo1OLSWFuPX7eSiifaOfQVzSYmKi2jZdVbKlfYMSUQBfF82vNAgpvSVyhzM8JsQaP6Oky0SAdoR5fPED5cU3qxsCB9wArmdGcgQoRzP7S6jEWHRcvxv/xauznjkJQMWCORzcbUbk6T7k80bdo2mpqw==
+ GITHUB_TOKEN: CiQADkR4Nt6nHLI52Kc1W55OwpLdc4vjBfVR0SGQNzm6VSVj9lUSUQBfF82vVhn43A1jNYOv8ScoWgrZONwNrUabHfGjkvl+IZxcii0JlOVUawbscs4OJga0eitNNlagAOruLs6C926X20ZZPqWtH97ui6CKNvxgkQ==
+ - kmsKeyName: projects/graphite-docker-images/locations/global/keyRings/environment-keyring/cryptoKeys/ci-project-key
+ secretEnv:
+ GOOGLE_PROJECT: CiQAis6xrDDU4Wcxn5s8Y790IMxTUEe2d3SaYEXUGScHfaLjOw8SPwDOc1nLe6Yz0zzA0mcYTsXaeGSFYu7uQ5+QCtTProJWRv2ITrNwCS3AF/kvMCrHvltx7O1CZnJveutlVpZH3w==
diff --git a/.ci/magic-modules/branch-magic-modules.sh b/.ci/magic-modules/branch-magic-modules.sh
deleted file mode 100755
index 61530090444a..000000000000
--- a/.ci/magic-modules/branch-magic-modules.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#! /bin/bash
-set -e
-set -x
-
-pushd "magic-modules"
-export GH_TOKEN
-if PR_ID=$(git config --get pullrequest.id) &&
- [ -z "$USE_SHA" ] &&
- DEPS=$(python ./.ci/magic-modules/get_downstream_prs.py "$PR_ID") &&
- [ -z "$DEPS" ]; then
- BRANCH="codegen-pr-$(git config --get pullrequest.id)"
-else
- BRANCH="codegen-sha-$(git rev-parse --short HEAD)"
-fi
-git checkout -B "$BRANCH"
-# ./branchname is intentionally never committed - it isn't necessary once
-# this output is no longer available.
-echo "$BRANCH" > ./branchname
-
-set +x
-# Don't show the credential in the output.
-echo "$CREDS" > ~/github_private_key
-set -x
-chmod 400 ~/github_private_key
-
-# Update to head on master on all submodules, so we avoid spurious diffs.
-# Note: $ALL_SUBMODULES will be re-split by the ssh-agent's "bash".
-ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init $ALL_SUBMODULES"
-
-cp -r ./ ../magic-modules-branched/
-
-if [ "true" == "$INCLUDE_PREVIOUS" ] ; then
- # Since this is fetched after a merge commit, HEAD~ is
- # the newest commit on the branch being merged into.
- git reset --hard HEAD~
- BRANCH="$BRANCH-previous"
- git checkout -B "$BRANCH"
- # ./branchname is intentionally never committed - it isn't necessary once
- # this output is no longer available.
- echo "$BRANCH" > ./branchname
- ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init $ALL_SUBMODULES"
- cp -r ./ ../magic-modules-previous/
-fi
diff --git a/.ci/magic-modules/branch.yml b/.ci/magic-modules/branch.yml
deleted file mode 100644
index 4bf6450772c7..000000000000
--- a/.ci/magic-modules/branch.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-# This file takes one input: magic-modules in detached-HEAD state.
-# It spits out "magic-modules-branched", a magic-modules repo on a new branch (named
-# after the HEAD commit on the PR).
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # This task requires a container with 'git', 'python', and the pip
- # package 'pygithub'.
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: magic-modules
-
-outputs:
- - name: magic-modules-branched
- - name: magic-modules-previous
-
-params:
- USE_SHA: ""
- GH_TOKEN: ""
- CREDS: ""
- ALL_SUBMODULES: ""
- INCLUDE_PREVIOUS: ""
-
-run:
- path: magic-modules/.ci/magic-modules/branch-magic-modules.sh
diff --git a/.ci/magic-modules/coverage-spreadsheet-upload.sh b/.ci/magic-modules/coverage-spreadsheet-upload.sh
deleted file mode 100755
index d67ee2e53044..000000000000
--- a/.ci/magic-modules/coverage-spreadsheet-upload.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${SERVICE_ACCOUNT}" > /tmp/google-account.json
-set -x
-
-gcloud auth activate-service-account magic-modules-spreadsheet@magic-modules.iam.gserviceaccount.com --key-file=$GOOGLE_CLOUD_KEYFILE_JSON
-
-pushd magic-modules-gcp
-bundle install
-gem install rspec
-
-# || true will suppress errors, but it's necessary for this to run. If unset,
-# Concourse will fail on *any* rspec step failing (eg: any API mismatch)
-bundle exec rspec tools/linter/spreadsheet.rb || true
-
-echo "File created"
-date=$(date +'%m%d%Y')
-echo "Date established"
-
-gsutil cp output.csv gs://magic-modules-coverage/$date.csv
-popd
diff --git a/.ci/magic-modules/coverage-spreadsheet-upload.yml b/.ci/magic-modules/coverage-spreadsheet-upload.yml
deleted file mode 100644
index 46bf98413ccb..000000000000
--- a/.ci/magic-modules/coverage-spreadsheet-upload.yml
+++ /dev/null
@@ -1,15 +0,0 @@
----
-platform: linux
-
-image_resource:
-# This image has gcloud, which we need for uploading coverage file to a bucket.
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-
-inputs:
- - name: magic-modules-gcp
-
-run:
- path: magic-modules-gcp/.ci/magic-modules/coverage-spreadsheet-upload.sh
diff --git a/.ci/magic-modules/create-diff-message.sh b/.ci/magic-modules/create-diff-message.sh
deleted file mode 100755
index 75ba4275f77b..000000000000
--- a/.ci/magic-modules/create-diff-message.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/bash
-
-pushd magic-modules-branched
-
-BRANCH_NAME=$(cat branchname)
-{
- echo "## 3.0.0 diff report as of $(git rev-parse HEAD^2)";
- echo "[TPG Diff](https://github.com/modular-magician/terraform-provider-google/compare/$BRANCH_NAME-previous..$BRANCH_NAME)";
- echo "[TPGB Diff](https://github.com/modular-magician/terraform-provider-google-beta/compare/$BRANCH_NAME-previous..$BRANCH_NAME)";
- echo "[Mapper Diff](https://github.com/modular-magician/terraform-google-conversion/compare/$BRANCH_NAME-previous..$BRANCH_NAME)";
-} > ../message/message.txt
diff --git a/.ci/magic-modules/create-diff-message.yml b/.ci/magic-modules/create-diff-message.yml
deleted file mode 100644
index 1545d789e7be..000000000000
--- a/.ci/magic-modules/create-diff-message.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # This task requires a container with 'git', 'python', and the pip
- # package 'pygithub'.
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: magic-modules-branched
-
-outputs:
- - name: message
-
-run:
- path: magic-modules-branched/.ci/magic-modules/create-diff-message.sh
diff --git a/.ci/magic-modules/create-pr.sh b/.ci/magic-modules/create-pr.sh
deleted file mode 100755
index 8aefacfdcda3..000000000000
--- a/.ci/magic-modules/create-pr.sh
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/bash
-
-# This script configures the git submodule under magic-modules so that it is
-# ready to create a new pull request. It is cloned in a detached-head state,
-# but its branch is relevant to the PR creation process, so we want to make
-# sure that it's on a branch, and most importantly that that branch tracks
-# a branch upstream.
-
-set -e
-set -x
-
-shopt -s dotglob
-cp -r magic-modules/* magic-modules-with-comment
-
-PR_ID="$(cat ./mm-initial-pr/.git/id)"
-ORIGINAL_PR_BRANCH="codegen-pr-$PR_ID"
-set +e
-ORIGINAL_PR_USER=$(curl "https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/$PR_ID" | jq -r ".user.login")
-set -e
-pushd magic-modules-with-comment
-echo "$ORIGINAL_PR_BRANCH" > ./original_pr_branch_name
-
-# Check out the magic-modules branch with the same name as the current tracked
-# branch of the terraform submodule. All the submodules will be on the the same
-# branch name - we pick terraform because it's the first one the magician supported.
-BRANCH_NAME="$(git config -f .gitmodules --get submodule.build/terraform.branch)"
-IFS="," read -ra TERRAFORM_VERSIONS <<< "$TERRAFORM_VERSIONS"
-
-git checkout -b "$BRANCH_NAME"
-NEWLINE=$'\n'
-MESSAGE="Hi! I'm the modular magician, I work on Magic Modules.$NEWLINE"
-LAST_USER_COMMIT="$(git rev-parse HEAD~1^2)"
-
-if [ "$BRANCH_NAME" = "$ORIGINAL_PR_BRANCH" ]; then
- MESSAGE="${MESSAGE}This PR seems not to have generated downstream PRs before, as of $LAST_USER_COMMIT. "
-else
- MESSAGE="${MESSAGE}I see that this PR has already had some downstream PRs generated. "
- MESSAGE="${MESSAGE}Any open downstreams are already updated to your most recent commit, $LAST_USER_COMMIT. "
-fi
-
-MESSAGE="${MESSAGE}${NEWLINE}## Pull request statuses"
-DEPENDENCIES=""
-LABELS=""
-# There is no existing PR - this is the first pass through the pipeline and
-# we will need to create a PR using 'hub'.
-
-# Check the files between this commit and HEAD
-# If they're only contained in third_party, add the third_party label.
-if [ -z "$(git diff --name-only HEAD^1 | grep -v "third_party" | grep -v ".gitmodules" | grep -r "build/")" ]; then
- LABELS="${LABELS}only_third_party,"
-fi
-
-VALIDATOR_WARN_FILES="$(git show --name-only "${LAST_USER_COMMIT}" | grep -v ".gitmodules" | grep -v "build/" | grep -Ff '.ci/magic-modules/vars/validator_handwritten_files.txt' | sed 's/^/* /')"
-if [ -n "${VALIDATOR_WARN_FILES}" ]; then
- MESSAGE="${MESSAGE}${NEWLINE}**WARNING**: The following files changed in commit ${LAST_USER_COMMIT} may need corresponding changes in third_party/validator:"
- MESSAGE="${MESSAGE}${NEWLINE}${VALIDATOR_WARN_FILES}${NEWLINE}"
-fi
-
-# Terraform
-if [ -n "$TERRAFORM_VERSIONS" ]; then
- for VERSION in "${TERRAFORM_VERSIONS[@]}"; do
- IFS=":" read -ra TERRAFORM_DATA <<< "$VERSION"
- PROVIDER_NAME="${TERRAFORM_DATA[0]}"
- SUBMODULE_DIR="${TERRAFORM_DATA[1]}"
- TERRAFORM_REPO_USER="${TERRAFORM_DATA[2]}"
-
- pushd "build/$SUBMODULE_DIR"
-
- git log -1 --pretty=%s > ./downstream_body
- echo "" >> ./downstream_body
- echo "" >> ./downstream_body
- if [ -n "$ORIGINAL_PR_USER" ]; then
- echo "Original Author: @$ORIGINAL_PR_USER" >> ./downstream_body
- fi
-
- git checkout -b "$BRANCH_NAME"
- if hub pull-request -b "$TERRAFORM_REPO_USER/$PROVIDER_NAME:master" -h "$ORIGINAL_PR_BRANCH" -F ./downstream_body > ./tf_pr 2> ./tf_pr_err ; then
- DEPENDENCIES="${DEPENDENCIES}depends: $(cat ./tf_pr) ${NEWLINE}"
- LABELS="${LABELS}${PROVIDER_NAME},"
- else
- echo "$SUBMODULE_DIR - did not generate a PR."
- if grep "No commits between" ./tf_pr_err; then
- echo "There were no diffs in $SUBMODULE_DIR."
- MESSAGE="$MESSAGE${NEWLINE}No diff detected in $PROVIDER_NAME."
- elif grep "A pull request already exists" ./tf_pr_err; then
- echo "Already have a PR for $SUBMODULE_DIR."
- MESSAGE="$MESSAGE${NEWLINE}$PROVIDER_NAME already has an open PR."
- fi
-
- fi
- popd
- done
-fi
-
-if [ -n "$ANSIBLE_REPO_USER" ]; then
- pushd build/ansible
-
- git log -1 --pretty=%s > ./downstream_body
- echo "" >> ./downstream_body
- echo "" >> ./downstream_body
- if [ -n "$ORIGINAL_PR_USER" ]; then
- echo "/cc @$ORIGINAL_PR_USER" >> ./downstream_body
- fi
-
- git checkout -b "$BRANCH_NAME"
- if hub pull-request -b "$ANSIBLE_REPO_USER/ansible_collections_google:master" -h "$ORIGINAL_PR_BRANCH" -F ./downstream_body > ./ansible_pr 2> ./ansible_pr_err ; then
- DEPENDENCIES="${DEPENDENCIES}depends: $(cat ./ansible_pr) ${NEWLINE}"
- LABELS="${LABELS}ansible,"
- else
- echo "Ansible - did not generate a PR."
- if grep "No commits between" ./ansible_pr_err; then
- echo "There were no diffs in Ansible."
- MESSAGE="$MESSAGE${NEWLINE}No diff detected in Ansible."
- elif grep "A pull request already exists" ./ansible_pr_err; then
- MESSAGE="$MESSAGE${NEWLINE}Ansible already has an open PR."
- fi
- fi
- popd
-
- pwd
-
- # If there is now a difference in the ansible_version_added files, those
- # should be pushed back up to the user's MM branch to be reviewed.
- if git diff --name-only HEAD^1 | grep "ansible_version_added.yaml"; then
- # Setup git config.
- git config --global user.email "magic-modules@google.com"
- git config --global user.name "Modular Magician"
-
- BRANCH=$(git config --get pullrequest.branch)
- REPO=$(git config --get pullrequest.repo)
- # Add user's branch + get latest copy.
- git remote add non-gcp-push-target "git@github.com:$REPO"
- git fetch non-gcp-push-target $BRANCH
-
- # Make a commit to the current branch and track that commit's SHA1.
- git add products/**/ansible_version_added.yaml
- git commit -m "Ansible version_added changes"
- CHERRY_PICKED_COMMIT=$(git rev-parse HEAD)
-
- # Checkout the user's branch + add the new cherry-picked commit.
- git checkout non-gcp-push-target/$BRANCH
- git cherry-pick $CHERRY_PICKED_COMMIT
-
- # Create commit + push (no force flag to avoid overwrites).
- # If the push doesn't work, it's not problematic because a commit
- # down the line will pick up the changes.
- ssh-agent bash -c "ssh-add ~/github_private_key; git push non-gcp-push-target \"HEAD:$BRANCH\"" || true
-
- # Check out the branch we were on to ensure that the downstream commits don't change.
- git checkout $CHERRY_PICKED_COMMIT
- fi
-fi
-
- if [ -n "$INSPEC_REPO_USER" ]; then
- pushd build/inspec
-
- git log -1 --pretty=%s > ./downstream_body
- echo "" >> ./downstream_body
- echo "" >> ./downstream_body
- if [ -n "$ORIGINAL_PR_USER" ]; then
- echo "/cc @$ORIGINAL_PR_USER" >> ./downstream_body
- fi
-
- git checkout -b "$BRANCH_NAME"
- if hub pull-request -b "$INSPEC_REPO_USER/inspec-gcp:master" -h "$ORIGINAL_PR_BRANCH" -F ./downstream_body > ./inspec_pr 2> ./inspec_pr_err ; then
- DEPENDENCIES="${DEPENDENCIES}depends: $(cat ./inspec_pr) ${NEWLINE}"
- LABELS="${LABELS}inspec,"
- else
- echo "InSpec - did not generate a PR."
- if grep "No commits between" ./inspec_pr_err; then
- echo "There were no diffs in Inspec."
- MESSAGE="$MESSAGE${NEWLINE}No diff detected in Inspec."
- elif grep "A pull request already exists" ./inspec_pr_err; then
- MESSAGE="$MESSAGE${NEWLINE}InSpec already has an open PR."
- fi
- fi
- popd
-fi
-
-MESSAGE="${MESSAGE}${NEWLINE}## New Pull Requests"
-
-# Create PR comment with the list of dependencies.
-if [ -z "$DEPENDENCIES" ]; then
- MESSAGE="${MESSAGE}${NEWLINE}I didn't open any new pull requests because of this PR."
-else
- MESSAGE="${MESSAGE}${NEWLINE}I built this PR into one or more new PRs on other repositories, "
- MESSAGE="${MESSAGE}and when those are closed, this PR will also be merged and closed."
- MESSAGE="${MESSAGE}${NEWLINE}${DEPENDENCIES}"
-fi
-
-echo "$MESSAGE" > ./pr_comment
-
-# Create Labels list with the comma-separated list of labels for this PR
-if [ -z "$LABELS" ]; then
- touch ./label_file
-else
- printf "%s" "$LABELS" > ./label_file
-fi
diff --git a/.ci/magic-modules/create-pr.yml b/.ci/magic-modules/create-pr.yml
deleted file mode 100644
index 63ef789cdcd9..000000000000
--- a/.ci/magic-modules/create-pr.yml
+++ /dev/null
@@ -1,27 +0,0 @@
----
-# This takes in the magic-modules repo in detached-HEAD state,
-# creates a PR on downstream modules, and writes a comment into
-# a file so that the PR can be updated with that comment.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/hub
- tag: '1.0'
-
-inputs:
- - name: magic-modules
- - name: mm-initial-pr
-
-outputs:
- - name: magic-modules-with-comment
-
-run:
- path: magic-modules/.ci/magic-modules/create-pr.sh
-
-params:
- GITHUB_TOKEN: ""
- ANSIBLE_REPO_USER: ""
- INSPEC_REPO_USER: ""
- TERRAFORM_VERSIONS: ""
diff --git a/.ci/magic-modules/diff-terraform.sh b/.ci/magic-modules/diff-terraform.sh
deleted file mode 100755
index 596ea881a016..000000000000
--- a/.ci/magic-modules/diff-terraform.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/bash
-
-# The vast majority of this file is a direct copy of generate-terraform.sh. We could factor out all that
-# code into a shared library, but I don't think we need to do that. This is an inherently temporary file,
-# until TPG 3.0.0 is released, which is in the relatively near future. The cost of the copy is that
-# we need to maintain both files - but the last change to that file was several months ago and I expect
-# we're looking at 1 - 2 changes that need to be made in both places. The cost of not copying it is
-# an extra few hours of work now, and some minor readability issues.
-
-set -x
-set -e
-source "$(dirname "$0")/helpers.sh"
-
-# Create $GOPATH structure - in order to successfully run Terraform codegen, we need to run
-# it with a correctly-set-up $GOPATH. It calls out to `goimports`, which means that
-# we need to have all the dependencies correctly downloaded.
-export GOPATH="${PWD}/go"
-mkdir -p "${GOPATH}/src/github.com/$GITHUB_ORG"
-
-for mm_dir in magic-modules-branched magic-modules-previous; do
-
- pushd $mm_dir
- # delete the symlink if it exists
- rm "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME" || true
- ln -s "${PWD}/build/$SHORT_NAME/" "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME"
- popd
-
- pushd "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME"
-
- # Other orgs are not fully-generated. This may be transitional - if this causes pain,
- # try vendoring into third-party, as with TPG and TPGB.
- if [ "$GITHUB_ORG" = "terraform-providers" ]; then
- # This line removes every file which is not specified here.
- # If you add files to Terraform which are not generated, you have to add them here.
- # It uses the somewhat obtuse 'find' command. To explain:
- # "find .": all files and directories recursively under the current directory, subject to matchers.
- # "-type f": all regular real files, i.e. not directories.
- # "-not": do the opposite of the next thing, always used with another matcher.
- # "-wholename": entire relative path - including directory names - matches following wildcard.
- # "-name": filename alone matches following string. e.g. -name README.md matches ./README.md *and* ./foo/bar/README.md
- # "-exec": for each file found, execute the command following until the literal ';'
- find . -type f -not -wholename "./.git*" -not -wholename "./vendor*" -not -name ".travis.yml" -not -name ".golangci.yml" -not -name "CHANGELOG.md" -not -name GNUmakefile -not -name LICENSE -not -name README.md -not -wholename "./examples*" -not -name "go.mod" -not -name "go.sum" -not -name "staticcheck.conf" -not -name ".hashibot.hcl" -exec git rm {} \;
- fi
-
- popd
-
- pushd $mm_dir
-
- # Choose the author of the most recent commit as the downstream author
- # Note that we don't use the last submitted commit, we use the primary GH email
- # of the GH PR submitted. If they've enabled a private email, we'll actually
- # use their GH noreply email which isn't compatible with CLAs.
- COMMIT_AUTHOR="$(git log --pretty="%an <%ae>" -n1 HEAD)"
-
- if [ -n "$OVERRIDE_PROVIDER" ] && [ "$OVERRIDE_PROVIDER" != "null" ]; then
- bundle exec compiler -a -e terraform -f "$OVERRIDE_PROVIDER" -o "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME/"
- else
- bundle exec compiler -a -e terraform -o "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME/" -v "$VERSION"
- fi
-
- if [ "$mm_dir" == "magic-modules-branched" ] ; then
- TERRAFORM_COMMIT_MSG="$(cat .git/title)"
- else
- TERRAFORM_COMMIT_MSG="Old generated base as of $(git rev-parse HEAD)."
- fi
-
- BRANCH_NAME="$(cat branchname)"
-
- pushd "build/$SHORT_NAME"
-
- # These config entries will set the "committer".
- git config --global user.email "magic-modules@google.com"
- git config --global user.name "Modular Magician"
-
- git add -A
-
- git commit -m "$TERRAFORM_COMMIT_MSG" --author="$COMMIT_AUTHOR" || true # don't crash if no changes
- git checkout -B "$BRANCH_NAME"
-
- popd
- popd
-
-done
-
-mkdir "./terraform-diff/$VERSION"
-
-git clone "magic-modules-branched/build/$SHORT_NAME" "./terraform-diff/$VERSION/new"
-git clone "magic-modules-previous/build/$SHORT_NAME" "./terraform-diff/$VERSION/old"
diff --git a/.ci/magic-modules/diff-terraform.yml b/.ci/magic-modules/diff-terraform.yml
deleted file mode 100644
index 337099ad8432..000000000000
--- a/.ci/magic-modules/diff-terraform.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# This file takes two inputs: magic-modules-branched in detached-HEAD state, and magic-modules-previous.
-# It spits out "terraform-diff/comment.txt", which contains the markdown-format diff, as well as
-# "terraform-diff/old" and "terraform-diff/new".
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-
-inputs:
- - name: magic-modules-branched
- - name: magic-modules-previous
-
-outputs:
- - name: terraform-diff
-
-run:
- path: magic-modules-branched/.ci/magic-modules/diff-terraform.sh
-
-params:
- VERSION: ""
- PROVIDER_NAME: ""
- SHORT_NAME: ""
- OVERRIDE_PROVIDER: ""
- GITHUB_ORG: "terraform-providers"
diff --git a/.ci/magic-modules/downstream-changelog-metadata-mergeprs.yml b/.ci/magic-modules/downstream-changelog-metadata-mergeprs.yml
deleted file mode 100644
index b71e7fff7a4c..000000000000
--- a/.ci/magic-modules/downstream-changelog-metadata-mergeprs.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# This file takes in mm-approved-prs (magic-modules) to get code that it runs
-# and upstream PR.
-# Required information:
-# - Github API token.
-# - Upstream PR (magic modules) number
-# It produces no output.
-
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # This task requires python + pip package 'pygithub'.
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: mm-approved-prs
-
-params:
- GITHUB_TOKEN: ""
- DOWNSTREAM_REPOS: ""
-
-run:
- path: mm-approved-prs/.ci/magic-modules/downstream_changelog_metadata.py
- args:
- - mm-approved-prs/.git/id
diff --git a/.ci/magic-modules/downstream-changelog-metadata.yml b/.ci/magic-modules/downstream-changelog-metadata.yml
deleted file mode 100644
index 08e12e758a3b..000000000000
--- a/.ci/magic-modules/downstream-changelog-metadata.yml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-# This file takes in mm-approved-prs (magic-modules) to get code that it runs
-# and upstream PR.
-# Required information:
-# - Github API token.
-# - Upstream PR (magic modules) number
-# It produces no output.
-
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # Requires python + pip packages 'pygithub', 'mistune', 'beautifulsoup4'
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: magic-modules-with-comment
- - name: mm-initial-pr
-
-params:
- GITHUB_TOKEN: ""
- DOWNSTREAM_REPOS: ""
-
-run:
- path: magic-modules-with-comment/.ci/magic-modules/downstream_changelog_metadata.py
- args:
- - mm-initial-pr/.git/id
diff --git a/.ci/magic-modules/downstream_changelog_metadata.py b/.ci/magic-modules/downstream_changelog_metadata.py
deleted file mode 100755
index 81640ca8fe75..000000000000
--- a/.ci/magic-modules/downstream_changelog_metadata.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/env python
-"""
-Script to edit downstream PRs with CHANGELOG release note and label metadata.
-
-Usage:
- ./downstream_changelog_info.py path/to/.git/.id
- python /downstream_changelog_info.py
-
-Note that release_note/labels are authoritative - if empty or not set in the MM
-upstream PR, release notes will be removed from downstreams and labels
-unset.
-"""
-import os
-import sys
-import github
-from pyutils import strutils, downstreams
-
-CHANGELOG_LABEL_PREFIX = "changelog: "
-
-def downstream_changelog_info(gh, upstream_pr_num, changelog_repos):
- """Edit downstream PRs with CHANGELOG info.
-
- Args:
- gh: github.Github client
- upstream_pr_num: Upstream PR number
- changelog_repos: List of repo names to downstream changelog metadata for
- """
- # Parse CHANGELOG info from upstream
- print "Fetching upstream PR '%s'..." % upstream_pr_num
- upstream_pr = gh.get_repo(downstreams.UPSTREAM_REPO)\
- .get_pull(upstream_pr_num)
- release_notes = strutils.get_release_notes(upstream_pr.body)
- labels_to_add = strutils.find_prefixed_labels(
- [l.name for l in upstream_pr.labels],
- CHANGELOG_LABEL_PREFIX)
-
- if not labels_to_add and not release_notes:
- print "No release note or labels found, skipping PR %d" % (
- upstream_pr_num)
- return
-
- print "Found changelog info on upstream PR %d:" % (
- upstream_pr.number)
- print "Release Note: \"%s\"" % release_notes
- print "Labels: %s" % labels_to_add
-
- parsed_urls = downstreams.get_parsed_downstream_urls(gh, upstream_pr.number)
- found = False
-
- for repo_name, pulls in parsed_urls:
- found = True
- print "Found downstream PR for repo %s" % repo_name
-
- if repo_name not in changelog_repos:
- print "[DEBUG] skipping repo %s with no CHANGELOG" % repo_name
- continue
-
- print "Generating changelog for pull requests in %s" % repo_name
-
- print "Fetching repo %s" % repo_name
- ghrepo = gh.get_repo(repo_name)
-
- for _r, prnum in pulls:
- print "Fetching %s PR %d" % (repo_name, prnum)
- pr = ghrepo.get_pull(int(prnum))
- set_changelog_info(pr, release_notes, labels_to_add)
-
- if not found:
- print "No downstreams found for upstream PR %d, returning!" % upstream_pr.number
-
-def set_changelog_info(gh_pull, release_notes, labels_to_add):
- """Set release note and labels on a downstream PR in Github.
-
- Args:
- gh_pull: A github.PullRequest.PullRequest handle
- release_note: String of release note text to set
- labels_to_add: List of strings. Changelog-related labels to add/replace.
- """
- print "Setting changelog info for downstream PR %s" % gh_pull.url
- edited_body = strutils.set_release_notes(release_notes, gh_pull.body)
- gh_pull.edit(body=edited_body)
-
- # Get all non-changelog-related labels
- labels_to_set = []
- for l in gh_pull.get_labels():
- if not l.name.startswith(CHANGELOG_LABEL_PREFIX):
- labels_to_set.append(l.name)
- labels_to_set += labels_to_add
- gh_pull.set_labels(*labels_to_set)
-
-
-if __name__ == '__main__':
- downstream_repos = os.environ.get('DOWNSTREAM_REPOS').split(',')
- if len(downstream_repos) == 0:
- print "Skipping, no downstreams repos given to downstream changelog info for"
- sys.exit(0)
-
- assert len(sys.argv) == 2, "expected id filename as argument"
- with open(sys.argv[1]) as f:
- pr_num = int(f.read())
- downstream_changelog_info(
- github.Github(os.environ.get('GITHUB_TOKEN')),
- pr_num, downstream_repos)
diff --git a/.ci/magic-modules/ensure-downstreams-merged.yml b/.ci/magic-modules/ensure-downstreams-merged.yml
deleted file mode 100644
index 389d122e2bc6..000000000000
--- a/.ci/magic-modules/ensure-downstreams-merged.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-# This file takes in only magic-modules, to get the code that
-# it runs. It does need the github API token.
-# It produces no output.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # This task requires a container with python and the pip
- # package 'pygithub'.
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: mm-approved-prs
-
-params:
- GH_TOKEN: ""
-
-run:
- path: mm-approved-prs/.ci/magic-modules/ensure_downstreams_merged.py
- args:
- - mm-approved-prs/.git/id
diff --git a/.ci/magic-modules/ensure_downstreams_merged.py b/.ci/magic-modules/ensure_downstreams_merged.py
deleted file mode 100755
index 25867f22c6cd..000000000000
--- a/.ci/magic-modules/ensure_downstreams_merged.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-"""
-This script takes the name of a file containing an upstream PR number
-and returns an error if not all of its downstreams have been merged.
-
-Required env vars:
- GH_TOKEN: Github token
-"""
-import os
-import sys
-from github import Github
-from pyutils import downstreams
-
-if __name__ == '__main__':
- assert len(sys.argv) == 2, "expected id filename as argument"
- with open(sys.argv[1]) as f:
- pr_num = int(f.read())
-
- client = Github(os.environ.get('GH_TOKEN'))
- unmerged = downstreams.find_unmerged_downstreams(client, pr_num)
- if unmerged:
- raise ValueError("some PRs are unmerged", unmerged)
diff --git a/.ci/magic-modules/generate-ansible.sh b/.ci/magic-modules/generate-ansible.sh
deleted file mode 100755
index 6e14d5a47f18..000000000000
--- a/.ci/magic-modules/generate-ansible.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-
-# This script takes in 'magic-modules-branched', a git repo tracking the head of a PR against magic-modules.
-# It outputs "ansible-generated", a non-submodule git repo containing the generated ansible code.
-
-set -x
-set -e
-source "$(dirname "$0")/helpers.sh"
-PATCH_DIR="$(pwd)/patches"
-
-pushd magic-modules-branched
-
-# Choose the author of the most recent commit as the downstream author
-# Note that we don't use the last submitted commit, we use the primary GH email
-# of the GH PR submitted. If they've enabled a private email, we'll actually
-# use their GH noreply email which isn't compatible with CLAs.
-COMMIT_AUTHOR="$(git log --pretty="%an <%ae>" -n1 HEAD)"
-
-# Remove all modules so that old files are removed in process.
-rm build/ansible/plugins/modules/gcp_*
-
-bundle exec compiler -a -e ansible -o "build/ansible/"
-
-ANSIBLE_COMMIT_MSG="$(cat .git/title)"
-
-pushd "build/ansible"
-# This module is handwritten. It's the only one.
-# It was deleted earlier, so it needs to be undeleted.
-git checkout HEAD -- plugins/modules/gcp_storage_object.py
-
-# These config entries will set the "committer".
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-
-git add -A
-
-git commit -m "$ANSIBLE_COMMIT_MSG" --author="$COMMIT_AUTHOR" || true # don't crash if no changes
-git checkout -B "$(cat ../../branchname)"
-
-apply_patches "$PATCH_DIR/modular-magician/ansible" "$ANSIBLE_COMMIT_MSG" "$COMMIT_AUTHOR" "master"
-
-popd
-popd
-
-git clone magic-modules-branched/build/ansible ./ansible-generated
diff --git a/.ci/magic-modules/generate-ansible.yml b/.ci/magic-modules/generate-ansible.yml
deleted file mode 100644
index 326d3458803b..000000000000
--- a/.ci/magic-modules/generate-ansible.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-# This file takes two inputs: magic-modules-branched in detached-HEAD state, and the patches.
-# It spits out "ansible-generated", a ansible repo on a new branch (named after the
-# HEAD commit on the PR), with the new generated code in it.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-
-inputs:
- - name: magic-modules-branched
- - name: patches
-
-outputs:
- - name: ansible-generated
-
-run:
- path: magic-modules-branched/.ci/magic-modules/generate-ansible.sh
diff --git a/.ci/magic-modules/generate-inspec.sh b/.ci/magic-modules/generate-inspec.sh
deleted file mode 100755
index 0ff8d96d7384..000000000000
--- a/.ci/magic-modules/generate-inspec.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# This script takes in 'magic-modules-branched', a git repo tracking the head of a PR against magic-modules.
-# It outputs "inspec-generated", a non-submodule git repo containing the generated inspec code.
-
-set -x
-set -e
-source "$(dirname "$0")/helpers.sh"
-PATCH_DIR="$(pwd)/patches"
-
-pushd magic-modules-branched
-
-# Choose the author of the most recent commit as the downstream author
-# Note that we don't use the last submitted commit, we use the primary GH email
-# of the GH PR submitted. If they've enabled a private email, we'll actually
-# use their GH noreply email which isn't compatible with CLAs.
-COMMIT_AUTHOR="$(git log --pretty="%an <%ae>" -n1 HEAD)"
-
-bundle exec compiler -a -e inspec -o "build/inspec/" -v beta
-
-INSPEC_COMMIT_MSG="$(cat .git/title)"
-
-pushd "build/inspec"
-
-# These config entries will set the "committer".
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-
-git add -A
-
-git commit -m "$INSPEC_COMMIT_MSG" --author="$COMMIT_AUTHOR" || true # don't crash if no changes
-git checkout -B "$(cat ../../branchname)"
-
-apply_patches "$PATCH_DIR/modular-magician/inspec-gcp" "$INSPEC_COMMIT_MSG" "$COMMIT_AUTHOR" "master"
-
-popd
-popd
-
-git clone magic-modules-branched/build/inspec ./inspec-generated
diff --git a/.ci/magic-modules/generate-inspec.yml b/.ci/magic-modules/generate-inspec.yml
deleted file mode 100644
index a984befdaaa9..000000000000
--- a/.ci/magic-modules/generate-inspec.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-# This file takes two inputs: magic-modules-branched in detached-HEAD state, and the patches.
-# It spits out "inspec-generated", an inspec repo on a new branch (named after the
-# HEAD commit on the PR), with the new generated code in it.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-
-inputs:
- - name: magic-modules-branched
- - name: patches
-
-outputs:
- - name: inspec-generated
-
-run:
- path: magic-modules-branched/.ci/magic-modules/generate-inspec.sh
diff --git a/.ci/magic-modules/generate-terraform-all-platforms.sh b/.ci/magic-modules/generate-terraform-all-platforms.sh
deleted file mode 100755
index 5e8283e47176..000000000000
--- a/.ci/magic-modules/generate-terraform-all-platforms.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env bash
-
-
-set -x
-
-function init {
- START_DIR=${PWD}
- # Setup GOPATH
- export GOPATH=${PWD}/go
- # Setup GOBIN
- export GOBIN=${PWD}/dist
- # Create GOBIN folder
- mkdir -p "$GOBIN"
- # Create GOPATH structure
- mkdir -p "${GOPATH}/src/github.com/terraform-providers"
- # Copy the repo
- cp -rf "$1" "${GOPATH}/src/github.com/terraform-providers/terraform-provider-google"
- # Paths and vars
- PROVIDER_NAME="google"
- PROVIDERPATH="$GOPATH/src/github.com/terraform-providers"
- SRC_DIR="$PROVIDERPATH/terraform-provider-$PROVIDER_NAME"
- TARGET_DIR="$START_DIR/dist"
- XC_ARCH=${XC_ARCH:-"386 amd64 arm"}
- XC_OS=${XC_OS:=linux darwin windows freebsd openbsd solaris}
- XC_EXCLUDE_OSARCH="!darwin/arm !darwin/386"
- export CGO_ENABLED=0
- mkdir -p "$TARGET_DIR"
-}
-
-function installGox {
- if ! which gox > /dev/null; then
- go get -u github.com/mitchellh/gox
- fi
-}
-
-function compile {
- pushd "$SRC_DIR"
- printf "\n"
- make fmtcheck
-
- # Set LD Flags
- LD_FLAGS="-s -w"
-
- # Clean any old directories (should never be here)
- rm -f bin/*
- rm -fr pkg/*
- # Build with gox
- "$GOBIN/gox" \
- -os="${XC_OS}" \
- -arch="${XC_ARCH}" \
- -osarch="${XC_EXCLUDE_OSARCH}" \
- -ldflags "${LD_FLAGS}" \
- -output "$TARGET_DIR/terraform-provider-${PROVIDER_NAME}.{{.OS}}_{{.Arch}}" \
- .
-
- popd
-}
-
-function main {
- init "$1"
- installGox
- compile
-}
-
-main "$@"
diff --git a/.ci/magic-modules/generate-terraform-all-platforms.yml b/.ci/magic-modules/generate-terraform-all-platforms.yml
deleted file mode 100644
index 75653b224346..000000000000
--- a/.ci/magic-modules/generate-terraform-all-platforms.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-platform: linux
-inputs:
- - name: terraform-head
- - name: magic-modules-gcp
-
-image_resource:
- type: docker-image
- source:
- repository: golang
- tag: '1.10'
-
-run:
- path: magic-modules-gcp/.ci/magic-modules/generate-terraform-all-platforms.sh
- args:
- - terraform-head
-
-outputs:
- - name: dist
diff --git a/.ci/magic-modules/generate-terraform.sh b/.ci/magic-modules/generate-terraform.sh
deleted file mode 100755
index f569b95c0460..000000000000
--- a/.ci/magic-modules/generate-terraform.sh
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/bin/bash
-
-# This script takes in 'magic-modules-branched', a git repo tracking the head of a PR against magic-modules.
-# It outputs "terraform-generated", a non-submodule git repo containing the generated terraform code.
-
-set -x
-set -e
-source "$(dirname "$0")/helpers.sh"
-PATCH_DIR="$(pwd)/patches"
-
-# Create $GOPATH structure - in order to successfully run Terraform codegen, we need to run
-# it with a correctly-set-up $GOPATH. It calls out to `goimports`, which means that
-# we need to have all the dependencies correctly downloaded.
-export GOPATH="${PWD}/go"
-mkdir -p "${GOPATH}/src/github.com/$GITHUB_ORG"
-
-pushd magic-modules-branched
-ln -s "${PWD}/build/$SHORT_NAME/" "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME"
-popd
-
-pushd "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME"
-
-# Other orgs are not fully-generated. This may be transitional - if this causes pain,
-# try vendoring into third-party, as with TPG and TPGB.
-if [ "$GITHUB_ORG" = "terraform-providers" ]; then
- # This line removes every file which is not specified here.
- # If you add files to Terraform which are not generated, you have to add them here.
- # It uses the somewhat obtuse 'find' command. To explain:
- # "find .": all files and directories recursively under the current directory, subject to matchers.
- # "-type f": all regular real files, i.e. not directories.
- # "-not": do the opposite of the next thing, always used with another matcher.
- # "-wholename": entire relative path - including directory names - matches following wildcard.
- # "-name": filename alone matches following string. e.g. -name README.md matches ./README.md *and* ./foo/bar/README.md
- # "-exec": for each file found, execute the command following until the literal ';'
- find . -type f -not -wholename "./.git*" -not -wholename "./vendor*" -not -name ".travis.yml" -not -name ".golangci.yml" -not -name "CHANGELOG.md" -not -name "GNUmakefile" -not -name "docscheck.sh" -not -name "LICENSE" -not -name "README.md" -not -wholename "./examples*" -not -name "go.mod" -not -name "go.sum" -not -name "staticcheck.conf" -not -name ".go-version" -not -name ".hashibot.hcl" -not -name "tools.go" -exec git rm {} \;
-fi
-
-popd
-
-pushd magic-modules-branched
-
-# Choose the author of the most recent commit as the downstream author
-# Note that we don't use the last submitted commit, we use the primary GH email
-# of the GH PR submitted. If they've enabled a private email, we'll actually
-# use their GH noreply email which isn't compatible with CLAs.
-COMMIT_AUTHOR="$(git log --pretty="%an <%ae>" -n1 HEAD)"
-
-if [ -n "$OVERRIDE_PROVIDER" ] && [ "$OVERRIDE_PROVIDER" != "null" ]; then
- bundle exec compiler -a -e terraform -f "$OVERRIDE_PROVIDER" -o "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME/"
-else
- bundle exec compiler -a -e terraform -o "${GOPATH}/src/github.com/$GITHUB_ORG/$PROVIDER_NAME/" -v "$VERSION"
-fi
-
-TERRAFORM_COMMIT_MSG="$(cat .git/title)"
-
-pushd "build/$SHORT_NAME"
-
-# These config entries will set the "committer".
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-
-git add -A
-
-git commit -m "$TERRAFORM_COMMIT_MSG" --author="$COMMIT_AUTHOR" || true # don't crash if no changes
-git checkout -B "$(cat ../../branchname)"
-
-apply_patches "$PATCH_DIR/$GITHUB_ORG/$PROVIDER_NAME" "$TERRAFORM_COMMIT_MSG" "$COMMIT_AUTHOR" "master"
-
-popd
-popd
-
-git clone "magic-modules-branched/build/$SHORT_NAME" "./terraform-generated/$VERSION"
diff --git a/.ci/magic-modules/generate-terraform.yml b/.ci/magic-modules/generate-terraform.yml
deleted file mode 100644
index ab20a5875400..000000000000
--- a/.ci/magic-modules/generate-terraform.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# This file takes two inputs: magic-modules-branched in detached-HEAD state, and the list of patches.
-# It spits out "terraform-generated", a terraform repo on a new branch (named after the
-# HEAD commit on the PR), with the new generated code in it.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-
-inputs:
- - name: magic-modules-branched
- - name: patches
-
-outputs:
- - name: terraform-generated
-
-run:
- path: magic-modules-branched/.ci/magic-modules/generate-terraform.sh
-
-params:
- VERSION: ""
- PROVIDER_NAME: ""
- SHORT_NAME: ""
- OVERRIDE_PROVIDER: ""
- GITHUB_ORG: "terraform-providers"
diff --git a/.ci/magic-modules/get-merged-patches.yml b/.ci/magic-modules/get-merged-patches.yml
deleted file mode 100644
index 7afae2e1094e..000000000000
--- a/.ci/magic-modules/get-merged-patches.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# This file takes in only magic-modules, to get the code that
-# it runs. It does need the github API token.
-# It produces "patches", a set of directories that contain
-# `git format-patch` style patches for any PR which was generated
-# by MagicModules, and which has already been merged, despite
-# the upstream MagicModules PR not yet being merged.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- # This task requires a container with python and the pip
- # package 'pygithub'.
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: magic-modules
-
-outputs:
- - name: patches
-
-params:
- GH_TOKEN: ""
-
-run:
- path: magic-modules/.ci/magic-modules/get_merged_patches.py
diff --git a/.ci/magic-modules/get_downstream_prs.py b/.ci/magic-modules/get_downstream_prs.py
deleted file mode 100755
index ce4c7c739da0..000000000000
--- a/.ci/magic-modules/get_downstream_prs.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-import os
-import sys
-from github import Github
-from pyutils import downstreams
-
-if __name__ == '__main__':
- assert len(sys.argv) == 2, "expected a Github PR ID as argument"
- upstream_pr = int(sys.argv[1])
-
- downstream_urls = downstreams.get_downstream_urls(
- Github(os.environ.get('GH_TOKEN')), upstream_pr)
- for url in downstream_urls:
- print url
diff --git a/.ci/magic-modules/get_merged_patches.py b/.ci/magic-modules/get_merged_patches.py
deleted file mode 100755
index dd4ba73a152a..000000000000
--- a/.ci/magic-modules/get_merged_patches.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-import os
-import urllib
-from github import Github
-from pyutils import downstreams
-
-def get_merged_patches(gh):
- """Download all merged patches for open upstream PRs.
-
- Args:
- gh: Github client to make calls to Github with.
- """
- open_pulls = gh.get_repo('GoogleCloudPlatform/magic-modules')\
- .get_pulls(state='open')
- for open_pr in open_pulls:
- print 'Downloading patches for upstream PR %d...' % open_pr.number
- parsed_urls = downstreams.get_parsed_downstream_urls(gh, open_pr.number)
- for repo_name, pulls in parsed_urls:
- repo = gh.get_repo(repo_name)
- for r, pr_num in pulls:
- print 'Check to see if %s/%s is merged and should be downloaded\n' % (
- r, pr_num)
- downstream_pr = repo.get_pull(int(pr_num))
- if downstream_pr.is_merged():
- download_patch(r, downstream_pr)
-
-def download_patch(repo, pr):
- """Download merged downstream PR patch.
-
- Args:
- pr: Github Pull request to download patch for
- """
- download_location = os.path.join('./patches', repo_name, '%d.patch' % pr.id)
- print download_location
- # Skip already downloaded patches
- if os.path.exists(download_location):
- return
-
- if not os.path.exists(os.path.dirname(download_location)):
- os.makedirs(os.path.dirname(download_location))
- urllib.urlretrieve(pr.patch_url, download_location)
-
-if __name__ == '__main__':
- gh = Github(os.environ.get('GH_TOKEN'))
- get_merged_patches(gh)
diff --git a/.ci/magic-modules/helpers.sh b/.ci/magic-modules/helpers.sh
deleted file mode 100644
index 8635966bba97..000000000000
--- a/.ci/magic-modules/helpers.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-# Arguments to 'apply_patches' are:
-# - name of patch directory
-# - commit message
-# - author
-# - target branch
-function apply_patches {
- # Apply necessary downstream patches.
- shopt -s nullglob
- for patch in "$1"/*; do
- # This is going to apply the patch as at least 1 commit, possibly more.
- git am --3way --signoff "$patch"
- done
- shopt -u nullglob
- # Now, collapse the patch commits into one.
- # This looks a little silly, but here's what we're doing.
- # We get rid of all the commits since we diverged from 'master',
- # We keep all the changes (--soft).
- git reset --soft "$(git merge-base HEAD "$4")"
- # Then we commit again.
- git commit -m "$2" --author="$3" --signoff || true # don't crash if no changes
-}
diff --git a/.ci/magic-modules/merge-pr.sh b/.ci/magic-modules/merge-pr.sh
deleted file mode 100755
index 23d90334b104..000000000000
--- a/.ci/magic-modules/merge-pr.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-
-# This script updates the submodule to track terraform master.
-set -e
-set -x
-shopt -s dotglob
-
-# Since these creds are going to be managed externally, we need to pass
-# them into the container as an environment variable. We'll use
-# ssh-agent to ensure that these are the credentials used to update.
-set +x
-echo "$CREDS" > ~/github_private_key
-set -x
-chmod 400 ~/github_private_key
-
-pushd mm-approved-prs
-ID=$(git config --get pullrequest.id)
-# We need to know what branch to check out for the update.
-BRANCH=$(git config --get pullrequest.branch)
-REPO=$(git config --get pullrequest.repo)
-popd
-
-cp -r mm-approved-prs/* mm-output
-
-pushd mm-output
-# The github pull request resource reads this value to find
-# out which pull request to update.
-git config pullrequest.id "$ID"
-
-# We should rebase onto master to avoid ugly merge histories.
-git fetch origin master
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-git rebase origin/master
-
-ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init $ALL_SUBMODULES"
-
-# Word-splitting here is intentional.
-git add $ALL_SUBMODULES
-
-# It's okay for the commit to fail if there's no changes.
-set +e
-git commit -m "Update tracked submodules -> HEAD on $(date)
-
-Tracked submodules are $ALL_SUBMODULES."
-echo "Merged PR #$ID." > ./commit_message
-
-# If the repo isn't 'GoogleCloudPlatform/magic-modules', then the PR has been
-# opened from someone's fork. We ought to have push rights to that fork, no
-# problem, but if we don't, that's also okay. This is a tiny bit dangerous
-# because it's a force-push.
-
-set +e
-if [ "$REPO" != "GoogleCloudPlatform/magic-modules" ]; then
- git remote add non-gcp-push-target "git@github.com:$REPO"
- # We know we have a commit, so all the machinery of the git resources is
- # unnecessary. We can just try to push directly.
- ssh-agent bash -c "ssh-add ~/github_private_key; git push -f non-gcp-push-target \"HEAD:$BRANCH\""
-fi
-set -e
diff --git a/.ci/magic-modules/merge.yml b/.ci/magic-modules/merge.yml
deleted file mode 100644
index 40545a7bd198..000000000000
--- a/.ci/magic-modules/merge.yml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-# This takes in the approved PR and CI repo, and updates the PR so that
-# its submodules track the `master` branch on their assorted repos.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby
- tag: '1.11.5-2.6.0'
-
-inputs:
- - name: mm-approved-prs
-
-outputs:
- - name: mm-output
-
-run:
- path: mm-approved-prs/.ci/magic-modules/merge-pr.sh
-
-params:
- CREDS: ""
- ALL_SUBMODULES: ""
diff --git a/.ci/magic-modules/point-to-submodules.sh b/.ci/magic-modules/point-to-submodules.sh
deleted file mode 100755
index 91bd868dd307..000000000000
--- a/.ci/magic-modules/point-to-submodules.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-
-# This script takes in 'magic-modules-branched', a git repo tracking the head of a PR against magic-modules.
-# It needs to output the same git repo, but with the code generation done and submodules updated, at 'magic-modules-submodules'.
-
-set -e
-set +x
-# Don't show the credential in the output.
-echo "$CREDS" > ~/github_private_key
-set -x
-chmod 400 ~/github_private_key
-
-pushd magic-modules-branched
-BRANCH="$(cat ./branchname)"
-# Update this repo to track the submodules we just pushed:
-
-if [ "$TERRAFORM_ENABLED" = "true" ]; then
- IFS="," read -ra TERRAFORM_VERSIONS <<< "$TERRAFORM_VERSIONS"
- for VERSION in "${TERRAFORM_VERSIONS[@]}"; do
- IFS=":" read -ra TERRAFORM_DATA <<< "$VERSION"
- PROVIDER_NAME="${TERRAFORM_DATA[0]}"
- SUBMODULE_DIR="${TERRAFORM_DATA[1]}"
-
- git config -f .gitmodules "submodule.build/$SUBMODULE_DIR.branch" "$BRANCH"
- git config -f .gitmodules "submodule.build/$SUBMODULE_DIR.url" "https://github.com/$GH_USERNAME/$PROVIDER_NAME.git"
- git submodule sync "build/$SUBMODULE_DIR"
- ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init build/$SUBMODULE_DIR"
- git add "build/$SUBMODULE_DIR"
- done
-fi
-
-if [ "$ANSIBLE_ENABLED" = "true" ]; then
- git config -f .gitmodules submodule.build/ansible.branch "$BRANCH"
- git config -f .gitmodules submodule.build/ansible.url "https://github.com/$GH_USERNAME/ansible_collections_google.git"
- git submodule sync build/ansible
- ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init build/ansible"
- git add build/ansible
-fi
-
-if [ "$INSPEC_ENABLED" = "true" ]; then
- git config -f .gitmodules submodule.build/inspec.branch "$BRANCH"
- git config -f .gitmodules submodule.build/inspec.url "https://github.com/$GH_USERNAME/inspec-gcp.git"
- git submodule sync build/inspec
- ssh-agent bash -c "ssh-add ~/github_private_key; git submodule update --remote --init build/inspec"
- git add build/inspec
-fi
-
-# Commit those changes so that they can be tested in the next phase.
-git add .gitmodules
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-git commit -m "Automatic submodule update to generated code." || true # don't crash if no changes
-git checkout -B "$BRANCH"
-
-cp -r ./ ../magic-modules-submodules
diff --git a/.ci/magic-modules/point-to-submodules.yml b/.ci/magic-modules/point-to-submodules.yml
deleted file mode 100644
index 2d16efb74955..000000000000
--- a/.ci/magic-modules/point-to-submodules.yml
+++ /dev/null
@@ -1,29 +0,0 @@
----
-# This file takes two inputs: magic-modules-branched in detached-HEAD state, and the CI repo.
-# It spits out "terraform-generated", a terraform repo on a new branch (named after the
-# HEAD commit on the PR), with the new generated code in it.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby
- tag: '1.11.5-2.6.0'
-
-inputs:
- - name: magic-modules-branched
-
-outputs:
- - name: magic-modules-submodules
-
-run:
- path: magic-modules-branched/.ci/magic-modules/point-to-submodules.sh
-
-params:
- GH_USERNAME: ""
- CREDS: ""
- TERRAFORM_ENABLED: false
- TERRAFORM_VERSIONS: ""
- ANSIBLE_ENABLED: false
- INSPEC_ENABLED: false
-
diff --git a/.ci/magic-modules/pyutils/README.md b/.ci/magic-modules/pyutils/README.md
deleted file mode 100644
index 8570ed3be9e7..000000000000
--- a/.ci/magic-modules/pyutils/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Magic Modules CI Utils
-
-This directory manages all Python utils that the Magician uses to take upstream Magic Module PRs and generate and manage PRs in various downstream repos.
-
-What this shouldn't contain:
-
-- Python scripts called directly by Concourse jobs.
-- Non-Python code
-
-## Tests
-
-Currently we use the standard [unittest](https://docs.python.org/3/library/unittest.html) library. Because CI development is mostly done locally on your developer machine before being directly deployed, these tests are run manually.
-
-This section reviews running/writing tests for someone fairly new to Python/unittest, so some of this information is just from unittest docs.
-
-### Running tests
-
-Set a test environment variable to make calls to Github:
-```
-export TEST_GITHUB_TOKEN=...
-```
-
-Otherwise, tests calling Github will be ignored (or likely be rate-limited).
-```
-cd pyutils
-
-python -m unittest discover -p "*_test.py"
-python ./changelog_utils_test.py
-```
-
-Read [unittest](https://docs.python.org/3/library/unittest.html#command-line-interface) docs to see how to run tests at finer granularity.
-
-*NOTE*: Don't forget to delete .pyc files if you feel like tests aren't reflecting your changes!
-
-### Writing Tests:
-
-This is mostly a very shallow review of unittest, but your test should inherit from the `unittest.TestCase` class in some way (i.e. we haven't had the need to write our own TestCase-inheriting Test class but feel free to in the future if needed).
-
-```
-class MyModuleTest(unittest.TestCase):
-```
-
-Make sure to include the following at the bottom of your test file, so it defaults to running the tests in this file if run as a normal Python script.
-```
-if __name__ == '__main__':
- unittest.main()
-```
-
-
-
diff --git a/.ci/magic-modules/pyutils/__init__.py b/.ci/magic-modules/pyutils/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/.ci/magic-modules/pyutils/downstreams.py b/.ci/magic-modules/pyutils/downstreams.py
deleted file mode 100644
index e26e767878cb..000000000000
--- a/.ci/magic-modules/pyutils/downstreams.py
+++ /dev/null
@@ -1,89 +0,0 @@
-"""Helper class for obtaining information about upstream PR and its downstreams.
-
- Typical usage example:
-
- import upstream_pull_request
-
- client = github.Github(github_token)
- downstreams = upstream_pull_request.downstream_urls(client, 100)
-
-"""
-
-import os
-import re
-import sys
-import itertools
-import operator
-from strutils import *
-
-UPSTREAM_REPO = 'GoogleCloudPlatform/magic-modules'
-
-def find_unmerged_downstreams(client, pr_num):
- """Returns list of urls for unmerged, open downstreams.
-
- For each downstream PR URL found from get_parsed_downstream_urls(),
- fetches the status of each downstream PR to determine which PRs are still
- unmerged (i.e. not closed and not merged).
-
- Args:
- client: github.Github client
- pr_num: PR Number for upstream PR
- Returns:
- All unmerged downstreams found for a PR.
- """
- unmerged_dependencies = []
- for r, pulls in get_parsed_downstream_urls(client, pr_num):
- repo = client.get_repo(r)
- for _repo, pr_num in pulls:
- pr = repo.get_pull(int(pr_num))
- # Disregard merged or closed PRs.
- if not pr.is_merged() and not pr.state == "closed":
- unmerged_dependencies.append(pr.html_url)
-
- return unmerged_dependencies
-
-def get_parsed_downstream_urls(client, pr_num):
- """Get parsed URLs for downstream PRs grouped by repo.
-
- For each downstream PR URL referenced by the upstream PR, this method
- parses the downstream repo name
- (i.e. "terraform-providers/terraform-providers-google") and PR number
- (e.g. 100) and groups them by repo name so calling code only needs to fetch
- each repo once.
-
- Example:
- parsed = UpstreamPullRequest(pr_num).parsed_downstream_urls
- for repo, repo_pulls in parsed:
- for _repo, pr in repo_pulls:
- print "Downstream is https://github.com/%s/pull/%d" % (repo, pr)
-
- Args:
- client: github.Github client
- pr_num: PR Number for upstream PR
-
- Returns:
- Iterator over $repo and sub-iterators of ($repo, $pr_num) parsed tuples
- """
- parsed = [parse_github_url(u) for u in get_downstream_urls(client, pr_num)]
- return itertools.groupby(parsed, key=operator.itemgetter(0))
-
-def get_downstream_urls(client, pr_num):
- """Get list of URLs for downstream PRs.
-
- This fetches the upstream PR and finds its downstream PR URLs by
- searching for references in its comments.
-
- Args:
- client: github.Github client
- pr_num: PR Number for upstream PR
-
- Returns:
- List of downstream PR URLs.
- """
- urls = []
- print "Getting downstream URLs for PR %d..." % pr_num
- pr = client.get_repo(UPSTREAM_REPO).get_pull(pr_num)
- for comment in pr.get_issue_comments():
- urls = urls + find_dependency_urls_in_comment(comment.body)
- print "Found downstream URLs: %s" % urls
- return urls
diff --git a/.ci/magic-modules/pyutils/downstreams_test.py b/.ci/magic-modules/pyutils/downstreams_test.py
deleted file mode 100644
index 255121bacd2e..000000000000
--- a/.ci/magic-modules/pyutils/downstreams_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from downstreams import *
-import unittest
-import os
-from github import Github
-
-TOKEN_ENV_VAR = "TEST_GITHUB_TOKEN"
-
-class TestUpstreamPullRequests(unittest.TestCase):
- """
- Terrible test data from scraping
- https://github.com/GoogleCloudPlatform/magic-modules/pull/1000
- TODO: If this test becomes load-bearing, mock out the Github client instead
- of using this.
- """
- TEST_PR_NUM = 1000
- EXPECTED_DOWNSTREAM_URLS = [
- "https://github.com/terraform-providers/terraform-provider-google-beta/pull/186",
- "https://github.com/terraform-providers/terraform-provider-google/pull/2591",
- "https://github.com/modular-magician/ansible/pull/142",
- ]
- EXPECTED_PARSED_DOWNSTREAMS = {
- "terraform-providers/terraform-provider-google-beta": [186],
- "terraform-providers/terraform-provider-google": [2591],
- "modular-magician/ansible": [142],
- }
-
- def setUp(self):
- gh_token = os.environ.get(TOKEN_ENV_VAR)
- if not gh_token:
- self.skipTest(
- "test env var %s not set, skip tests calling Github" % TOKEN_ENV_VAR)
- self.test_client = Github(gh_token)
-
- def test_find_unmerged_downstreams(self):
- self.assertFalse(find_unmerged_downstreams(self.test_client, self.TEST_PR_NUM))
-
- def test_parsed_downstream_urls(self):
- result = get_parsed_downstream_urls(self.test_client, self.TEST_PR_NUM)
- repo_cnt = 0
- for repo, pulls in result:
- # Verify each repo in result.
- self.assertIn(repo, self.EXPECTED_PARSED_DOWNSTREAMS,
- "unexpected repo %s in result" % repo)
- repo_cnt += 1
-
- # Verify each pull request in result.
- expected_pulls = self.EXPECTED_PARSED_DOWNSTREAMS[repo]
- pull_cnt = 0
- for repo, prid in pulls:
- self.assertIn(int(prid), expected_pulls)
- pull_cnt += 1
- # Verify exact count of pulls (here because iterator).
- self.assertEquals(pull_cnt, len(expected_pulls),
- "expected %d pull requests in result[%s]" % (len(expected_pulls), repo))
-
- # Verify exact count of repos (here because iterator).
- self.assertEquals(repo_cnt, len(self.EXPECTED_PARSED_DOWNSTREAMS),
- "expected %d pull requests in result[%s]" % (
- len(self.EXPECTED_PARSED_DOWNSTREAMS), repo))
-
- def test_downstream_urls(self):
- test_client = Github(os.environ.get(TOKEN_ENV_VAR))
- result = get_downstream_urls(self.test_client,self.TEST_PR_NUM)
-
- expected_len = len(self.EXPECTED_DOWNSTREAM_URLS)
- self.assertEquals(len(result), expected_len,
- "expected %d downstream urls, got %d" % (expected_cnt, len(result)))
- for url in result:
- self.assertIn(str(url), self.EXPECTED_DOWNSTREAM_URLS)
-
-
-if __name__ == '__main__':
- unittest.main()
-
-
diff --git a/.ci/magic-modules/pyutils/strutils.py b/.ci/magic-modules/pyutils/strutils.py
deleted file mode 100644
index 2e80bba27014..000000000000
--- a/.ci/magic-modules/pyutils/strutils.py
+++ /dev/null
@@ -1,125 +0,0 @@
-import re
-from bs4 import BeautifulSoup
-import mistune
-
-def find_dependency_urls_in_comment(body):
- """Util to parse downstream dependencies from a given comment body.
-
- Example:
- $ find_dependency_urls_in_comment(\"""
- This is a comment on an MM PR.
-
- depends: https://github.com/ownerFoo/repoFoo/pull/100
- depends: https://github.com/ownerBar/repoBar/pull/10
- \""")
- [https://github.com/ownerFoo/repoFoo/pull/100,
- https://github.com/ownerBar/repoBar/pull/10]
-
- Args:
- body (string): Text of comment in upstream PR
-
- Returns:
- List of PR URLs found.
- """
- return re.findall(
- r'^depends: (https://github.com/[^\s]*)', body, re.MULTILINE)
-
-def parse_github_url(gh_url):
- """Util to parse Github repo/PR id from a Github PR URL.
-
- Args:
- gh_url (string): URL of Github pull request.
-
- Returns:
- Tuple of (repo name, pr number)
- """
- matches = re.match(r'https://github.com/([\w-]+/[\w-]+)/pull/(\d+)', gh_url)
- if matches:
- repo, prnum = matches.groups()
- return (repo, int(prnum))
- return None
-
-def get_release_notes(body):
- """Parse release note blocks from a given text block.
-
- Each code-block with a "release-note:..." language class.
- Example:
- ```release-note:new-resource
- a_new_resource
- ```
-
- ```release-note:bug
- Fixed a bug
- ```
- Args:
- body (string): PR body to pull release note block from
-
- Returns:
- List of tuples of (`release-note` heading, release note)
- """
- release_notes = []
-
- # Parse markdown and find all code blocks
- md = mistune.markdown(body)
- soup = BeautifulSoup(md, 'html.parser')
- for codeblock in soup.find_all('code'):
- block_classes = codeblock.get('class')
- if not block_classes:
- continue
-
- note_type = get_release_note_type_from_class(block_classes[0])
- note_text = codeblock.get_text().strip()
- if note_type and note_text:
- release_notes.append((note_type, note_text))
-
- return release_notes
-
-def get_release_note_type_from_class(class_str):
- # expected class is 'lang-release-note:...' for release notes
- prefix_len = len("lang-release-note:")
- if class_str[:prefix_len] == "lang-release-note:":
- return class_str[len("lang-"):]
- return None
-
-def set_release_notes(release_notes, body):
- """Sanitize and adds the given release note block for PR body text.
-
- For a given text block, removes any existing "releasenote" markdown code
- blocks and adds the given release notes at the end.
-
- Args:
- release_note (list(Tuple(string)): List of
- (release-note heading, release note)
- body (string): Text body to find and edit release note blocks in
-
- Returns:
- Modified text
- """
- edited = ""
- md = mistune.markdown(body)
- soup = BeautifulSoup(md, 'html.parser')
- for blob in soup.find_all('p'):
- edited += blob.get_text().strip() + "\n\n"
-
- for heading, note in release_notes:
- edited += "\n```%s\n%s\n```\n" % (heading, note.strip())
- return edited
-
-def find_prefixed_labels(labels, prefix):
- """Util for filtering and cleaning labels that start with a given prefix.
-
- Given a list of labels, find only the specific labels with the given prefix.
-
- Args:
- prefix: String expected to be prefix of relevant labels
- labels: List of string labels
-
- Return:
- Filtered labels (i.e. all labels starting with prefix)
- """
- changelog_labels = []
- for l in labels:
- l = l.strip()
- if l.startswith(prefix) and len(l) > len(prefix):
- changelog_labels.append(l)
- return changelog_labels
diff --git a/.ci/magic-modules/pyutils/strutils_test.py b/.ci/magic-modules/pyutils/strutils_test.py
deleted file mode 100644
index 6c60059ca07a..000000000000
--- a/.ci/magic-modules/pyutils/strutils_test.py
+++ /dev/null
@@ -1,169 +0,0 @@
-from strutils import *
-import unittest
-import os
-from github import Github
-
-
-class TestStringUtils(unittest.TestCase):
- def test_find_dependency_urls(self):
- test_urls = [
- "https://github.com/repo-owner/repo-A/pull/1",
- "https://github.com/repo-owner/repo-A/pull/2",
- "https://github.com/repo-owner/repo-B/pull/3",
- ]
- test_body = "".join(["\ndepends: %s\n" % u for u in test_urls])
- result = find_dependency_urls_in_comment(test_body)
- self.assertEquals(len(result), len(test_urls),
- "expected %d urls to be parsed from comment" % len(test_urls))
- for test_url in test_urls:
- self.assertIn(test_url, result)
-
- def test_parse_github_url(self):
- test_cases = {
- "https://github.com/repoowner/reponame/pull/1234": ("repoowner/reponame", 1234),
- "not a real url": None,
- }
- for k in test_cases:
- result = parse_github_url(k)
- expected = test_cases[k]
- if not expected:
- self.assertIsNone(result, "expected None, got %s" % result)
- else:
- self.assertEquals(result[0], expected[0])
- self.assertEquals(int(result[1]), expected[1])
-
- def test_get_release_notes(self):
- test_cases = [
- ("releasenote text not found", []),
- (
-"""Empty release note:
-```release-note:test
-
-```
-""", []),
- ("""
-Random code block
-```
-This is not a release note
-```
-""", []),
- ("""
-Empty release note with non-empty code block:
-```release-note:test
-
-```
-
-```
-This is not a release note
-```
-""", []),
- ("""
-Empty code block with non-empty release note:
-
-```invalid
-
-```
-
-```release-note:test
-This is a release note
-```
-""", [("release-note:test", "This is a release note")]),
- ("""
-Single release notes
-```release-note:test
-This is a release note
-```
-""", [("release-note:test", "This is a release note")])
- # ("""
- # Multiple release notes
- # ```release-note:foo
- # note foo
- # ```
-
- # ```release-note:bar
- # note bar
- # ```
-
- # ```release-note:baz
- # note baz
- # ```
- # """, [
- # ("release-note:foo", "note foo"),
- # ("release-note:bar", "note bar"),
- # ("release-note:baz", "note baz"),
- # ]),
- ]
- for k, expected in test_cases:
- actual = get_release_notes(k)
- self.assertEqual(len(actual), len(expected),
- "test %s\n: expected %d items, got %d: %s" % (k, len(expected), len(actual), actual))
- for idx, note_tuple in enumerate(expected):
- self.assertEqual(actual[idx][0], note_tuple[0],
- "test %s\n: expected note type %s, got %s" % (
- k, note_tuple[0], actual[idx][0]))
-
- self.assertEqual(actual[idx][1], note_tuple[1],
- "test %s\n: expected note type %s, got %s" % (
- k, note_tuple[1], actual[idx][1]))
-
-
- def test_set_release_notes(self):
- downstream_body = """
-All of the blocks below should be replaced
-
-```releasenote
-This should be replaced
-```
-
-More text
-
-```releasenote
-```
-
-```test
-```
- """
- release_notes = [
- ("release-note:foo", "new message foo"),
- ("release-note:bar", "new message bar"),
- ]
-
- replaced = set_release_notes(release_notes, downstream_body)
-
- # Existing non-code-block text should still be in body
- self.assertIn("All of the blocks below should be replaced\n", replaced)
- self.assertIn("More text\n", replaced)
-
- # New release notes should have been added.
- self.assertIn("```release-note:foo\nnew message foo\n```\n", replaced)
- self.assertIn("```release-note:bar\nnew message bar\n```\n", replaced)
-
- # Old release notes and code blocks should be removed.
- self.assertEqual(len(re.findall("```.+\n", replaced)), 2,
- "expected only two release note blocks in text. Result:\n%s" % replaced)
- self.assertNotIn("This should be replaced", replaced)
-
-
- def test_find_prefixed_labels(self):
- self.assertFalse(find_prefixed_labels([], "test: "))
- self.assertFalse(find_prefixed_labels(["", ""], "test: "))
- labels = find_prefixed_labels(["foo", "bar"], "")
- self.assertIn("foo", labels)
- self.assertIn("bar", labels)
-
- test_labels = [
- "test: foo",
- "test: bar",
- # Not valid changelog labels
- "not a changelog label",
- "test: "
- ]
- result = find_prefixed_labels(test_labels, prefix="test: ")
-
- self.assertEqual(len(result), 2, "expected only 2 labels returned")
- self.assertIn("test: foo", result)
- self.assertIn("test: bar", result)
-if __name__ == '__main__':
- unittest.main()
-
-
diff --git a/.ci/magic-modules/release-ansible.sh b/.ci/magic-modules/release-ansible.sh
deleted file mode 100755
index 5afcf2683b44..000000000000
--- a/.ci/magic-modules/release-ansible.sh
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-# Constants + functions
-declare -a ignored_modules=(
- gcp_backend_service
- gcp_forwarding_rule
- gcp_healthcheck
- gcp_target_proxy
- gcp_url_map
-)
-
-get_all_modules() {
- remote_name=$1
- file_name=$remote_name
- ssh-agent bash -c "ssh-add ~/github_private_key; git fetch $remote_name"
- git checkout $remote_name/devel
- git ls-files -- lib/ansible/modules/cloud/google/gcp_* | cut -d/ -f 6 | cut -d. -f 1 > $file_name
-
- for i in "${ignored_modules[@]}"; do
- sed -i "/$i/d" $file_name
- done
-}
-
-# Install dependencies for Template Generator
-pushd "magic-modules-gcp"
-bundle install
-
-# Setup SSH keys.
-
-# Since these creds are going to be managed externally, we need to pass
-# them into the container as an environment variable. We'll use
-# ssh-agent to ensure that these are the credentials used to update.
-set +x
-echo "$CREDS" > ~/github_private_key
-set -x
-chmod 400 ~/github_private_key
-popd
-
-# Clone ansible/ansible
-ssh-agent bash -c "ssh-add ~/github_private_key; git clone git@github.com:modular-magician/ansible.git"
-
-# Setup Git config and remotes.
-pushd "ansible"
-git config --global user.email "magic-modules@google.com"
-git config --global user.name "Modular Magician"
-
-git remote remove origin
-git remote add origin git@github.com:modular-magician/ansible.git
-git remote add upstream git@github.com:ansible/ansible.git
-git remote add magician git@github.com:modular-magician/ansible.git
-echo "Remotes setup properly"
-popd
-
-# Copy code into ansible/ansible + commit to our fork
-# By using the "ansible_devel" provider, we get versions of the resources that work
-# with ansible devel.
-pushd "magic-modules-gcp"
-ruby compiler.rb -a -e ansible -f ansible_devel -o ../ansible/
-popd
-
-# Commit code from magic modules into our fork
-pushd "ansible"
-git add lib/ansible/modules/cloud/google/gcp_* test/integration/targets/gcp_*
-git commit -m "Migrating code from collection"
-ssh-agent bash -c "ssh-add ~/github_private_key; git push magician devel"
-
-set -e
-
-ssh-agent bash -c "ssh-add ~/github_private_key; git fetch magician devel"
-ssh-agent bash -c "ssh-add ~/github_private_key; git fetch upstream devel"
-
-# Create files with list of modules in a given branch.
-get_all_modules "upstream"
-get_all_modules "magician"
-
-# Split existing modules into sets of 23
-# Max 50 files per PR and a module can have 2 files (module + test)
-# 23 = 50/2 - 2 (to account for module_util files)
-split -l 23 upstream mm-bug
-
-for filename in mm-bug*; do
- echo "Building a Bug Fix PR for $filename"
- # Checkout all files that file specifies and create a commit.
- git checkout upstream/devel
- git checkout -b bug_fixes$filename
-
-
- while read p; do
- git checkout magician/devel -- "lib/ansible/modules/cloud/google/$p.py"
- if [[ $p != *"info"* ]]; then
- git checkout magician/devel -- "test/integration/targets/$p"
- fi
- done < $filename
-
- git checkout magician/devel -- "lib/ansible/module_utils/gcp_utils.py"
- git checkout magician/devel -- "lib/ansible/plugins/doc_fragments/gcp.py"
-
- # This commit may be empty
- set +e
- git commit -m "Bug fixes for GCP modules"
-
- # Create a PR message + save to file
- ruby ../magic-modules-gcp/tools/ansible-pr/generate_template.rb > bug_fixes$filename
-
- # Create PR
- ssh-agent bash -c "ssh-add ~/github_private_key; git push origin bug_fixes$filename --force"
- hub pull-request -b ansible/ansible:devel -F bug_fixes$filename -f
- set -e
-
- echo "Bug Fix PR built for $filename"
-done
-
-## Get list of new modules (in magician, not in upstream)
-comm -3 <(sort magician) <(sort upstream) > new_modules
-
-while read module; do
- echo "Building a New Module PR for $module"
- git checkout upstream/devel
- git checkout -b $module
-
- git checkout magician/devel -- "lib/ansible/modules/cloud/google/$module.py"
- if [[ $module != *"info"* ]]; then
- git checkout magician/devel -- "test/integration/targets/$module"
- fi
-
- git checkout magician/devel -- "lib/ansible/module_utils/gcp_utils.py"
-
- # Create a PR message + save to file
- set +e
- git commit -m "New Module: $module"
- ruby ../magic-modules-gcp/tools/ansible-pr/generate_template.rb --new-module-name $module > $module
-
- # Create PR
- ssh-agent bash -c "ssh-add ~/github_private_key; git push origin $module --force"
- hub pull-request -b ansible/ansible:devel -F $module -f
- set -e
-
- echo "New Module PR built for $module"
-done < new_modules
diff --git a/.ci/magic-modules/release-ansible.yml b/.ci/magic-modules/release-ansible.yml
deleted file mode 100644
index 33fbe41aab06..000000000000
--- a/.ci/magic-modules/release-ansible.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-# This file takes one input: magic-modules-branched in detached-HEAD state
-# It will create a series of PRs on Ansible.
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/hub
- tag: '1.2'
-
-inputs:
- - name: magic-modules-gcp
-
-run:
- path: "magic-modules-gcp/.ci/magic-modules/release-ansible.sh"
-
-params:
- GITHUB_TOKEN: ""
diff --git a/.ci/magic-modules/vars/validator_handwritten_files.txt b/.ci/magic-modules/vars/validator_handwritten_files.txt
deleted file mode 100644
index a38dd479a40c..000000000000
--- a/.ci/magic-modules/vars/validator_handwritten_files.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-resource_compute_instance.go
-resource_google_project.go
-resource_sql_database_instance.go
-resource_storage_bucket.go
-iam_folder.go
-iam_organization.go
-iam_project.go.erb
diff --git a/.ci/magic-modules/welcome-contributor.sh b/.ci/magic-modules/welcome-contributor.sh
deleted file mode 100755
index 0b521ad24e6c..000000000000
--- a/.ci/magic-modules/welcome-contributor.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-set -x
-
-ASSIGNEE=$(shuf -n 1 <(printf "danawillow\nrambleraptor\nemilymye\nrileykarson\nSirGitsalot\nslevenick\nchrisst\nc2thorn\nndmckinley"))
-
-cat > comment/pr_comment << EOF
-Hello! I am a robot who works on Magic Modules PRs.
-
-I have detected that you are a community contributor, so your PR will be assigned to someone with a commit-bit on this repo for initial review.
-
-Thanks for your contribution! A human will be with you soon.
-
-@$ASSIGNEE, please review this PR or find an appropriate assignee.
-EOF
-
-# Something is preventing the magician from actually assigning the PRs.
-# Leave this part in so we know what was supposed to happen, but the real
-# logic is above.
-echo $ASSIGNEE > comment/assignee
-cat comment/assignee
diff --git a/.ci/magic-modules/welcome-contributor.yml b/.ci/magic-modules/welcome-contributor.yml
deleted file mode 100644
index 295163b61642..000000000000
--- a/.ci/magic-modules/welcome-contributor.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: magic-modules-gcp
-
-outputs:
- - name: comment
-
-run:
- path: magic-modules-gcp/.ci/magic-modules/welcome-contributor.sh
diff --git a/.ci/magic-modules/write-branch-name.sh b/.ci/magic-modules/write-branch-name.sh
deleted file mode 100755
index 2322d3493b6e..000000000000
--- a/.ci/magic-modules/write-branch-name.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /bin/bash
-set -e
-set -x
-
-PR_ID="$(cat ./mm-initial-pr/.git/id)"
-ORIGINAL_PR_BRANCH="codegen-pr-$PR_ID"
-pushd branchname
-echo "$ORIGINAL_PR_BRANCH" > ./original_pr_branch_name
diff --git a/.ci/magic-modules/write-branch-name.yml b/.ci/magic-modules/write-branch-name.yml
deleted file mode 100644
index ca961b2f1a32..000000000000
--- a/.ci/magic-modules/write-branch-name.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-platform: linux
-
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/python
- tag: '1.0'
-
-inputs:
- - name: mm-initial-pr
-
-outputs:
- - name: branchname
-
-run:
- path: mm-initial-pr/.ci/magic-modules/write-branch-name.sh
diff --git a/.ci/release.yml.tmpl b/.ci/release.yml.tmpl
deleted file mode 100644
index f268046c3564..000000000000
--- a/.ci/release.yml.tmpl
+++ /dev/null
@@ -1,119 +0,0 @@
-{% import "vars.tmpl" as vars %}
-# These resource types are here until the PRs get merged in upstream. :)
-resource_types:
- - name: git-branch
- type: docker-image
- source:
- # Note: resource types cannot use credhub substitution - "gcr.io/magic-modules" is hardcoded here.
- repository: gcr.io/magic-modules/concourse-git-resource
- tag: '1.0'
-
- - name: gcs-resource
- type: docker-image
- source:
- repository: frodenas/gcs-resource
-
- - name: github-pull-request
- type: docker-image
- source:
- repository: gcr.io/magic-modules/concourse-github-pr-resource
- tag: '1.1'
-
-resources:
- - name: magic-modules-gcp
- type: git-branch
- source:
- uri: git@github.com:GoogleCloudPlatform/magic-modules.git
- private_key: ((repo-key.private_key))
-
- - name: gcp-bucket
- type: gcs-resource
- source:
- bucket: ((gcp-bucket))
- json_key: ((gcp-bucket-json-key))
- regexp: dist/terraform-provider-google.*
-
- - name: night-trigger
- type: time
- source:
- start: 11:00 PM
- stop: 11:59 PM
- location: America/Los_Angeles
-
- - name: terraform-head
- type: git-branch
- source:
- uri: git@github.com:terraform-providers/terraform-provider-google.git
- private_key: ((repo-key.private_key))
-jobs:
- - name: coverage-spreadsheet-release
- plan:
- - get: night-trigger
- trigger: true
- - get: magic-modules-gcp
- trigger: false
- - task: build
- file: magic-modules-gcp/.ci/magic-modules/coverage-spreadsheet-upload.yml
- params:
- SERVICE_ACCOUNT: ((magic-modules-service-account))
- - name: nightly-build
- plan:
- - get: night-trigger
- trigger: true
- - get: magic-modules-gcp
- - get: terraform-head
-
- - task: build
- file: magic-modules-gcp/.ci/magic-modules/generate-terraform-all-platforms.yml
-
-{% for arch in ['darwin_amd64', 'freebsd_386', 'freebsd_amd64', 'freebsd_arm',
-'linux_386', 'linux_amd64', 'linux_arm', 'openbsd_386', 'openbsd_amd64',
-'solaris_amd64', 'windows_386.exe', 'windows_amd64.exe'] %}
- - put: gcp-bucket
- params:
- file: dist/terraform-provider-google.{{arch}}
-{% endfor %}
-
- - name: inspec-integration-test
- serial: true
- plan:
- - get: night-trigger
- trigger: true
- - get: magic-modules-gcp
- - task: inspec-integration
- file: magic-modules-gcp/.ci/acceptance-tests/inspec-integration.yml
- params:
- TERRAFORM_KEY: ((terraform-key))
- PROJECT_NAME: ((inspec-project-name))
- PROJECT_NUMBER: ((inspec-project-number))
-
-{% for v in vars.terraform_v.itervalues() %}
- - name: {{v.short_name}}-integration-test
- serial: true
- serial_groups: [terraform-integration]
- plan:
-{% if v.short_name == "terraform-beta" %}
- - get: night-trigger
- trigger: true
-{% endif %}
- - get: magic-modules-gcp
- - task: {{v.short_name}}-integration
- file: magic-modules-gcp/.ci/acceptance-tests/terraform-integration.yml
- params:
- PROVIDER_NAME: {{v.provider_name}}
- SHORT_NAME: {{v.short_name}}
- TEST_DIR: {{v.test_dir}}
-{% endfor %}
-
- - name: ansible-integration-test
- serial: true
- plan:
- - get: night-trigger
- trigger: true
- - get: magic-modules-gcp
- - task: ansible-integration
- file: magic-modules-gcp/.ci/acceptance-tests/ansible-integration.yml
- params:
- SERVICE_ACCOUNT_KEY: ((ansible-integration-key))
- ANSIBLE_TEMPLATE: ((ansible-integration-template))
- IMAGE_KEY: ((image-key))
diff --git a/.ci/unit-tests/inspec.sh b/.ci/unit-tests/inspec.sh
deleted file mode 100755
index 9c0ddd784f9d..000000000000
--- a/.ci/unit-tests/inspec.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# Service account credentials for GCP to allow terraform to work
-export GOOGLE_CLOUD_KEYFILE_JSON="/tmp/google-account.json"
-export GOOGLE_APPLICATION_CREDENTIALS="/tmp/google-account.json"
-
-# CI sets the contents of our json account secret in our environment; dump it
-# to disk for use in tests.
-set +x
-echo "${TERRAFORM_KEY}" > /tmp/google-account.json
-export GCP_PROJECT_NUMBER=${PROJECT_NUMBER}
-export GCP_PROJECT_ID=${PROJECT_NAME}
-export GCP_PROJECT_NAME=${PROJECT_NAME}
-set -x
-
-gcloud auth activate-service-account terraform@graphite-test-sam-chef.iam.gserviceaccount.com --key-file=$GOOGLE_CLOUD_KEYFILE_JSON
-PR_ID="$(cat ./magic-modules-new-prs/.git/id)"
-
-
-pushd magic-modules
-rm build/inspec/test/integration/verify/controls/*
-export VCR_MODE=none
-bundle install
-bundle exec compiler -a -e inspec -o "build/inspec/" -v beta
-
-cp templates/inspec/vcr_config.rb build/inspec
-
-pushd build/inspec
-
-bundle
-# Run rubocop on the generated resources
-bundle exec rubocop -c .rubocop.yml
-
-mkdir inspec-cassettes
-# Check if PR_ID folder exists
-set +e
-gsutil ls gs://magic-modules-inspec-bucket/$PR_ID
-if [ $? -eq 0 ]; then
- gsutil -m cp gs://magic-modules-inspec-bucket/$PR_ID/inspec-cassettes/* inspec-cassettes/
-else
- gsutil -m cp gs://magic-modules-inspec-bucket/master/inspec-cassettes/* inspec-cassettes/
-fi
-set -e
-
-bundle exec rake test:init_workspace
-if test -f "inspec-cassettes/seed.txt"; then
- # Seed the plan with the seed used to record the VCR cassettes.
- # This lets randomly generated suffixes be the same between runs
- bundle exec rake test:plan_integration_tests[$(cat inspec-cassettes/seed.txt)]
-else
- bundle exec rake test:plan_integration_tests
-fi
-
-bundle exec rake test:run_integration_tests
-
-popd
-popd
\ No newline at end of file
diff --git a/.ci/unit-tests/inspec.yml b/.ci/unit-tests/inspec.yml
deleted file mode 100644
index 343104cde4ae..000000000000
--- a/.ci/unit-tests/inspec.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-platform: linux
-inputs:
- - name: magic-modules
- - name: magic-modules-new-prs
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/terraform-gcloud-inspec
- tag: '0.12.16-4.0'
-run:
- path: magic-modules/.ci/unit-tests/inspec.sh
-params:
- PRODUCT: ""
- PROVIDER: inspec
- EXCLUDE_PATTERN: ""
diff --git a/.ci/unit-tests/run.sh b/.ci/unit-tests/run.sh
deleted file mode 100755
index d58fd5f866c3..000000000000
--- a/.ci/unit-tests/run.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-set -x
-
-# Create GOPATH structure
-mkdir -p "${GOPATH}/src/github.com/terraform-providers"
-ln -s "${PWD}/magic-modules/build/$SHORT_NAME" "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-cd "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-go test -v ./$TEST_DIR -parallel 16 -run '^Test' -timeout 1m
diff --git a/.ci/unit-tests/task.yml b/.ci/unit-tests/task.yml
deleted file mode 100644
index a2f4143c9dd8..000000000000
--- a/.ci/unit-tests/task.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-platform: linux
-inputs:
- - name: magic-modules
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-run:
- path: magic-modules/.ci/unit-tests/run.sh
-params:
- PROVIDER_NAME: ""
- SHORT_NAME: ""
- TEST_DIR: ""
diff --git a/.ci/unit-tests/test-terraform.yml b/.ci/unit-tests/test-terraform.yml
deleted file mode 100644
index b65fd0dddbca..000000000000
--- a/.ci/unit-tests/test-terraform.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-platform: linux
-inputs:
- - name: terraform
- - name: magic-modules
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-run:
- path: magic-modules/.ci/unit-tests/run.sh
- args:
- - terraform/
diff --git a/.ci/unit-tests/tf-3.sh b/.ci/unit-tests/tf-3.sh
deleted file mode 100755
index 76168df49deb..000000000000
--- a/.ci/unit-tests/tf-3.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-# Setup GOPATH
-export GOPATH=${PWD}/go
-
-set -x
-
-# Create GOPATH structure
-mkdir -p "${GOPATH}/src/github.com/terraform-providers"
-ln -s "${PWD}/terraform-diff/${SUBDIR}/new" "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-cd "${GOPATH}/src/github.com/terraform-providers/$PROVIDER_NAME"
-
-go test -v ./$TEST_DIR -parallel 16 -run '^Test' -timeout 1m
-
diff --git a/.ci/unit-tests/tf-3.yml b/.ci/unit-tests/tf-3.yml
deleted file mode 100644
index 5565cb003196..000000000000
--- a/.ci/unit-tests/tf-3.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-platform: linux
-inputs:
- - name: magic-modules-branched
- - name: terraform-diff
-image_resource:
- type: docker-image
- source:
- repository: gcr.io/magic-modules/go-ruby-python
- tag: '1.11.5-2.6.0-2.7-v6'
-run:
- path: magic-modules-branched/.ci/unit-tests/tf-3.sh
-params:
- PROVIDER_NAME: ""
- TEST_DIR: ""
- SUBDIR: ""
diff --git a/.ci/vars.tmpl b/.ci/vars.tmpl
deleted file mode 100644
index 52c02eae3e9f..000000000000
--- a/.ci/vars.tmpl
+++ /dev/null
@@ -1,45 +0,0 @@
-{% set terraform_v = {
- 'ga': {
- 'provider_name': 'terraform-provider-google',
- 'short_name': 'terraform',
- 'test_dir': 'google',
- 'github_org': 'terraform-providers',
- 'override_provider': ''
- },
- 'beta': {
- 'provider_name': 'terraform-provider-google-beta',
- 'short_name': 'terraform-beta',
- 'test_dir': 'google-beta',
- 'github_org': 'terraform-providers',
- 'override_provider': ''
- },
- 'validator': {
- 'provider_name': 'terraform-google-conversion',
- 'short_name': 'terraform-mapper',
- 'test_dir': 'google',
- 'github_org': 'GoogleCloudPlatform',
- 'override_provider': 'validator'
- }
- }
-%}
-{% set downstreams_with_changelogs = [
- 'terraform-providers/terraform-provider-google-beta',
- 'terraform-providers/terraform-provider-google'
- ]
-%}
-{% macro build_folder(names) -%}
-{% for name in names %}
-build/{{name}}
-{%- endfor %}
-{% endmacro -%}
-{% set terraform_submodules = build_folder(terraform_v.values()|map(attribute='short_name')).split() %}
-{% set all_submodules =
- (terraform_submodules + ['build/ansible'] + ['build/inspec'])
-%}
-{% set all_submodules_yaml_format = '[' + ','.join(all_submodules) + ']' %}
-{% macro serialize_terraform_properties(objs) -%}
-{% for obj in objs %}
-{{obj.provider_name}}:{{obj.short_name}}:{{obj.github_org}}
-{%- endfor %}
-{% endmacro -%}
-{% set terraform_properties_serialized = serialize_terraform_properties(terraform_v.values()).split() %}
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c35a115c6d31..471b7ed8b855 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,18 +1,6 @@
**Release Note Template for Downstream PRs (will be copied)**
diff --git a/.gitignore b/.gitignore
index 62096f2bee00..858c72df21be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,9 @@
*.pyc
*.python-version
+# Python virtual environment
+.env/*
+
# IDEA files
.idea/*
*.iml
diff --git a/Gemfile.lock b/Gemfile.lock
index a2a8b4588813..3450bc664951 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (5.2.3)
+ activesupport (5.2.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -11,16 +11,16 @@ GEM
ast (2.4.0)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
- concurrent-ruby (1.1.5)
+ concurrent-ruby (1.1.6)
debug_inspector (0.0.3)
diff-lcs (1.3)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
- i18n (1.6.0)
+ i18n (1.8.2)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.4)
metaclass (0.0.4)
- minitest (5.11.3)
+ minitest (5.14.1)
mocha (1.3.0)
metaclass (~> 0.0.1)
multipart-post (2.0.0)
@@ -57,7 +57,7 @@ GEM
addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0)
thread_safe (0.3.6)
- tzinfo (1.2.5)
+ tzinfo (1.2.7)
thread_safe (~> 0.1)
unicode-display_width (1.6.0)
diff --git a/api/product.rb b/api/product.rb
index 23d448e0a766..58e6e0978580 100644
--- a/api/product.rb
+++ b/api/product.rb
@@ -30,8 +30,8 @@ class Product < Api::Object::Named
# Example inputs: "Compute", "AccessContextManager"
# attr_reader :name
- # The full name of the GCP product; eg "Cloud Bigtable"
- attr_reader :display_name
+ # Display Name: The full name of the GCP product; eg "Cloud Bigtable"
+ # A custom getter is used for :display_name instead of `attr_reader`
attr_reader :objects
@@ -76,9 +76,9 @@ def api_name
# The product full name is the "display name" in string form intended for
# users to read in documentation; "Google Compute Engine", "Cloud Bigtable"
- def product_full_name
- if !display_name.nil?
- display_name
+ def display_name
+ if !@display_name.nil?
+ @display_name
else
name.underscore.humanize
end
@@ -92,7 +92,7 @@ def lowest_version
return product_version if ordered_version_name == product_version.name
end
end
- raise "Unable to find lowest version for product #{product_full_name}"
+ raise "Unable to find lowest version for product #{display_name}"
end
def version_obj(name)
@@ -116,7 +116,7 @@ def version_obj_or_closest(name)
return version_obj(version) if exists_at_version(version)
end
- raise "Could not find object for version #{name} and product #{product_full_name}"
+ raise "Could not find object for version #{name} and product #{display_name}"
end
def exists_at_version_or_lower(name)
diff --git a/api/resource.rb b/api/resource.rb
index 10fcbbc33778..21bb1c27fee8 100644
--- a/api/resource.rb
+++ b/api/resource.rb
@@ -205,6 +205,16 @@ def required_properties
all_user_properties.select(&:required)
end
+ def all_nested_properties(props)
+ nested = props
+ props.each do |prop|
+ if !prop.flatten_object && prop.nested_properties?
+ nested += all_nested_properties(prop.nested_properties)
+ end
+ end
+ nested
+ end
+
# Returns all resourcerefs at any depth
def all_resourcerefs
resourcerefs_for_properties(all_user_properties, self)
diff --git a/api/type.rb b/api/type.rb
index 1ff7239d935e..b3f369477b41 100644
--- a/api/type.rb
+++ b/api/type.rb
@@ -31,6 +31,11 @@ module Fields
# string, as providers expect a single-line one w/o a newline.
attr_reader :deprecation_message
+ # Add a removed message for fields no longer supported in the API. This should
+ # be used for fields supported in one version but have been removed from
+ # a different version.
+ attr_reader :removed_message
+
attr_reader :output # If set value will not be sent to server on sync
attr_reader :input # If set to true value is used only on creation
@@ -70,6 +75,7 @@ module Fields
attr_reader :allow_empty_object
attr_reader :min_version
+ attr_reader :exact_version
# A list of properties that conflict with this property.
attr_reader :conflicts
@@ -99,7 +105,9 @@ def validate
check :description, type: ::String, required: true
check :exclude, type: :boolean, default: false, required: true
check :deprecation_message, type: ::String
+ check :removed_message, type: ::String
check :min_version, type: ::String
+ check :exact_version, type: ::String
check :output, type: :boolean
check :required, type: :boolean
check :send_empty_value, type: :boolean
@@ -132,9 +140,9 @@ def to_s
# The only intended purpose is to allow better error messages. Some objects
# and at some points in the build this doesn't output a valid output.
def lineage
- return name if __parent.nil?
+ return name&.underscore if __parent.nil?
- __parent.lineage + '.' + name
+ __parent.lineage + '.' + name&.underscore
end
def to_json(opts = nil)
@@ -258,7 +266,14 @@ def min_version
end
end
+ def exact_version
+ return nil if @exact_version.nil? || @exact_version.blank?
+
+ @__resource.__product.version_obj(@exact_version)
+ end
+
def exclude_if_not_in_version!(version)
+ @exclude ||= exact_version != version unless exact_version.nil?
@exclude ||= version < min_version
end
@@ -289,6 +304,10 @@ def nested_properties?
!nested_properties.empty?
end
+ def removed?
+ !(@removed_message.nil? || @removed_message == '')
+ end
+
def deprecated?
!(@deprecation_message.nil? || @deprecation_message == '')
end
@@ -437,10 +456,12 @@ def item_type_class
# Represents an enum, and store is valid values
class Enum < Primitive
attr_reader :values
+ attr_reader :skip_docs_values
def validate
super
check :values, type: ::Array, item_type: [Symbol, ::String, ::Integer], required: true
+ check :skip_docs_values, type: :boolean
end
end
diff --git a/compile/core.rb b/compile/core.rb
index d5731df55ee0..883e0c5e53e5 100644
--- a/compile/core.rb
+++ b/compile/core.rb
@@ -226,9 +226,9 @@ def compile_string(ctx, source)
end
end
- def autogen_notice(lang)
+ def autogen_notice(lang, pwd)
Thread.current[:autogen] = true
- comment_block(compile('templates/autogen_notice.erb').split("\n"), lang)
+ comment_block(compile(pwd + '/templates/autogen_notice.erb').split("\n"), lang)
end
def autogen_exception
diff --git a/compiler.rb b/compiler.rb
index 8f4bfb4c46dc..167e40c9535b 100755
--- a/compiler.rb
+++ b/compiler.rb
@@ -24,6 +24,7 @@
ENV['TZ'] = 'UTC'
require 'active_support/inflector'
+require 'active_support/core_ext/array/conversions'
require 'api/compiler'
require 'google/logger'
require 'optparse'
diff --git a/overrides/terraform/resource_override.rb b/overrides/terraform/resource_override.rb
index b009b7e2b5bc..316af5d576c9 100644
--- a/overrides/terraform/resource_override.rb
+++ b/overrides/terraform/resource_override.rb
@@ -24,6 +24,13 @@ module Terraform
class ResourceOverride < Overrides::ResourceOverride
def self.attributes
[
+ # If non-empty, overrides the full filename prefix
+ # i.e. google/resource_product_{{resource_filename_override}}.go
+ # i.e. google/resource_product_{{resource_filename_override}}_test.go
+ # Note this doesn't override the actual resource name
+ # use :legacy_name instead.
+ :filename_override,
+
# If non-empty, overrides the full given resource name.
# i.e. 'google_project' for resourcemanager.Project
# Use Provider::Terraform::Config.legacy_name to override just
@@ -75,7 +82,12 @@ def self.attributes
# This enables resources that get their project via a reference to a different resource
# instead of a project field to use User Project Overrides
- :supports_indirect_user_project_override
+ :supports_indirect_user_project_override,
+
+ # Function to transform a read error so that handleNotFound recognises
+ # it as a 404. This should be added as a handwritten fn that takes in
+ # an error and returns one.
+ :read_error_transform
]
end
@@ -87,11 +99,12 @@ def validate
@examples ||= []
+ check :filename_override, type: String
check :legacy_name, type: String
check :id_format, type: String
check :examples, item_type: Provider::Terraform::Examples, type: Array, default: []
check :virtual_fields,
- item_type: Provider::Terraform::VirtualFields,
+ item_type: Api::Type,
type: Array,
default: []
@@ -108,6 +121,7 @@ def validate
check :skip_sweeper, type: :boolean, default: false
check :skip_delete, type: :boolean, default: false
check :supports_indirect_user_project_override, type: :boolean, default: false
+ check :read_error_transform, type: String
end
def apply(resource)
diff --git a/products/accesscontextmanager/api.yaml b/products/accesscontextmanager/api.yaml
index edb683651bca..a9ba4660e640 100644
--- a/products/accesscontextmanager/api.yaml
+++ b/products/accesscontextmanager/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: AccessContextManager
-display_name: Access Context Manager
+display_name: Access Context Manager (VPC Service Controls)
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -148,6 +148,8 @@ objects:
name: 'basic'
description: |
A set of predefined conditions for the access level and a combining function.
+ conflicts:
+ - custom
properties:
- !ruby/object:Api::Type::Enum
name: 'combiningFunction'
@@ -156,7 +158,7 @@ objects:
is granted this AccessLevel. If AND is used, each Condition in
conditions must be satisfied for the AccessLevel to be applied. If
OR is used, at least one Condition in conditions must be satisfied
- for the AccessLevel to be applied. Defaults to AND if unspecified.
+ for the AccessLevel to be applied.
default_value: :AND
values:
- :AND
@@ -221,6 +223,7 @@ objects:
properties:
- !ruby/object:Api::Type::Boolean
name: 'requireScreenLock'
+ api_name: 'requireScreenlock'
description: |
Whether or not screenlock is required for the DevicePolicy
to be true. Defaults to false.
@@ -293,6 +296,35 @@ objects:
countries/regions.
Format: A valid ISO 3166-1 alpha-2 code.
item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'custom'
+ description: |
+ Custom access level conditions are set using the Cloud Common Expression Language to represent the necessary conditions for the level to apply to a request.
+ See CEL spec at: https://github.com/google/cel-spec.
+ conflicts:
+ - basic
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'expr'
+ required: true
+ description: |
+ Represents a textual expression in the Common Expression Language (CEL) syntax. CEL is a C-like expression language.
+ This page details the objects and attributes that are used to the build the CEL expressions for
+ custom access levels - https://cloud.google.com/access-context-manager/docs/custom-access-level-spec.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'expression'
+ required: true
+ description: Textual representation of an expression in Common Expression Language syntax.
+ - !ruby/object:Api::Type::String
+ name: 'title'
+ description: Title for the expression, i.e. a short string describing its purpose.
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: Description of the expression
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ description: String indicating the location of the expression for error reporting, e.g. a file name and a position in the file
- !ruby/object:Api::Resource
name: 'ServicePerimeter'
# This is an unusual API, so we need to use a few fields to map the methods
diff --git a/products/activedirectory/api.yaml b/products/activedirectory/api.yaml
new file mode 100644
index 000000000000..f63f88d9f02b
--- /dev/null
+++ b/products/activedirectory/api.yaml
@@ -0,0 +1,107 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: ActiveDirectory
+display_name: Managed Microsoft Active Directory
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://managedidentities.googleapis.com/v1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ path: 'name'
+ base_url: '{{op_id}}'
+ wait_ms: 1000
+ # It takes about 35-40 mins to get the resource created
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 60
+ update_minutes: 60
+ delete_minutes: 60
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: true
+ allowed:
+ - true
+ - false
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Domain'
+ kind: 'activedirectory#domain'
+ base_url : projects/{{project}}/locations/global/domains?domainName={{domain_name}}
+ update_verb: :PATCH
+ update_mask: true
+ self_link: '{{name}}'
+ description: Creates a Microsoft AD domain
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Managed Microsoft Active Directory Quickstart': 'https://cloud.google.com/managed-microsoft-ad/docs/quickstarts'
+ api: 'https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: domainName
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ The fully qualified domain name. e.g. mydomain.myorganization.com, with the restrictions,
+ https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ output: true
+ description: 'The unique name of the domain using the format: `projects/{project}/locations/global/domains/{domainName}`.'
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: 'Resource labels that can contain user-provided metadata'
+ - !ruby/object:Api::Type::Array
+ name: 'authorizedNetworks'
+ item_type: Api::Type::String
+ description: |
+ The full names of the Google Compute Engine networks the domain instance is connected to. The domain is only available on networks listed in authorizedNetworks.
+ If CIDR subnets overlap between networks, domain creation will fail.
+ - !ruby/object:Api::Type::String
+ name: 'reservedIpRange'
+ required: true
+ input: true
+ description: |
+ The CIDR range of internal addresses that are reserved for this domain. Reserved networks must be /24 or larger.
+ Ranges must be unique and non-overlapping with existing subnets in authorizedNetworks
+ - !ruby/object:Api::Type::Array
+ name: 'locations'
+ required: true
+ item_type: Api::Type::String
+ description: |
+ Locations where domain needs to be provisioned. [regions][compute/docs/regions-zones/]
+ e.g. us-west1 or us-east4 Service supports up to 4 locations at once. Each location will use a /26 block.
+ - !ruby/object:Api::Type::String
+ name: 'admin'
+ default_value: 'setupadmin'
+ input: true
+ description: |
+ The name of delegated administrator account used to perform Active Directory operations.
+ If not specified, setupadmin will be used.
+ - !ruby/object:Api::Type::String
+ name: 'fqdn'
+ output: true
+ description: |
+ The fully-qualified domain name of the exposed domain used by clients to connect to the service.
+ Similar to what would be chosen for an Active Directory set up on an internal network.
\ No newline at end of file
diff --git a/products/activedirectory/terraform.yaml b/products/activedirectory/terraform.yaml
new file mode 100644
index 000000000000..8ff5dfbda36c
--- /dev/null
+++ b/products/activedirectory/terraform.yaml
@@ -0,0 +1,39 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Domain: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ autogen_async: true
+ properties:
+ authorizedNetworks: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ domainName: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateADDomainName()'
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "active_directory_domain_basic"
+ primary_resource_id: "ad-domain"
+ vars:
+ name: "myorg"
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/appengine/api.yaml b/products/appengine/api.yaml
index 58ab43d0f5db..a7e6987ec445 100644
--- a/products/appengine/api.yaml
+++ b/products/appengine/api.yaml
@@ -185,7 +185,7 @@ objects:
- !ruby/object:Api::Resource
name: 'Service'
description: |
- A Service resource is a logical component of an application that can share state and communicate in a secure fashion with other services.
+ A Service resource is a logical component of an application that can share state and communicate in a secure fashion with other services.
For example, an application that handles customer requests might include separate services to handle tasks such as backend data analysis or API requests from mobile devices.
Each service has a collection of versions that define a specific set of code used to implement the functionality of that service.
base_url: 'apps/{{project}}/services'
@@ -215,8 +215,9 @@ objects:
name: 'StandardAppVersion'
description: |
Standard App Version resource to create a new version of standard GAE Application.
+ Learn about the differences between the standard environment and the flexible environment
+ at https://cloud.google.com/appengine/docs/the-appengine-environments.
Currently supporting Zip and File Containers.
- Currently does not support async operation checking.
collection_url_key: 'versions'
base_url: 'apps/{{project}}/services/{{service}}/versions'
delete_url: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}'
@@ -224,7 +225,8 @@ objects:
update_url: 'apps/{{project}}/services/{{service}}/versions'
update_verb: :POST
update_mask: false
- self_link: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}'
+ create_url: 'apps/{{project}}/services/{{service}}/versions'
+ self_link: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}?view=FULL'
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation':
@@ -254,6 +256,7 @@ objects:
url_param_only: true
resource: 'Service'
imports: 'name'
+ required: true
description: |
AppEngine service resource
properties:
@@ -271,7 +274,7 @@ objects:
name: 'runtime'
description: |
Desired runtime. Example python27.
- required: true
+ required: true
- !ruby/object:Api::Type::Boolean
name: 'threadsafe'
description: |
@@ -279,19 +282,19 @@ objects:
- !ruby/object:Api::Type::String
name: 'runtimeApiVersion'
description: |
- The version of the API in the given runtime environment.
+ The version of the API in the given runtime environment.
Please see the app.yaml reference for valid values at https://cloud.google.com/appengine/docs/standard//config/appref
- !ruby/object:Api::Type::Array
name: 'handlers'
description: |
- An ordered list of URL-matching patterns that should be applied to incoming requests.
- The first matching URL handles the request and other request handlers are not attempted.
+ An ordered list of URL-matching patterns that should be applied to incoming requests.
+ The first matching URL handles the request and other request handlers are not attempted.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: 'urlRegex'
description: |
- URL prefix. Uses regular expression syntax, which means regexp special characters must be escaped, but should not contain groupings.
+ URL prefix. Uses regular expression syntax, which means regexp special characters must be escaped, but should not contain groupings.
All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path.
- !ruby/object:Api::Type::Enum
name: 'securityLevel'
@@ -334,7 +337,7 @@ objects:
name: 'script'
# TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set
description: |
- Executes a script to handle the requests that match this URL pattern.
+ Executes a script to handle the requests that match this URL pattern.
Only the auto value is supported for Node.js in the App Engine standard environment, for example "script:" "auto".
properties:
- !ruby/object:Api::Type::String
@@ -378,7 +381,9 @@ objects:
- !ruby/object:Api::Type::Boolean
name: 'applicationReadable'
description: |
- Whether files should also be uploaded as code data. By default, files declared in static file handlers are uploaded as static data and are only served to end users; they cannot be read by the application. If enabled, uploads are charged against both your code and static data storage resource quotas.
+ Whether files should also be uploaded as code data. By default, files declared in static file handlers are uploaded as
+ static data and are only served to end users; they cannot be read by the application. If enabled, uploads are charged
+ against both your code and static data storage resource quotas.
- !ruby/object:Api::Type::Array
name: 'libraries'
description: |
@@ -401,8 +406,8 @@ objects:
name: 'deployment'
description: |
Code and application artifacts that make up this version.
- required: false
- properties:
+ required: true
+ properties:
- !ruby/object:Api::Type::NestedObject
name: 'zip'
description: 'Zip File'
@@ -453,12 +458,107 @@ objects:
required: true
description: |
The format should be a shell command that can be fed to bash -c.
+ - !ruby/object:Api::Type::Array
+ name: 'inboundServices'
+ description: |
+ Before an application can receive email or XMPP messages, the application must be configured to enable the service.
+ item_type: Api::Type::String
- !ruby/object:Api::Type::String
name: 'instanceClass'
description: |
Instance class that is used to run this version. Valid values are
- AutomaticScaling F1, F2, F4, F4_1G
- (Only AutomaticScaling is supported at the moment)
+ AutomaticScaling: F1, F2, F4, F4_1G
+ BasicScaling or ManualScaling: B1, B2, B4, B4_1G, B8
+ Defaults to F1 for AutomaticScaling and B2 for ManualScaling and BasicScaling. If no scaling is specified, AutomaticScaling is chosen.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'automaticScaling'
+ description: |
+ Automatic scaling is based on request rate, response latencies, and other application metrics.
+ conflicts:
+ - basicScaling
+ - manualScaling
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'maxConcurrentRequests'
+ description: |
+ Number of concurrent requests an automatic scaling instance can accept before the scheduler spawns a new instance.
+
+ Defaults to a runtime-specific value.
+ - !ruby/object:Api::Type::Integer
+ name: 'maxIdleInstances'
+ description: |
+ Maximum number of idle instances that should be maintained for this version.
+ - !ruby/object:Api::Type::String
+ name: 'maxPendingLatency'
+ description: |
+ Maximum amount of time that a request should wait in the pending queue before starting a new instance to handle it.
+ A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".
+ - !ruby/object:Api::Type::Integer
+ name: 'minIdleInstances'
+ description: |
+ Minimum number of idle instances that should be maintained for this version. Only applicable for the default version of a service.
+ - !ruby/object:Api::Type::String
+ name: 'minPendingLatency'
+ description: |
+ Minimum amount of time a request should wait in the pending queue before starting a new instance to handle it.
+ A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".
+ - !ruby/object:Api::Type::NestedObject
+ name: 'standardSchedulerSettings'
+ description: |
+ Scheduler settings for standard environment.
+ properties:
+ - !ruby/object:Api::Type::Double
+ name: 'targetCpuUtilization'
+ description: |
+ Target CPU utilization ratio to maintain when scaling. Should be a value in the range [0.50, 0.95], zero, or a negative value.
+ - !ruby/object:Api::Type::Double
+ name: 'targetThroughputUtilization'
+ description: |
+ Target throughput utilization ratio to maintain when scaling. Should be a value in the range [0.50, 0.95], zero, or a negative value.
+ - !ruby/object:Api::Type::Integer
+ name: 'minInstances'
+ description: |
+ Minimum number of instances to run for this version. Set to zero to disable minInstances configuration.
+ - !ruby/object:Api::Type::Integer
+ name: 'maxInstances'
+ description: |
+ Maximum number of instances to run for this version. Set to zero to disable maxInstances configuration.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'basicScaling'
+ description: |
+ Basic scaling creates instances when your application receives requests. Each instance will be shut down when the application becomes idle. Basic scaling is ideal for work that is intermittent or driven by user activity.
+ conflicts:
+ - automaticScaling
+ - manualScaling
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'idleTimeout'
+ default_value: 900s
+ description: |
+ Duration of time after the last request that an instance must wait before the instance is shut down.
+ A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s". Defaults to 900s.
+ - !ruby/object:Api::Type::Integer
+ name: 'maxInstances'
+ required: true
+ description: |
+ Maximum number of instances to create for this version. Must be in the range [1.0, 200.0].
+ - !ruby/object:Api::Type::NestedObject
+ name: 'manualScaling'
+ description: |
+ A service with manual scaling runs continuously, allowing you to perform complex initialization and rely on the state of its memory over time.
+ conflicts:
+ - automaticScaling
+ - basicScaling
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'instances'
+ required: true
+ description: |
+ Number of instances to assign to the service at the start.
+
+ **Note:** When managing the number of instances at runtime through the App Engine Admin API or the (now deprecated) Python 2
+ Modules API set_num_instances() you must use `lifecycle.ignore_changes = ["manual_scaling"[0].instances]` to prevent drift detection.
+
# StandardAppVersion and FlexibleAppVersion use the same API endpoint (apps.services.versions)
# They are split apart as some of the fields will are necessary for one and not the other, and
# other fields may have different defaults. However, some fields are the same. If fixing a bug
@@ -479,7 +579,7 @@ objects:
update_url: 'apps/{{project}}/services/{{service}}/versions'
update_verb: :POST
update_mask: false
- self_link: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}'
+ self_link: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}?view=FULL'
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation':
@@ -510,6 +610,7 @@ objects:
parameters:
- !ruby/object:Api::Type::ResourceRef
name: 'service'
+ required: true
url_param_only: true
resource: 'Service'
imports: 'name'
@@ -644,7 +745,6 @@ objects:
name: 'servingStatus'
description: |
Current serving status of this version. Only the versions with a SERVING status create instances and can be billed.
- Defaults to SERVING.
default_value: :SERVING
values:
- :SERVING
@@ -652,8 +752,112 @@ objects:
- !ruby/object:Api::Type::String
name: 'runtimeApiVersion'
description: |
- The version of the API in the given runtime environment.
+ The version of the API in the given runtime environment.
Please see the app.yaml reference for valid values at https://cloud.google.com/appengine/docs/standard//config/appref
+ - !ruby/object:Api::Type::Array
+ name: 'handlers'
+ description: |
+ An ordered list of URL-matching patterns that should be applied to incoming requests.
+ The first matching URL handles the request and other request handlers are not attempted.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'urlRegex'
+ description: |
+ URL prefix. Uses regular expression syntax, which means regexp special characters must be escaped, but should not contain groupings.
+ All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path.
+ - !ruby/object:Api::Type::Enum
+ name: 'securityLevel'
+ required: false
+ description: |
+ Security (HTTPS) enforcement for this URL.
+ values:
+ - :SECURE_DEFAULT
+ - :SECURE_NEVER
+ - :SECURE_OPTIONAL
+ - :SECURE_ALWAYS
+ - !ruby/object:Api::Type::Enum
+ name: 'login'
+ description: |
+ Methods to restrict access to a URL based on login status.
+ required: false
+ values:
+ - :LOGIN_OPTIONAL
+ - :LOGIN_ADMIN
+ - :LOGIN_REQUIRED
+ - !ruby/object:Api::Type::Enum
+ name: 'authFailAction'
+ description: |
+ Actions to take when the user is not logged in.
+ required: false
+ values:
+ - :AUTH_FAIL_ACTION_REDIRECT
+ - :AUTH_FAIL_ACTION_UNAUTHORIZED
+ - !ruby/object:Api::Type::Enum
+ name: 'redirectHttpResponseCode'
+ description: |
+ 30x code to use when performing redirects for the secure field.
+ required: false
+ values:
+ - :REDIRECT_HTTP_RESPONSE_CODE_301
+ - :REDIRECT_HTTP_RESPONSE_CODE_302
+ - :REDIRECT_HTTP_RESPONSE_CODE_303
+ - :REDIRECT_HTTP_RESPONSE_CODE_307
+ - !ruby/object:Api::Type::NestedObject
+ name: 'script'
+ # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set
+ description: |
+ Executes a script to handle the requests that match this URL pattern.
+ Only the auto value is supported for Node.js in the App Engine standard environment, for example "script:" "auto".
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'scriptPath'
+ required: true
+ description: |
+ Path to the script from the application root directory.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'staticFiles'
+ # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set
+ description: |
+ Files served directly to the user for a given URL, such as images, CSS stylesheets, or JavaScript source files.
+ Static file handlers describe which files in the application directory are static files, and which URLs serve them.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'path'
+ description: |
+ Path to the static files matched by the URL pattern, from the application root directory.
+ The path can refer to text matched in groupings in the URL pattern.
+ - !ruby/object:Api::Type::String
+ name: 'uploadPathRegex'
+ description: |
+ Regular expression that matches the file paths for all files that should be referenced by this handler.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'httpHeaders'
+ description: |
+ HTTP headers to use for all responses from these URLs.
+ An object containing a list of "key:value" value pairs.".
+ - !ruby/object:Api::Type::String
+ name: 'mimeType'
+ description: |
+ MIME type used to serve all files served by this handler.
+ Defaults to file-specific MIME types, which are derived from each file's filename extension.
+ - !ruby/object:Api::Type::String
+ name: 'expiration'
+ description: |
+ Time a static file served by this handler should be cached by web proxies and browsers.
+ A duration in seconds with up to nine fractional digits, terminated by 's'. Example "3.5s".
+ Default is '0s'
+ default_value: '0s'
+ - !ruby/object:Api::Type::Boolean
+ name: 'requireMatchingFile'
+ description: |
+ Whether this handler should match the request if the file referenced by the handler does not exist.
+ - !ruby/object:Api::Type::Boolean
+ name: 'applicationReadable'
+ description: |
+ Whether files should also be uploaded as code data. By default, files declared in static file handlers are
+ uploaded as static data and are only served to end users; they cannot be read by the application. If enabled,
+ uploads are charged against both your code and static data storage resource quotas.
- !ruby/object:Api::Type::String
name: 'runtimeMainExecutablePath'
description: |
@@ -666,7 +870,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'authFailAction'
description: |
- Action to take when users access resources that require authentication. Defaults to "AUTH_FAIL_ACTION_REDIRECT".
+ Action to take when users access resources that require authentication.
default_value: :AUTH_FAIL_ACTION_REDIRECT
values:
- :AUTH_FAIL_ACTION_REDIRECT
@@ -674,7 +878,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'login'
description: |
- Level of login required to access this resource. Defaults to "LOGIN_OPTIONAL".
+ Level of login required to access this resource.
default_value: :LOGIN_OPTIONAL
values:
- :LOGIN_OPTIONAL
@@ -895,7 +1099,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'rolloutStrategy'
description: |
- Endpoints rollout strategy. If FIXED, configId must be specified. If MANAGED, configId must be omitted. Default is "FIXED".
+ Endpoints rollout strategy. If FIXED, configId must be specified. If MANAGED, configId must be omitted.
default_value: :FIXED
values:
- :FIXED
@@ -1100,7 +1304,10 @@ objects:
name: 'instances'
required: true
description: |
- Number of instances to assign to the service at the start. This number can later be altered by using the Modules API set_num_instances() function.
+ Number of instances to assign to the service at the start.
+
+ **Note:** When managing the number of instances at runtime through the App Engine Admin API or the (now deprecated) Python 2
+ Modules API set_num_instances() you must use `lifecycle.ignore_changes = ["manual_scaling"[0].instances]` to prevent drift detection.
- !ruby/object:Api::Resource
name: 'ApplicationUrlDispatchRules'
description: |
@@ -1132,7 +1339,7 @@ objects:
path: 'error/errors'
message: 'message'
properties:
- - !ruby/object:Api::Type::Array
+ - !ruby/object:Api::Type::Array
name: 'dispatchRules'
required: true
description: |
@@ -1206,7 +1413,7 @@ objects:
description: |
Mapping that defines fractional HTTP traffic diversion to different versions within the service.
required: true
- properties:
+ properties:
- !ruby/object:Api::Type::Enum
name: 'shardBy'
description: |
@@ -1221,5 +1428,3 @@ objects:
required: true
description: |
Mapping from version IDs within the service to fractional (0.000, 1] allocations of traffic for that version. Each version can be specified only once, but some versions in the service may not have any traffic allocation. Services that have traffic allocated cannot be deleted until either the service is deleted or their traffic allocation is removed. Allocations must sum to 1. Up to two decimal place precision is supported for IP-based splits and up to three decimal places is supported for cookie-based splits.
-
-
diff --git a/products/appengine/terraform.yaml b/products/appengine/terraform.yaml
index 4f3b3d155274..a69384a76a54 100644
--- a/products/appengine/terraform.yaml
+++ b/products/appengine/terraform.yaml
@@ -16,6 +16,14 @@ overrides: !ruby/object:Overrides::ResourceOverrides
FirewallRule: !ruby/object:Overrides::Terraform::ResourceOverride
import_format: ["apps/{{project}}/firewall/ingressRules/{{priority}}"]
mutex: "apps/{{project}}"
+ async: !ruby/object:Provider::Terraform::PollAsync
+ check_response_func_existence: PollCheckForExistence
+ actions: ['create']
+ operation: !ruby/object:Api::Async::Operation
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 4
+ update_minutes: 4
+ delete_minutes: 4
# This resource is a child resource (requires app ID in the URL)
skip_sweeper: true
examples:
@@ -28,6 +36,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
org_id: :ORG_ID
StandardAppVersion: !ruby/object:Overrides::Terraform::ResourceOverride
import_format: ["apps/{{project}}/services/{{service}}/versions/{{version_id}}"]
+ id_format: "apps/{{project}}/services/{{service}}/versions/{{version_id}}"
mutex: "apps/{{project}}"
error_retry_predicates: ["isAppEngineRetryableError"]
parameters:
@@ -35,12 +44,14 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_from_api: true
required: false
virtual_fields:
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'noop_on_destroy'
+ default_value: false
description: |
If set to `true`, the application version will not be deleted.
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'delete_service_on_destroy'
+ default_value: false
description: |
If set to `true`, the service will be deleted if it is the last version.
custom_code: !ruby/object:Provider::Terraform::CustomCode
@@ -57,8 +68,13 @@ overrides: !ruby/object:Overrides::ResourceOverrides
ignore_read: true
threadsafe: !ruby/object:Overrides::Terraform::PropertyOverride
ignore_read: true
+ handlers: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ # instanceClass defaults to a value based on the scaling method
instanceClass: !ruby/object:Overrides::Terraform::PropertyOverride
- ignore_read: true
+ default_from_api: true
+ inboundServices: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "app_engine_standard_app_version"
@@ -73,6 +89,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
org_id: :ORG_ID
FlexibleAppVersion: !ruby/object:Overrides::Terraform::ResourceOverride
import_format: ["apps/{{project}}/services/{{service}}/versions/{{version_id}}"]
+ id_format: "apps/{{project}}/services/{{service}}/versions/{{version_id}}"
mutex: "apps/{{project}}"
error_retry_predicates: ["isAppEngineRetryableError"]
parameters:
@@ -80,17 +97,19 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_from_api: true
required: false
virtual_fields:
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'noop_on_destroy'
+ default_value: false
description: |
If set to `true`, the application version will not be deleted.
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'delete_service_on_destroy'
+ default_value: false
description: |
If set to `true`, the service will be deleted if it is the last version.
custom_code: !ruby/object:Provider::Terraform::CustomCode
custom_delete: templates/terraform/custom_delete/appversion_delete.go.erb
- test_check_destroy: templates/terraform/custom_check_destroy/appengine.go.erb
+ test_check_destroy: templates/terraform/custom_check_destroy/skip_delete_during_test.go.erb
encoder: templates/terraform/encoders/flex_app_version.go.erb
properties:
id: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -116,15 +135,22 @@ overrides: !ruby/object:Overrides::ResourceOverrides
# runtimeApiVersion defaults to a runtime-specific value
runtimeApiVersion: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ handlers: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ inboundServices: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "app_engine_flexible_app_version"
primary_resource_id: "myapp_v1"
ignore_read_extra:
- - "delete_service_on_destroy"
+ - "noop_on_destroy"
vars:
bucket_name: "appengine-static-content"
- service_name: "service-"
+ project: "appeng-flex"
+ test_env_vars:
+ org_id: :ORG_ID
+ billing_account: :BILLING_ACCT
Service: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
DomainMapping: !ruby/object:Overrides::Terraform::ResourceOverride
diff --git a/products/artifactregistry/api.yaml b/products/artifactregistry/api.yaml
new file mode 100644
index 000000000000..8b2747014458
--- /dev/null
+++ b/products/artifactregistry/api.yaml
@@ -0,0 +1,118 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: ArtifactRegistry
+display_name: Artifact Registry
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://artifactregistry.googleapis.com/v1beta1/
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Artifact Registry API
+ url: https://console.cloud.google.com/apis/library/artifactregistry.googleapis.com/
+async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ path: 'name'
+ base_url: '{{op_id}}'
+ wait_ms: 1000
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: true
+ allowed:
+ - true
+ - false
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Repository'
+ base_url: projects/{{project}}/locations/{{location}}/repositories
+ create_url: projects/{{project}}/locations/{{location}}/repositories?repository_id={{repository_id}}
+ min_version: beta
+ description: A repository for storing artifacts
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/artifact-registry/docs/overview'
+ api: 'https://cloud.google.com/artifact-registry/docs/reference/rest/'
+ iam_policy: !ruby/object:Api::Resource::IamPolicy
+ exclude: false
+ method_name_separator: ':'
+ parent_resource_attribute: 'repository'
+ import_format: ["projects/{{project}}/locations/{{location}}/repositories/{{repository}}", "{{repository}}"]
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |-
+ The name of the repository, for example:
+ "projects/p1/locations/us-central1/repositories/repo1"
+ output: true
+ - !ruby/object:Api::Type::String
+ name: repository_id
+ description: |-
+ The last part of the repository name, for example:
+ "repo1"
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ description: |
+ The name of the location this repository is located in.
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::Enum
+ name: format
+ description: |-
+ The format of packages that are stored in the repoitory.
+ values:
+ - :DOCKER
+ required: true
+ input: true
+ - !ruby/object:Api::Type::String
+ name: description
+ description: |-
+ The user-provided description of the repository.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Labels with user-defined metadata.
+ This field may contain up to 64 entries. Label keys and values may be no
+ longer than 63 characters. Label keys must begin with a lowercase letter
+ and may only contain lowercase letters, numeric characters, underscores,
+ and dashes.
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyName'
+ description: |-
+ The Cloud KMS resource name of the customer managed encryption key that’s
+ used to encrypt the contents of the Repository. Has the form:
+ `projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key`.
+ This value may not be changed after the Repository has been created.
+ input: true
+ - !ruby/object:Api::Type::Time
+ name: createTime
+ description: The time when the repository was created.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: updateTime
+ description: The time when the repository was last updated.
+ output: true
diff --git a/products/artifactregistry/terraform.yaml b/products/artifactregistry/terraform.yaml
new file mode 100644
index 000000000000..bf0b1314ee25
--- /dev/null
+++ b/products/artifactregistry/terraform.yaml
@@ -0,0 +1,52 @@
+# Copyright 2019 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Repository: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: projects/{{project}}/locations/{{location}}/repositories/{{repsitory_id}}
+ autogen_async: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "artifact_registry_repository_basic"
+ min_version: 'beta'
+ primary_resource_id: "my-repo"
+ vars:
+ repository_id: "my-repository"
+ description: "example docker repository"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "artifact_registry_repository_cmek"
+ min_version: 'beta'
+ primary_resource_id: "my-repo"
+ vars:
+ repository_id: "my-repository"
+ kms_key_name: "kms-key"
+ test_vars_overrides:
+ kms_key_name: 'BootstrapKMSKeyInLocation(t, "us-central1").CryptoKey.Name'
+ - !ruby/object:Provider::Terraform::Examples
+ name: "artifact_registry_repository_iam"
+ min_version: 'beta'
+ primary_resource_id: "my-repo"
+ vars:
+ account_id: "my-account"
+ repository_id: "my-repository"
+ description: "example docker repository with iam"
+ properties:
+ location: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ repository_id: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
diff --git a/products/bigquery/ansible.yaml b/products/bigquery/ansible.yaml
index 635d75872a83..fcf0bd70ac05 100644
--- a/products/bigquery/ansible.yaml
+++ b/products/bigquery/ansible.yaml
@@ -51,6 +51,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
underscores. The maximum length is 1,024 characters.
DatasetAccess: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ Job: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
files: !ruby/object:Provider::Config::Files
resource:
<%= lines(indent(compile('provider/ansible/resource~compile.yaml'), 4)) -%>
diff --git a/products/bigquery/api.yaml b/products/bigquery/api.yaml
index c81b707516d6..2113120d43bb 100644
--- a/products/bigquery/api.yaml
+++ b/products/bigquery/api.yaml
@@ -61,7 +61,7 @@ objects:
member of the access object. Primitive, Predefined and custom
roles are supported. Predefined roles that have equivalent
primitive roles are swapped by the API to their Primitive
- counterparts, and will show a diff post-create. See
+ counterparts. See
[official docs](https://cloud.google.com/bigquery/docs/access-control).
- !ruby/object:Api::Type::String
name: 'specialGroup'
@@ -383,6 +383,605 @@ objects:
A-Z), numbers (0-9), or underscores (_). The maximum length
is 1,024 characters.
required: true
+
+ - !ruby/object:Api::Resource
+ name: 'Job'
+ kind: 'bigquery#job'
+ base_url: projects/{{project}}/jobs
+ self_link: projects/{{project}}/jobs/{{job_id}}
+ input: true
+ description: |
+ Jobs are actions that BigQuery runs on your behalf to load data, export data, query data, or copy data.
+ Once a BigQuery job is created, it cannot be changed or deleted.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ output: true
+ description: |
+ Opaque ID field of the job.
+ - !ruby/object:Api::Type::String
+ name: 'user_email'
+ output: true
+ description: |
+ Email address of the user who ran the job.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'configuration'
+ description: 'Describes the job configuration.'
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'jobType'
+ description: |
+ The type of the job.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'jobTimeoutMs'
+ description: |
+ Job timeout in milliseconds. If this time limit is exceeded, BigQuery may attempt to terminate the job.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ The labels associated with this job. You can use these to organize and group your jobs.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'query'
+ description: 'Configures a query job.'
+ exactly_one_of:
+ - query
+ - load
+ - copy
+ - extract
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'query'
+ description: |
+ SQL query text to execute. The useLegacySql field can be used to indicate whether the query uses legacy SQL or standard SQL.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationTable'
+ description: |
+ Describes the table where the query results should be stored.
+ This property must be set for large results that exceed the maximum response size.
+ For queries that produce anonymous (cached) results, this field will be populated by BigQuery.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tableId'
+ description: 'The ID of the table.'
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'userDefinedFunctionResources'
+ description: |
+ Describes user-defined function resources used in the query.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'resourceUri'
+ description: 'A code resource to load from a Google Cloud Storage URI (gs://bucket/path).'
+ # TODO (mbang): exactly_one_of: resourceUri, inlineCode
+ - !ruby/object:Api::Type::String
+ name: 'inlineCode'
+ description: |
+ An inline resource that contains code for a user-defined function (UDF).
+ Providing a inline code resource is equivalent to providing a URI for a file containing the same code.
+ # TODO (mbang): exactly_one_of: resourceUri, inlineCode
+ - !ruby/object:Api::Type::Enum
+ name: 'createDisposition'
+ description: |
+ Specifies whether the job is allowed to create new tables. The following values are supported:
+ CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the table.
+ CREATE_NEVER: The table must already exist. If it does not, a 'notFound' error is returned in the job result.
+ Creation, truncation and append actions occur as one atomic update upon job completion
+ default_value: :CREATE_IF_NEEDED
+ values:
+ - :CREATE_IF_NEEDED
+ - :CREATE_NEVER
+ - !ruby/object:Api::Type::Enum
+ name: 'writeDisposition'
+ description: |
+ Specifies the action that occurs if the destination table already exists. The following values are supported:
+ WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the table data and uses the schema from the query result.
+ WRITE_APPEND: If the table already exists, BigQuery appends the data to the table.
+ WRITE_EMPTY: If the table already exists and contains data, a 'duplicate' error is returned in the job result.
+ Each action is atomic and only occurs if BigQuery is able to complete the job successfully.
+ Creation, truncation and append actions occur as one atomic update upon job completion.
+ default_value: :WRITE_EMPTY
+ values:
+ - :WRITE_TRUNCATE
+ - :WRITE_APPEND
+ - :WRITE_EMPTY
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultDataset'
+ description: |
+ Specifies the default dataset to use for unqualified table names in the query. Note that this does not alter behavior of unqualified dataset names.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'A unique ID for this dataset, without the project name.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ - !ruby/object:Api::Type::Enum
+ name: 'priority'
+ description: |
+ Specifies a priority for the query.
+ default_value: :INTERACTIVE
+ values:
+ - :INTERACTIVE
+ - :BATCH
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowLargeResults'
+ description: |
+ If true and query uses legacy SQL dialect, allows the query to produce arbitrarily large result tables at a slight cost in performance.
+ Requires destinationTable to be set. For standard SQL queries, this flag is ignored and large results are always allowed.
+ However, you must still set destinationTable when result size exceeds the allowed maximum response size.
+ - !ruby/object:Api::Type::Boolean
+ name: 'useQueryCache'
+ description: |
+ Whether to look for the result in the query cache. The query cache is a best-effort cache that will be flushed whenever
+ tables in the query are modified. Moreover, the query cache is only available when a query does not have a destination table specified.
+ The default value is true.
+ default_value: true
+ - !ruby/object:Api::Type::Boolean
+ name: 'flattenResults'
+ description: |
+ If true and query uses legacy SQL dialect, flattens all nested and repeated fields in the query results.
+ allowLargeResults must be true if this is set to false. For standard SQL queries, this flag is ignored and results are never flattened.
+ - !ruby/object:Api::Type::Integer
+ name: 'maximumBillingTier'
+ description: |
+ Limits the billing tier for this job. Queries that have resource usage beyond this tier will fail (without incurring a charge).
+ If unspecified, this will be set to your project default.
+ - !ruby/object:Api::Type::String
+ name: 'maximumBytesBilled'
+ description: |
+ Limits the bytes billed for this job. Queries that will have bytes billed beyond this limit will fail (without incurring a charge).
+ If unspecified, this will be set to your project default.
+ - !ruby/object:Api::Type::Boolean
+ name: 'useLegacySql'
+ description: |
+ Specifies whether to use BigQuery's legacy SQL dialect for this query. The default value is true.
+ If set to false, the query will use BigQuery's standard SQL.
+ default_value: true
+ - !ruby/object:Api::Type::String
+ name: 'parameterMode'
+ description: |
+ Standard SQL only. Set to POSITIONAL to use positional (?) query parameters or to NAMED to use named (@myparam) query parameters in this query.
+ - !ruby/object:Api::Type::Array
+ name: 'schemaUpdateOptions'
+ description: |
+ Allows the schema of the destination table to be updated as a side effect of the query job.
+ Schema update options are supported in two cases: when writeDisposition is WRITE_APPEND;
+ when writeDisposition is WRITE_TRUNCATE and the destination table is a partition of a table,
+ specified by partition decorators. For normal tables, WRITE_TRUNCATE will always overwrite the schema.
+ One or more of the following values are specified:
+ ALLOW_FIELD_ADDITION: allow adding a nullable field to the schema.
+ ALLOW_FIELD_RELAXATION: allow relaxing a required field in the original schema to nullable.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationEncryptionConfiguration'
+ description: |
+ Custom encryption configuration (e.g., Cloud KMS keys)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyName'
+ description: |
+ Describes the Cloud KMS encryption key that will be used to protect destination BigQuery table.
+ The BigQuery Service Account associated with your project requires access to this encryption key.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'scriptOptions'
+ description: |
+ Options controlling the execution of scripts.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'statementTimeoutMs'
+ description: 'Timeout period for each statement in a script.'
+ at_least_one_of:
+ - query.0.scriptOptions.0.statementTimeoutMs
+ - query.0.scriptOptions.0.statementByteBudget
+ - query.0.scriptOptions.0.keyResultStatement
+ - !ruby/object:Api::Type::String
+ name: 'statementByteBudget'
+ description: 'Limit on the number of bytes billed per statement. Exceeding this budget results in an error.'
+ at_least_one_of:
+ - query.0.scriptOptions.0.statementTimeoutMs
+ - query.0.scriptOptions.0.statementByteBudget
+ - query.0.scriptOptions.0.keyResultStatement
+ - !ruby/object:Api::Type::Enum
+ name: 'keyResultStatement'
+ description: |
+ Determines which statement in the script represents the "key result",
+ used to populate the schema and query results of the script job.
+ at_least_one_of:
+ - query.0.scriptOptions.0.statementTimeoutMs
+ - query.0.scriptOptions.0.statementByteBudget
+ - query.0.scriptOptions.0.keyResultStatement
+ values:
+ - :LAST
+ - :FIRST_SELECT
+ - !ruby/object:Api::Type::NestedObject
+ name: 'load'
+ description: 'Configures a load job.'
+ exactly_one_of:
+ - query
+ - load
+ - copy
+ - extract
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'sourceUris'
+ description: |
+ The fully-qualified URIs that point to your data in Google Cloud.
+ For Google Cloud Storage URIs: Each URI can contain one '*' wildcard character
+ and it must come after the 'bucket' name. Size limits related to load jobs apply
+ to external data sources. For Google Cloud Bigtable URIs: Exactly one URI can be
+ specified and it has be a fully specified and valid HTTPS URL for a Google Cloud Bigtable table.
+ For Google Cloud Datastore backups: Exactly one URI can be specified. Also, the '*' wildcard character is not allowed.
+ item_type: Api::Type::String
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationTable'
+ description: |
+ The destination table to load the data into.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tableId'
+ description: 'The ID of the table.'
+ required: true
+ - !ruby/object:Api::Type::Enum
+ name: 'createDisposition'
+ description: |
+ Specifies whether the job is allowed to create new tables. The following values are supported:
+ CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the table.
+ CREATE_NEVER: The table must already exist. If it does not, a 'notFound' error is returned in the job result.
+ Creation, truncation and append actions occur as one atomic update upon job completion
+ default_value: :CREATE_IF_NEEDED
+ values:
+ - :CREATE_IF_NEEDED
+ - :CREATE_NEVER
+ - !ruby/object:Api::Type::Enum
+ name: 'writeDisposition'
+ description: |
+ Specifies the action that occurs if the destination table already exists. The following values are supported:
+ WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the table data and uses the schema from the query result.
+ WRITE_APPEND: If the table already exists, BigQuery appends the data to the table.
+ WRITE_EMPTY: If the table already exists and contains data, a 'duplicate' error is returned in the job result.
+ Each action is atomic and only occurs if BigQuery is able to complete the job successfully.
+ Creation, truncation and append actions occur as one atomic update upon job completion.
+ default_value: :WRITE_EMPTY
+ values:
+ - :WRITE_TRUNCATE
+ - :WRITE_APPEND
+ - :WRITE_EMPTY
+ - !ruby/object:Api::Type::String
+ name: 'nullMarker'
+ description: |
+ Specifies a string that represents a null value in a CSV file. For example, if you specify "\N", BigQuery interprets "\N" as a null value
+ when loading a CSV file. The default value is the empty string. If you set this property to a custom value, BigQuery throws an error if an
+ empty string is present for all data types except for STRING and BYTE. For STRING and BYTE columns, BigQuery interprets the empty string as
+ an empty value.
+ default_value: ''
+ - !ruby/object:Api::Type::String
+ name: 'fieldDelimiter'
+ description: |
+ The separator for fields in a CSV file. The separator can be any ISO-8859-1 single-byte character.
+ To use a character in the range 128-255, you must encode the character as UTF8. BigQuery converts
+ the string to ISO-8859-1 encoding, and then uses the first byte of the encoded string to split the
+ data in its raw, binary state. BigQuery also supports the escape sequence "\t" to specify a tab separator.
+ The default value is a comma (',').
+ - !ruby/object:Api::Type::Integer
+ name: 'skipLeadingRows'
+ description: |
+ The number of rows at the top of a CSV file that BigQuery will skip when loading the data.
+ The default value is 0. This property is useful if you have header rows in the file that should be skipped.
+ When autodetect is on, the behavior is the following:
+ skipLeadingRows unspecified - Autodetect tries to detect headers in the first row. If they are not detected,
+ the row is read as data. Otherwise data is read starting from the second row.
+ skipLeadingRows is 0 - Instructs autodetect that there are no headers and data should be read starting from the first row.
+ skipLeadingRows = N > 0 - Autodetect skips N-1 rows and tries to detect headers in row N. If headers are not detected,
+ row N is just skipped. Otherwise row N is used to extract column names for the detected schema.
+ default_value: 0
+ - !ruby/object:Api::Type::String
+ name: 'encoding'
+ description: |
+ The character encoding of the data. The supported values are UTF-8 or ISO-8859-1.
+ The default value is UTF-8. BigQuery decodes the data after the raw, binary data
+ has been split using the values of the quote and fieldDelimiter properties.
+ default_value: 'UTF-8'
+ - !ruby/object:Api::Type::String
+ name: 'quote'
+ description: |
+ The value that is used to quote data sections in a CSV file. BigQuery converts the string to ISO-8859-1 encoding,
+ and then uses the first byte of the encoded string to split the data in its raw, binary state.
+ The default value is a double-quote ('"'). If your data does not contain quoted sections, set the property value to an empty string.
+ If your data contains quoted newline characters, you must also set the allowQuotedNewlines property to true.
+ - !ruby/object:Api::Type::Integer
+ name: 'maxBadRecords'
+ description: |
+ The maximum number of bad records that BigQuery can ignore when running the job. If the number of bad records exceeds this value,
+ an invalid error is returned in the job result. The default value is 0, which requires that all records are valid.
+ default_value: 0
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowQuotedNewlines'
+ description: |
+ Indicates if BigQuery should allow quoted data sections that contain newline characters in a CSV file.
+ The default value is false.
+ default_value: false
+ - !ruby/object:Api::Type::String
+ name: 'sourceFormat'
+ description: |
+ The format of the data files. For CSV files, specify "CSV". For datastore backups, specify "DATASTORE_BACKUP".
+ For newline-delimited JSON, specify "NEWLINE_DELIMITED_JSON". For Avro, specify "AVRO". For parquet, specify "PARQUET".
+ For orc, specify "ORC". The default value is CSV.
+ default_value: 'CSV'
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowJaggedRows'
+ description: |
+ Accept rows that are missing trailing optional columns. The missing values are treated as nulls.
+ If false, records with missing trailing columns are treated as bad records, and if there are too many bad records,
+ an invalid error is returned in the job result. The default value is false. Only applicable to CSV, ignored for other formats.
+ default_value: false
+ - !ruby/object:Api::Type::Boolean
+ name: 'ignoreUnknownValues'
+ description: |
+ Indicates if BigQuery should allow extra values that are not represented in the table schema.
+ If true, the extra values are ignored. If false, records with extra columns are treated as bad records,
+ and if there are too many bad records, an invalid error is returned in the job result.
+ The default value is false. The sourceFormat property determines what BigQuery treats as an extra value:
+ CSV: Trailing columns
+ JSON: Named values that don't match any column names
+ default_value: false
+ - !ruby/object:Api::Type::Array
+ name: 'projectionFields'
+ description: |
+ If sourceFormat is set to "DATASTORE_BACKUP", indicates which entity properties to load into BigQuery from a Cloud Datastore backup.
+ Property names are case sensitive and must be top-level properties. If no properties are specified, BigQuery loads all properties.
+ If any named property isn't found in the Cloud Datastore backup, an invalid error is returned in the job result.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Boolean
+ name: 'autodetect'
+ description: |
+ Indicates if we should automatically infer the options and schema for CSV and JSON sources.
+ - !ruby/object:Api::Type::Array
+ name: 'schemaUpdateOptions'
+ description: |
+ Allows the schema of the destination table to be updated as a side effect of the load job if a schema is autodetected or
+ supplied in the job configuration. Schema update options are supported in two cases: when writeDisposition is WRITE_APPEND;
+ when writeDisposition is WRITE_TRUNCATE and the destination table is a partition of a table, specified by partition decorators.
+ For normal tables, WRITE_TRUNCATE will always overwrite the schema. One or more of the following values are specified:
+ ALLOW_FIELD_ADDITION: allow adding a nullable field to the schema.
+ ALLOW_FIELD_RELAXATION: allow relaxing a required field in the original schema to nullable.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'timePartitioning'
+ description: |
+ Time-based partitioning specification for the destination table.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'type'
+ description: |
+ The only type supported is DAY, which will generate one partition per day. Providing an empty string used to cause an error,
+ but in OnePlatform the field will be treated as unset.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'expirationMs'
+ description: |
+ Number of milliseconds for which to keep the storage for a partition. A wrapper is used here because 0 is an invalid value.
+ - !ruby/object:Api::Type::String
+ name: 'field'
+ description: |
+ If not set, the table is partitioned by pseudo column '_PARTITIONTIME'; if set, the table is partitioned by this field.
+ The field must be a top-level TIMESTAMP or DATE field. Its mode must be NULLABLE or REQUIRED.
+ A wrapper is used here because an empty string is an invalid value.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationEncryptionConfiguration'
+ description: |
+ Custom encryption configuration (e.g., Cloud KMS keys)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyName'
+ description: |
+ Describes the Cloud KMS encryption key that will be used to protect destination BigQuery table.
+ The BigQuery Service Account associated with your project requires access to this encryption key.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'copy'
+ description: 'Copies a table.'
+ exactly_one_of:
+ - query
+ - load
+ - copy
+ - extract
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'sourceTables'
+ description: |
+ Source tables to copy.
+ required: true
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tableId'
+ description: 'The ID of the table.'
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationTable'
+ description: 'The destination table.'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tableId'
+ description: 'The ID of the table.'
+ required: true
+ - !ruby/object:Api::Type::Enum
+ name: 'createDisposition'
+ description: |
+ Specifies whether the job is allowed to create new tables. The following values are supported:
+ CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the table.
+ CREATE_NEVER: The table must already exist. If it does not, a 'notFound' error is returned in the job result.
+ Creation, truncation and append actions occur as one atomic update upon job completion
+ default_value: :CREATE_IF_NEEDED
+ values:
+ - :CREATE_IF_NEEDED
+ - :CREATE_NEVER
+ - !ruby/object:Api::Type::Enum
+ name: 'writeDisposition'
+ description: |
+ Specifies the action that occurs if the destination table already exists. The following values are supported:
+ WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the table data and uses the schema from the query result.
+ WRITE_APPEND: If the table already exists, BigQuery appends the data to the table.
+ WRITE_EMPTY: If the table already exists and contains data, a 'duplicate' error is returned in the job result.
+ Each action is atomic and only occurs if BigQuery is able to complete the job successfully.
+ Creation, truncation and append actions occur as one atomic update upon job completion.
+ default_value: :WRITE_EMPTY
+ values:
+ - :WRITE_TRUNCATE
+ - :WRITE_APPEND
+ - :WRITE_EMPTY
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destinationEncryptionConfiguration'
+ description: |
+ Custom encryption configuration (e.g., Cloud KMS keys)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyName'
+ description: |
+ Describes the Cloud KMS encryption key that will be used to protect destination BigQuery table.
+ The BigQuery Service Account associated with your project requires access to this encryption key.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'extract'
+ description: 'Configures an extract job.'
+ exactly_one_of:
+ - query
+ - load
+ - copy
+ - extract
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'destinationUris'
+ description: |
+ A list of fully-qualified Google Cloud Storage URIs where the extracted table should be written.
+ required: true
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Boolean
+ name: 'printHeader'
+ description: |
+ Whether to print out a header row in the results. Default is true.
+ default_value: true
+ - !ruby/object:Api::Type::String
+ name: 'fieldDelimiter'
+ description: |
+ When extracting data in CSV format, this defines the delimiter to use between fields in the exported data.
+ Default is ','
+ - !ruby/object:Api::Type::String
+ name: 'destinationFormat'
+ description: |
+ The exported file format. Possible values include CSV, NEWLINE_DELIMITED_JSON and AVRO for tables and SAVED_MODEL for models.
+ The default value for tables is CSV. Tables with nested or repeated fields cannot be exported as CSV.
+ The default value for models is SAVED_MODEL.
+ - !ruby/object:Api::Type::String
+ name: 'compression'
+ description: |
+ The compression type to use for exported files. Possible values include GZIP, DEFLATE, SNAPPY, and NONE.
+ The default value is NONE. DEFLATE and SNAPPY are only supported for Avro.
+ default_value: 'NONE'
+ - !ruby/object:Api::Type::Boolean
+ name: 'useAvroLogicalTypes'
+ description: |
+ Whether to use logical types when extracting to AVRO format.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'sourceTable'
+ description: |
+ A reference to the table being exported.
+ exactly_one_of:
+ - extract.0.source_table
+ - extract.0.source_model
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this table.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tableId'
+ description: 'The ID of the table.'
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'sourceModel'
+ description: |
+ A reference to the model being exported.
+ exactly_one_of:
+ - extract.0.source_table
+ - extract.0.source_model
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: 'The ID of the project containing this model.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'datasetId'
+ description: 'The ID of the dataset containing this model.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'modelId'
+ description: 'The ID of the model.'
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'jobReference'
+ description: |
+ Reference describing the unique-per-user name of the job.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'projectId'
+ description: |
+ The project ID of the project containing this job.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'jobId'
+ description: |
+ The ID of the job. The ID must contain only letters (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-). The maximum length is 1,024 characters.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ description: |
+ The geographic location of the job. The default value is US.
+ default_value: 'US'
- !ruby/object:Api::Resource
name: 'Table'
kind: 'bigquery#table'
diff --git a/products/bigquery/inspec.yaml b/products/bigquery/inspec.yaml
index 1b060701840c..28c20a2a8f05 100644
--- a/products/bigquery/inspec.yaml
+++ b/products/bigquery/inspec.yaml
@@ -31,10 +31,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
lastModifiedTime: !ruby/object:Overrides::Inspec::PropertyOverride
exclude_plural: true
additional_functions: 'third_party/inspec/custom_functions/bigquery_dataset_name.erb'
-
DatasetAccess: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
-
+ Job: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
Table: !ruby/object:Overrides::Inspec::ResourceOverride
properties:
description: !ruby/object:Overrides::Inspec::PropertyOverride
diff --git a/products/bigquery/terraform.yaml b/products/bigquery/terraform.yaml
index 789789642a46..3a80567bf675 100644
--- a/products/bigquery/terraform.yaml
+++ b/products/bigquery/terraform.yaml
@@ -17,6 +17,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
Dataset: !ruby/object:Overrides::Terraform::ResourceOverride
import_format: ["projects/{{project}}/datasets/{{dataset_id}}"]
delete_url: projects/{{project}}/datasets/{{dataset_id}}?deleteContents={{delete_contents_on_destroy}}
+ # Skipping sweeper due to the abnormal delete_url
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "bigquery_dataset_basic"
@@ -33,8 +35,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides
key_name: "example-key"
keyring_name: "example-keyring"
virtual_fields:
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'delete_contents_on_destroy'
+ default_value: false
description: |
If set to `true`, delete all the tables in the
dataset when destroying the resource; otherwise,
@@ -88,6 +91,213 @@ overrides: !ruby/object:Overrides::ResourceOverrides
properties:
datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
ignore_read: true
+ role: !ruby/object:Overrides::Terraform::PropertyOverride
+ # Bigquery allows for two different formats for specific roles
+ # (IAM vs "primitive" format), but will return the primative role in API
+ # responses. We identify this fine-grained resource from a list
+ # of DatasetAccess objects by comparing role, and we must use the same
+ # format when comparing.
+ diff_suppress_func: 'resourceBigQueryDatasetAccessRoleDiffSuppress'
+ # This custom expand makes sure we are correctly
+ # converting IAM roles set in state to their primitive equivalents
+ # before comparison.
+ custom_expand: "templates/terraform/custom_expand/bigquery_access_role.go.erb"
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ constants: templates/terraform/constants/bigquery_dataset_access.go
+ Job: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["projects/{{project}}/jobs/{{job_id}}"]
+ skip_delete: true
+ async: !ruby/object:Provider::Terraform::PollAsync
+ check_response_func_existence: PollCheckForExistence
+ actions: ['create']
+ operation: !ruby/object:Api::Async::Operation
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 4
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_query"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_query"
+ account_name: "bqowner"
+ ignore_read_extra:
+ - "etag"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_query_table_reference"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_query"
+ account_name: "bqowner"
+ ignore_read_extra:
+ - "etag"
+ - "query.0.default_dataset.0.dataset_id"
+ - "query.0.destination_table.0.table_id"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_load"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_load"
+ ignore_read_extra:
+ - "etag"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_load_table_reference"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_load"
+ ignore_read_extra:
+ - "etag"
+ - "load.0.destination_table.0.table_id"
+ skip_docs: true # there are a lot of examples for this resource, so omitting some that are similar to others
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_copy"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_copy"
+ account_name: "bqowner"
+ key_name: "example-key"
+ keyring_name: "example-keyring"
+ test_env_vars:
+ project: :PROJECT_NAME
+ ignore_read_extra:
+ - "etag"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_copy_table_reference"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_copy"
+ account_name: "bqowner"
+ key_name: "example-key"
+ keyring_name: "example-keyring"
+ test_env_vars:
+ project: :PROJECT_NAME
+ ignore_read_extra:
+ - "etag"
+ - "copy.0.destination_table.0.table_id"
+ - "copy.0.source_tables.0.table_id"
+ - "copy.0.source_tables.1.table_id"
+ skip_docs: true # there are a lot of examples for this resource, so omitting some that are similar to others
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_extract"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_extract"
+ account_name: "bqowner"
+ ignore_read_extra:
+ - "etag"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "bigquery_job_extract_table_reference"
+ primary_resource_id: "job"
+ vars:
+ job_id: "job_extract"
+ account_name: "bqowner"
+ ignore_read_extra:
+ - "etag"
+ - "extract.0.source_table.0.table_id"
+ skip_docs: true # there are a lot of examples for this resource, so omitting some that are similar to others
+ properties:
+ id: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ configuration: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ configuration.copy.destinationTable: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_table_ref.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_table_ref_copy_destinationtable.go.erb'
+ configuration.copy.destinationTable.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.copy.destinationTable.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.copy.destinationTable.tableId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The table. Can be specified `{{table_id}}` if `project_id` and `dataset_id` are also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}/tables/{{table_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ configuration.copy.sourceTables: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_table_ref_array.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_table_ref_copy_sourcetables.go.erb'
+ configuration.copy.sourceTables.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.copy.sourceTables.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.copy.sourceTables.tableId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The table. Can be specified `{{table_id}}` if `project_id` and `dataset_id` are also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}/tables/{{table_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ configuration.load.destinationTable: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_table_ref.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_table_ref_load_destinationtable.go.erb'
+ configuration.load.destinationTable.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.load.destinationTable.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.load.destinationTable.tableId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The table. Can be specified `{{table_id}}` if `project_id` and `dataset_id` are also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}/tables/{{table_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ configuration.load.skipLeadingRows: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntAtLeast(0)'
+ configuration.load.fieldDelimiter: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ configuration.load.quote: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ configuration.extract.fieldDelimiter: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ configuration.extract.destinationFormat: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ configuration.extract.sourceTable: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_table_ref.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_table_ref_extract_sourcetable.go.erb'
+ configuration.extract.sourceTable.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.extract.sourceTable.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.extract.sourceTable.tableId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The table. Can be specified `{{table_id}}` if `project_id` and `dataset_id` are also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}/tables/{{table_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ configuration.query.destinationTable: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_table_ref.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_table_ref_query_destinationtable.go.erb'
+ configuration.query.destinationTable.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.query.destinationTable.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.query.destinationTable.tableId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The table. Can be specified `{{table_id}}` if `project_id` and `dataset_id` are also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}/tables/{{table_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ configuration.query.defaultDataset: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/bigquery_dataset_ref.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_dataset_ref.go.erb'
+ configuration.query.defaultDataset.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
+ configuration.query.defaultDataset.datasetId: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ The dataset. Can be specified `{{dataset_id}}` if `project_id` is also set,
+ or of the form `projects/{{project}}/datasets/{{dataset_id}}` if not.
+ diff_suppress_func: 'compareSelfLinkRelativePaths'
+ jobReference: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ jobReference.projectId: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ constants: templates/terraform/constants/bigquery_job.go
+ encoder: templates/terraform/encoders/bigquery_job.go.erb
Table: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
diff --git a/products/bigqueryconnection/api.yaml b/products/bigqueryconnection/api.yaml
new file mode 100644
index 000000000000..25eaeb87fc3e
--- /dev/null
+++ b/products/bigqueryconnection/api.yaml
@@ -0,0 +1,111 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: BigqueryConnection
+display_name: BigQuery Connection
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://bigqueryconnection.googleapis.com/v1beta1/
+scopes:
+ - https://www.googleapis.com/auth/bigquery
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: BigQueryConnection API
+ url: https://console.cloud.google.com/apis/api/bigqueryconnection.googleapis.com/
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Connection'
+ base_url: projects/{{project}}/locations/{{location}}/connections
+ self_link: "{{name}}"
+ create_url: projects/{{project}}/locations/{{location}}/connections?connectionId={{connection_id}}
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A connection allows BigQuery connections to external data sources..
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ "Cloud SQL federated queries": "https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries"
+ api: "https://cloud.google.com/bigquery/docs/reference/bigqueryconnection/rest/v1beta1/projects.locations.connections/create"
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |-
+ The resource name of the connection in the form of:
+ "projects/{project_id}/locations/{location_id}/connections/{connectionId}"
+ input: true
+ output: true
+ - !ruby/object:Api::Type::String
+ name: connection_id
+ description: |
+ Optional connection id that should be assigned to the created connection.
+ required: false
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ required: false
+ input: true
+ url_param_only: true
+ default_value: US
+ description: |-
+ The geographic location where the connection should reside.
+ Cloud SQL instance must be in the same location as the connection
+ with following exceptions: Cloud SQL us-central1 maps to BigQuery US, Cloud SQL europe-west1 maps to BigQuery EU.
+ Examples: US, EU, asia-northeast1, us-central1, europe-west1. The default value is US.
+ - !ruby/object:Api::Type::String
+ name: 'friendlyName'
+ description: A descriptive name for the connection
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: A descriptive description for the connection
+ - !ruby/object:Api::Type::Boolean
+ name: 'hasCredential'
+ output: true
+ description: |
+ True if the connection has credential assigned.
+ - !ruby/object:Api::Type::NestedObject
+ name: cloudSql
+ description: Cloud SQL properties.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'instanceId'
+ description: Cloud SQL instance ID in the form project:location:instance.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'database'
+ description: Database name.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: credential
+ description: Cloud SQL properties.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: username
+ description: Username for database.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: password
+ description: Password for database.
+ required: true
+ - !ruby/object:Api::Type::Enum
+ name: 'type'
+ description: Type of the Cloud SQL database.
+ required: true
+ values:
+ - :DATABASE_TYPE_UNSPECIFIED
+ - :POSTGRES
+ - :MYSQL
diff --git a/products/bigqueryconnection/terraform.yaml b/products/bigqueryconnection/terraform.yaml
new file mode 100644
index 000000000000..5fd7cb44cf68
--- /dev/null
+++ b/products/bigqueryconnection/terraform.yaml
@@ -0,0 +1,46 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+legacy_name: bigquery
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Connection: !ruby/object:Overrides::Terraform::ResourceOverride
+ properties:
+ cloudSql.credential: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: 'templates/terraform/custom_flatten/bigquery_connection_flatten.go.erb'
+ cloudSql.credential.password: !ruby/object:Overrides::Terraform::PropertyOverride
+ sensitive: true
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "bigquery_connection_basic"
+ primary_resource_id: "connection"
+ vars:
+ database_instance_name: "my-database-instance"
+ username: "user"
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "bigquery_connection_full"
+ primary_resource_id: "connection"
+ vars:
+ database_instance_name: "my-database-instance"
+ username: "user"
+ connection_id: "my-connection"
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/bigquerydatatransfer/api.yaml b/products/bigquerydatatransfer/api.yaml
index a85475147bea..e9c08724dc03 100644
--- a/products/bigquerydatatransfer/api.yaml
+++ b/products/bigquerydatatransfer/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: BigqueryDataTransfer
-display_name: BigQueryDataTransfer
+display_name: BigQuery Data Transfer
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -27,8 +27,10 @@ apis_required:
objects:
- !ruby/object:Api::Resource
name: 'Config'
- base_url: projects/{{project}}/locations/{{location}}/transferConfigs
+ base_url: projects/{{project}}/locations/{{location}}/transferConfigs?serviceAccountName={{service_account_name}}
self_link: "{{name}}"
+ # see comment at service_account_name, PATCHing service_account_name also required update_mask entry
+ # update_url: "{{name}}?serviceAccountName={{service_account_name}}"
update_verb: :PATCH
update_mask: true
description: |
@@ -47,6 +49,18 @@ objects:
description: |
The geographic location where the transfer config should reside.
Examples: US, EU, asia-northeast1. The default value is US.
+ - !ruby/object:Api::Type::String
+ name: 'serviceAccountName'
+ url_param_only: true
+ # The API would support PATCHing the service account, but setting the
+ # update_mask accordingly for a url_param_only is currently not
+ # supported in magic-modules
+ input: true
+ default_value: ''
+ description: |
+ Optional service account name. If this field is set, transfer config will
+ be created with this service account credentials. It requires that
+ requesting user calling this API has permissions to act as this service account.
properties:
- !ruby/object:Api::Type::String
name: 'displayName'
diff --git a/products/bigquerydatatransfer/terraform.yaml b/products/bigquerydatatransfer/terraform.yaml
index fe561caf0a83..601c87abdfca 100644
--- a/products/bigquerydatatransfer/terraform.yaml
+++ b/products/bigquerydatatransfer/terraform.yaml
@@ -28,7 +28,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
examples:
- !ruby/object:Provider::Terraform::Examples
skip_test: true
- name: "scheduled_query"
+ name: "bigquerydatatransfer_config_scheduled_query"
primary_resource_id: "query_config"
vars:
display_name: "my-query"
diff --git a/products/bigqueryreservation/api.yaml b/products/bigqueryreservation/api.yaml
index 5bef09d5646f..4f9e70e95637 100644
--- a/products/bigqueryreservation/api.yaml
+++ b/products/bigqueryreservation/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: BigqueryReservation
-display_name: BigQueryReservation
+display_name: BigQuery Reservation
versions:
- !ruby/object:Api::Product::Version
name: beta
diff --git a/products/bigtable/api.yaml b/products/bigtable/api.yaml
index 1d37d48de4d7..019bfe171cf2 100644
--- a/products/bigtable/api.yaml
+++ b/products/bigtable/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: Bigtable
-display_name: Bigtable
+display_name: Cloud Bigtable
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/bigtable/terraform.yaml b/products/bigtable/terraform.yaml
index be9ec743dc8e..307199112a19 100644
--- a/products/bigtable/terraform.yaml
+++ b/products/bigtable/terraform.yaml
@@ -28,6 +28,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
instance_name: "bt-instance"
app_profile_name: "bt-profile"
+ deletion_protection: "true"
+ test_vars_overrides:
+ deletion_protection: "false"
+ oics_vars_overrides:
+ deletion_protection: "false"
ignore_read_extra:
- "ignore_warnings"
- !ruby/object:Provider::Terraform::Examples
@@ -36,6 +41,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
instance_name: "bt-instance"
app_profile_name: "bt-profile"
+ deletion_protection: "true"
+ test_vars_overrides:
+ deletion_protection: "false"
+ oics_vars_overrides:
+ deletion_protection: "false"
ignore_read_extra:
- "ignore_warnings"
properties:
diff --git a/products/cloudasset/api.yaml b/products/cloudasset/api.yaml
new file mode 100644
index 000000000000..37779b19f188
--- /dev/null
+++ b/products/cloudasset/api.yaml
@@ -0,0 +1,291 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: CloudAsset
+display_name: Cloud Asset Inventory
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://cloudasset.googleapis.com/v1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Cloud Asset API
+ url: https://console.cloud.google.com/apis/library/cloudasset.googleapis.com/
+objects:
+ - !ruby/object:Api::Resource
+ name: ProjectFeed
+ base_url: projects/{{project}}/feeds
+ create_url: projects/{{project}}/feeds?feedId={{feed_id}}
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ update_mask: true
+ collection_url_key: 'feeds'
+ description: |
+ Describes a Cloud Asset Inventory feed used to to listen to asset updates.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/asset-inventory/docs'
+ api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: billing_project
+ url_param_only: true
+ input: true
+ description: |
+ The project whose identity will be used when sending messages to the
+ destination pubsub topic. It also specifies the project for API
+ enablement check, quota, and billing. If not specified, the resource's
+ project will be used.
+ - !ruby/object:Api::Type::String
+ name: name
+ output: true
+ description: |
+ The format will be projects/{projectNumber}/feeds/{client-assigned_feed_identifier}.
+ - !ruby/object:Api::Type::String
+ name: feedId
+ description: |
+ This is the client-assigned asset feed identifier and it needs to be unique under a specific parent.
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::Array
+ name: assetNames
+ item_type: Api::Type::String
+ description: |
+ A list of the full names of the assets to receive updates. You must specify either or both of
+ assetNames and assetTypes. Only asset updates matching specified assetNames and assetTypes are
+ exported to the feed. For example: //compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1.
+ See https://cloud.google.com/apis/design/resourceNames#fullResourceName for more info.
+ - !ruby/object:Api::Type::Array
+ name: assetTypes
+ item_type: Api::Type::String
+ description: |
+ A list of types of the assets to receive updates. You must specify either or both of assetNames
+ and assetTypes. Only asset updates matching specified assetNames and assetTypes are exported to
+ the feed. For example: "compute.googleapis.com/Disk"
+ See https://cloud.google.com/asset-inventory/docs/supported-asset-types for a list of all
+ supported asset types.
+ - !ruby/object:Api::Type::Enum
+ name: contentType
+ description: |
+ Asset content type. If not specified, no content but the asset name and type will be returned.
+ values:
+ - :CONTENT_TYPE_UNSPECIFIED
+ - :RESOURCE
+ - :IAM_POLICY
+ - :ORG_POLICY
+ - :ACCESS_POLICY
+ - !ruby/object:Api::Type::NestedObject
+ name: feedOutputConfig
+ required: true
+ description: |
+ Output configuration for asset feed destination.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: pubsubDestination
+ required: true
+ description: |
+ Destination on Cloud Pubsub.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: topic
+ required: true
+ description: |
+ Destination on Cloud Pubsub topic.
+ - !ruby/object:Api::Resource
+ name: FolderFeed
+ base_url: folders/{{folder_id}}/feeds
+ create_url: folders/{{folder_id}}/feeds?feedId={{feed_id}}
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ update_mask: true
+ collection_url_key: 'feeds'
+ description: |
+ Describes a Cloud Asset Inventory feed used to to listen to asset updates.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/asset-inventory/docs'
+ api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: folder
+ required: true
+ input: true
+ url_param_only: true
+ description: |
+ The folder this feed should be created in.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: billing_project
+ required: true
+ input: true
+ url_param_only: true
+ description: |
+ The project whose identity will be used when sending messages to the
+ destination pubsub topic. It also specifies the project for API
+ enablement check, quota, and billing.
+ - !ruby/object:Api::Type::String
+ name: folder_id
+ output: true
+ description: |
+ The ID of the folder where this feed has been created. Both [FOLDER_NUMBER]
+ and folders/[FOLDER_NUMBER] are accepted.
+ - !ruby/object:Api::Type::String
+ name: name
+ output: true
+ description: |
+ The format will be folders/{folder_number}/feeds/{client-assigned_feed_identifier}.
+ - !ruby/object:Api::Type::String
+ name: feedId
+ description: |
+ This is the client-assigned asset feed identifier and it needs to be unique under a specific parent.
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::Array
+ name: assetNames
+ item_type: Api::Type::String
+ description: |
+ A list of the full names of the assets to receive updates. You must specify either or both of
+ assetNames and assetTypes. Only asset updates matching specified assetNames and assetTypes are
+ exported to the feed. For example: //compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1.
+ See https://cloud.google.com/apis/design/resourceNames#fullResourceName for more info.
+ - !ruby/object:Api::Type::Array
+ name: assetTypes
+ item_type: Api::Type::String
+ description: |
+ A list of types of the assets to receive updates. You must specify either or both of assetNames
+ and assetTypes. Only asset updates matching specified assetNames and assetTypes are exported to
+ the feed. For example: "compute.googleapis.com/Disk"
+ See https://cloud.google.com/asset-inventory/docs/supported-asset-types for a list of all
+ supported asset types.
+ - !ruby/object:Api::Type::Enum
+ name: contentType
+ description: |
+ Asset content type. If not specified, no content but the asset name and type will be returned.
+ values:
+ - :CONTENT_TYPE_UNSPECIFIED
+ - :RESOURCE
+ - :IAM_POLICY
+ - :ORG_POLICY
+ - :ACCESS_POLICY
+ - !ruby/object:Api::Type::NestedObject
+ name: feedOutputConfig
+ required: true
+ description: |
+ Output configuration for asset feed destination.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: pubsubDestination
+ required: true
+ description: |
+ Destination on Cloud Pubsub.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: topic
+ required: true
+ description: |
+ Destination on Cloud Pubsub topic.
+ - !ruby/object:Api::Resource
+ name: OrganizationFeed
+ base_url: "organizations/{{org_id}}/feeds"
+ create_url: "organizations/{{org_id}}/feeds?feedId={{feed_id}}"
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ update_mask: true
+ collection_url_key: 'feeds'
+ description: |
+ Describes a Cloud Asset Inventory feed used to to listen to asset updates.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/asset-inventory/docs'
+ api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: org_id
+ required: true
+ input: true
+ url_param_only: true
+ description: |
+ The organization this feed should be created in.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: billing_project
+ required: true
+ input: true
+ url_param_only: true
+ description: |
+ The project whose identity will be used when sending messages to the
+ destination pubsub topic. It also specifies the project for API
+ enablement check, quota, and billing.
+ - !ruby/object:Api::Type::String
+ name: name
+ output: true
+ description: |
+ The format will be organizations/{organization_number}/feeds/{client-assigned_feed_identifier}.
+ - !ruby/object:Api::Type::String
+ name: feedId
+ description: |
+ This is the client-assigned asset feed identifier and it needs to be unique under a specific parent.
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::Array
+ name: assetNames
+ item_type: Api::Type::String
+ description: |
+ A list of the full names of the assets to receive updates. You must specify either or both of
+ assetNames and assetTypes. Only asset updates matching specified assetNames and assetTypes are
+ exported to the feed. For example: //compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1.
+ See https://cloud.google.com/apis/design/resourceNames#fullResourceName for more info.
+ - !ruby/object:Api::Type::Array
+ name: assetTypes
+ item_type: Api::Type::String
+ description: |
+ A list of types of the assets to receive updates. You must specify either or both of assetNames
+ and assetTypes. Only asset updates matching specified assetNames and assetTypes are exported to
+ the feed. For example: "compute.googleapis.com/Disk"
+ See https://cloud.google.com/asset-inventory/docs/supported-asset-types for a list of all
+ supported asset types.
+ - !ruby/object:Api::Type::Enum
+ name: contentType
+ description: |
+ Asset content type. If not specified, no content but the asset name and type will be returned.
+ values:
+ - :CONTENT_TYPE_UNSPECIFIED
+ - :RESOURCE
+ - :IAM_POLICY
+ - :ORG_POLICY
+ - :ACCESS_POLICY
+ - !ruby/object:Api::Type::NestedObject
+ name: feedOutputConfig
+ required: true
+ description: |
+ Output configuration for asset feed destination.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: pubsubDestination
+ required: true
+ description: |
+ Destination on Cloud Pubsub.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: topic
+ required: true
+ description: |
+ Destination on Cloud Pubsub topic.
diff --git a/products/cloudasset/terraform.yaml b/products/cloudasset/terraform.yaml
new file mode 100644
index 000000000000..8318b9bb158d
--- /dev/null
+++ b/products/cloudasset/terraform.yaml
@@ -0,0 +1,62 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ ProjectFeed: !ruby/object:Overrides::Terraform::ResourceOverride
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ pre_create: templates/terraform/pre_create/cloud_asset_feed.go.erb
+ post_create: templates/terraform/post_create/cloud_asset_feed.go.erb
+ custom_import: templates/terraform/custom_import/cloud_asset_feed.go.erb
+ encoder: templates/terraform/encoders/cloud_asset_feed.go.erb
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_asset_project_feed"
+ primary_resource_id: "project_feed"
+ vars:
+ feed_id: "network-updates"
+ test_env_vars:
+ project: :PROJECT_NAME
+ FolderFeed: !ruby/object:Overrides::Terraform::ResourceOverride
+ supports_indirect_user_project_override: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ pre_create: templates/terraform/pre_create/cloud_asset_feed.go.erb
+ post_create: templates/terraform/post_create/cloud_asset_feed.go.erb
+ custom_import: templates/terraform/custom_import/cloud_asset_feed.go.erb
+ encoder: templates/terraform/encoders/cloud_asset_feed.go.erb
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_asset_folder_feed"
+ primary_resource_id: "folder_feed"
+ vars:
+ feed_id: "network-updates"
+ folder_name: "Networking"
+ test_env_vars:
+ project: :PROJECT_NAME
+ org_id: :ORG_ID
+ OrganizationFeed: !ruby/object:Overrides::Terraform::ResourceOverride
+ supports_indirect_user_project_override: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ pre_create: templates/terraform/pre_create/cloud_asset_feed.go.erb
+ post_create: templates/terraform/post_create/cloud_asset_feed.go.erb
+ custom_import: templates/terraform/custom_import/cloud_asset_feed.go.erb
+ encoder: templates/terraform/encoders/cloud_asset_feed.go.erb
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_asset_organization_feed"
+ primary_resource_id: "organization_feed"
+ vars:
+ feed_id: "network-updates"
+ test_env_vars:
+ project: :PROJECT_NAME
+ org_id: :ORG_ID
diff --git a/products/cloudbuild/api.yaml b/products/cloudbuild/api.yaml
index 0a96068cfba3..ecd96549f0bd 100644
--- a/products/cloudbuild/api.yaml
+++ b/products/cloudbuild/api.yaml
@@ -133,6 +133,11 @@ objects:
This must be a relative path. If a step's dir is specified and
is an absolute path, this value is ignored for that step's
execution.
+
+ - !ruby/object:Api::Type::Boolean
+ name: 'invertRegex'
+ description: |
+ Only trigger a build if the revision regex does NOT match the revision regex.
- !ruby/object:Api::Type::String
name: 'branchName'
description: |
@@ -198,6 +203,10 @@ objects:
values:
- :COMMENTS_DISABLED
- :COMMENTS_ENABLED
+ - !ruby/object:Api::Type::Boolean
+ name: 'invertRegex'
+ description: |
+ If true, branches that do NOT match the git_ref will trigger a build.
- !ruby/object:Api::Type::NestedObject
name: 'push'
description: |
@@ -206,6 +215,10 @@ objects:
- github.0.pull_request
- github.0.push
properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'invertRegex'
+ description: |
+ When true, only trigger a build if the revision regex does NOT match the git_ref regex.
- !ruby/object:Api::Type::String
name: 'branch'
description: |
diff --git a/products/cloudidentity/api.yaml b/products/cloudidentity/api.yaml
new file mode 100644
index 000000000000..a665dd471532
--- /dev/null
+++ b/products/cloudidentity/api.yaml
@@ -0,0 +1,321 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: CloudIdentity
+display_name: Cloud Identity
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://cloudidentity.googleapis.com/v1beta1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-identity
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Cloud Identity API
+ url: https://console.cloud.google.com/apis/api/cloudidentity.googleapis.com/overview
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Group'
+ base_url: groups
+ update_url: '{{name}}'
+ self_link: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Cloud Identity resource representing a Group.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ output: true
+ description: |
+ Resource name of the Group in the format: groups/{group_id}, where group_id
+ is the unique ID assigned to the Group.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'groupKey'
+ required: true
+ input: true
+ description: |
+ EntityKey of the Group.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ required: true
+ input: true
+ description: |
+ The ID of the entity.
+
+ For Google-managed entities, the id must be the email address of an existing
+ group or user.
+
+ For external-identity-mapped entities, the id must be a string conforming
+ to the Identity Source's requirements.
+
+ Must be unique within a namespace.
+ - !ruby/object:Api::Type::String
+ name: 'namespace'
+ input: true
+ description: |
+ The namespace in which the entity exists.
+
+ If not specified, the EntityKey represents a Google-managed entity
+ such as a Google user or a Google Group.
+
+ If specified, the EntityKey represents an external-identity-mapped group.
+ The namespace must correspond to an identity source created in Admin Console
+ and must be in the form of `identitysources/{identity_source_id}`.
+ - !ruby/object:Api::Type::String
+ name: 'parent'
+ required: true
+ input: true
+ description: |
+ The resource name of the entity under which this Group resides in the
+ Cloud Identity resource hierarchy.
+
+ Must be of the form identitysources/{identity_source_id} for external-identity-mapped
+ groups or customers/{customer_id} for Google Groups.
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ description: |
+ The display name of the Group.
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ An extended description to help users determine the purpose of a Group.
+ Must not be longer than 4,096 characters.
+ - !ruby/object:Api::Type::String
+ name: 'createTime'
+ output: true
+ description: |
+ The time when the Group was created.
+ - !ruby/object:Api::Type::String
+ name: 'updateTime'
+ output: true
+ description: |
+ The time when the Group was last updated.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ required: true
+ input: true
+ description: |
+ The labels that apply to the Group.
+
+ Must not contain more than one entry. Must contain the entry
+ 'cloudidentity.googleapis.com/groups.discussion_forum': '' if the Group is a Google Group or
+ 'system/groups/external': '' if the Group is an external-identity-mapped group.
+ # TODO (mbang): The full API doesn't seem to be implemented yet
+ # - !ruby/object:Api::Type::Array
+ # name: 'additionalGroupKeys'
+ # input: true
+ # description: |
+ # Additional entity key aliases for a Group.
+ # item_type: !ruby/object:Api::Type::NestedObject
+ # properties:
+ # - !ruby/object:Api::Type::String
+ # name: 'id'
+ # required: true
+ # description: |
+ # The ID of the entity.
+
+ # For Google-managed entities, the id must be the email address of an existing
+ # group or user.
+
+ # For external-identity-mapped entities, the id must be a string conforming
+ # to the Identity Source's requirements.
+
+ # Must be unique within a namespace.
+ # - !ruby/object:Api::Type::String
+ # name: 'namespace'
+ # description: |
+ # The namespace in which the entity exists.
+
+ # If not specified, the EntityKey represents a Google-managed entity
+ # such as a Google user or a Google Group.
+
+ # If specified, the EntityKey represents an external-identity-mapped group.
+ # The namespace must correspond to an identity source created in Admin Console
+ # and must be in the form of `identitysources/{identity_source_id}.
+ # - !ruby/object:Api::Type::NestedObject
+ # name: 'dynamicGroupMetadata'
+ # input: true
+ # description: |
+ # Dynamic group metadata like queries and status.
+ # properties:
+ # - !ruby/object:Api::Type::Array
+ # name: 'queries'
+ # required: true
+ # description: |
+ # Memberships will be the union of all queries. Only one entry with USER resource is currently supported.
+ # item_type: !ruby/object:Api::Type::NestedObject
+ # properties:
+ # - !ruby/object:Api::Type::Enum
+ # name: 'resourceType'
+ # description: |
+ # Resources supported for dynamic groups.
+ # default_value: :USER
+ # values:
+ # - :USER
+ # - !ruby/object:Api::Type::String
+ # name: 'query'
+ # description: |
+ # Query that determines the memberships of the dynamic group.
+
+ # Examples: All users with at least one organizations.department of engineering.
+
+ # user.organizations.exists(org, org.department=='engineering')
+
+ # All users with at least one location that has area of foo and building_id of bar.
+
+ # user.locations.exists(loc, loc.area=='foo' && loc.building_id=='bar')
+ # - !ruby/object:Api::Type::NestedObject
+ # name: 'DynamicGroupStatus'
+ # output: true
+ # description: |
+ # Status of the dynamic group.
+ # properties:
+ # - !ruby/object:Api::Type::String
+ # name: 'status'
+ # description: |
+ # Status of the dynamic group.
+ # - !ruby/object:Api::Type::String
+ # name: 'statusTime'
+ # description: |
+ # The latest time at which the dynamic group is guaranteed to be in the given status.
+ # For example, if status is: UP_TO_DATE - The latest time at which this dynamic group
+ # was confirmed to be up to date. UPDATING_MEMBERSHIPS - The time at which dynamic group was created.
+
+ # A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Resource
+ name: 'GroupMembership'
+ base_url: '{{group}}/memberships'
+ self_link: '{{name}}'
+ description: |
+ A Membership defines a relationship between a Group and an entity belonging to that Group, referred to as a "member".
+ parameters:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'group'
+ resource: 'Group'
+ imports: 'name'
+ description: |
+ The name of the Group to create this membership in.
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ output: true
+ description: |
+ The resource name of the Membership, of the form groups/{group_id}/memberships/{membership_id}.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'memberKey'
+ input: true
+ description: |
+ EntityKey of the member.
+ exactly_one_of:
+ - member_key
+ - preferred_member_key
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ required: true
+ input: true
+ description: |
+ The ID of the entity.
+
+ For Google-managed entities, the id must be the email address of an existing
+ group or user.
+
+ For external-identity-mapped entities, the id must be a string conforming
+ to the Identity Source's requirements.
+
+ Must be unique within a namespace.
+ - !ruby/object:Api::Type::String
+ name: 'namespace'
+ input: true
+ description: |
+ The namespace in which the entity exists.
+
+ If not specified, the EntityKey represents a Google-managed entity
+ such as a Google user or a Google Group.
+
+ If specified, the EntityKey represents an external-identity-mapped group.
+ The namespace must correspond to an identity source created in Admin Console
+ and must be in the form of `identitysources/{identity_source_id}`.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'preferredMemberKey'
+ input: true
+ description: |
+ EntityKey of the member.
+ exactly_one_of:
+ - member_key
+ - preferred_member_key
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ required: true
+ input: true
+ description: |
+ The ID of the entity.
+
+ For Google-managed entities, the id must be the email address of an existing
+ group or user.
+
+ For external-identity-mapped entities, the id must be a string conforming
+ to the Identity Source's requirements.
+
+ Must be unique within a namespace.
+ - !ruby/object:Api::Type::String
+ name: 'namespace'
+ input: true
+ description: |
+ The namespace in which the entity exists.
+
+ If not specified, the EntityKey represents a Google-managed entity
+ such as a Google user or a Google Group.
+
+ If specified, the EntityKey represents an external-identity-mapped group.
+ The namespace must correspond to an identity source created in Admin Console
+ and must be in the form of `identitysources/{identity_source_id}`.
+ - !ruby/object:Api::Type::String
+ name: 'createTime'
+ output: true
+ description: |
+ The time when the Membership was created.
+ - !ruby/object:Api::Type::String
+ name: 'updateTime'
+ output: true
+ description: |
+ The time when the Membership was last updated.
+ - !ruby/object:Api::Type::Array
+ name: 'roles'
+ required: true
+ description: |
+ The MembershipRoles that apply to the Membership.
+ Must not contain duplicate MembershipRoles with the same name.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'name'
+ required: true
+ description: |
+ The name of the MembershipRole. Must be one of OWNER, MANAGER, MEMBER.
+ values:
+ - :OWNER
+ - :MANAGER
+ - :MEMBER
+ - !ruby/object:Api::Type::String
+ name: 'type'
+ output: true
+ description: |
+ The type of the membership.
diff --git a/products/cloudidentity/terraform.yaml b/products/cloudidentity/terraform.yaml
new file mode 100644
index 000000000000..d6583f133597
--- /dev/null
+++ b/products/cloudidentity/terraform.yaml
@@ -0,0 +1,75 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Group: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_identity_groups_basic"
+ primary_resource_id: "cloud_identity_group_basic"
+ min_version: beta
+ vars:
+ id_group: "my-identity-group"
+ test_env_vars:
+ org_domain: :ORG_DOMAIN
+ cust_id: :CUST_ID
+ ### The full API doesn't seem to be implemented yet
+ # - !ruby/object:Provider::Terraform::Examples
+ # name: "cloud_identity_groups_full"
+ # primary_resource_id: "cloud_identity_group_full"
+ # min_version: beta
+ # vars:
+ # id_group: "my-identity-group"
+ # test_env_vars:
+ # org_domain: :ORG_DOMAIN
+ # cust_id: :CUST_ID
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ post_create: templates/terraform/post_create/set_computed_name.erb
+ GroupMembership: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_identity_group_membership"
+ primary_resource_id: "cloud_identity_group_membership_basic"
+ min_version: beta
+ vars:
+ id_group: "my-identity-group"
+ test_env_vars:
+ org_domain: :ORG_DOMAIN
+ cust_id: :CUST_ID
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_identity_group_membership_user"
+ primary_resource_id: "cloud_identity_group_membership_basic"
+ min_version: beta
+ vars:
+ id_group: "my-identity-group"
+ test_env_vars:
+ org_domain: :ORG_DOMAIN
+ cust_id: :CUST_ID
+ identity_user: :IDENTITY_USER
+ properties:
+ memberKey: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ preferredMemberKey: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ post_create: templates/terraform/post_create/set_computed_name.erb
+
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/cloudiot/api.yaml b/products/cloudiot/api.yaml
new file mode 100644
index 000000000000..d0f82d7e952f
--- /dev/null
+++ b/products/cloudiot/api.yaml
@@ -0,0 +1,405 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: CloudIot
+display_name: Cloud IoT Core
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://cloudiot.googleapis.com/v1/
+scopes:
+ - https://www.googleapis.com/auth/cloudiot
+ - https://www.googleapis.com/auth/cloud-platform
+objects:
+ - !ruby/object:Api::Resource
+ name: 'DeviceRegistry'
+ base_url: 'projects/{{project}}/locations/{{region}}/registries'
+ self_link: 'projects/{{project}}/locations/{{region}}/registries/{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Google Cloud IoT Core device registry.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/iot/docs/'
+ api: 'https://cloud.google.com/iot/docs/reference/cloudiot/rest/'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: region
+ input: true
+ url_param_only: true
+ required: true
+ description: |
+ The region of this Device Registry.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ input: true
+ required: true
+ description: |
+ The unique identifier for the device registry. For example,
+ `myRegistry`.
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource path name. For example,
+ `projects/example-proj/locations/us-central1/registries/my-registry`.
+ - !ruby/object:Api::Type::Array
+ name: 'eventNotificationConfigs'
+ description: |
+ List of configurations for event notifications, such as PubSub topics
+ to publish device events to.
+ max_size: 10
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'subfolderMatches'
+ description: |
+ If the subfolder name matches this string exactly, this
+ configuration will be used. The string must not include the
+ leading '/' character. If empty, all strings are matched. Empty
+ value can only be used for the last `event_notification_configs`
+ item.
+ - !ruby/object:Api::Type::String
+ name: 'pubsubTopicName'
+ required: true
+ description: |
+ PubSub topic name to publish device events.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'stateNotificationConfig'
+ description: |
+ A PubSub topic to publish device state updates.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'pubsubTopicName'
+ required: true
+ description: |
+ PubSub topic name to publish device state updates.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'mqttConfig'
+ description: |
+ Activate or deactivate MQTT.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'mqttEnabledState'
+ description: |
+ The field allows `MQTT_ENABLED` or `MQTT_DISABLED`
+ required: true
+ values:
+ - :MQTT_ENABLED
+ - :MQTT_DISABLED
+ - !ruby/object:Api::Type::NestedObject
+ name: 'httpConfig'
+ description: |
+ Activate or deactivate HTTP.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'httpEnabledState'
+ required: true
+ description: |
+ The field allows `HTTP_ENABLED` or `HTTP_DISABLED`.
+ values:
+ - :HTTP_ENABLED
+ - :HTTP_DISABLED
+ - !ruby/object:Api::Type::Enum
+ name: 'logLevel'
+ default_value: :NONE
+ description: |
+ The default logging verbosity for activity from devices in this
+ registry. Specifies which events should be written to logs. For
+ example, if the LogLevel is ERROR, only events that terminate in
+ errors will be logged. LogLevel is inclusive; enabling INFO logging
+ will also enable ERROR logging.
+ values:
+ - :NONE
+ - :ERROR
+ - :INFO
+ - :DEBUG
+ - !ruby/object:Api::Type::Array
+ name: 'credentials'
+ description: |
+ List of public key certificates to authenticate devices.
+ max_size: 10
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'publicKeyCertificate'
+ required: true
+ description: |
+ A public key certificate format and data.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'format'
+ required: true
+ description: |
+ The field allows only `X509_CERTIFICATE_PEM`.
+ values:
+ - :X509_CERTIFICATE_PEM
+ - !ruby/object:Api::Type::String
+ name: 'certificate'
+ required: true
+ description: |
+ The certificate data.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'x509Details'
+ output: true
+ description: |
+ The certificate details. Used only for X.509 certificates.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'issuer'
+ output: true
+ description: |
+ The entity that signed the certificate.
+ - !ruby/object:Api::Type::String
+ name: 'subject'
+ output: true
+ description: |
+ The entity the certificate and public key belong to.
+ - !ruby/object:Api::Type::String
+ name: 'startTime'
+ output: true
+ description: |
+ The time the certificate becomes valid. A timestamp in
+ RFC3339 UTC "Zulu" format, accurate to nanoseconds.
+ Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'expiryTime'
+ output: true
+ description: |
+ The time the certificate becomes invalid. A timestamp in
+ RFC3339 UTC "Zulu" format, accurate to nanoseconds.
+ Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'signatureAlgorithm'
+ output: true
+ description: |
+ The algorithm used to sign the certificate.
+ - !ruby/object:Api::Type::String
+ name: 'publicKeyType'
+ output: true
+ description: |
+ The type of public key in the certificate.
+ - !ruby/object:Api::Resource
+ name: 'Device'
+ base_url: '{{registry}}/devices'
+ self_link: '{{registry}}/devices/{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Google Cloud IoT Core device.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/iot/docs/'
+ api: 'https://cloud.google.com/iot/docs/reference/cloudiot/rest/'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: registry
+ input: true
+ url_param_only: true
+ required: true
+ description: |
+ The name of the device registry where this device should be created.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ input: true
+ required: true
+ description: |
+ The unique identifier for the device. For example,
+ `Device0`.
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource path name. For example,
+ `projects/example-proj/locations/us-central1/registries/my-registry/devices/device0`.
+ - !ruby/object:Api::Type::String
+ name: 'numId'
+ output: true
+ description: |
+ A server-defined unique numeric ID for the device.
+ This is a more compact way to identify devices, and it is globally unique.
+ - !ruby/object:Api::Type::Array
+ name: 'credentials'
+ description: |
+ The credentials used to authenticate this device.
+ max_size: 3
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::Time
+ name: 'expirationTime'
+ description: |
+ The time at which this credential becomes invalid.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'publicKey'
+ required: true
+ description: |
+ A public key used to verify the signature of JSON Web Tokens (JWTs).
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'format'
+ required: true
+ description: |
+ The format of the key.
+ values:
+ - :RSA_PEM
+ - :RSA_X509_PEM
+ - :ES256_PEM
+ - :ES256_X509_PEM
+ - !ruby/object:Api::Type::String
+ name: 'key'
+ required: true
+ description: |
+ The key data.
+ - !ruby/object:Api::Type::Time
+ name: 'lastHeartbeatTime'
+ output: true
+ description: |
+ The last time an MQTT PINGREQ was received.
+ - !ruby/object:Api::Type::Time
+ name: 'lastEventTime'
+ output: true
+ description: |
+ The last time a telemetry event was received.
+ - !ruby/object:Api::Type::Time
+ name: 'lastStateTime'
+ output: true
+ description: |
+ The last time a state event was received.
+ - !ruby/object:Api::Type::Time
+ name: 'lastConfigAckTime'
+ output: true
+ description: |
+ The last time a cloud-to-device config version acknowledgment was received from the device.
+ - !ruby/object:Api::Type::Time
+ name: 'lastConfigSendTime'
+ output: true
+ description: |
+ The last time a cloud-to-device config version was sent to the device.
+ - !ruby/object:Api::Type::Boolean
+ name: 'blocked'
+ description: |
+ If a device is blocked, connections or requests from this device will fail.
+ - !ruby/object:Api::Type::Time
+ name: 'lastErrorTime'
+ output: true
+ description: |
+ The time the most recent error occurred, such as a failure to publish to Cloud Pub/Sub.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'lastErrorStatus'
+ output: true
+ description: |
+ The error message of the most recent error, such as a failure to publish to Cloud Pub/Sub.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'number'
+ description: |
+ The status code, which should be an enum value of google.rpc.Code.
+ - !ruby/object:Api::Type::String
+ name: 'message'
+ description: |
+ A developer-facing error message, which should be in English.
+ - !ruby/object:Api::Type::Array
+ name: 'details'
+ description: |
+ A list of messages that carry the error details.
+ item_type: Api::Type::KeyValuePairs
+ - !ruby/object:Api::Type::NestedObject
+ name: 'config'
+ output: true
+ description: |
+ The most recent device configuration, which is eventually sent from Cloud IoT Core to the device.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'version'
+ output: true
+ description: |
+ The version of this update.
+ - !ruby/object:Api::Type::String
+ name: 'cloudUpdateTime'
+ output: true
+ description: |
+ The time at which this configuration version was updated in Cloud IoT Core.
+ - !ruby/object:Api::Type::String
+ name: 'deviceAckTime'
+ output: true
+ description: |
+ The time at which Cloud IoT Core received the acknowledgment from the device,
+ indicating that the device has received this configuration version.
+ - !ruby/object:Api::Type::String
+ name: 'binaryData'
+ description: |
+ The device configuration data.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'state'
+ output: true
+ description: |
+ The state most recently received from the device.
+ properties:
+ - !ruby/object:Api::Type::Time
+ name: 'updateTime'
+ description: |
+ The time at which this state version was updated in Cloud IoT Core.
+ - !ruby/object:Api::Type::String
+ name: 'binaryData'
+ description: |
+ The device state data.
+ - !ruby/object:Api::Type::Enum
+ name: 'logLevel'
+ allow_empty_object: true
+ description: |
+ The logging verbosity for device activity.
+ values:
+ - :NONE
+ - :ERROR
+ - :INFO
+ - :DEBUG
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ The metadata key-value pairs assigned to the device.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gatewayConfig'
+ description: |
+ Gateway-related configuration and state.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'gatewayType'
+ default_value: :NON_GATEWAY
+ input: true
+ description: |
+ Indicates whether the device is a gateway.
+ values:
+ - :GATEWAY
+ - :NON_GATEWAY
+ - !ruby/object:Api::Type::Enum
+ name: 'gatewayAuthMethod'
+ description: |
+ Indicates whether the device is a gateway.
+ values:
+ - :ASSOCIATION_ONLY
+ - :DEVICE_AUTH_TOKEN_ONLY
+ - :ASSOCIATION_AND_DEVICE_AUTH_TOKEN
+ - !ruby/object:Api::Type::String
+ name: 'lastAccessedGatewayId'
+ output: true
+ description: |
+ The ID of the gateway the device accessed most recently.
+ - !ruby/object:Api::Type::Time
+ name: 'lastAccessedGatewayTime'
+ output: true
+ description: |
+ The most recent time at which the device accessed the gateway specified in last_accessed_gateway.
diff --git a/products/cloudiot/terraform.yaml b/products/cloudiot/terraform.yaml
new file mode 100644
index 000000000000..3a2d52cbb3e7
--- /dev/null
+++ b/products/cloudiot/terraform.yaml
@@ -0,0 +1,192 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+legacy_name: "cloudiot"
+overrides: !ruby/object:Overrides::ResourceOverrides
+ DeviceRegistry: !ruby/object:Overrides::Terraform::ResourceOverride
+ legacy_name: "google_cloudiot_registry"
+ import_format: ["{{project}}/locations/{{region}}/registries/{{name}}"]
+ id_format: "projects/{{project}}/locations/{{region}}/registries/{{name}}"
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ constants: templates/terraform/constants/cloudiot.go.erb
+ decoder: templates/terraform/decoders/cloudiot_device_registry.go.erb
+ encoder: templates/terraform/encoders/cloudiot_device_registry.go.erb
+ extra_schema_entry: templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb
+ pre_update: templates/terraform/pre_update/cloudiot_device_registry.go.erb
+ docs: !ruby/object:Provider::Terraform::Docs
+ optional_properties: |+
+ * `state_notification_config` - A PubSub topic to publish device state updates.
+ The structure is documented below.
+
+ * `mqtt_config` - Activate or deactivate MQTT.
+ The structure is documented below.
+
+ * `http_config` - Activate or deactivate HTTP.
+ The structure is documented below.
+
+ * `credentials` - List of public key certificates to authenticate devices.
+ The structure is documented below.
+
+ The `state_notification_config` block supports:
+
+ * `pubsub_topic_name` - PubSub topic name to publish device state updates.
+
+ The `mqtt_config` block supports:
+
+ * `mqtt_enabled_state` - The field allows `MQTT_ENABLED` or `MQTT_DISABLED`.
+
+ The `http_config` block supports:
+
+ * `http_enabled_state` - The field allows `HTTP_ENABLED` or `HTTP_DISABLED`.
+
+ The `credentials` block supports:
+
+ * `public_key_certificate` - A public key certificate format and data.
+
+ The `public_key_certificate` block supports:
+
+ * `format` - The field allows only `X509_CERTIFICATE_PEM`.
+
+ * `certificate` - The certificate data.
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloudiot_device_registry_basic"
+ primary_resource_id: "test-registry"
+ vars:
+ cloudiot_registry_name: "cloudiot-registry"
+ test_env_vars:
+ project: :PROJECT_NAME
+ region: :REGION
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloudiot_device_registry_single_event_notification_configs"
+ primary_resource_id: "test-registry"
+ vars:
+ cloudiot_registry_name: "cloudiot-registry"
+ cloudiot_device_telemetry_topic_name: "default-telemetry"
+ test_env_vars:
+ project: :PROJECT_NAME
+ region: :REGION
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloudiot_device_registry_full"
+ primary_resource_id: "test-registry"
+ vars:
+ cloudiot_registry_name: "cloudiot-registry"
+ cloudiot_device_status_topic_name: "default-devicestatus"
+ cloudiot_device_telemetry_topic_name: "default-telemetry"
+ cloudiot_additional_device_telemetry_topic_name: "additional-telemetry"
+ cloudiot_subfolder_matches_additional_device_telemetry_topic: "test/path"
+ test_env_vars:
+ project: :PROJECT_NAME
+ region: :REGION
+ properties:
+ id: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ name: 'name'
+ description: |
+ A unique name for the resource, required by device registry.
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateCloudIotDeviceRegistryID'
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ # We don't need this field, because it has the same format as the ID
+ exclude: true
+ region: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ required: false
+ default_from_api: true
+ description: |
+ The region in which the created registry should reside.
+ If it is not provided, the provider region is used.
+ logLevel: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: 'emptyOrDefaultStringSuppress("NONE")'
+ eventNotificationConfigs: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ eventNotificationConfigs.subfolderMatches: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateCloudIotDeviceRegistrySubfolderMatch'
+ eventNotificationConfigs.pubsubTopicName: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: 'compareSelfLinkOrResourceName'
+ stateNotificationConfig: !ruby/object:Overrides::Terraform::PropertyOverride
+ # Excluding this because the original (manually-generated) implementation
+ # wrongly set this to be a Map, instead of a NestedObject. To avoid breaking
+ # changes, we observe that behaviour by excluding this field and adding a
+ # corresponding custom element (of type Map) to the schema. When we're
+ # ready to introduce this breaking change, remove this "exclude" directive
+ # along with the corresponding custom schema element.
+ exclude: true
+ stateNotificationConfig.pubsubTopicName: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ mqttConfig: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ mqttConfig.mqttEnabledState: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ httpConfig: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ httpConfig.httpEnabledState: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ credentials: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ credentials.publicKeyCertificate: !ruby/object:Overrides::Terraform::PropertyOverride
+ # See the comment on stateNotificationConfig.exclude
+ exclude: true
+ Device: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: [ "{{%registry}}/devices/{{name}}" ]
+ properties:
+ id: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ name: 'name'
+ description: |
+ A unique name for the resource.
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ # We don't need this field, because it has the same format as the ID
+ exclude: true
+ credentials.expirationTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ # If you don't set an expirationTime for a key, the API returns
+ # 1970-01-01T00:00:00Z, so we've to eventually accept that value.
+ default_from_api: true
+ gatewayConfig: !ruby/object:Overrides::Terraform::PropertyOverride
+ # The only mutable gateway_config field is gateway_auth_method,
+ # at least according to the API responses.
+ update_mask_fields:
+ - "gateway_config.gateway_auth_method"
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloudiot_device_basic"
+ primary_resource_id: "test-device"
+ vars:
+ cloudiot_device_name: "cloudiot-device"
+ cloudiot_device_registry_name: "cloudiot-device-registry"
+ test_env_vars:
+ project: :PROJECT_NAME
+ region: :REGION
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloudiot_device_full"
+ primary_resource_id: "test-device"
+ vars:
+ cloudiot_device_name: "cloudiot-device"
+ cloudiot_device_registry_name: "cloudiot-device-registry"
+ test_env_vars:
+ project: :PROJECT_NAME
+ region: :REGION
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/cloudrun/api.yaml b/products/cloudrun/api.yaml
index 07f7d6db82e5..380fb7f080a7 100644
--- a/products/cloudrun/api.yaml
+++ b/products/cloudrun/api.yaml
@@ -509,6 +509,24 @@ objects:
references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
+ - !ruby/object:Api::Type::Array
+ name: ports
+ description: |-
+ List of open ports in the container.
+ More Info:
+ https://cloud.google.com/run/docs/reference/rest/v1/RevisionSpec#ContainerPort
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: Name of the port.
+ - !ruby/object:Api::Type::String
+ name: protocol
+ description: Protocol used on port. Defaults to TCP.
+ - !ruby/object:Api::Type::Integer
+ name: containerPort
+ description: Port number.
+ required: true
- !ruby/object:Api::Type::NestedObject
name: resources
description: |-
@@ -540,6 +558,10 @@ objects:
the default value.
- `1` not-thread-safe. Single concurrency
- `2-N` thread-safe, max concurrency of N
+ - !ruby/object:Api::Type::Integer
+ name: timeoutSeconds
+ description: |-
+ TimeoutSeconds holds the max duration the instance is allowed for responding to a request.
- !ruby/object:Api::Type::String
name: serviceAccountName
description: |-
diff --git a/products/cloudrun/terraform.yaml b/products/cloudrun/terraform.yaml
index 1969381dfc56..495918258175 100644
--- a/products/cloudrun/terraform.yaml
+++ b/products/cloudrun/terraform.yaml
@@ -17,7 +17,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: "locations/{{location}}/namespaces/{{project}}/domainmappings/{{name}}"
import_format: ["locations/{{location}}/namespaces/{{project}}/domainmappings/{{name}}"]
async: !ruby/object:Provider::Terraform::PollAsync
- check_response_func: PollCheckKnativeStatus
+ check_response_func_existence: PollCheckKnativeStatus
actions: ['create', 'update']
operation: !ruby/object:Api::Async::Operation
timeouts: !ruby/object:Api::Timeouts
@@ -58,7 +58,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: "locations/{{location}}/namespaces/{{project}}/services/{{name}}"
import_format: ["locations/{{location}}/namespaces/{{project}}/services/{{name}}"]
async: !ruby/object:Provider::Terraform::PollAsync
- check_response_func: PollCheckKnativeStatus
+ check_response_func_existence: PollCheckKnativeStatus
actions: ['create', 'update']
operation: !ruby/object:Api::Async::Operation
timeouts: !ruby/object:Api::Timeouts
@@ -102,9 +102,19 @@ overrides: !ruby/object:Overrides::ResourceOverrides
project: :PROJECT_NAME
ignore_read_extra:
- "autogenerate_revision_name"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "cloud_run_service_traffic_split"
+ skip_test: true
+ primary_resource_id: "default"
+ primary_resource_name: "fmt.Sprintf(\"tf-test-cloudrun-srv%s\", context[\"random_suffix\"])"
+ vars:
+ cloud_run_service_name: "cloudrun-srv"
+ test_env_vars:
+ project: :PROJECT_NAME
virtual_fields:
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'autogenerate_revision_name'
+ default_value: false
description: |
If set to `true`, the revision name (template.metadata.name) will be omitted and
autogenerated by Cloud Run. This cannot be set to `true` while `template.metadata.name`
@@ -142,8 +152,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_from_api: true
spec.template.spec.containerConcurrency: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ spec.template.spec.timeoutSeconds: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
spec.template.spec.containers: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ spec.template.spec.containers.ports: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
spec.template.spec.containers.resources: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
spec.template.spec.containers.resources.limits: !ruby/object:Overrides::Terraform::PropertyOverride
diff --git a/products/cloudscheduler/api.yaml b/products/cloudscheduler/api.yaml
index 6a6d3729c643..c212e6f269a7 100644
--- a/products/cloudscheduler/api.yaml
+++ b/products/cloudscheduler/api.yaml
@@ -180,7 +180,7 @@ objects:
name: topicName
description: |
The full resource name for the Cloud Pub/Sub topic to which
- messages will be published when a job is delivered. ~>**NOTE**:
+ messages will be published when a job is delivered. ~>**NOTE:**
The topic name must be in the same format as required by PubSub's
PublishRequest.name, e.g. `projects/my-project/topics/my-topic`.
required: true
diff --git a/products/cloudscheduler/terraform.yaml b/products/cloudscheduler/terraform.yaml
index a14505bc0475..411b0e87fbcc 100644
--- a/products/cloudscheduler/terraform.yaml
+++ b/products/cloudscheduler/terraform.yaml
@@ -77,6 +77,16 @@ overrides: !ruby/object:Overrides::ResourceOverrides
region: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
ignore_read: true
+ retryConfig.retryCount: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ retryConfig.maxRetryDuration: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ retryConfig.minBackoffDuration: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ retryConfig.maxBackoffDuration: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ retryConfig.maxDoublings: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
# This is for copying files over
files: !ruby/object:Provider::Config::Files
diff --git a/products/compute/ansible.yaml b/products/compute/ansible.yaml
index 9e6858b82e07..f62507069980 100644
--- a/products/compute/ansible.yaml
+++ b/products/compute/ansible.yaml
@@ -31,6 +31,8 @@ datasources: !ruby/object:Overrides::ResourceOverrides
exclude: true
License: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ MachineImage: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
MachineType: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
NetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
@@ -51,8 +53,14 @@ datasources: !ruby/object:Overrides::ResourceOverrides
exclude: true
RouterNat: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ SecurityPolicy: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
Zone: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ PerInstanceConfig: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
+ RegionPerInstanceConfig: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
overrides: !ruby/object:Overrides::ResourceOverrides
Autoscaler: !ruby/object:Overrides::Ansible::ResourceOverride
properties:
@@ -261,6 +269,14 @@ overrides: !ruby/object:Overrides::ResourceOverrides
description: |
The source snapshot used to create this disk. You can provide this as
a partial or full URL to the resource.
+ RegionUrlMap: !ruby/object:Overrides::Ansible::ResourceOverride
+ properties:
+ pathMatchers.defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
+ defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
+ pathMatchers.pathRules.urlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
Reservation: !ruby/object:Overrides::Ansible::ResourceOverride
properties:
specificReservation.instanceProperties.minCpuPlatform: !ruby/object:Overrides::Ansible::PropertyOverride
@@ -309,6 +325,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
MachineType: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ MachineImage: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
NetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
GlobalNetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
@@ -329,8 +347,22 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
RouterNat: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ SecurityPolicy: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
+ UrlMap: !ruby/object:Overrides::Ansible::ResourceOverride
+ properties:
+ pathMatchers.defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
+ defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
+ pathMatchers.pathRules.urlRedirect.stripQuery: !ruby/object:Overrides::Ansible::PropertyOverride
+ default_value: false
Zone: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
+ PerInstanceConfig: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
+ RegionPerInstanceConfig: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
files: !ruby/object:Provider::Config::Files
resource:
<%= lines(indent(compile('provider/ansible/resource~compile.yaml'), 4)) -%>
diff --git a/products/compute/api.yaml b/products/compute/api.yaml
index 0cf418d8f1fa..813aca4836e8 100644
--- a/products/compute/api.yaml
+++ b/products/compute/api.yaml
@@ -94,8 +94,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'addressType'
description: |
- The type of address to reserve, either INTERNAL or EXTERNAL.
- If unspecified, defaults to EXTERNAL.
+ The type of address to reserve.
values:
- :INTERNAL
- :EXTERNAL
@@ -123,6 +122,7 @@ objects:
required: true
- !ruby/object:Api::Type::Enum
name: purpose
+ exact_version: ga
description: |
The purpose of this resource, which can be one of the following values:
@@ -131,11 +131,21 @@ objects:
This should only be set when using an Internal address.
values:
- :GCE_ENDPOINT
+ - !ruby/object:Api::Type::Enum
+ name: purpose
+ exact_version: beta
+ description: |
+ The purpose of this resource, which can be one of the following values:
+ - GCE_ENDPOINT for addresses that are used by VM instances, alias IP ranges, internal load balancers, and similar resources.
+ - SHARED_LOADBALANCER_VIP for an address that can be used by multiple internal load balancers
+ This should only be set when using an Internal address.
+ values:
+ - :GCE_ENDPOINT
+ - :SHARED_LOADBALANCER_VIP
- !ruby/object:Api::Type::Enum
name: 'networkTier'
description: |
- The networking tier used for configuring this address. This field can
- take the following values: PREMIUM or STANDARD. If this field is not
+ The networking tier used for configuring this address. If this field is not
specified, it is assumed to be PREMIUM.
values:
- :PREMIUM
@@ -291,6 +301,46 @@ objects:
instance may take to initialize. To do this, create an instance
and time the startup process.
default_value: 60
+ - !ruby/object:Api::Type::Enum
+ name: 'mode'
+ default_value: :ON
+ description: |
+ Defines operating mode for this policy.
+ values:
+ - :OFF
+ - :ONLY_UP
+ - :ON
+ - !ruby/object:Api::Type::NestedObject
+ name: 'scaleDownControl'
+ min_version: beta
+ at_least_one_of:
+ - scale_down_control.0.max_scaled_down_replicas
+ - scale_down_control.0.time_window_sec
+ description: |
+ Defines scale down controls to reduce the risk of response latency
+ and outages due to abrupt scale-in events
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'maxScaledDownReplicas'
+ at_least_one_of:
+ - scale_down_control.0.max_scaled_down_replicas.0.fixed
+ - scale_down_control.0.max_scaled_down_replicas.0.percent
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'fixed'
+ description: |
+ Specifies a fixed number of VM instances. This must be a positive
+ integer.
+ - !ruby/object:Api::Type::Integer
+ name: 'percent'
+ description: |
+ Specifies a percentage of instances between 0 to 100%, inclusive.
+ For example, specify 80 for 80%.
+ - !ruby/object:Api::Type::Integer
+ name: 'timeWindowSec'
+ description: |
+ How long back autoscaling should look when computing recommendations
+ to include directives regarding slower scale down, as described above.
- !ruby/object:Api::Type::NestedObject
name: 'cpuUtilization'
description: |
@@ -364,8 +414,7 @@ objects:
name: 'utilizationTargetType'
description: |
Defines how target utilization value is expressed for a
- Stackdriver Monitoring metric. Either GAUGE, DELTA_PER_SECOND,
- or DELTA_PER_MINUTE.
+ Stackdriver Monitoring metric.
values:
- :GAUGE
- :DELTA_PER_SECOND
@@ -741,10 +790,10 @@ objects:
description: |
Settings controlling the volume of connections to a backend service. This field
is applicable only when the load_balancing_scheme is set to INTERNAL_SELF_MANAGED.
- min_version: beta
properties:
- !ruby/object:Api::Type::NestedObject
name: 'connectTimeout'
+ min_version: beta
at_least_one_of:
- circuit_breakers.0.connect_timeout
- circuit_breakers.0.max_requests_per_connection
@@ -845,7 +894,6 @@ objects:
hashing. This field only applies if the load_balancing_scheme is set to
INTERNAL_SELF_MANAGED. This field is only applicable when locality_lb_policy is
set to MAGLEV or RING_HASH.
- min_version: beta
properties:
- !ruby/object:Api::Type::NestedObject
name: 'httpCookie'
@@ -1039,7 +1087,6 @@ objects:
output: true
- !ruby/object:Api::Type::Array
name: 'customRequestHeaders'
- min_version: beta
item_type: Api::Type::String
description: |
Headers that the HTTP/S load balancer should add to proxied
@@ -1061,13 +1108,14 @@ objects:
- !ruby/object:Api::Type::Array
name: 'healthChecks'
item_type: Api::Type::String
- required: true
min_size: 1
max_size: 1
description: |
The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource
for health checking this BackendService. Currently at most one health
- check can be specified, and a health check is required.
+ check can be specified.
+
+ A health check must be specified unless the backend service uses an internet NEG as a backend.
For internal load balancing, a URL to a HealthCheck resource must be specified instead.
- !ruby/object:Api::Type::Integer
@@ -1102,8 +1150,7 @@ objects:
description: |
Indicates whether the backend service will be used with internal or
external load balancing. A backend service created for one type of
- load balancing cannot be used with the other. Must be `EXTERNAL` or
- `INTERNAL_SELF_MANAGED` for a global backend service. Defaults to `EXTERNAL`.
+ load balancing cannot be used with the other.
default_value: :EXTERNAL
# If you're modifying this value, it probably means Global ILB is now
# an option. If that's the case, all of the documentation is based on
@@ -1113,8 +1160,6 @@ objects:
- :INTERNAL_SELF_MANAGED
- !ruby/object:Api::Type::Enum
name: 'localityLbPolicy'
- input: true
- min_version: beta
values:
- :ROUND_ROBIN
- :LEAST_REQUEST
@@ -1166,7 +1211,6 @@ objects:
character, which cannot be a dash.
- !ruby/object:Api::Type::NestedObject
name: 'outlierDetection'
- min_version: beta
description: |
Settings controlling eviction of unhealthy hosts from the load balancing pool.
This field is applicable only when the load_balancing_scheme is set
@@ -1420,8 +1464,7 @@ objects:
name: 'protocol'
description: |
The protocol this BackendService uses to communicate with backends.
- Possible values are HTTP, HTTPS, HTTP2, TCP, and SSL. The default is
- HTTP. **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer
+ The default is HTTP. **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer
types and may result in errors if used with the GA API.
values:
- :HTTP
@@ -1457,7 +1500,6 @@ objects:
failed request. Default is 30 seconds. Valid range is [1, 86400].
- !ruby/object:Api::Type::NestedObject
name: 'logConfig'
- min_version: beta
description: |
This field denotes the logging options for the load balancer traffic served by this backend service.
If logging is enabled, logs will be exported to Stackdriver.
@@ -1521,7 +1563,6 @@ objects:
properties:
- !ruby/object:Api::Type::Integer
name: 'affinityCookieTtlSec'
- min_version: beta
description: |
Lifetime of cookies in seconds if session_affinity is
GENERATED_COOKIE. If set to 0, the cookie is non-persistent and lasts
@@ -1543,7 +1584,7 @@ objects:
- :RATE
- :CONNECTION
description: |
- Specifies the balancing mode for this backend. Defaults to CONNECTION.
+ Specifies the balancing mode for this backend.
- !ruby/object:Api::Type::Double
name: 'capacityScaler'
description: |
@@ -1568,7 +1609,6 @@ objects:
description: |
This field designates whether this is a failover backend. More
than one failover backend can be configured for a given RegionBackendService.
- min_version: beta
- !ruby/object:Api::Type::String
name: 'group'
required: true
@@ -1663,10 +1703,10 @@ objects:
Settings controlling the volume of connections to a backend service. This field
is applicable only when the `load_balancing_scheme` is set to INTERNAL_MANAGED
and the `protocol` is set to HTTP, HTTPS, or HTTP2.
- min_version: beta
properties:
- !ruby/object:Api::Type::NestedObject
name: 'connectTimeout'
+ min_version: beta
at_least_one_of:
- circuit_breakers.0.connect_timeout
- circuit_breakers.0.max_requests_per_connection
@@ -1769,7 +1809,6 @@ objects:
* `load_balancing_scheme` is set to INTERNAL_MANAGED
* `protocol` is set to HTTP, HTTPS, or HTTP2
* `locality_lb_policy` is set to MAGLEV or RING_HASH
- min_version: beta
properties:
- !ruby/object:Api::Type::NestedObject
name: 'httpCookie'
@@ -1867,7 +1906,6 @@ objects:
An optional description of this resource.
- !ruby/object:Api::Type::NestedObject
name: 'failoverPolicy'
- min_version: beta
description: |
Policy for failovers.
properties:
@@ -1938,16 +1976,13 @@ objects:
description: |
Indicates what kind of load balancing this regional backend service
will be used for. A backend service created for one type of load
- balancing cannot be used with the other(s). Must be `INTERNAL` or
- `INTERNAL_MANAGED`. Defaults to `INTERNAL`.
+ balancing cannot be used with the other(s).
default_value: :INTERNAL
values:
- :INTERNAL
- :INTERNAL_MANAGED
- !ruby/object:Api::Type::Enum
name: 'localityLbPolicy'
- input: true
- min_version: beta
values:
- :ROUND_ROBIN
- :LEAST_REQUEST
@@ -1999,7 +2034,6 @@ objects:
character, which cannot be a dash.
- !ruby/object:Api::Type::NestedObject
name: 'outlierDetection'
- min_version: beta
description: |
Settings controlling eviction of unhealthy hosts from the load balancing pool.
This field is applicable only when the `load_balancing_scheme` is set
@@ -2242,12 +2276,21 @@ objects:
success rate: mean - (stdev * success_rate_stdev_factor). This factor is divided
by a thousand to get a double. That is, if the desired factor is 1.9, the
runtime value should be 1900. Defaults to 1900.
+ - !ruby/object:Api::Type::String
+ name: 'portName'
+ description: |
+ A named port on a backend instance group representing the port for
+ communication to the backend VMs in that group. Required when the
+ loadBalancingScheme is EXTERNAL, INTERNAL_MANAGED, or INTERNAL_SELF_MANAGED
+ and the backends are instance groups. The named port must be defined on each
+ backend instance group. This parameter has no meaning if the backends are NEGs. API sets a
+ default of "http" if not given.
+ Must be omitted when the loadBalancingScheme is INTERNAL (Internal TCP/UDP Load Balancing).
- !ruby/object:Api::Type::Enum
name: 'protocol'
description: |
The protocol this RegionBackendService uses to communicate with backends.
- Possible values are HTTP, HTTPS, HTTP2, SSL, TCP, and UDP. The default is
- HTTP. **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer
+ The default is HTTP. **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer
types and may result in errors if used with the GA API.
# This is removed to avoid breaking terraform, as default values cannot be
# unspecified. Providers should include this as needed via overrides
@@ -2279,7 +2322,6 @@ objects:
failed request. Default is 30 seconds. Valid range is [1, 86400].
- !ruby/object:Api::Type::NestedObject
name: 'logConfig'
- min_version: beta
description: |
This field denotes the logging options for the load balancer traffic served by this backend service.
If logging is enabled, logs will be exported to Stackdriver.
@@ -2948,13 +2990,9 @@ objects:
The list of ALLOW rules specified by this firewall. Each rule
specifies a protocol and port-range tuple that describes a permitted
connection.
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- allow
- deny
- conflicts:
- - denied
item_type: !ruby/object:Api::Type::NestedObject
properties:
# IPProtocol has to be string, instead of Enum because user can
@@ -2985,13 +3023,9 @@ objects:
output: true
- !ruby/object:Api::Type::Array
name: 'denied'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- allow
- deny
- conflicts:
- - allowed
description: |
The list of DENY rules specified by this firewall. Each rule specifies
a protocol and port-range tuple that describes a denied connection.
@@ -3055,17 +3089,22 @@ objects:
- !ruby/object:Api::Type::NestedObject
name: 'logConfig'
description: |
- This field denotes whether to enable logging for a particular
- firewall rule. If logging is enabled, logs will be exported to
- Stackdriver.
+ This field denotes the logging options for a particular firewall rule.
+ If logging is enabled, logs will be exported to Cloud Logging.
properties:
- !ruby/object:Api::Type::Boolean
- name: 'enableLogging'
- api_name: enable
+ name: 'enable'
description: |
This field denotes whether to enable logging for a particular
firewall rule. If logging is enabled, logs will be exported to
Stackdriver.
+ - !ruby/object:Api::Type::Enum
+ name: 'metadata'
+ description: |
+ This field denotes whether to include or exclude metadata for firewall logs.
+ values:
+ - :EXCLUDE_ALL_METADATA
+ - :INCLUDE_ALL_METADATA
- !ruby/object:Api::Type::Integer
name: 'id'
description: 'The unique identifier for the resource.'
@@ -3281,8 +3320,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'IPProtocol'
description: |
- The IP protocol to which this rule applies. Valid options are TCP,
- UDP, ESP, AH, SCTP or ICMP.
+ The IP protocol to which this rule applies.
When the load balancing scheme is INTERNAL, only TCP and UDP are
valid.
@@ -3436,8 +3474,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'networkTier'
description: |
- The networking tier used for configuring this address. This field can
- take the following values: PREMIUM or STANDARD. If this field is not
+ The networking tier used for configuring this address. If this field is not
specified, it is assumed to be PREMIUM.
values:
- :PREMIUM
@@ -3548,8 +3585,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'ipVersion'
description: |
- The IP Version that will be used by this address. Valid options are
- `IPV4` or `IPV6`. The default value is `IPV4`.
+ The IP Version that will be used by this address. The default value is `IPV4`.
values:
- :IPV4
- :IPV6
@@ -3570,7 +3606,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'addressType'
description: |
- The type of the address to reserve, default is EXTERNAL.
+ The type of the address to reserve.
* EXTERNAL indicates public/external single IP address.
* INTERNAL indicates internal IP ranges belonging to some network.
@@ -3679,8 +3715,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'IPProtocol'
description: |
- The IP protocol to which this rule applies. Valid options are TCP,
- UDP, ESP, AH, SCTP or ICMP. When the load balancing scheme is
+ The IP protocol to which this rule applies. When the load balancing scheme is
INTERNAL_SELF_MANAGED, only TCP is valid.
values:
- :TCP
@@ -3693,7 +3728,6 @@ objects:
name: 'ipVersion'
description: |
The IP Version that will be used by this global forwarding rule.
- Valid options are IPV4 or IPV6.
values:
- :IPV4
- :IPV6
@@ -4148,19 +4182,12 @@ objects:
- :HTTP2
- !ruby/object:Api::Type::NestedObject
name: 'httpHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpsHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -4242,7 +4269,7 @@ objects:
- http_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -4278,19 +4305,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'httpsHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -4372,7 +4392,7 @@ objects:
- https_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -4408,19 +4428,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'tcpHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - http2HealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'request'
@@ -4484,7 +4497,7 @@ objects:
- tcp_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -4519,19 +4532,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'sslHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'request'
@@ -4595,7 +4601,7 @@ objects:
- ssl_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -4630,19 +4636,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'http2HealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -4724,7 +4723,7 @@ objects:
- http2_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -6982,6 +6981,36 @@ objects:
description: |
The IEEE 802.1Q VLAN tag for this attachment, in the range 2-4094. When
using PARTNER type this will be managed upstream.
+ - !ruby/object:Api::Resource
+ name: 'MachineImage'
+ kind: 'compute#machineImage'
+ base_url: projects/{{project}}/global/machineImages
+ collection_url_key: 'items'
+ has_self_link: true
+ description: |
+ Represents a MachineImage resource. Machine images store all the configuration,
+ metadata, permissions, and data from one or more disks required to create a
+ Virtual machine (VM) instance.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': 'https://cloud.google.com/compute/docs/machine-images'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/beta/machineImages'
+ min_version: beta
+
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: 'Name of the resource.'
+ required: true
+ - !ruby/object:Api::Type::String
+ name: description
+ description: 'A text description of the resource.'
+ - !ruby/object:Api::Type::ResourceRef
+ name: sourceInstance
+ description: 'The source instance used to create the machine image. You can provide this as a partial or full URL to the resource.'
+ resource: 'Instance'
+ imports: 'selfLink'
+ required: true
- !ruby/object:Api::Resource
name: 'MachineType'
kind: 'compute#machineType'
@@ -7356,7 +7385,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'networkEndpointType'
description: |
- Type of network endpoints in this network endpoint group. The only supported value is GCE_VM_IP_PORT
+ Type of network endpoints in this network endpoint group.
values:
- :GCE_VM_IP_PORT
default_value: :GCE_VM_IP_PORT
@@ -7515,9 +7544,7 @@ objects:
name: 'networkEndpointType'
required: true
description: |
- Type of network endpoints in this network endpoint group. Supported values are:
- * INTERNET_IP_PORT
- * INTERNET_FQDN_PORT
+ Type of network endpoints in this network endpoint group.
values:
- :INTERNET_IP_PORT
- :INTERNET_FQDN_PORT
@@ -7609,8 +7636,8 @@ objects:
The autoscaling mode. Set to one of the following:
- OFF: Disables the autoscaler.
- ON: Enables scaling in and scaling out.
- - ONLY_SCALE_OUT: Enables only scaling out.
- You must use this mode if your node groups are configured to
+ - ONLY_SCALE_OUT: Enables only scaling out.
+ You must use this mode if your node groups are configured to
restart their hosted VMs on minimal servers.
values:
- :OFF
@@ -7619,7 +7646,7 @@ objects:
- !ruby/object:Api::Type::Integer
name: 'minNodes'
description: |
- Minimum size of the node group. Must be less
+ Minimum size of the node group. Must be less
than or equal to max-nodes. The default value is 0.
- !ruby/object:Api::Type::Integer
name: 'maxNodes'
@@ -7817,6 +7844,15 @@ objects:
values:
- :RESTART_NODE_ON_ANY_SERVER
- :RESTART_NODE_ON_MINIMAL_SERVERS
+ - !ruby/object:Api::Type::Enum
+ name: 'cpuOvercommitType'
+ description: |
+ CPU overcommit.
+ min_version: beta
+ values:
+ - :ENABLED
+ - :NONE
+ default_value: :NONE
- !ruby/object:Api::Resource
name: 'PacketMirroring'
min_version: beta
@@ -7856,7 +7892,7 @@ objects:
description: The name of the packet mirroring rule
required: true
- !ruby/object:Api::Type::String
- name: description
+ name: description
description: A human-readable description of the rule.
input: true
- !ruby/object:Api::Type::String
@@ -7900,7 +7936,7 @@ objects:
imports: 'selfLink'
description: The URL of the forwarding rule.
- !ruby/object:Api::Type::NestedObject
- name: filter
+ name: filter
description: |
A filter for mirrored traffic. If unset, all traffic is mirrored.
properties:
@@ -7973,56 +8009,297 @@ objects:
description: |
All instances with these tags will be mirrored.
item_type: Api::Type::String
-
+
- !ruby/object:Api::Resource
- name: 'ProjectInfo'
- base_url: projects
- self_link: projects/{{project}}
- readonly: true
+ name: 'PerInstanceConfig'
+ base_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}'
+ min_version: beta
description: |
- Information about the project specifically for compute.
+ A config defined for a single managed instance that belongs to an instance group manager. It preserves the instance name
+ across instance group manager operations and can define stateful disks or metadata that are unique to the instance.
+ create_verb: :POST
+ create_url: projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/createInstances
+ update_verb: :POST
+ update_url: projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/updatePerInstanceConfigs
+ delete_verb: :POST
+ delete_url: projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/deletePerInstanceConfigs
+ read_verb: :POST
+ self_link: projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/listPerInstanceConfigs
+ identity:
+ - name
+ nested_query: !ruby/object:Api::Resource::NestedQuery
+ keys:
+ - items
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': 'https://cloud.google.com/compute/docs/instance-groups/stateful-migs#per-instance_configs'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/beta/instanceGroupManagers'
+ async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ kind: 'compute#operation'
+ path: 'name'
+ base_url: 'projects/{{project}}/zones/{{zone}}/operations/{{op_id}}'
+ wait_ms: 1000
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 15
+ update_minutes: 6
+ delete_minutes: 15
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'targetLink'
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'status'
+ complete: 'DONE'
+ allowed:
+ - 'PENDING'
+ - 'RUNNING'
+ - 'DONE'
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error/errors'
+ message: 'message'
+ parameters:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'zone'
+ resource: 'Zone'
+ imports: 'name'
+ description: |
+ Zone where the containing instance group manager is located
+ required: true
+ url_param_only: true
+ input: true
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'instanceGroupManager'
+ resource: 'InstanceGroupManager'
+ imports: 'name'
+ description: |
+ The instance group manager this instance config is part of.
+ required: true
+ url_param_only: true
+ input: true
properties:
- !ruby/object:Api::Type::String
- name: name
- description: The name of this project
+ name: 'name'
+ description: |
+ The name for this per-instance config and its corresponding instance.
+ required: true
+ input: true
- !ruby/object:Api::Type::NestedObject
- name: 'commonInstanceMetadata'
- description: 'Metadata shared for all instances in this project'
+ name: 'preservedState'
+ description: 'The preserved state for this instance.'
+ update_verb: :POST
+ update_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/updatePerInstanceConfigs'
properties:
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ Preserved metadata defined for this instance. This is a list of key->value pairs.
- !ruby/object:Api::Type::Array
- name: 'items'
+ name: 'disk'
+ api_name: disks
description: |
- Array of key/values
+ Stateful disks for the instance.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
- name: 'key'
- description: 'Key of the metadata key/value pair'
+ name: deviceName
+ required: true
+ description: |
+ A unique device name that is reflected into the /dev/ tree of a Linux operating system running within the instance.
- !ruby/object:Api::Type::String
- name: 'value'
- description: 'Value of the metadata key/value pair'
- - !ruby/object:Api::Type::Array
- name: 'enabledFeatures'
+ name: source
+ required: true
+ description: |
+ The URI of an existing persistent disk to attach under the specified device-name in the format
+ `projects/project-id/zones/zone/disks/disk-name`.
+ - !ruby/object:Api::Type::Enum
+ name: mode
+ description: |
+ The mode of the disk.
+ values:
+ - :READ_ONLY
+ - :READ_WRITE
+ default_value: :READ_WRITE
+ - !ruby/object:Api::Type::Enum
+ name: deleteRule
+ description: |
+ A value that prescribes what should happen to the stateful disk when the VM instance is deleted.
+ The available options are `NEVER` and `ON_PERMANENT_INSTANCE_DELETION`.
+ `NEVER` detatch the disk when the VM is deleted, but not delete the disk.
+ `ON_PERMANENT_INSTANCE_DELETION` will delete the stateful disk when the VM is permanently
+ deleted from the instance group.
+ values:
+ - :NEVER
+ - :ON_PERMANENT_INSTANCE_DELETION
+ default_value: :NEVER
+ - !ruby/object:Api::Resource
+ name: 'RegionPerInstanceConfig'
+ base_url: 'projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}'
+ min_version: beta
+ description: |
+ A config defined for a single managed instance that belongs to an instance group manager. It preserves the instance name
+ across instance group manager operations and can define stateful disks or metadata that are unique to the instance.
+ This resource works with regional instance group managers.
+ create_verb: :POST
+ create_url: projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/createInstances
+ update_verb: :POST
+ update_url: projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/updatePerInstanceConfigs
+ delete_verb: :POST
+ delete_url: projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/deletePerInstanceConfigs
+ read_verb: :POST
+ self_link: projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/listPerInstanceConfigs
+ identity:
+ - name
+ nested_query: !ruby/object:Api::Resource::NestedQuery
+ keys:
+ - items
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': 'https://cloud.google.com/compute/docs/instance-groups/stateful-migs#per-instance_configs'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/beta/instanceGroupManagers'
+ async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ kind: 'compute#operation'
+ path: 'name'
+ base_url: 'projects/{{project}}/regions/{{region}}/operations/{{op_id}}'
+ wait_ms: 1000
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 15
+ update_minutes: 6
+ delete_minutes: 15
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'targetLink'
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'status'
+ complete: 'DONE'
+ allowed:
+ - 'PENDING'
+ - 'RUNNING'
+ - 'DONE'
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error/errors'
+ message: 'message'
+ parameters:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'region'
+ resource: 'Region'
+ imports: 'name'
description: |
- Restricted features enabled for use on this project
- item_type: Api::Type::String
- - !ruby/object:Api::Type::String
- name: defaultServiceAccount
- description: Default service account used by VMs in this project
- - !ruby/object:Api::Type::String
- name: xpnProjectStatus
- description: The role this project has in a shared VPC configuration.
+ Region where the containing instance group manager is located
+ required: true
+ url_param_only: true
+ input: true
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'regionInstanceGroupManager'
+ resource: 'RegionInstanceGroupManager'
+ imports: 'name'
+ description: |
+ The region instance group manager this instance config is part of.
+ required: true
+ url_param_only: true
+ input: true
+ properties:
- !ruby/object:Api::Type::String
- name: defaultNetworkTier
- description: The default network tier used for configuring resources in this project
- - !ruby/object:Api::Type::Array
- name: 'quotas'
+ name: 'name'
description: |
- Quotas applied to this project
- item_type: !ruby/object:Api::Type::NestedObject
- properties:
- - !ruby/object:Api::Type::String
- name: 'metric'
+ The name for this per-instance config and its corresponding instance.
+ required: true
+ input: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'preservedState'
+ description: 'The preserved state for this instance.'
+ update_verb: :POST
+ update_url: 'projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/updatePerInstanceConfigs'
+ properties:
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ Preserved metadata defined for this instance. This is a list of key->value pairs.
+ - !ruby/object:Api::Type::Array
+ name: 'disk'
+ api_name: disks
+ description: |
+ Stateful disks for the instance.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: deviceName
+ required: true
+ description: |
+ A unique device name that is reflected into the /dev/ tree of a Linux operating system running within the instance.
+ - !ruby/object:Api::Type::String
+ name: source
+ required: true
+ description: |
+ The URI of an existing persistent disk to attach under the specified device-name in the format
+ `projects/project-id/zones/zone/disks/disk-name`.
+ - !ruby/object:Api::Type::Enum
+ name: mode
+ description: |
+ The mode of the disk.
+ values:
+ - :READ_ONLY
+ - :READ_WRITE
+ default_value: :READ_WRITE
+ - !ruby/object:Api::Type::Enum
+ name: deleteRule
+ description: |
+ A value that prescribes what should happen to the stateful disk when the VM instance is deleted.
+ The available options are `NEVER` and `ON_PERMANENT_INSTANCE_DELETION`.
+ `NEVER` detatch the disk when the VM is deleted, but not delete the disk.
+ `ON_PERMANENT_INSTANCE_DELETION` will delete the stateful disk when the VM is permanently
+ deleted from the instance group.
+ values:
+ - :NEVER
+ - :ON_PERMANENT_INSTANCE_DELETION
+ default_value: :NEVER
+ - !ruby/object:Api::Resource
+ name: 'ProjectInfo'
+ base_url: projects
+ self_link: projects/{{project}}
+ readonly: true
+ description: |
+ Information about the project specifically for compute.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: The name of this project
+ - !ruby/object:Api::Type::NestedObject
+ name: 'commonInstanceMetadata'
+ description: 'Metadata shared for all instances in this project'
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'items'
+ description: |
+ Array of key/values
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'key'
+ description: 'Key of the metadata key/value pair'
+ - !ruby/object:Api::Type::String
+ name: 'value'
+ description: 'Value of the metadata key/value pair'
+ - !ruby/object:Api::Type::Array
+ name: 'enabledFeatures'
+ description: |
+ Restricted features enabled for use on this project
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::String
+ name: defaultServiceAccount
+ description: Default service account used by VMs in this project
+ - !ruby/object:Api::Type::String
+ name: xpnProjectStatus
+ description: The role this project has in a shared VPC configuration.
+ - !ruby/object:Api::Type::String
+ name: defaultNetworkTier
+ description: The default network tier used for configuring resources in this project
+ - !ruby/object:Api::Type::Array
+ name: 'quotas'
+ description: |
+ Quotas applied to this project
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'metric'
description: 'Name of the quota metric'
- !ruby/object:Api::Type::String
name: 'limit'
@@ -8249,6 +8526,46 @@ objects:
instance may take to initialize. To do this, create an instance
and time the startup process.
default_value: 60
+ - !ruby/object:Api::Type::Enum
+ name: 'mode'
+ default_value: :ON
+ description: |
+ Defines operating mode for this policy.
+ values:
+ - :OFF
+ - :ONLY_UP
+ - :ON
+ - !ruby/object:Api::Type::NestedObject
+ name: 'scaleDownControl'
+ min_version: beta
+ at_least_one_of:
+ - scale_down_control.0.max_scaled_down_replicas
+ - scale_down_control.0.time_window_sec
+ description: |
+ Defines scale down controls to reduce the risk of response latency
+ and outages due to abrupt scale-in events
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'maxScaledDownReplicas'
+ at_least_one_of:
+ - scale_down_control.0.max_scaled_down_replicas.0.fixed
+ - scale_down_control.0.max_scaled_down_replicas.0.percent
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'fixed'
+ description: |
+ Specifies a fixed number of VM instances. This must be a positive
+ integer.
+ - !ruby/object:Api::Type::Integer
+ name: 'percent'
+ description: |
+ Specifies a percentage of instances between 0 to 100%, inclusive.
+ For example, specify 80 for 80%.
+ - !ruby/object:Api::Type::Integer
+ name: 'timeWindowSec'
+ description: |
+ How long back autoscaling should look when computing recommendations
+ to include directives regarding slower scale down, as described above.
- !ruby/object:Api::Type::NestedObject
name: 'cpuUtilization'
description: |
@@ -8322,8 +8639,7 @@ objects:
name: 'utilizationTargetType'
description: |
Defines how target utilization value is expressed for a
- Stackdriver Monitoring metric. Either GAUGE, DELTA_PER_SECOND,
- or DELTA_PER_MINUTE.
+ Stackdriver Monitoring metric.
values:
- :GAUGE
- :DELTA_PER_SECOND
@@ -8498,7 +8814,7 @@ objects:
guides:
'Adding or Resizing Regional Persistent Disks':
'https://cloud.google.com/compute/docs/disks/regional-persistent-disk'
- api: 'https://cloud.google.com/compute/docs/reference/rest/beta/regionDisks'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/v1/regionDisks'
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'compute#operation'
@@ -8750,11 +9066,20 @@ objects:
output: true
- !ruby/object:Api::Type::ResourceRef
name: 'defaultService'
+ # TODO: add defaultRouteAction.weightedBackendService here once they are supported.
+ exactly_one_of:
+ - default_service
+ - default_url_redirect
resource: 'RegionBackendService'
imports: 'selfLink'
- description:
- A reference to RegionBackendService resource if none of the hostRules match.
- required: true
+ description: |
+ The full or partial URL of the defaultService resource to which traffic is directed if
+ none of the hostRules match. If defaultRouteAction is additionally specified, advanced
+ routing actions like URL Rewrites, etc. take effect prior to sending the request to the
+ backend. However, if defaultService is specified, defaultRouteAction cannot contain any
+ weightedBackendServices. Conversely, if routeAction specifies any
+ weightedBackendServices, service must not be specified. Only one of defaultService,
+ defaultUrlRedirect or defaultRouteAction.weightedBackendService must be set.
- !ruby/object:Api::Type::String
name: 'description'
description: |
@@ -8814,6 +9139,10 @@ objects:
properties:
- !ruby/object:Api::Type::ResourceRef
name: 'defaultService'
+ # TODO: add defaultRouteAction.weightedBackendService here once they are supported.
+ exactly_one_of:
+ - path_matchers.0.default_service
+ - path_matchers.0.default_url_redirect
required: true
resource: 'RegionBackendService'
imports: 'selfLink'
@@ -9463,36 +9792,52 @@ objects:
- !ruby/object:Api::Type::String
name: 'hostRedirect'
description: |
- The host that will be used in the redirect response instead of the one that was
- supplied in the request. The value must be between 1 and 255 characters.
+ The host that will be used in the redirect response instead of the one
+ that was supplied in the request. The value must be between 1 and 255
+ characters.
- !ruby/object:Api::Type::Boolean
name: 'httpsRedirect'
default_value: false
description: |
- If set to true, the URL scheme in the redirected request is set to https. If set
- to false, the URL scheme of the redirected request will remain the same as that
- of the request. This must only be set for UrlMaps used in TargetHttpProxys.
- Setting this true for TargetHttpsProxy is not permitted. Defaults to false.
+ If set to true, the URL scheme in the redirected request is set to https.
+ If set to false, the URL scheme of the redirected request will remain the
+ same as that of the request. This must only be set for UrlMaps used in
+ TargetHttpProxys. Setting this true for TargetHttpsProxy is not
+ permitted. The default is set to false.
- !ruby/object:Api::Type::String
name: 'pathRedirect'
description: |
- The path that will be used in the redirect response instead of the one that was
- supplied in the request. Only one of pathRedirect or prefixRedirect must be
- specified. The value must be between 1 and 1024 characters.
+ The path that will be used in the redirect response instead of the one
+ that was supplied in the request. pathRedirect cannot be supplied
+ together with prefixRedirect. Supply one alone or neither. If neither is
+ supplied, the path of the original request will be used for the redirect.
+ The value must be between 1 and 1024 characters.
- !ruby/object:Api::Type::String
name: 'prefixRedirect'
description: |
- The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
- retaining the remaining portion of the URL before redirecting the request.
+ The prefix that replaces the prefixMatch specified in the
+ HttpRouteRuleMatch, retaining the remaining portion of the URL before
+ redirecting the request. prefixRedirect cannot be supplied together with
+ pathRedirect. Supply one alone or neither. If neither is supplied, the
+ path of the original request will be used for the redirect. The value
+ must be between 1 and 1024 characters.
- !ruby/object:Api::Type::Enum
name: 'redirectResponseCode'
description: |
- The HTTP Status code to use for this RedirectAction. Supported values are: -
- MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301. -
- FOUND, which corresponds to 302. - SEE_OTHER which corresponds to 303. -
- TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
- will be retained. - PERMANENT_REDIRECT, which corresponds to 308. In this case,
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+ will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
the request method will be retained.
+ skip_docs_values: true
values:
- :FOUND
- :MOVED_PERMANENTLY_DEFAULT
@@ -9503,9 +9848,9 @@ objects:
name: 'stripQuery'
default_value: false
description: |
- If set to true, any accompanying query portion of the original URL is removed
- prior to redirecting the request. If set to false, the query portion of the
- original URL is retained. Defaults to false.
+ If set to true, any accompanying query portion of the original URL is
+ removed prior to redirecting the request. If set to false, the query
+ portion of the original URL is retained. The default value is false.
- !ruby/object:Api::Type::Array
name: 'pathRules'
description: |
@@ -9865,45 +10210,59 @@ objects:
- !ruby/object:Api::Type::NestedObject
name: 'urlRedirect'
description: |
- When a path pattern is matched, the request is redirected to a URL specified by
- urlRedirect. If urlRedirect is specified, service or routeAction must not be
- set.
+ When a path pattern is matched, the request is redirected to a URL specified
+ by urlRedirect. If urlRedirect is specified, service or routeAction must not
+ be set.
properties:
- !ruby/object:Api::Type::String
name: 'hostRedirect'
description: |
- The host that will be used in the redirect response instead of the one that was
- supplied in the request. The value must be between 1 and 255 characters.
+ The host that will be used in the redirect response instead of the one
+ that was supplied in the request. The value must be between 1 and 255
+ characters.
- !ruby/object:Api::Type::Boolean
name: 'httpsRedirect'
default_value: false
description: |
- If set to true, the URL scheme in the redirected request is set to https. If set
- to false, the URL scheme of the redirected request will remain the same as that
- of the request. This must only be set for UrlMaps used in TargetHttpProxys.
- Setting this true for TargetHttpsProxy is not permitted. Defaults to false.
+ If set to true, the URL scheme in the redirected request is set to https.
+ If set to false, the URL scheme of the redirected request will remain the
+ same as that of the request. This must only be set for UrlMaps used in
+ TargetHttpProxys. Setting this true for TargetHttpsProxy is not
+ permitted. The default is set to false.
- !ruby/object:Api::Type::String
name: 'pathRedirect'
description: |
- The path that will be used in the redirect response instead of the one that was
- supplied in the request. Only one of pathRedirect or prefixRedirect must be
- specified. The value must be between 1 and 1024 characters.
+ The path that will be used in the redirect response instead of the one
+ that was supplied in the request. pathRedirect cannot be supplied
+ together with prefixRedirect. Supply one alone or neither. If neither is
+ supplied, the path of the original request will be used for the redirect.
+ The value must be between 1 and 1024 characters.
- !ruby/object:Api::Type::String
name: 'prefixRedirect'
description: |
- The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
- retaining the remaining portion of the URL before redirecting the request.
+ The prefix that replaces the prefixMatch specified in the
+ HttpRouteRuleMatch, retaining the remaining portion of the URL before
+ redirecting the request. prefixRedirect cannot be supplied together with
+ pathRedirect. Supply one alone or neither. If neither is supplied, the
+ path of the original request will be used for the redirect. The value
+ must be between 1 and 1024 characters.
- !ruby/object:Api::Type::Enum
name: 'redirectResponseCode'
description: |
The HTTP Status code to use for this RedirectAction. Supported values are:
- - MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
- - FOUND, which corresponds to 302.
- - SEE_OTHER which corresponds to 303.
- - TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
will be retained.
- - PERMANENT_REDIRECT, which corresponds to 308. In this case,
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
the request method will be retained.
+ skip_docs_values: true
values:
- :FOUND
- :MOVED_PERMANENTLY_DEFAULT
@@ -9912,11 +10271,79 @@ objects:
- :TEMPORARY_REDIRECT
- !ruby/object:Api::Type::Boolean
name: 'stripQuery'
- required: true
description: |
If set to true, any accompanying query portion of the original URL is removed
prior to redirecting the request. If set to false, the query portion of the
original URL is retained.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultUrlRedirect'
+ # TODO: add defaultRouteAction.weightedBackendService here once they are supported.
+ exactly_one_of:
+ - path_matchers.0.default_service
+ - path_matchers.0.default_url_redirect
+ description: |
+ When none of the specified hostRules match, the request is redirected to a URL specified
+ by defaultUrlRedirect. If defaultUrlRedirect is specified, defaultService or
+ defaultRouteAction must not be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'hostRedirect'
+ description: |
+ The host that will be used in the redirect response instead of the one that was
+ supplied in the request. The value must be between 1 and 255 characters.
+ - !ruby/object:Api::Type::Boolean
+ name: 'httpsRedirect'
+ default_value: false
+ description: |
+ If set to true, the URL scheme in the redirected request is set to https. If set to
+ false, the URL scheme of the redirected request will remain the same as that of the
+ request. This must only be set for UrlMaps used in TargetHttpProxys. Setting this
+ true for TargetHttpsProxy is not permitted. The default is set to false.
+ - !ruby/object:Api::Type::String
+ name: 'pathRedirect'
+ description: |
+ The path that will be used in the redirect response instead of the one that was
+ supplied in the request. pathRedirect cannot be supplied together with
+ prefixRedirect. Supply one alone or neither. If neither is supplied, the path of the
+ original request will be used for the redirect. The value must be between 1 and 1024
+ characters.
+ - !ruby/object:Api::Type::String
+ name: 'prefixRedirect'
+ description: |
+ The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
+ retaining the remaining portion of the URL before redirecting the request.
+ prefixRedirect cannot be supplied together with pathRedirect. Supply one alone or
+ neither. If neither is supplied, the path of the original request will be used for
+ the redirect. The value must be between 1 and 1024 characters.
+ - !ruby/object:Api::Type::Enum
+ name: 'redirectResponseCode'
+ description: |
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+ will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
+ the request method will be retained.
+ skip_docs_values: true
+ values:
+ - :FOUND
+ - :MOVED_PERMANENTLY_DEFAULT
+ - :PERMANENT_REDIRECT
+ - :SEE_OTHER
+ - :TEMPORARY_REDIRECT
+ - !ruby/object:Api::Type::Boolean
+ name: 'stripQuery'
+ description: |
+ If set to true, any accompanying query portion of the original URL is removed prior
+ to redirecting the request. If set to false, the query portion of the original URL is
+ retained.
- !ruby/object:Api::Type::Array
name: 'tests'
description: |
@@ -9943,6 +10370,75 @@ objects:
description:
A reference to expected RegionBackendService resource the given URL
should be mapped to.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultUrlRedirect'
+ # TODO: add defaultRouteAction.weightedBackendService here once they are supported.
+ exactly_one_of:
+ - default_service
+ - default_url_redirect
+ description: |
+ When none of the specified hostRules match, the request is redirected to a URL specified
+ by defaultUrlRedirect. If defaultUrlRedirect is specified, defaultService or
+ defaultRouteAction must not be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'hostRedirect'
+ description: |
+ The host that will be used in the redirect response instead of the one that was
+ supplied in the request. The value must be between 1 and 255 characters.
+ - !ruby/object:Api::Type::Boolean
+ name: 'httpsRedirect'
+ default_value: false
+ description: |
+ If set to true, the URL scheme in the redirected request is set to https. If set to
+ false, the URL scheme of the redirected request will remain the same as that of the
+ request. This must only be set for UrlMaps used in TargetHttpProxys. Setting this
+ true for TargetHttpsProxy is not permitted. The default is set to false.
+ - !ruby/object:Api::Type::String
+ name: 'pathRedirect'
+ description: |
+ The path that will be used in the redirect response instead of the one that was
+ supplied in the request. pathRedirect cannot be supplied together with
+ prefixRedirect. Supply one alone or neither. If neither is supplied, the path of the
+ original request will be used for the redirect. The value must be between 1 and 1024
+ characters.
+ - !ruby/object:Api::Type::String
+ name: 'prefixRedirect'
+ description: |
+ The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
+ retaining the remaining portion of the URL before redirecting the request.
+ prefixRedirect cannot be supplied together with pathRedirect. Supply one alone or
+ neither. If neither is supplied, the path of the original request will be used for
+ the redirect. The value must be between 1 and 1024 characters.
+ - !ruby/object:Api::Type::Enum
+ name: 'redirectResponseCode'
+ description: |
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+ will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
+ the request method will be retained.
+ skip_docs_values: true
+ values:
+ - :FOUND
+ - :MOVED_PERMANENTLY_DEFAULT
+ - :PERMANENT_REDIRECT
+ - :SEE_OTHER
+ - :TEMPORARY_REDIRECT
+ - !ruby/object:Api::Type::Boolean
+ name: 'stripQuery'
+ description: |
+ If set to true, any accompanying query portion of the original URL is removed prior
+ to redirecting the request. If set to false, the query portion of the original URL is
+ retained.
- !ruby/object:Api::Resource
name: 'RegionHealthCheck'
kind: 'compute#healthCheck'
@@ -9952,7 +10448,7 @@ objects:
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/load-balancing/docs/health-checks'
- api: 'https://cloud.google.com/compute/docs/reference/rest/beta/regionHealthChecks'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/v1/regionHealthChecks'
description: |
Health Checks determine whether instances are responsive and able to do work.
They are an important part of a comprehensive load balancing configuration,
@@ -10059,19 +10555,12 @@ objects:
- :HTTP2
- !ruby/object:Api::Type::NestedObject
name: 'httpHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpsHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -10153,7 +10642,7 @@ objects:
- http_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -10189,19 +10678,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'httpsHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -10283,7 +10765,7 @@ objects:
- https_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -10319,19 +10801,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'tcpHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - http2HealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'request'
@@ -10395,7 +10870,7 @@ objects:
- tcp_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -10430,19 +10905,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'sslHealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - http2HealthCheck
- - tcpHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'request'
@@ -10506,7 +10974,7 @@ objects:
- ssl_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -10541,19 +11009,12 @@ objects:
- :USE_SERVING_PORT
- !ruby/object:Api::Type::NestedObject
name: 'http2HealthCheck'
- # TODO(terraform-providers/terraform-provider-google#5193): Change back to exactly_one_of
- # once hashicorp/terraform-plugin-sdk#280 is fixed
- at_least_one_of:
+ exactly_one_of:
- http_health_check
- https_health_check
- http2_health_check
- tcp_health_check
- ssl_health_check
- conflicts:
- - httpHealthCheck
- - httpsHealthCheck
- - tcpHealthCheck
- - sslHealthCheck
properties:
- !ruby/object:Api::Type::String
name: 'host'
@@ -10635,7 +11096,7 @@ objects:
- http2_health_check.0.port_specification
description: |
Specifies the type of proxy header to append before sending data to the
- backend, either NONE or PROXY_V1. The default is NONE.
+ backend.
values:
- :NONE
- :PROXY_V1
@@ -10729,6 +11190,8 @@ objects:
which cannot be a dash.
- !ruby/object:Api::Type::NestedObject
name: 'snapshotSchedulePolicy'
+ conflicts:
+ - 'groupPlacementPolicy'
description: |
Policy for creating snapshots of persistent disks.
properties:
@@ -10833,7 +11296,6 @@ objects:
description: |
Specifies the behavior to apply to scheduled snapshots when
the source disk is deleted.
- Valid options are KEEP_AUTO_SNAPSHOTS and APPLY_RETENTION_POLICY
default_value: :KEEP_AUTO_SNAPSHOTS
values:
- :KEEP_AUTO_SNAPSHOTS
@@ -10870,6 +11332,37 @@ objects:
- snapshot_schedule_policy.0.snapshot_properties.0.guest_flush
description: |
Whether to perform a 'guest aware' snapshot.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'groupPlacementPolicy'
+ conflicts:
+ - 'snapshotSchedulePolicy'
+ description: |
+ Policy for creating snapshots of persistent disks.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'vmCount'
+ at_least_one_of:
+ - group_placement_policy.0.vm_count
+ - group_placement_policy.0.availability_domain_count
+ description: |
+ Number of vms in this placement group.
+ - !ruby/object:Api::Type::Integer
+ name: 'availabilityDomainCount'
+ at_least_one_of:
+ - group_placement_policy.0.vm_count
+ - group_placement_policy.0.availability_domain_count
+ description: |
+ The number of availability domains instances will be spread across. If two instances are in different
+ availability domain, they will not be put in the same low latency network
+ - !ruby/object:Api::Type::Enum
+ name: 'collocation'
+ description: |
+ Collocation specifies whether to place VMs inside the same availability domain on the same low-latency network.
+ Specify `COLLOCATED` to enable collocation. Can only be specified with `vm_count`. If compute instances are created
+ with a COLLOCATED policy, then exactly `vm_count` instances must be created at the same time with the resource policy
+ attached.
+ values:
+ - :COLLOCATED
- !ruby/object:Api::Resource
name: 'Route'
kind: 'compute#route'
@@ -11153,8 +11646,6 @@ objects:
name: advertiseMode
description: |
User-specified flag to indicate which mode to use for advertisement.
-
- Valid values of this enum field are: DEFAULT, CUSTOM
values:
- :DEFAULT
- :CUSTOM
@@ -11387,8 +11878,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'filter'
description: |
- Specifies the desired filtering of logs on this NAT. Valid
- values are: `"ERRORS_ONLY"`, `"TRANSLATIONS_ONLY"`, `"ALL"`
+ Specifies the desired filtering of logs on this NAT.
required: true
values:
- :ERRORS_ONLY
@@ -11564,6 +12054,106 @@ objects:
PARTNER InterconnectAttachment is created, updated,
or deleted.
output: true
+ - !ruby/object:Api::Resource
+ name: 'SecurityPolicy'
+ kind: 'compute#securityPolicy'
+ base_url: projects/{{project}}/global/securityPolicies
+ collection_url_key: 'items'
+ has_self_link: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': 'https://cloud.google.com/armor/docs/security-policy-concepts'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/v1/securityPolicies'
+ description: |
+ Represents a Cloud Armor Security Policy resource.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: 'Name of the security policy.'
+ required: true
+ - !ruby/object:Api::Type::Integer
+ name: 'id'
+ description: 'The unique identifier for the resource.'
+ output: true
+ - !ruby/object:Api::Type::Array
+ name: 'rules'
+ description: |
+ A list of rules that belong to this policy.
+ There must always be a default rule (rule with priority 2147483647 and match "*").
+ If no rules are provided when creating a security policy, a default rule with action "allow" will be added.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ A description of the rule.
+ - !ruby/object:Api::Type::Integer
+ name: 'priority'
+ description: |
+ An integer indicating the priority of a rule in the list. The priority must be a positive value
+ between 0 and 2147483647. Rules are evaluated from highest to lowest priority where 0 is the
+ highest priority and 2147483647 is the lowest prority.
+ - !ruby/object:Api::Type::String
+ name: 'action'
+ description: |
+ The Action to preform when the client connection triggers the rule. Can currently be either
+ "allow" or "deny()" where valid values for status are 403, 404, and 502.
+ - !ruby/object:Api::Type::Boolean
+ name: 'preview'
+ description: |
+ If set to true, the specified action is not enforced.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'match'
+ description:
+ A match condition that incoming traffic is evaluated against. If it evaluates to true,
+ the corresponding 'action' is enforced.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ A description of the rule.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'expr'
+ description:
+ User defined CEVAL expression. A CEVAL expression is used to specify match criteria such as origin.ip,
+ source.region_code and contents in the request header.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'expression'
+ description: |
+ Textual representation of an expression in Common Expression Language syntax.
+ - !ruby/object:Api::Type::String
+ name: 'title'
+ description: |
+ Optional. Title for the expression, i.e. a short string describing its purpose.
+ This can be used e.g. in UIs which allow to enter the expression.
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ Optional. Description of the expression. This is a longer text which describes the expression,
+ e.g. when hovered over it in a UI.
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ description: |
+ Optional. String indicating the location of the expression for error reporting,
+ e.g. a file name and a position in the file.
+ - !ruby/object:Api::Type::String
+ name: 'versionedExpr'
+ description: |
+ Preconfigured versioned expression. If this field is specified, config must also be specified.
+ Available preconfigured expressions along with their requirements are: `SRC_IPS_V1` - must specify
+ the corresponding srcIpRange field in config.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'config'
+ description:
+ The configuration options available when specifying versionedExpr. This field must be specified
+ if versionedExpr is specified and cannot be specified if versionedExpr is not specified.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'srcIpRanges'
+ description: |
+ CIDR IP address range.
+ item_type: Api::Type::String
- !ruby/object:Api::Resource
name: 'Snapshot'
kind: 'compute#snapshot'
@@ -11713,7 +12303,7 @@ objects:
- !ruby/object:Api::Type::Integer
name: 'storageBytes'
description: |
- A size of the the storage used by the snapshot. As snapshots share
+ A size of the storage used by the snapshot. As snapshots share
storage, this number is expected to change with snapshot
creation/deletion.
output: true
@@ -12147,8 +12737,7 @@ objects:
- :SCSI
- :NVME
description: |
- The disk interface to use for attaching this disk, one
- of `SCSI` or `NVME`. The default is `SCSI`.
+ The disk interface to use for attaching this disk.
- !ruby/object:Api::Type::Integer
name: 'diskSizeGb'
required: true
@@ -12216,8 +12805,7 @@ objects:
name: 'profile'
description: |
Profile specifies the set of SSL features that can be used by the
- load balancer when negotiating SSL with clients. This can be one of
- `COMPATIBLE`, `MODERN`, `RESTRICTED`, or `CUSTOM`. If using `CUSTOM`,
+ load balancer when negotiating SSL with clients. If using `CUSTOM`,
the set of SSL features to enable must be specified in the
`customFeatures` field.
values:
@@ -12229,8 +12817,7 @@ objects:
name: 'minTlsVersion'
description: |
The minimum version of SSL protocol that can be used by the clients
- to establish a connection with the load balancer. This can be one of
- `TLS_1_0`, `TLS_1_1`, `TLS_1_2`.
+ to establish a connection with the load balancer.
values:
- :TLS_1_0
- :TLS_1_1
@@ -12446,7 +13033,7 @@ objects:
resource: 'Region'
imports: 'name'
description: |
- URL of the GCP region for this subnetwork.
+ The GCP region for this subnetwork.
required: true
input: true
- !ruby/object:Api::Type::NestedObject
@@ -12506,7 +13093,7 @@ objects:
description: |
Can only be specified if VPC flow logging for this subnetwork is enabled.
Configures whether metadata fields should be added to the reported VPC
- flow logs. Default is `INCLUDE_ALL_METADATA`.
+ flow logs.
values:
- :EXCLUDE_ALL_METADATA
- :INCLUDE_ALL_METADATA
@@ -12648,8 +13235,7 @@ objects:
whether the load balancer will attempt to negotiate QUIC with clients
or not. Can specify one of NONE, ENABLE, or DISABLE. If NONE is
specified, uses the QUIC policy with no user overrides, which is
- equivalent to DISABLE. Not specifying this field is equivalent to
- specifying NONE.
+ equivalent to DISABLE.
values:
- :NONE
- :ENABLE
@@ -12707,7 +13293,7 @@ objects:
guides:
'Official Documentation':
'https://cloud.google.com/compute/docs/load-balancing/http/target-proxies'
- api: 'https://cloud.google.com/compute/docs/reference/rest/beta/regionTargetHttpProxies'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/v1/regionTargetHttpProxies'
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'compute#operation'
@@ -12781,7 +13367,7 @@ objects:
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/compute/docs/load-balancing/http/target-proxies'
- api: 'https://cloud.google.com/compute/docs/reference/rest/beta/regionTargetHttpsProxies'
+ api: 'https://cloud.google.com/compute/docs/reference/rest/v1/regionTargetHttpsProxies'
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'compute#operation'
@@ -13175,7 +13761,7 @@ objects:
name: 'proxyHeader'
description: |
Specifies the type of proxy header to append before sending data to
- the backend, either NONE or PROXY_V1. The default is NONE.
+ the backend.
values:
- :NONE
- :PROXY_V1
@@ -13279,7 +13865,7 @@ objects:
name: 'proxyHeader'
description: |
Specifies the type of proxy header to append before sending data to
- the backend, either NONE or PROXY_V1. The default is NONE.
+ the backend.
values:
- :NONE
- :PROXY_V1
@@ -13588,17 +14174,20 @@ objects:
output: true
- !ruby/object:Api::Type::ResourceRef
name: 'defaultService'
+ exactly_one_of:
+ - default_service
+ - default_url_redirect
+ - default_route_action.0.weighted_backend_services
resource: 'BackendService'
imports: 'selfLink'
description: |
- The BackendService resource to which traffic is
- directed if none of the hostRules match. If defaultRouteAction is additionally
- specified, advanced routing actions like URL Rewrites, etc. take effect prior to
- sending the request to the backend. However, if defaultService is specified,
- defaultRouteAction cannot contain any weightedBackendServices. Conversely, if
- routeAction specifies any weightedBackendServices, service must not be
- specified. Only one of defaultService, defaultUrlRedirect or
- defaultRouteAction.weightedBackendService must be set.
+ The full or partial URL of the defaultService resource to which traffic is directed if
+ none of the hostRules match. If defaultRouteAction is additionally specified, advanced
+ routing actions like URL Rewrites, etc. take effect prior to sending the request to the
+ backend. However, if defaultService is specified, defaultRouteAction cannot contain any
+ weightedBackendServices. Conversely, if routeAction specifies any
+ weightedBackendServices, service must not be specified. Only one of defaultService,
+ defaultUrlRedirect or defaultRouteAction.weightedBackendService must be set.
- !ruby/object:Api::Type::String
name: 'description'
description: |
@@ -13743,25 +14332,30 @@ objects:
properties:
- !ruby/object:Api::Type::ResourceRef
name: 'defaultService'
+ # TODO: (mbang) won't work for array path matchers yet, uncomment here once they are supported.
+ # (github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ # exactly_one_of:
+ # - path_matchers.0.default_service
+ # - path_matchers.0.default_url_redirect
+ # - path_matchers.0.default_route_action.0.weighted_backend_services
resource: 'BackendService'
imports: 'selfLink'
description: |
- The BackendService resource. This will be used if
- none of the pathRules or routeRules defined by this PathMatcher are matched. For
- example, the following are all valid URLs to a BackendService resource:
- - https://www.googleapis.com/compute/v1/projects/project/global/backendServices/backen
- dService
+ The full or partial URL to the BackendService resource. This will be used if none
+ of the pathRules or routeRules defined by this PathMatcher are matched. For example,
+ the following are all valid URLs to a BackendService resource:
+ - https://www.googleapis.com/compute/v1/projects/project/global/backendServices/backendService
- compute/v1/projects/project/global/backendServices/backendService
- global/backendServices/backendService
- If defaultRouteAction is additionally
- specified, advanced routing actions like URL Rewrites, etc. take effect prior to
- sending the request to the backend. However, if defaultService is specified,
- defaultRouteAction cannot contain any weightedBackendServices. Conversely, if
- defaultRouteAction specifies any weightedBackendServices, defaultService must
- not be specified. Only one of defaultService, defaultUrlRedirect or
- defaultRouteAction.weightedBackendService must be set. Authorization requires
- one or more of the following Google IAM permissions on the specified resource
- default_service:
+ If defaultRouteAction is additionally specified, advanced routing actions like URL
+ Rewrites, etc. take effect prior to sending the request to the backend. However, if
+ defaultService is specified, defaultRouteAction cannot contain any
+ weightedBackendServices. Conversely, if defaultRouteAction specifies any
+ weightedBackendServices, defaultService must not be specified.
+ Only one of defaultService, defaultUrlRedirect or
+ defaultRouteAction.weightedBackendService must be set. Authorization requires one
+ or more of the following Google IAM permissions on the
+ specified resource defaultService:
- compute.backendBuckets.use
- compute.backendServices.use
- !ruby/object:Api::Type::String
@@ -14199,45 +14793,59 @@ objects:
- !ruby/object:Api::Type::NestedObject
name: 'urlRedirect'
description: |
- When a path pattern is matched, the request is redirected to a URL specified by
- urlRedirect. If urlRedirect is specified, service or routeAction must not be
- set.
+ When a path pattern is matched, the request is redirected to a URL specified
+ by urlRedirect. If urlRedirect is specified, service or routeAction must not
+ be set.
properties:
- !ruby/object:Api::Type::String
name: 'hostRedirect'
description: |
- The host that will be used in the redirect response instead of the one that was
- supplied in the request. The value must be between 1 and 255 characters.
+ The host that will be used in the redirect response instead of the one
+ that was supplied in the request. The value must be between 1 and 255
+ characters.
- !ruby/object:Api::Type::Boolean
name: 'httpsRedirect'
default_value: false
description: |
- If set to true, the URL scheme in the redirected request is set to https. If set
- to false, the URL scheme of the redirected request will remain the same as that
- of the request. This must only be set for UrlMaps used in TargetHttpProxys.
- Setting this true for TargetHttpsProxy is not permitted. Defaults to false.
+ If set to true, the URL scheme in the redirected request is set to https.
+ If set to false, the URL scheme of the redirected request will remain the
+ same as that of the request. This must only be set for UrlMaps used in
+ TargetHttpProxys. Setting this true for TargetHttpsProxy is not
+ permitted. The default is set to false.
- !ruby/object:Api::Type::String
name: 'pathRedirect'
description: |
- The path that will be used in the redirect response instead of the one that was
- supplied in the request. Only one of pathRedirect or prefixRedirect must be
- specified. The value must be between 1 and 1024 characters.
+ The path that will be used in the redirect response instead of the one
+ that was supplied in the request. pathRedirect cannot be supplied
+ together with prefixRedirect. Supply one alone or neither. If neither is
+ supplied, the path of the original request will be used for the redirect.
+ The value must be between 1 and 1024 characters.
- !ruby/object:Api::Type::String
name: 'prefixRedirect'
description: |
- The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
- retaining the remaining portion of the URL before redirecting the request.
+ The prefix that replaces the prefixMatch specified in the
+ HttpRouteRuleMatch, retaining the remaining portion of the URL before
+ redirecting the request. prefixRedirect cannot be supplied together with
+ pathRedirect. Supply one alone or neither. If neither is supplied, the
+ path of the original request will be used for the redirect. The value
+ must be between 1 and 1024 characters.
- !ruby/object:Api::Type::Enum
name: 'redirectResponseCode'
description: |
The HTTP Status code to use for this RedirectAction. Supported values are:
- - MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
- - FOUND, which corresponds to 302.
- - SEE_OTHER which corresponds to 303.
- - TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
will be retained.
- - PERMANENT_REDIRECT, which corresponds to 308. In this case,
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
the request method will be retained.
+ skip_docs_values: true
values:
- :FOUND
- :MOVED_PERMANENTLY_DEFAULT
@@ -14246,11 +14854,10 @@ objects:
- :TEMPORARY_REDIRECT
- !ruby/object:Api::Type::Boolean
name: 'stripQuery'
- required: true
description: |
- If set to true, any accompanying query portion of the original URL is removed
- prior to redirecting the request. If set to false, the query portion of the
- original URL is retained.
+ If set to true, any accompanying query portion of the original URL is
+ removed prior to redirecting the request. If set to false, the query
+ portion of the original URL is retained.
- !ruby/object:Api::Type::Array
name: 'routeRules'
description: |
@@ -14911,12 +15518,18 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'redirectResponseCode'
description: |
- The HTTP Status code to use for this RedirectAction. Supported values are: -
- MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301. -
- FOUND, which corresponds to 302. - SEE_OTHER which corresponds to 303. -
- TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
- will be retained. - PERMANENT_REDIRECT, which corresponds to 308. In this case,
- the request method will be retained.
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case, the request method will be retained.
+ skip_docs_values: true
values:
- :FOUND
- :MOVED_PERMANENTLY_DEFAULT
@@ -14930,6 +15543,388 @@ objects:
If set to true, any accompanying query portion of the original URL is removed
prior to redirecting the request. If set to false, the query portion of the
original URL is retained. Defaults to false.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultUrlRedirect'
+ # TODO: (mbang) won't work for array path matchers yet, uncomment here once they are supported.
+ # (github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ # exactly_one_of:
+ # - path_matchers.0.default_service
+ # - path_matchers.0.default_url_redirect
+ # - path_matchers.0.default_route_action.0.weighted_backend_services
+ description: |
+ When none of the specified hostRules match, the request is redirected to a URL specified
+ by defaultUrlRedirect. If defaultUrlRedirect is specified, defaultService or
+ defaultRouteAction must not be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'hostRedirect'
+ description: |
+ The host that will be used in the redirect response instead of the one that was
+ supplied in the request. The value must be between 1 and 255 characters.
+ - !ruby/object:Api::Type::Boolean
+ name: 'httpsRedirect'
+ default_value: false
+ description: |
+ If set to true, the URL scheme in the redirected request is set to https. If set to
+ false, the URL scheme of the redirected request will remain the same as that of the
+ request. This must only be set for UrlMaps used in TargetHttpProxys. Setting this
+ true for TargetHttpsProxy is not permitted. The default is set to false.
+ - !ruby/object:Api::Type::String
+ name: 'pathRedirect'
+ description: |
+ The path that will be used in the redirect response instead of the one that was
+ supplied in the request. pathRedirect cannot be supplied together with
+ prefixRedirect. Supply one alone or neither. If neither is supplied, the path of the
+ original request will be used for the redirect. The value must be between 1 and 1024
+ characters.
+ - !ruby/object:Api::Type::String
+ name: 'prefixRedirect'
+ description: |
+ The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
+ retaining the remaining portion of the URL before redirecting the request.
+ prefixRedirect cannot be supplied together with pathRedirect. Supply one alone or
+ neither. If neither is supplied, the path of the original request will be used for
+ the redirect. The value must be between 1 and 1024 characters.
+ - !ruby/object:Api::Type::Enum
+ name: 'redirectResponseCode'
+ description: |
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+ will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
+ the request method will be retained.
+ skip_docs_values: true
+ values:
+ - :FOUND
+ - :MOVED_PERMANENTLY_DEFAULT
+ - :PERMANENT_REDIRECT
+ - :SEE_OTHER
+ - :TEMPORARY_REDIRECT
+ - !ruby/object:Api::Type::Boolean
+ name: 'stripQuery'
+ description: |
+ If set to true, any accompanying query portion of the original URL is removed prior
+ to redirecting the request. If set to false, the query portion of the original URL is
+ retained.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultRouteAction'
+ # TODO: (mbang) conflicts also won't work for array path matchers yet, uncomment here once supported.
+ # conflicts:
+ # - defaultUrlRedirect
+ description: |
+ defaultRouteAction takes effect when none of the pathRules or routeRules match. The load balancer performs
+ advanced routing actions like URL rewrites, header transformations, etc. prior to forwarding the request
+ to the selected backend. If defaultRouteAction specifies any weightedBackendServices, defaultService must not be set.
+ Conversely if defaultService is set, defaultRouteAction cannot contain any weightedBackendServices.
+
+ Only one of defaultRouteAction or defaultUrlRedirect must be set.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'weightedBackendServices'
+ # TODO: (mbang) won't work for array path matchers yet, uncomment here once they are supported.
+ # (github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ # exactly_one_of:
+ # - path_matchers.0.default_service
+ # - path_matchers.0.default_url_redirect
+ # - path_matchers.0.default_route_action.0.weighted_backend_services
+ description: |
+ A list of weighted backend services to send traffic to when a route match occurs.
+ The weights determine the fraction of traffic that flows to their corresponding backend service.
+ If all traffic needs to go to a single backend service, there must be one weightedBackendService
+ with weight set to a non 0 number.
+
+ Once a backendService is identified and before forwarding the request to the backend service,
+ advanced routing actions like Url rewrites and header transformations are applied depending on
+ additional settings specified in this HttpRouteAction.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'backendService'
+ resource: 'BackendService'
+ imports: 'selfLink'
+ description: |
+ The full or partial URL to the default BackendService resource. Before forwarding the
+ request to backendService, the loadbalancer applies any relevant headerActions
+ specified as part of this backendServiceWeight.
+ - !ruby/object:Api::Type::Integer
+ name: 'weight'
+ description: |
+ Specifies the fraction of traffic sent to backendService, computed as
+ weight / (sum of all weightedBackendService weights in routeAction) .
+
+ The selection of a backend service is determined only for new traffic. Once a user's request
+ has been directed to a backendService, subsequent requests will be sent to the same backendService
+ as determined by the BackendService's session affinity policy.
+
+ The value must be between 0 and 1000
+ - !ruby/object:Api::Type::NestedObject
+ name: 'headerAction'
+ description: |
+ Specifies changes to request and response headers that need to take effect for
+ the selected backendService.
+
+ headerAction specified here take effect before headerAction in the enclosing
+ HttpRouteRule, PathMatcher and UrlMap.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'requestHeadersToRemove'
+ description: |
+ A list of header names for headers that need to be removed from the request prior to
+ forwarding the request to the backendService.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'requestHeadersToAdd'
+ description: |
+ Headers to add to a matching request prior to forwarding the request to the backendService.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'headerName'
+ description: |
+ The name of the header to add.
+ - !ruby/object:Api::Type::String
+ name: 'headerValue'
+ description: |
+ The value of the header to add.
+ - !ruby/object:Api::Type::Boolean
+ name: 'replace'
+ description: |
+ If false, headerValue is appended to any values that already exist for the header.
+ If true, headerValue is set for the header, discarding any values that were set for that header.
+ default_value: false
+ - !ruby/object:Api::Type::Array
+ name: 'responseHeadersToRemove'
+ description: |
+ A list of header names for headers that need to be removed from the response prior to sending the
+ response back to the client.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'responseHeadersToAdd'
+ description: |
+ Headers to add the response prior to sending the response back to the client.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'headerName'
+ description: |
+ The name of the header to add.
+ - !ruby/object:Api::Type::String
+ name: 'headerValue'
+ description: |
+ The value of the header to add.
+ - !ruby/object:Api::Type::Boolean
+ name: 'replace'
+ description: |
+ If false, headerValue is appended to any values that already exist for the header.
+ If true, headerValue is set for the header, discarding any values that were set for that header.
+ default_value: false
+ - !ruby/object:Api::Type::NestedObject
+ name: 'urlRewrite'
+ description: |
+ The spec to modify the URL of the request, prior to forwarding the request to the matched service.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'pathPrefixRewrite'
+ description: |
+ Prior to forwarding the request to the selected backend service, the matching portion of the
+ request's path is replaced by pathPrefixRewrite.
+
+ The value must be between 1 and 1024 characters.
+ - !ruby/object:Api::Type::String
+ name: 'hostRewrite'
+ description: |
+ Prior to forwarding the request to the selected service, the request's host header is replaced
+ with contents of hostRewrite.
+
+ The value must be between 1 and 255 characters.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'timeout'
+ description: |
+ Specifies the timeout for the selected route. Timeout is computed from the time the request has been
+ fully processed (i.e. end-of-stream) up until the response has been completely processed. Timeout includes all retries.
+
+ If not specified, will use the largest timeout among all backend services associated with the route.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are represented
+ with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'retryPolicy'
+ description: |
+ Specifies the retry policy associated with this route.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'retryConditions'
+ description: |
+ Specfies one or more conditions when this retry rule applies. Valid values are:
+
+ 5xx: Loadbalancer will attempt a retry if the backend service responds with any 5xx response code,
+ or if the backend service does not respond at all, example: disconnects, reset, read timeout,
+ connection failure, and refused streams.
+ gateway-error: Similar to 5xx, but only applies to response codes 502, 503 or 504.
+ connect-failure: Loadbalancer will retry on failures connecting to backend services,
+ for example due to connection timeouts.
+ retriable-4xx: Loadbalancer will retry for retriable 4xx response codes.
+ Currently the only retriable error supported is 409.
+ refused-stream:Loadbalancer will retry if the backend service resets the stream with a REFUSED_STREAM error code.
+ This reset type indicates that it is safe to retry.
+ cancelled: Loadbalancer will retry if the gRPC status code in the response header is set to cancelled
+ deadline-exceeded: Loadbalancer will retry if the gRPC status code in the response header is set to deadline-exceeded
+ resource-exhausted: Loadbalancer will retry if the gRPC status code in the response header is set to resource-exhausted
+ unavailable: Loadbalancer will retry if the gRPC status code in the response header is set to unavailable
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Integer
+ name: 'numRetries'
+ description: |
+ Specifies the allowed number retries. This number must be > 0. If not specified, defaults to 1.
+ default_value: 1
+ - !ruby/object:Api::Type::NestedObject
+ name: 'perTryTimeout'
+ description: |
+ Specifies a non-zero timeout per retry attempt.
+
+ If not specified, will use the timeout set in HttpRouteAction. If timeout in HttpRouteAction is not set,
+ will use the largest timeout among all backend services associated with the route.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are
+ represented with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'requestMirrorPolicy'
+ description: |
+ Specifies the policy on how requests intended for the route's backends are shadowed to a separate mirrored backend service.
+ Loadbalancer does not wait for responses from the shadow service. Prior to sending traffic to the shadow service,
+ the host / authority header is suffixed with -shadow.
+ properties:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'backendService'
+ resource: 'BackendService'
+ imports: 'selfLink'
+ description: |
+ The full or partial URL to the BackendService resource being mirrored to.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'corsPolicy'
+ description: |
+ The specification for allowing client side cross-origin requests. Please see
+ [W3C Recommendation for Cross Origin Resource Sharing](https://www.w3.org/TR/cors/)
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowOrigins'
+ description: |
+ Specifies the list of origins that will be allowed to do CORS requests.
+ An origin is allowed if it matches either an item in allowOrigins or an item in allowOriginRegexes.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowOriginRegexes'
+ description: |
+ Specifies the regualar expression patterns that match allowed origins. For regular expression grammar
+ please see en.cppreference.com/w/cpp/regex/ecmascript
+ An origin is allowed if it matches either an item in allowOrigins or an item in allowOriginRegexes.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowMethods'
+ description: |
+ Specifies the content for the Access-Control-Allow-Methods header.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowHeaders'
+ description: |
+ Specifies the content for the Access-Control-Allow-Headers header.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exposeHeaders'
+ description: |
+ Specifies the content for the Access-Control-Expose-Headers header.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Integer
+ name: 'maxAge'
+ description: |
+ Specifies how long results of a preflight request can be cached in seconds.
+ This translates to the Access-Control-Max-Age header.
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowCredentials'
+ description: |
+ In response to a preflight request, setting this to true indicates that the actual request can include user credentials.
+ This translates to the Access-Control-Allow-Credentials header.
+ default_value: false
+ - !ruby/object:Api::Type::Boolean
+ name: 'disabled'
+ description: |
+ If true, specifies the CORS policy is disabled. The default value is false, which indicates that the CORS policy is in effect.
+ default_value: false
+ - !ruby/object:Api::Type::NestedObject
+ name: 'faultInjectionPolicy'
+ description: |
+ The specification for fault injection introduced into traffic to test the resiliency of clients to backend service failure.
+ As part of fault injection, when clients send requests to a backend service, delays can be introduced by Loadbalancer on a
+ percentage of requests before sending those request to the backend service. Similarly requests from clients can be aborted
+ by the Loadbalancer for a percentage of requests.
+
+ timeout and retryPolicy will be ignored by clients that are configured with a faultInjectionPolicy.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'delay'
+ description: |
+ The specification for how client requests are delayed as part of fault injection, before being sent to a backend service.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fixedDelay'
+ description: |
+ Specifies the value of the fixed delay interval.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are
+ represented with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ - !ruby/object:Api::Type::Double
+ name: 'percentage'
+ description: |
+ The percentage of traffic (connections/operations/requests) on which delay will be introduced as part of fault injection.
+ The value must be between 0.0 and 100.0 inclusive.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'abort'
+ description: |
+ The specification for how client requests are aborted as part of fault injection.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'httpStatus'
+ description: |
+ The HTTP status code used to abort the request.
+ The value must be between 200 and 599 inclusive.
+ - !ruby/object:Api::Type::Double
+ name: 'percentage'
+ description: |
+ The percentage of traffic (connections/operations/requests) which will be aborted as part of fault injection.
+ The value must be between 0.0 and 100.0 inclusive.
- !ruby/object:Api::Type::Array
name: 'tests'
description: |
@@ -14959,6 +15954,567 @@ objects:
required: true
description: |
Expected BackendService resource the given URL should be mapped to.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultUrlRedirect'
+ exactly_one_of:
+ - default_service
+ - default_url_redirect
+ - default_route_action.0.weighted_backend_services
+ conflicts:
+ - defaultRouteAction
+ description: |
+ When none of the specified hostRules match, the request is redirected to a URL specified
+ by defaultUrlRedirect. If defaultUrlRedirect is specified, defaultService or
+ defaultRouteAction must not be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'hostRedirect'
+ description: |
+ The host that will be used in the redirect response instead of the one that was
+ supplied in the request. The value must be between 1 and 255 characters.
+ - !ruby/object:Api::Type::Boolean
+ name: 'httpsRedirect'
+ default_value: false
+ description: |
+ If set to true, the URL scheme in the redirected request is set to https. If set to
+ false, the URL scheme of the redirected request will remain the same as that of the
+ request. This must only be set for UrlMaps used in TargetHttpProxys. Setting this
+ true for TargetHttpsProxy is not permitted. The default is set to false.
+ - !ruby/object:Api::Type::String
+ name: 'pathRedirect'
+ description: |
+ The path that will be used in the redirect response instead of the one that was
+ supplied in the request. pathRedirect cannot be supplied together with
+ prefixRedirect. Supply one alone or neither. If neither is supplied, the path of the
+ original request will be used for the redirect. The value must be between 1 and 1024
+ characters.
+ - !ruby/object:Api::Type::String
+ name: 'prefixRedirect'
+ description: |
+ The prefix that replaces the prefixMatch specified in the HttpRouteRuleMatch,
+ retaining the remaining portion of the URL before redirecting the request.
+ prefixRedirect cannot be supplied together with pathRedirect. Supply one alone or
+ neither. If neither is supplied, the path of the original request will be used for
+ the redirect. The value must be between 1 and 1024 characters.
+ - !ruby/object:Api::Type::Enum
+ name: 'redirectResponseCode'
+ description: |
+ The HTTP Status code to use for this RedirectAction. Supported values are:
+
+ * MOVED_PERMANENTLY_DEFAULT, which is the default value and corresponds to 301.
+
+ * FOUND, which corresponds to 302.
+
+ * SEE_OTHER which corresponds to 303.
+
+ * TEMPORARY_REDIRECT, which corresponds to 307. In this case, the request method
+ will be retained.
+
+ * PERMANENT_REDIRECT, which corresponds to 308. In this case,
+ the request method will be retained.
+ skip_docs_values: true
+ values:
+ - :FOUND
+ - :MOVED_PERMANENTLY_DEFAULT
+ - :PERMANENT_REDIRECT
+ - :SEE_OTHER
+ - :TEMPORARY_REDIRECT
+ - !ruby/object:Api::Type::Boolean
+ name: 'stripQuery'
+ description: |
+ If set to true, any accompanying query portion of the original URL is removed prior
+ to redirecting the request. If set to false, the query portion of the original URL is
+ retained. The default is set to false.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'defaultRouteAction'
+ conflicts:
+ - defaultUrlRedirect
+ description: |
+ defaultRouteAction takes effect when none of the hostRules match. The load balancer performs advanced routing actions
+ like URL rewrites, header transformations, etc. prior to forwarding the request to the selected backend.
+ If defaultRouteAction specifies any weightedBackendServices, defaultService must not be set. Conversely if defaultService
+ is set, defaultRouteAction cannot contain any weightedBackendServices.
+
+ Only one of defaultRouteAction or defaultUrlRedirect must be set.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'weightedBackendServices'
+ exactly_one_of:
+ - default_service
+ - default_url_redirect
+ - default_route_action.0.weighted_backend_services
+ description: |
+ A list of weighted backend services to send traffic to when a route match occurs.
+ The weights determine the fraction of traffic that flows to their corresponding backend service.
+ If all traffic needs to go to a single backend service, there must be one weightedBackendService
+ with weight set to a non 0 number.
+
+ Once a backendService is identified and before forwarding the request to the backend service,
+ advanced routing actions like Url rewrites and header transformations are applied depending on
+ additional settings specified in this HttpRouteAction.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'backendService'
+ resource: 'BackendService'
+ imports: 'selfLink'
+ description: |
+ The full or partial URL to the default BackendService resource. Before forwarding the
+ request to backendService, the loadbalancer applies any relevant headerActions
+ specified as part of this backendServiceWeight.
+ - !ruby/object:Api::Type::Integer
+ name: 'weight'
+ description: |
+ Specifies the fraction of traffic sent to backendService, computed as
+ weight / (sum of all weightedBackendService weights in routeAction) .
+
+ The selection of a backend service is determined only for new traffic. Once a user's request
+ has been directed to a backendService, subsequent requests will be sent to the same backendService
+ as determined by the BackendService's session affinity policy.
+
+ The value must be between 0 and 1000
+ - !ruby/object:Api::Type::NestedObject
+ name: 'headerAction'
+ description: |
+ Specifies changes to request and response headers that need to take effect for
+ the selected backendService.
+
+ headerAction specified here take effect before headerAction in the enclosing
+ HttpRouteRule, PathMatcher and UrlMap.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'requestHeadersToRemove'
+ description: |
+ A list of header names for headers that need to be removed from the request prior to
+ forwarding the request to the backendService.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'requestHeadersToAdd'
+ description: |
+ Headers to add to a matching request prior to forwarding the request to the backendService.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'headerName'
+ description: |
+ The name of the header to add.
+ - !ruby/object:Api::Type::String
+ name: 'headerValue'
+ description: |
+ The value of the header to add.
+ - !ruby/object:Api::Type::Boolean
+ name: 'replace'
+ description: |
+ If false, headerValue is appended to any values that already exist for the header.
+ If true, headerValue is set for the header, discarding any values that were set for that header.
+ default_value: false
+ - !ruby/object:Api::Type::Array
+ name: 'responseHeadersToRemove'
+ description: |
+ A list of header names for headers that need to be removed from the response prior to sending the
+ response back to the client.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'responseHeadersToAdd'
+ description: |
+ Headers to add the response prior to sending the response back to the client.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'headerName'
+ description: |
+ The name of the header to add.
+ - !ruby/object:Api::Type::String
+ name: 'headerValue'
+ description: |
+ The value of the header to add.
+ - !ruby/object:Api::Type::Boolean
+ name: 'replace'
+ description: |
+ If false, headerValue is appended to any values that already exist for the header.
+ If true, headerValue is set for the header, discarding any values that were set for that header.
+ default_value: false
+ - !ruby/object:Api::Type::NestedObject
+ name: 'urlRewrite'
+ description: |
+ The spec to modify the URL of the request, prior to forwarding the request to the matched service.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'pathPrefixRewrite'
+ description: |
+ Prior to forwarding the request to the selected backend service, the matching portion of the
+ request's path is replaced by pathPrefixRewrite.
+
+ The value must be between 1 and 1024 characters.
+ at_least_one_of:
+ - default_route_action.0.url_rewrite.0.path_prefix_rewrite
+ - default_route_action.0.url_rewrite.0.host_rewrite
+ - !ruby/object:Api::Type::String
+ name: 'hostRewrite'
+ description: |
+ Prior to forwarding the request to the selected service, the request's host header is replaced
+ with contents of hostRewrite.
+
+ The value must be between 1 and 255 characters.
+ at_least_one_of:
+ - default_route_action.0.url_rewrite.0.path_prefix_rewrite
+ - default_route_action.0.url_rewrite.0.host_rewrite
+ - !ruby/object:Api::Type::NestedObject
+ name: 'timeout'
+ description: |
+ Specifies the timeout for the selected route. Timeout is computed from the time the request has been
+ fully processed (i.e. end-of-stream) up until the response has been completely processed. Timeout includes all retries.
+
+ If not specified, will use the largest timeout among all backend services associated with the route.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ at_least_one_of:
+ - default_route_action.0.timeout.0.seconds
+ - default_route_action.0.timeout.0.nanos
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are represented
+ with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ at_least_one_of:
+ - default_route_action.0.timeout.0.seconds
+ - default_route_action.0.timeout.0.nanos
+ - !ruby/object:Api::Type::NestedObject
+ name: 'retryPolicy'
+ description: |
+ Specifies the retry policy associated with this route.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'retryConditions'
+ description: |
+ Specfies one or more conditions when this retry rule applies. Valid values are:
+
+ 5xx: Loadbalancer will attempt a retry if the backend service responds with any 5xx response code,
+ or if the backend service does not respond at all, example: disconnects, reset, read timeout,
+ connection failure, and refused streams.
+ gateway-error: Similar to 5xx, but only applies to response codes 502, 503 or 504.
+ connect-failure: Loadbalancer will retry on failures connecting to backend services,
+ for example due to connection timeouts.
+ retriable-4xx: Loadbalancer will retry for retriable 4xx response codes.
+ Currently the only retriable error supported is 409.
+ refused-stream:Loadbalancer will retry if the backend service resets the stream with a REFUSED_STREAM error code.
+ This reset type indicates that it is safe to retry.
+ cancelled: Loadbalancer will retry if the gRPC status code in the response header is set to cancelled
+ deadline-exceeded: Loadbalancer will retry if the gRPC status code in the response header is set to deadline-exceeded
+ resource-exhausted: Loadbalancer will retry if the gRPC status code in the response header is set to resource-exhausted
+ unavailable: Loadbalancer will retry if the gRPC status code in the response header is set to unavailable
+ at_least_one_of:
+ - default_route_action.0.retry_policy.0.retry_conditions
+ - default_route_action.0.retry_policy.0.num_retries
+ - default_route_action.0.retry_policy.0.per_try_timeout
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Integer
+ name: 'numRetries'
+ description: |
+ Specifies the allowed number retries. This number must be > 0. If not specified, defaults to 1.
+ at_least_one_of:
+ - default_route_action.0.retry_policy.0.retry_conditions
+ - default_route_action.0.retry_policy.0.num_retries
+ - default_route_action.0.retry_policy.0.per_try_timeout
+ default_value: 1
+ - !ruby/object:Api::Type::NestedObject
+ name: 'perTryTimeout'
+ description: |
+ Specifies a non-zero timeout per retry attempt.
+
+ If not specified, will use the timeout set in HttpRouteAction. If timeout in HttpRouteAction is not set,
+ will use the largest timeout among all backend services associated with the route.
+ at_least_one_of:
+ - default_route_action.0.retry_policy.0.retry_conditions
+ - default_route_action.0.retry_policy.0.num_retries
+ - default_route_action.0.retry_policy.0.per_try_timeout
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ at_least_one_of:
+ - default_route_action.0.retry_policy.0.per_try_timeout.0.seconds
+ - default_route_action.0.retry_policy.0.per_try_timeout.0.nanos
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are
+ represented with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ at_least_one_of:
+ - default_route_action.0.retry_policy.0.per_try_timeout.0.seconds
+ - default_route_action.0.retry_policy.0.per_try_timeout.0.nanos
+ - !ruby/object:Api::Type::NestedObject
+ name: 'requestMirrorPolicy'
+ description: |
+ Specifies the policy on how requests intended for the route's backends are shadowed to a separate mirrored backend service.
+ Loadbalancer does not wait for responses from the shadow service. Prior to sending traffic to the shadow service,
+ the host / authority header is suffixed with -shadow.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'backendService'
+ resource: 'BackendService'
+ imports: 'selfLink'
+ description: |
+ The full or partial URL to the BackendService resource being mirrored to.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'corsPolicy'
+ description: |
+ The specification for allowing client side cross-origin requests. Please see
+ [W3C Recommendation for Cross Origin Resource Sharing](https://www.w3.org/TR/cors/)
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowOrigins'
+ description: |
+ Specifies the list of origins that will be allowed to do CORS requests.
+ An origin is allowed if it matches either an item in allowOrigins or an item in allowOriginRegexes.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowOriginRegexes'
+ description: |
+ Specifies the regualar expression patterns that match allowed origins. For regular expression grammar
+ please see en.cppreference.com/w/cpp/regex/ecmascript
+ An origin is allowed if it matches either an item in allowOrigins or an item in allowOriginRegexes.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowMethods'
+ description: |
+ Specifies the content for the Access-Control-Allow-Methods header.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowHeaders'
+ description: |
+ Specifies the content for the Access-Control-Allow-Headers header.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exposeHeaders'
+ description: |
+ Specifies the content for the Access-Control-Expose-Headers header.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Integer
+ name: 'maxAge'
+ description: |
+ Specifies how long results of a preflight request can be cached in seconds.
+ This translates to the Access-Control-Max-Age header.
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowCredentials'
+ description: |
+ In response to a preflight request, setting this to true indicates that the actual request can include user credentials.
+ This translates to the Access-Control-Allow-Credentials header.
+ default_value: false
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ - !ruby/object:Api::Type::Boolean
+ name: 'disabled'
+ description: |
+ If true, specifies the CORS policy is disabled. The default value is false, which indicates that the CORS policy is in effect.
+ default_value: false
+ at_least_one_of:
+ - default_route_action.0.cors_policy.0.allow_origins
+ - default_route_action.0.cors_policy.0.allow_origin_regexes
+ - default_route_action.0.cors_policy.0.allow_methods
+ - default_route_action.0.cors_policy.0.allow_headers
+ - default_route_action.0.cors_policy.0.expose_headers
+ - default_route_action.0.cors_policy.0.max_age
+ - default_route_action.0.cors_policy.0.allow_credentials
+ - default_route_action.0.cors_policy.0.disabled
+ - !ruby/object:Api::Type::NestedObject
+ name: 'faultInjectionPolicy'
+ description: |
+ The specification for fault injection introduced into traffic to test the resiliency of clients to backend service failure.
+ As part of fault injection, when clients send requests to a backend service, delays can be introduced by Loadbalancer on a
+ percentage of requests before sending those request to the backend service. Similarly requests from clients can be aborted
+ by the Loadbalancer for a percentage of requests.
+
+ timeout and retryPolicy will be ignored by clients that are configured with a faultInjectionPolicy.
+ at_least_one_of:
+ - default_route_action.0.weighted_backend_services
+ - default_route_action.0.url_rewrite
+ - default_route_action.0.timeout
+ - default_route_action.0.retry_policy
+ - default_route_action.0.request_mirror_policy
+ - default_route_action.0.cors_policy
+ - default_route_action.0.fault_injection_policy
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'delay'
+ description: |
+ The specification for how client requests are delayed as part of fault injection, before being sent to a backend service.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay
+ - default_route_action.0.fault_injection_policy.0.abort
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fixedDelay'
+ description: |
+ Specifies the value of the fixed delay interval.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay.0.delay
+ - default_route_action.0.fault_injection_policy.0.delay.0.percentage
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'seconds'
+ description: |
+ Span of time at a resolution of a second. Must be from 0 to 315,576,000,000 inclusive.
+ Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay.0.fixed_delay.0.seconds
+ - default_route_action.0.fault_injection_policy.0.delay.0.fixed_delay.0.nanos
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ description: |
+ Span of time that's a fraction of a second at nanosecond resolution. Durations less than one second are
+ represented with a 0 seconds field and a positive nanos field. Must be from 0 to 999,999,999 inclusive.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay.0.fixed_delay.0.seconds
+ - default_route_action.0.fault_injection_policy.0.delay.0.fixed_delay.0.nanos
+ - !ruby/object:Api::Type::Double
+ name: 'percentage'
+ description: |
+ The percentage of traffic (connections/operations/requests) on which delay will be introduced as part of fault injection.
+ The value must be between 0.0 and 100.0 inclusive.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay.0.delay
+ - default_route_action.0.fault_injection_policy.0.delay.0.percentage
+ - !ruby/object:Api::Type::NestedObject
+ name: 'abort'
+ description: |
+ The specification for how client requests are aborted as part of fault injection.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.delay
+ - default_route_action.0.fault_injection_policy.0.abort
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'httpStatus'
+ description: |
+ The HTTP status code used to abort the request.
+ The value must be between 200 and 599 inclusive.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.abort.0.http_status
+ - default_route_action.0.fault_injection_policy.0.abort.0.percentage
+ - !ruby/object:Api::Type::Double
+ name: 'percentage'
+ description: |
+ The percentage of traffic (connections/operations/requests) which will be aborted as part of fault injection.
+ The value must be between 0.0 and 100.0 inclusive.
+ at_least_one_of:
+ - default_route_action.0.fault_injection_policy.0.abort.0.http_status
+ - default_route_action.0.fault_injection_policy.0.abort.0.percentage
- !ruby/object:Api::Resource
name: 'VpnTunnel'
kind: 'compute#vpnTunnel'
diff --git a/products/compute/inspec.yaml b/products/compute/inspec.yaml
index d00aa66a49a1..0453560b0801 100644
--- a/products/compute/inspec.yaml
+++ b/products/compute/inspec.yaml
@@ -93,6 +93,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
MachineType: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
+ MachineImage: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
ManagedSslCertificate: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
Network: !ruby/object:Overrides::Inspec::ResourceOverride
@@ -183,6 +185,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
pathMatchers.pathRules: !ruby/object:Overrides::Inspec::PropertyOverride
exclude: true
+ pathMatchers.defaultRouteAction.weightedBackendServices: !ruby/object:Overrides::Inspec::PropertyOverride
+ exclude: true
VpnGateway: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
VpnTunnel: !ruby/object:Overrides::Inspec::ResourceOverride
@@ -202,3 +206,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
override_name: "zone_status"
id: !ruby/object:Overrides::Inspec::PropertyOverride
override_name: "zone_id"
+ PerInstanceConfig: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
+ RegionPerInstanceConfig: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
diff --git a/products/compute/terraform.yaml b/products/compute/terraform.yaml
index f1d7eeef7186..7eb456a56138 100644
--- a/products/compute/terraform.yaml
+++ b/products/compute/terraform.yaml
@@ -32,6 +32,13 @@ overrides: !ruby/object:Overrides::ResourceOverrides
primary_resource_id: "internal_with_gce_endpoint"
vars:
address_name: "my-internal-address-"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "address_with_shared_loadbalancer_vip"
+ primary_resource_id: "internal_with_shared_loadbalancer_vip"
+ min_version: 'beta'
+ vars:
+ address_name: "my-internal-address"
+ skip_docs: true # It is almost identical to internal_with_gce_endpoint
# TODO(rileykarson): Remove this example when instance is supported
- !ruby/object:Provider::Terraform::Examples
name: "instance_with_ip"
@@ -107,6 +114,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides
name: maxReplicas
autoscalingPolicy.coolDownPeriodSec: !ruby/object:Overrides::Terraform::PropertyOverride
name: cooldownPeriod
+ autoscalingPolicy.scaleDownControl: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: false
+ default_from_api: true
autoscalingPolicy.cpuUtilization: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
autoscalingPolicy.cpuUtilization.utilizationTarget: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -166,12 +176,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
keyValue: !ruby/object:Overrides::Terraform::PropertyOverride
sensitive: true
ignore_read: true
- docs: !ruby/object:Provider::Terraform::Docs
- warning: |
- All arguments including the key's value will be stored in the raw
- state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html).
- Because the API does not return the sensitive key value,
- we cannot confirm or reverse changes to a key outside of Terraform.
BackendService: !ruby/object:Overrides::Terraform::ResourceOverride
examples:
- !ruby/object:Provider::Terraform::Examples
@@ -194,6 +198,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
backend_service_name: "backend-service"
health_check_name: "health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "backend_service_network_endpoint"
+ primary_resource_id: "default"
+ vars:
+ backend_service_name: "backend-service"
+ neg_name: "network-endpoint"
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: 'templates/terraform/constants/backend_service.go.erb'
encoder: 'templates/terraform/encoders/backend_service.go.erb'
@@ -263,21 +273,18 @@ overrides: !ruby/object:Overrides::ResourceOverrides
health_check_name: "rbs-health-check"
- !ruby/object:Provider::Terraform::Examples
name: "region_backend_service_ilb_round_robin"
- min_version: beta
primary_resource_id: "default"
vars:
region_backend_service_name: "region-service"
health_check_name: "rbs-health-check"
- !ruby/object:Provider::Terraform::Examples
name: "region_backend_service_ilb_ring_hash"
- min_version: beta
primary_resource_id: "default"
vars:
region_backend_service_name: "region-service"
health_check_name: "rbs-health-check"
- !ruby/object:Provider::Terraform::Examples
name: "region_backend_service_balancing_mode"
- min_version: beta
primary_resource_id: "default"
vars:
region_backend_service_name: "region-service"
@@ -287,6 +294,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/region_backend_service.go.erb
encoder: templates/terraform/encoders/region_backend_service.go.erb
+ decoder: templates/terraform/decoders/region_backend_service.go.erb
resource_definition: 'templates/terraform/resource_definition/region_backend_service.go.erb'
properties:
region: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -319,6 +327,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
protocol: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ portName: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
sessionAffinity: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
timeoutSec: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -346,18 +356,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
keyValue: !ruby/object:Overrides::Terraform::PropertyOverride
sensitive: true
ignore_read: true
- docs: !ruby/object:Provider::Terraform::Docs
- warning: |
- All arguments including the key's value will be stored in the raw
- state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html).
- Because the API does not return the sensitive key value,
- we cannot confirm or reverse changes to a key outside of Terraform.
RegionDiskResourcePolicyAttachment: !ruby/object:Overrides::Terraform::ResourceOverride
description: |
Adds existing resource policies to a disk. You can only add one policy
which will be applied to this disk for scheduling snapshot creation.
- ~> **Note:** This resource does not support zonal disks (`google_compute_disk`).
+ ~> **Note:** This resource does not support zonal disks (`google_compute_disk`). For zonal disks, please refer to [`google_compute_disk_resource_policy_attachment`](https://www.terraform.io/docs/providers/google/r/compute_disk_resource_policy_attachment.html)
examples:
- !ruby/object:Provider::Terraform::Examples
name: "region_disk_resource_policy_attachment_basic"
@@ -381,7 +385,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
Adds existing resource policies to a disk. You can only add one policy
which will be applied to this disk for scheduling snapshot creation.
- ~> **Note:** This resource does not support regional disks (`google_compute_region_disk`).
+ ~> **Note:** This resource does not support regional disks (`google_compute_region_disk`). For regional disks, please refer to [`google_compute_region_disk_resource_policy_attachment`](https://www.terraform.io/docs/providers/google/r/compute_region_disk_resource_policy_attachment.html)
examples:
- !ruby/object:Provider::Terraform::Examples
name: "disk_resource_policy_attachment_basic"
@@ -445,7 +449,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
`global/images/family/{family}`, `family/{family}`, `{project}/{family}`,
`{project}/{image}`, `{family}`, or `{image}`. If referred by family, the
images names must include the family name. If they don't, use the
- [google_compute_image data source](/docs/providers/google/d/datasource_compute_image.html).
+ [google_compute_image data source](/docs/providers/google/d/compute_image.html).
For instance, the image `centos-6-v20180104` includes its family name `centos-6`.
These images can be referred by family name here.
diskEncryptionKey.rawKey: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -481,17 +485,20 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_from_api: true
resourcePolicies: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ description: |
+ {{description}}
+
+ ~>**NOTE** This value does not support updating the
+ resource policy, as resource policies can not be updated more than
+ one at a time. Use
+ [`google_compute_disk_resource_policy_attachment`](https://www.terraform.io/docs/providers/google/r/compute_disk_resource_policy_attachment.html)
+ to allow for updating the resource policy attached to the disk.
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/detach_disk.erb
constants: templates/terraform/constants/disk.erb
encoder: templates/terraform/encoders/disk.erb
decoder: templates/terraform/decoders/disk.erb
resource_definition: templates/terraform/resource_definition/disk.erb
- docs: !ruby/object:Provider::Terraform::Docs
- warning: |
- All arguments including the disk encryption key will be stored in the raw
- state as plain-text.
- [Read more about sensitive data in state](/docs/state/sensitive-data.html).
examples:
- !ruby/object:Provider::Terraform::Examples
name: "disk_basic"
@@ -501,6 +508,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
DiskType: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
Firewall: !ruby/object:Overrides::Terraform::ResourceOverride
+ docs: !ruby/object:Provider::Terraform::Docs
+ optional_properties: |+
+ * `enable_logging` - (Optional, Deprecated) This field denotes whether to enable logging for a particular firewall rule.
+ If logging is enabled, logs will be exported to Stackdriver. Deprecated in favor of `log_config`
examples:
- !ruby/object:Provider::Terraform::Examples
name: "firewall_basic"
@@ -511,6 +522,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/firewall.erb
resource_definition: templates/terraform/resource_definition/firewall.erb
+ extra_schema_entry: templates/terraform/extra_schema_entry/firewall.erb
properties:
id: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
@@ -539,9 +551,17 @@ overrides: !ruby/object:Overrides::ResourceOverrides
# See terraform issue #2713 for more context.
input: true
logConfig: !ruby/object:Overrides::Terraform::PropertyOverride
- flatten_object: true
- logConfig.enableLogging: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ This field denotes the logging options for a particular firewall rule.
+ If defined, logging is enabled, and logs will be exported to Cloud Logging.
send_empty_value: true
+ custom_expand: 'templates/terraform/custom_expand/firewall_log_config.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/firewall_log_config.go.erb'
+ diff_suppress_func: 'diffSuppressEnableLogging'
+ logConfig.enable: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ logConfig.metadata: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
name: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateGCPName'
@@ -594,6 +614,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
region_url_map_name: "website-map"
region_backend_service_name: "website-backend"
region_health_check_name: "website-hc"
+ rigm_name: "website-rigm"
network_name: "website-net"
fw_name: "website-fw"
custom_code: !ruby/object:Provider::Terraform::CustomCode
@@ -631,7 +652,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
internal IP address will be automatically allocated from the IP range
of the subnet or network configured for this forwarding rule.
- An address must be specified by a literal IP address. ~> **NOTE**: While
+ An address must be specified by a literal IP address. ~> **NOTE:** While
the API allows you to specify various resource paths for an address resource
instead, Terraform requires this to specifically be an IP address to
avoid needing to fetching the IP address from resource paths on refresh
@@ -956,6 +977,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "instance_group_named_port_gke"
primary_resource_id: "my_port"
+ # Multiple fine-grained resources
+ skip_vcr: true
vars:
network_name: "container-network"
subnetwork_name: "container-subnetwork"
@@ -1001,12 +1024,23 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_from_api: true
candidateSubnets: !ruby/object:Overrides::Terraform::PropertyOverride
ignore_read: true
+ edgeAvailabilityDomain: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/interconnect_attachment.go.erb
post_create: templates/terraform/post_create/interconnect_attachment.go.erb
pre_delete: templates/terraform/pre_delete/interconnect_attachment.go.erb
License: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
+ MachineImage: !ruby/object:Overrides::Terraform::ResourceOverride
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "machine_image_basic"
+ primary_resource_id: "image"
+ vars:
+ vm_name: "vm"
+ image_name: "image"
+
MachineType: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
Network: !ruby/object:Overrides::Terraform::ResourceOverride
@@ -1017,8 +1051,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
network_name: "vpc-network"
virtual_fields:
- - !ruby/object:Provider::Terraform::VirtualFields
+ - !ruby/object:Api::Type::Boolean
name: 'delete_default_routes_on_create'
+ default_value: false
description: |
If set to `true`, default routes (`0.0.0.0/0`) will be deleted
immediately after network creation. Defaults to `false`.
@@ -1176,6 +1211,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
properties:
network: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ importCustomRoutes: !ruby/object:Overrides::Terraform::PropertyOverride
+ send_empty_value: true
+ exportCustomRoutes: !ruby/object:Overrides::Terraform::PropertyOverride
+ send_empty_value: true
custom_code: !ruby/object:Provider::Terraform::CustomCode
custom_delete: 'templates/terraform/custom_delete/skip_delete.go.erb'
encoder: 'templates/terraform/encoders/network_peering_routes_config.go.erb'
@@ -1272,6 +1311,140 @@ overrides: !ruby/object:Overrides::ResourceOverrides
The Region in which the created address should reside.
If it is not provided, the provider region is used.
+ PerInstanceConfig: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{project}}/{{zone}}/{{instance_group_manager}}/{{name}}"
+ mutex: instanceGroupManager/{{project}}/{{zone}}/{{instance_group_manager}}
+ # Fine-grained resources don't actually exist as standalone GCP resource
+ # in Cloud Asset Inventory
+ exclude_validator: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "stateful_igm"
+ primary_resource_id: "stateful-instance"
+ # Fine-grained resource need different autogenerated tests, as
+ # we need to check destroy during a test step where the parent resource
+ # still exists, rather than during CheckDestroy (when read returns
+ # nothing because the parent resource has then also been destroyed)
+ skip_test: true
+ vars:
+ template_name: "my-template"
+ igm_name: "my-igm"
+ properties:
+ preservedState.disk: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ custom_flatten: templates/terraform/custom_flatten/preserved_state_disks.go.erb
+ custom_expand: templates/terraform/custom_expand/preserved_state_disks.go.erb
+ virtual_fields:
+ - !ruby/object:Api::Type::Enum
+ name: 'minimal_action'
+ description: |
+ The minimal action to perform on the instance during an update.
+ Default is `NONE`. Possible values are:
+ * REPLACE
+ * RESTART
+ * REFRESH
+ * NONE
+ values:
+ - :REPLACE
+ - :RESTART
+ - :REFRESH
+ - :NONE
+ default_value: :NONE
+ - !ruby/object:Api::Type::Enum
+ name: 'most_disruptive_allowed_action'
+ description: |
+ The most disruptive action to perform on the instance during an update.
+ Default is `REPLACE`. Possible values are:
+ * REPLACE
+ * RESTART
+ * REFRESH
+ * NONE
+ values:
+ - :REPLACE
+ - :RESTART
+ - :REFRESH
+ - :NONE
+ default_value: :REPLACE
+ - !ruby/object:Api::Type::Boolean
+ name: 'remove_instance_state_on_destroy'
+ description: |
+ When true, deleting this config will immediately remove any specified state from the underlying instance.
+ When false, deleting this config will *not* immediately remove any state from the underlying instance.
+ State will be removed on the next instance recreation or update.
+ default_value: false
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ encoder: templates/terraform/encoders/compute_per_instance_config.go.erb
+ update_encoder: templates/terraform/update_encoder/compute_per_instance_config.go.erb
+ pre_delete: templates/terraform/pre_delete/compute_per_instance_config.go.erb
+ post_update: templates/terraform/post_update/compute_per_instance_config.go.erb
+ custom_delete: templates/terraform/custom_delete/per_instance_config.go.erb
+ RegionPerInstanceConfig: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{project}}/{{region}}/{{region_instance_group_manager}}/{{name}}"
+ mutex: instanceGroupManager/{{project}}/{{region}}/{{region_instance_group_manager}}
+ # Fine-grained resources don't actually exist as standalone GCP resource
+ # in Cloud Asset Inventory
+ exclude_validator: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "stateful_rigm"
+ primary_resource_id: "stateful-instance"
+ # Fine-grained resource need different autogenerated tests, as
+ # we need to check destroy during a test step where the parent resource
+ # still exists, rather than during CheckDestroy (when read returns
+ # nothing because the parent resource has then also been destroyed)
+ skip_test: true
+ vars:
+ template_name: "my-template"
+ igm_name: "my-rigm"
+ properties:
+ preservedState.disk: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ custom_flatten: templates/terraform/custom_flatten/preserved_state_disks.go.erb
+ custom_expand: templates/terraform/custom_expand/preserved_state_disks.go.erb
+ virtual_fields:
+ - !ruby/object:Api::Type::Enum
+ name: 'minimal_action'
+ description: |
+ The minimal action to perform on the instance during an update.
+ Default is `NONE`. Possible values are:
+ * REPLACE
+ * RESTART
+ * REFRESH
+ * NONE
+ values:
+ - :REPLACE
+ - :RESTART
+ - :REFRESH
+ - :NONE
+ default_value: :NONE
+ - !ruby/object:Api::Type::Enum
+ name: 'most_disruptive_allowed_action'
+ description: |
+ The most disruptive action to perform on the instance during an update.
+ Default is `REPLACE`. Possible values are:
+ * REPLACE
+ * RESTART
+ * REFRESH
+ * NONE
+ values:
+ - :REPLACE
+ - :RESTART
+ - :REFRESH
+ - :NONE
+ default_value: :REPLACE
+ - !ruby/object:Api::Type::Boolean
+ name: 'remove_instance_state_on_destroy'
+ description: |
+ When true, deleting this config will immediately remove any specified state from the underlying instance.
+ When false, deleting this config will *not* immediately remove any state from the underlying instance.
+ State will be removed on the next instance recreation or update.
+ default_value: false
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ encoder: templates/terraform/encoders/compute_per_instance_config.go.erb
+ update_encoder: templates/terraform/update_encoder/compute_per_instance_config.go.erb
+ pre_delete: templates/terraform/pre_delete/compute_per_instance_config.go.erb
+ post_update: templates/terraform/post_update/compute_region_per_instance_config.go.erb
+ custom_delete: templates/terraform/custom_delete/region_per_instance_config.go.erb
ProjectInfo: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
Region: !ruby/object:Overrides::Terraform::ResourceOverride
@@ -1355,16 +1528,13 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
physicalBlockSizeBytes: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ diskEncryptionKey.rawKey: !ruby/object:Overrides::Terraform::PropertyOverride
+ sensitive: true
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/detach_disk.erb
encoder: templates/terraform/encoders/disk.erb
decoder: templates/terraform/decoders/disk.erb
resource_definition: templates/terraform/resource_definition/disk.erb
- docs: !ruby/object:Provider::Terraform::Docs
- warning: |
- All arguments including the disk encryption key will be stored in the raw
- state as plain-text.
- [Read more about sensitive data in state](/docs/state/sensitive-data.html).
examples:
- !ruby/object:Provider::Terraform::Examples
name: "region_disk_basic"
@@ -1460,7 +1630,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
sslHealthCheck: !ruby/object:Overrides::Terraform::PropertyOverride
diff_suppress_func: 'portDiffSuppress'
RegionUrlMap: !ruby/object:Overrides::Terraform::ResourceOverride
- min_version: 'beta'
examples:
- !ruby/object:Provider::Terraform::Examples
name: "region_url_map_basic"
@@ -1521,6 +1690,15 @@ overrides: !ruby/object:Overrides::ResourceOverrides
is_set: true
tests: !ruby/object:Overrides::Terraform::PropertyOverride
name: "test"
+ pathMatchers.defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
+ defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
+ pathMatchers.pathRules.urlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
ResourcePolicy: !ruby/object:Overrides::Terraform::ResourceOverride
examples:
- !ruby/object:Provider::Terraform::Examples
@@ -1533,6 +1711,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
primary_resource_id: "bar"
vars:
name: "policy"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "resource_policy_placement_policy"
+ primary_resource_id: "baz"
+ vars:
+ name: "policy"
properties:
region: !ruby/object:Overrides::Terraform::PropertyOverride
required: false
@@ -1565,6 +1748,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides
validation: !ruby/object:Provider::Terraform::Validation
function: 'validation.IntAtLeast(1)'
Route: !ruby/object:Overrides::Terraform::ResourceOverride
+ # Route cannot be added while a peering is on progress on the network
+ mutex: 'projects/{{project}}/global/networks/{{network}}/peerings'
+ error_retry_predicates: ["isPeeringOperationInProgress"]
examples:
- !ruby/object:Provider::Terraform::Examples
name: "route_basic"
@@ -1726,6 +1912,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
router_name: "my-router"
peer_name: "my-router-peer"
properties:
+ advertiseMode: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: 'templates/terraform/custom_flatten/default_if_empty.erb'
name: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateRFC1035Name(2, 63)'
@@ -1738,6 +1926,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
description: |
{{description}}
If it is not provided, the provider region is used.
+ SecurityPolicy: !ruby/object:Overrides::Terraform::ResourceOverride
+ exclude: true
Snapshot: !ruby/object:Overrides::Terraform::ResourceOverride
timeouts: !ruby/object:Api::Timeouts
insert_minutes: 5
@@ -1814,6 +2004,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
dns_zone_name: "dnszone"
forwarding_rule_name: "forwarding-rule"
http_health_check_name: "http-health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "managed_ssl_certificate_recreation"
+ primary_resource_id: "default"
+ min_version: beta
description: |
{{description}}
For a resource where you provide the key, see the
@@ -1838,14 +2032,20 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "ssl_certificate_basic"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
ignore_read_extra:
- "name_prefix"
- !ruby/object:Provider::Terraform::Examples
name: "ssl_certificate_random_provider"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
- !ruby/object:Provider::Terraform::Examples
name: "ssl_certificate_target_https_proxies"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
vars:
target_https_proxy_name: "test-proxy"
url_map_name: "url-map"
@@ -1883,15 +2083,20 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "region_ssl_certificate_basic"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
ignore_read_extra:
- "name_prefix"
- !ruby/object:Provider::Terraform::Examples
name: "region_ssl_certificate_random_provider"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
- !ruby/object:Provider::Terraform::Examples
name: "region_ssl_certificate_target_https_proxies"
- min_version: "beta"
primary_resource_id: "default"
+ # Uses resource.UniqueId
+ skip_vcr: true
vars:
region_target_https_proxy_name: "test-proxy"
region_url_map_name: "url-map"
@@ -1968,10 +2173,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
See the [official documentation](https://cloud.google.com/compute/docs/load-balancing/ssl-policies#profilefeaturesupport)
for information on what cipher suites each profile provides. If
`CUSTOM` is used, the `custom_features` attribute **must be set**.
- Default is `COMPATIBLE`.
minTlsVersion: !ruby/object:Overrides::Terraform::PropertyOverride
default_value: :TLS_1_0
- description : '{{description}} Default is `TLS_1_0`.'
warnings: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
Subnetwork: !ruby/object:Overrides::Terraform::ResourceOverride
@@ -2021,7 +2224,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
function: 'validateIpCidrRange'
region: !ruby/object:Overrides::Terraform::PropertyOverride
required: false
- input: false
default_from_api: true
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
purpose: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -2061,6 +2263,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
url_map_name: "url-map"
backend_service_name: "backend-service"
http_health_check_name: "http-health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "target_http_proxy_https_redirect"
+ primary_resource_id: "default"
+ vars:
+ target_http_proxy_name: "test-https-redirect-proxy"
+ url_map_name: "url-map"
properties:
id: !ruby/object:Overrides::Terraform::PropertyOverride
name: proxyId
@@ -2082,7 +2290,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
default_value: :NONE
custom_flatten: 'templates/terraform/custom_flatten/default_if_empty.erb'
RegionTargetHttpProxy: !ruby/object:Overrides::Terraform::ResourceOverride
- min_version: 'beta'
examples:
- !ruby/object:Provider::Terraform::Examples
name: "region_target_http_proxy_basic"
@@ -2092,6 +2299,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
region_url_map_name: "url-map"
region_backend_service_name: "backend-service"
region_health_check_name: "http-health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "region_target_http_proxy_https_redirect"
+ primary_resource_id: "default"
+ vars:
+ region_target_http_proxy_name: "test-https-redirect-proxy"
+ region_url_map_name: "url-map"
properties:
region: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
@@ -2103,7 +2316,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id: !ruby/object:Overrides::Terraform::PropertyOverride
name: proxyId
RegionTargetHttpsProxy: !ruby/object:Overrides::Terraform::ResourceOverride
- min_version: 'beta'
examples:
- !ruby/object:Provider::Terraform::Examples
name: "region_target_https_proxy_basic"
@@ -2299,6 +2511,24 @@ overrides: !ruby/object:Overrides::ResourceOverrides
url_map_name: "urlmap"
home_backend_service_name: "home"
health_check_name: "health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "url_map_header_based_routing"
+ primary_resource_id: "urlmap"
+ vars:
+ url_map_name: "urlmap"
+ default_backend_service_name: "default"
+ service_a_backend_service_name: "service-a"
+ service_b_backend_service_name: "service-b"
+ health_check_name: "health-check"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "url_map_parameter_based_routing"
+ primary_resource_id: "urlmap"
+ vars:
+ url_map_name: "urlmap"
+ default_backend_service_name: "default"
+ service_a_backend_service_name: "service-a"
+ service_b_backend_service_name: "service-b"
+ health_check_name: "health-check"
properties:
id: !ruby/object:Overrides::Terraform::PropertyOverride
name: "map_id"
@@ -2335,6 +2565,49 @@ overrides: !ruby/object:Overrides::ResourceOverrides
description: The backend service or backend bucket link that should be matched by this test.
tests: !ruby/object:Overrides::Terraform::PropertyOverride
name: "test"
+ pathMatchers.defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
+ defaultUrlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
+ pathMatchers.pathRules.urlRedirect.stripQuery: !ruby/object:Overrides::Terraform::PropertyOverride
+ required: true
+ description: '{{description}} This field is required to ensure an empty block is not set. The normal default value is false.'
+ pathMatchers.defaultRouteAction.weightedBackendServices.weight: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0, 1000)'
+ pathMatchers.defaultRouteAction.timeout: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ pathMatchers.defaultRouteAction.retryPolicy.numRetries: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntAtLeast(1)'
+ pathMatchers.defaultRouteAction.faultInjectionPolicy.delay.percentage: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.FloatBetween(0, 100)'
+ pathMatchers.defaultRouteAction.faultInjectionPolicy.abort.httpStatus: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(200, 599)'
+ pathMatchers.defaultRouteAction.faultInjectionPolicy.abort.percentage: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.FloatBetween(0, 100)'
+ defaultRouteAction.weightedBackendServices.weight: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0, 1000)'
+ defaultRouteAction.timeout: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ defaultRouteAction.retryPolicy.numRetries: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntAtLeast(1)'
+ defaultRouteAction.faultInjectionPolicy.delay.percentage: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.FloatBetween(0, 100)'
+ defaultRouteAction.faultInjectionPolicy.abort.httpStatus: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(200, 599)'
+ defaultRouteAction.faultInjectionPolicy.abort.percentage: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.FloatBetween(0, 100)'
VpnTunnel: !ruby/object:Overrides::Terraform::ResourceOverride
examples:
- !ruby/object:Provider::Terraform::Examples
@@ -2362,11 +2635,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
udp500_forwarding_rule_name: "fr-udp500"
udp4500_forwarding_rule_name: "fr-udp4500"
route_name: "route1"
- docs: !ruby/object:Provider::Terraform::Docs
- warning: |
- All arguments including the shared secret will be stored in the raw
- state as plain-text.
- [Read more about sensitive data in state](/docs/state/sensitive-data.html).
properties:
targetVpnGateway: !ruby/object:Overrides::Terraform::PropertyOverride
resource: 'VpnGateway'
@@ -2415,7 +2683,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
post_create: templates/terraform/post_create/labels.erb
Zone: !ruby/object:Overrides::Terraform::ResourceOverride
exclude: true
-
# This is for copying files over
files: !ruby/object:Provider::Config::Files
# These files have templating (ERB) code that will be run.
diff --git a/products/container/ansible.yaml b/products/container/ansible.yaml
index eaaf7ca05386..c95ed2d2fe5c 100644
--- a/products/container/ansible.yaml
+++ b/products/container/ansible.yaml
@@ -17,6 +17,8 @@ datasources: !ruby/object:Overrides::ResourceOverrides
properties:
location: !ruby/object:Overrides::Ansible::PropertyOverride
aliases: ["region", "zone"]
+ initialClusterVersion: !ruby/object:Overrides::Ansible::PropertyOverride
+ aliases: ["cluster_version"]
kubectlPath: !ruby/object:Overrides::Ansible::PropertyOverride
exclude: true
kubectlContext: !ruby/object:Overrides::Ansible::PropertyOverride
diff --git a/products/container/ansible_version_added.yaml b/products/container/ansible_version_added.yaml
index 156dac302c40..79b1c9fb10c4 100644
--- a/products/container/ansible_version_added.yaml
+++ b/products/container/ansible_version_added.yaml
@@ -53,6 +53,12 @@
:version_added: '2.9'
:effect:
:version_added: '2.9'
+ :shieldedInstanceConfig:
+ :version_added: '2.10'
+ :enableSecureBoot:
+ :version_added: '2.10'
+ :enableIntegrityMonitoring:
+ :version_added: '2.10'
:masterAuth:
:version_added: '2.6'
:username:
@@ -79,6 +85,8 @@
:version_added: '2.8'
:clusterIpv4Cidr:
:version_added: '2.6'
+ :enableTpu:
+ :version_added: '2.9'
:addonsConfig:
:version_added: '2.6'
:httpLoadBalancing:
@@ -133,10 +141,10 @@
:version_added: '2.9'
:tpuIpv4CidrBlock:
:version_added: '2.9'
- :enableTpu:
- :version_added: '2.9'
- :tpuIpv4CidrBlock:
- :version_added: '2.9'
+ :tpuIpv4CidrBlock:
+ :version_added: '2.9'
+ :initialClusterVersion:
+ :version_added: '2.10'
:masterAuthorizedNetworksConfig:
:version_added: '2.10'
:enabled:
@@ -147,6 +155,14 @@
:version_added: '2.10'
:cidrBlock:
:version_added: '2.10'
+ :binaryAuthorization:
+ :version_added: '2.10'
+ :enabled:
+ :version_added: '2.10'
+ :shieldedNodes:
+ :version_added: '2.10'
+ :enabled:
+ :version_added: '2.10'
:location:
:version_added: '2.8'
:kubectlPath:
@@ -197,6 +213,12 @@
:version_added: '2.9'
:effect:
:version_added: '2.9'
+ :shieldedInstanceConfig:
+ :version_added: '2.10'
+ :enableSecureBoot:
+ :version_added: '2.10'
+ :enableIntegrityMonitoring:
+ :version_added: '2.10'
:initialNodeCount:
:version_added: '2.6'
:version:
diff --git a/products/container/api.yaml b/products/container/api.yaml
index 3aae7b0ffb9e..6ceea5747630 100644
--- a/products/container/api.yaml
+++ b/products/container/api.yaml
@@ -257,6 +257,27 @@ objects:
- "NO_SCHEDULE"
- "PREFER_NO_SCHEDULE"
- "NO_EXECUTE"
+ - !ruby/object:Api::Type::NestedObject
+ name: 'shieldedInstanceConfig'
+ description: 'Shielded Instance options.'
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'enableSecureBoot'
+ description: |
+ Defines whether the instance has Secure Boot enabled.
+
+ Secure Boot helps ensure that the system only runs authentic software by
+ verifying the digital signature of all boot components, and halting the
+ boot process if signature verification fails.
+ - !ruby/object:Api::Type::Boolean
+ name: 'enableIntegrityMonitoring'
+ description: |
+ Defines whether the instance has integrity monitoring enabled.
+
+ Enables monitoring and attestation of the boot integrity of the instance.
+ The attestation is performed against the integrity policy baseline. This
+ baseline is initially derived from the implicitly trusted boot image when
+ the instance is created.
- !ruby/object:Api::Type::NestedObject
name: 'masterAuth'
description: |
@@ -576,7 +597,6 @@ objects:
The software version of the master endpoint and kubelets used in the
cluster when it was first created. The version can be upgraded over
time.
- output: true
- !ruby/object:Api::Type::String
name: 'currentMasterVersion'
description: 'The current software version of the master endpoint.'
@@ -688,6 +708,29 @@ objects:
- !ruby/object:Api::Type::Boolean
name: 'enabled'
description: If enabled, all container images will be validated by Binary Authorization.
+ - !ruby/object:Api::Type::NestedObject
+ min_version: beta
+ name: 'releaseChannel'
+ description: |
+ ReleaseChannel indicates which release channel a cluster is subscribed to.
+ Release channels are arranged in order of risk and frequency of updates.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'channel'
+ description: 'Which release channel the cluster is subscribed to.'
+ values:
+ - UNSPECIFIED
+ - RAPID
+ - REGULAR
+ - STABLE
+ name: 'shieldedNodes'
+ description: 'Shielded Nodes configuration.'
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'enabled'
+ description: |
+ Whether Shielded Nodes features are enabled on all nodes in this
+ cluster.
- !ruby/object:Api::Resource
name: 'NodePool'
base_url: projects/{{project}}/locations/{{location}}/clusters/{{cluster}}/nodePools
@@ -853,6 +896,27 @@ objects:
- !ruby/object:Api::Type::String
name: 'effect'
description: Effect for taint
+ - !ruby/object:Api::Type::NestedObject
+ name: 'shieldedInstanceConfig'
+ description: 'Shielded Instance options.'
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'enableSecureBoot'
+ description: |
+ Defines whether the instance has Secure Boot enabled.
+
+ Secure Boot helps ensure that the system only runs authentic software by
+ verifying the digital signature of all boot components, and halting the
+ boot process if signature verification fails.
+ - !ruby/object:Api::Type::Boolean
+ name: 'enableIntegrityMonitoring'
+ description: |
+ Defines whether the instance has integrity monitoring enabled.
+
+ Enables monitoring and attestation of the boot integrity of the instance.
+ The attestation is performed against the integrity policy baseline. This
+ baseline is initially derived from the implicitly trusted boot image when
+ the instance is created.
- !ruby/object:Api::Type::Integer
name: 'initialNodeCount'
description: |
diff --git a/products/containeranalysis/api.yaml b/products/containeranalysis/api.yaml
index 6a765cbe1c38..ff8d62a82f3c 100644
--- a/products/containeranalysis/api.yaml
+++ b/products/containeranalysis/api.yaml
@@ -29,11 +29,14 @@ objects:
base_url: projects/{{project}}/notes?noteId={{name}}
self_link: projects/{{project}}/notes/{{name}}
update_verb: :PATCH
+ update_mask: true
description: |
- Provides a detailed description of a Note.
+ A Container Analysis note is a high-level piece of metadata that
+ describes a type of analysis that can be done for a resource.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/container-analysis/'
+ 'Creating Attestations (Occurrences)': 'https://cloud.google.com/binary-authorization/docs/making-attestations'
api: 'https://cloud.google.com/container-analysis/api/reference/rest/'
properties:
- !ruby/object:Api::Type::String
@@ -42,6 +45,61 @@ objects:
The name of the note.
required: true
input: true
+ - !ruby/object:Api::Type::String
+ name: shortDescription
+ description: |
+ A one sentence description of the note.
+ - !ruby/object:Api::Type::String
+ name: longDescription
+ description: |
+ A detailed description of the note
+ - !ruby/object:Api::Type::Enum
+ name: 'kind'
+ description: |
+ The type of analysis this note describes
+ values:
+ - NOTE_KIND_UNSPECIFIED
+ - VULNERABILITY
+ - BUILD
+ - IMAGE
+ - PACKAGE
+ - DEPLOYMENT
+ - DISCOVERY
+ - ATTESTATION
+ - UPGRADE
+ output: true
+ - !ruby/object:Api::Type::Array
+ name: relatedUrl
+ description: |
+ URLs associated with this note and related metadata.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: url
+ description: |
+ Specific URL associated with the resource.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: label
+ description: |
+ Label to describe usage of the URL
+ - !ruby/object:Api::Type::Time
+ name: expirationTime
+ description: |
+ Time of expiration for this note. Leave empty if note does not expire.
+ - !ruby/object:Api::Type::Time
+ name: createTime
+ description: The time this note was created.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: updateTime
+ description: The time this note was last updated.
+ output: true
+ - !ruby/object:Api::Type::Array
+ name: relatedNoteNames
+ description: |
+ Names of other notes related to this note.
+ item_type: Api::Type::String
- !ruby/object:Api::Type::NestedObject
name: attestationAuthority
description: |
@@ -75,3 +133,113 @@ objects:
The human readable name of this Attestation Authority, for
example "qa".
required: true
+
+ - !ruby/object:Api::Resource
+ name: 'Occurrence'
+ base_url: projects/{{project}}/occurrences
+ self_link: projects/{{project}}/occurrences/{{name}}
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ An occurrence is an instance of a Note, or type of analysis that
+ can be done for a resource.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': 'https://cloud.google.com/container-analysis/'
+ api: 'https://cloud.google.com/container-analysis/api/reference/rest/'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The name of the occurrence.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: resourceUri
+ description: |
+ Required. Immutable. A URI that represents the resource for which
+ the occurrence applies. For example,
+ https://gcr.io/project/image@sha256:123abc for a Docker image.
+ required: true
+ input: true
+ - !ruby/object:Api::Type::String
+ name: noteName
+ description: |
+ The analysis note associated with this occurrence, in the form of
+ projects/[PROJECT]/notes/[NOTE_ID]. This field can be used as a
+ filter in list requests.
+ required: true
+ input: true
+ - !ruby/object:Api::Type::String
+ name: kind
+ description: |
+ The note kind which explicitly denotes which of the occurrence
+ details are specified. This field can be used as a filter in list
+ requests.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: remediation
+ description: |
+ A description of actions that can be taken to remedy the note.
+ - !ruby/object:Api::Type::Time
+ name: createTime
+ description: The time when the repository was created.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: updateTime
+ description: The time when the repository was last updated.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: attestation
+ description: |
+ Occurrence that represents a single "attestation". The authenticity
+ of an attestation can be verified using the attached signature.
+ If the verifier trusts the public key of the signer, then verifying
+ the signature is sufficient to establish trust. In this circumstance,
+ the authority to which this attestation is attached is primarily
+ useful for lookup (how to find this attestation if you already
+ know the authority and artifact to be verified) and intent (for
+ which authority this attestation was intended to sign.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: serializedPayload
+ description: |
+ The serialized payload that is verified by one or
+ more signatures. A base64-encoded string.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: signatures
+ description: |
+ One or more signatures over serializedPayload.
+ Verifier implementations should consider this attestation
+ message verified if at least one signature verifies
+ serializedPayload. See Signature in common.proto for more
+ details on signature structure and verification.
+ required: true
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: signature
+ description: |
+ The content of the signature, an opaque bytestring.
+ The payload that this signature verifies MUST be
+ unambiguously provided with the Signature during
+ verification. A wrapper message might provide the
+ payload explicitly. Alternatively, a message might
+ have a canonical serialization that can always be
+ unambiguously computed to derive the payload.
+ - !ruby/object:Api::Type::String
+ name: publicKeyId
+ required: true
+ description: |
+ The identifier for the public key that verifies this
+ signature. MUST be an RFC3986 conformant
+ URI. * When possible, the key id should be an
+ immutable reference, such as a cryptographic digest.
+ Examples of valid values:
+
+ * OpenPGP V4 public key fingerprint. See https://www.iana.org/assignments/uri-schemes/prov/openpgp4fpr
+ for more details on this scheme.
+ * `openpgp4fpr:74FAF3B861BDA0870C7B6DEF607E48D2A663AEEA`
+ * RFC6920 digest-named SubjectPublicKeyInfo (digest of the DER serialization):
+ * "ni:///sha-256;cD9o9Cq6LG3jD0iKXqEi_vdjJGecm_iXkbqVoScViaU"
diff --git a/products/containeranalysis/terraform.yaml b/products/containeranalysis/terraform.yaml
index 99a3579f59f6..3a87f106bd92 100644
--- a/products/containeranalysis/terraform.yaml
+++ b/products/containeranalysis/terraform.yaml
@@ -14,10 +14,10 @@
--- !ruby/object:Provider::Terraform::Config
overrides: !ruby/object:Overrides::ResourceOverrides
Note: !ruby/object:Overrides::Terraform::ResourceOverride
+ mutex: "projects/{{project}}/notes/{{name}}"
id_format: "projects/{{project}}/notes/{{name}}"
import_format: ["projects/{{project}}/notes/{{name}}"]
custom_code: !ruby/object:Provider::Terraform::CustomCode
- pre_update: 'templates/terraform/pre_update/containeranalysis_note.erb'
encoder: templates/terraform/encoders/containeranalysis_attestation_field_name.go.erb
decoder: templates/terraform/decoders/containeranalysis_attestation_field_name.go.erb
examples:
@@ -25,10 +25,42 @@ overrides: !ruby/object:Overrides::ResourceOverrides
name: "container_analysis_note_basic"
primary_resource_id: "note"
vars:
- note_name: "test-attestor-note"
+ note_name: "attestor-note"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "container_analysis_note_attestation_full"
+ primary_resource_id: "note"
+ vars:
+ note_name: "attestor-note"
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ relatedUrl: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ relatedNoteNames: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ Occurrence: !ruby/object:Overrides::Terraform::ResourceOverride
+ # "projects/{{project}}/notes/{{name}}"
+ mutex: "{{note_name}}"
+ id_format: "projects/{{project}}/occurrences/{{name}}"
+ import_format: ["projects/{{project}}/occurrences/{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "container_analysis_occurrence_kms"
+ # Occurrence requires custom logic for signing payloads.
+ skip_test: true
+ primary_resource_id: "occurrence"
+ vars:
+ note_name: "attestation-note"
+ attestor: "attestor"
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ encoder: templates/terraform/encoders/containeranalysis_occurrence.go.erb
+ update_encoder: templates/terraform/update_encoder/containeranalysis_occurrence.go.erb
+ decoder: templates/terraform/decoders/containeranalysis_occurrence.go.erb
+ properties:
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
+ attestation.signatures: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
# This is for copying files over
files: !ruby/object:Provider::Config::Files
diff --git a/products/datacatalog/api.yaml b/products/datacatalog/api.yaml
new file mode 100644
index 000000000000..25476010e224
--- /dev/null
+++ b/products/datacatalog/api.yaml
@@ -0,0 +1,488 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: DataCatalog
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://datacatalog.googleapis.com/v1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Google Cloud Data Catalog API
+ url: https://console.cloud.google.com/apis/library/datacatalog.googleapis.com
+objects:
+ - !ruby/object:Api::Resource
+ name: EntryGroup
+ base_url: projects/{{project}}/locations/{{region}}/entryGroups
+ create_url: projects/{{project}}/locations/{{region}}/entryGroups?entryGroupId={{entry_group_id}}
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ An EntryGroup resource represents a logical grouping of zero or more Data Catalog Entry resources.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': https://cloud.google.com/data-catalog/docs
+ api: https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.entryGroups
+ iam_policy: !ruby/object:Api::Resource::IamPolicy
+ method_name_separator: ':'
+ fetch_iam_policy_verb: :POST
+ parent_resource_attribute: 'entry_group'
+ import_format: ["projects/{{project}}/locations/{{region}}/entryGroups/{{entry_group}}", "{{entry_group}}"]
+ base_url: projects/{{project}}/locations/{{region}}/entryGroups/{{entry_group}}
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: region
+ url_param_only: true
+ input: true
+ description: |
+ EntryGroup location region.
+ - !ruby/object:Api::Type::String
+ name: entryGroupId
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ The id of the entry group to create. The id must begin with a letter or underscore,
+ contain only English letters, numbers and underscores, and be at most 64 characters.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The resource name of the entry group in URL format. Example: projects/{project}/locations/{location}/entryGroups/{entryGroupId}
+ output: true
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ A short name to identify the entry group, for example, "analytics data - jan 2011".
+ - !ruby/object:Api::Type::String
+ name: description
+ description: |
+ Entry group description, which can consist of several sentences or paragraphs that describe entry group contents.
+ - !ruby/object:Api::Resource
+ name: Entry
+ base_url: '{{entry_group}}/entries'
+ create_url: '{{entry_group}}/entries?entryId={{entry_id}}'
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ Entry Metadata. A Data Catalog Entry resource represents another resource in Google Cloud Platform
+ (such as a BigQuery dataset or a Pub/Sub topic) or outside of Google Cloud Platform. Clients can use
+ the linkedResource field in the Entry resource to refer to the original resource ID of the source system.
+
+ An Entry resource contains resource details, such as its schema. An Entry can also be used to attach
+ flexible metadata, such as a Tag.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': https://cloud.google.com/data-catalog/docs
+ api: https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.entryGroups.entries
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: entryGroup
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ The name of the entry group this entry is in.
+ - !ruby/object:Api::Type::String
+ name: entryId
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ The id of the entry to create.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The Data Catalog resource name of the entry in URL format.
+ Example: projects/{project_id}/locations/{location}/entryGroups/{entryGroupId}/entries/{entryId}.
+ Note that this Entry and its child resources may not actually be stored in the location in this name.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: linkedResource
+ description: |
+ The resource this metadata entry refers to.
+ For Google Cloud Platform resources, linkedResource is the full name of the resource.
+ For example, the linkedResource for a table resource from BigQuery is:
+ //bigquery.googleapis.com/projects/projectId/datasets/datasetId/tables/tableId
+ Output only when Entry is of type in the EntryType enum. For entries with userSpecifiedType,
+ this field is optional and defaults to an empty string.
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ Display information such as title and description. A short name to identify the entry,
+ for example, "Analytics Data - Jan 2011".
+ - !ruby/object:Api::Type::String
+ name: description
+ description: |
+ Entry description, which can consist of several sentences or paragraphs that describe entry contents.
+ - !ruby/object:Api::Type::String
+ # This is a string instead of a NestedObject because schemas contain ColumnSchemas, which can contain nested ColumnSchemas.
+ # We'll have people provide the json blob for the schema instead.
+ name: schema
+ description: |
+ Schema of the entry (e.g. BigQuery, GoogleSQL, Avro schema), as a json string. An entry might not have any schema
+ attached to it. See
+ https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.entryGroups.entries#schema
+ for what fields this schema can contain.
+ - !ruby/object:Api::Type::Enum
+ name: type
+ description: |
+ The type of the entry. Only used for Entries with types in the EntryType enum.
+ Currently, only FILESET enum value is allowed. All other entries created through Data Catalog must use userSpecifiedType.
+ values:
+ - :FILESET
+ input: true
+ exactly_one_of:
+ - type
+ - user_specified_type
+ - !ruby/object:Api::Type::String
+ name: userSpecifiedType
+ description: |
+ Entry type if it does not fit any of the input-allowed values listed in EntryType enum above.
+ When creating an entry, users should check the enum values first, if nothing matches the entry
+ to be created, then provide a custom value, for example "my_special_type".
+ userSpecifiedType strings must begin with a letter or underscore and can only contain letters,
+ numbers, and underscores; are case insensitive; must be at least 1 character and at most 64 characters long.
+ exactly_one_of:
+ - type
+ - user_specified_type
+ - !ruby/object:Api::Type::String
+ name: integratedSystem
+ description: |
+ This field indicates the entry's source system that Data Catalog integrates with, such as BigQuery or Pub/Sub.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: userSpecifiedSystem
+ description: |
+ This field indicates the entry's source system that Data Catalog does not integrate with.
+ userSpecifiedSystem strings must begin with a letter or underscore and can only contain letters, numbers,
+ and underscores; are case insensitive; must be at least 1 character and at most 64 characters long.
+ - !ruby/object:Api::Type::NestedObject
+ name: gcsFilesetSpec
+ description: |
+ Specification that applies to a Cloud Storage fileset. This is only valid on entries of type FILESET.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: filePatterns
+ description: |
+ Patterns to identify a set of files in Google Cloud Storage.
+ See [Cloud Storage documentation](https://cloud.google.com/storage/docs/gsutil/addlhelp/WildcardNames)
+ for more information. Note that bucket wildcards are currently not supported. Examples of valid filePatterns:
+
+ * gs://bucket_name/dir/*: matches all files within bucket_name/dir directory.
+ * gs://bucket_name/dir/**: matches all files in bucket_name/dir spanning all subdirectories.
+ * gs://bucket_name/file*: matches files prefixed by file in bucket_name
+ * gs://bucket_name/??.txt: matches files with two characters followed by .txt in bucket_name
+ * gs://bucket_name/[aeiou].txt: matches files that contain a single vowel character followed by .txt in bucket_name
+ * gs://bucket_name/[a-m].txt: matches files that contain a, b, ... or m followed by .txt in bucket_name
+ * gs://bucket_name/a/*/b: matches all files in bucket_name that match a/*/b pattern, such as a/c/b, a/d/b
+ * gs://another_bucket/a.txt: matches gs://another_bucket/a.txt
+ required: true
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: sampleGcsFileSpecs
+ description: |
+ Sample files contained in this fileset, not all files contained in this fileset are represented here.
+ output: true
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: filePath
+ description: |
+ The full file path
+ output: true
+ - !ruby/object:Api::Type::Integer
+ name: sizeBytes
+ description: |
+ The size of the file, in bytes.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: bigqueryTableSpec
+ description: |
+ Specification that applies to a BigQuery table. This is only valid on entries of type TABLE.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: tableSourceType
+ description: |
+ The table source type.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: viewSpec
+ description: |
+ Table view specification. This field should only be populated if tableSourceType is BIGQUERY_VIEW.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: viewQuery
+ description: |
+ The query that defines the table view.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: tableSpec
+ description: |
+ Spec of a BigQuery table. This field should only be populated if tableSourceType is BIGQUERY_TABLE.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: groupedEntry
+ description: |
+ If the table is a dated shard, i.e., with name pattern [prefix]YYYYMMDD, groupedEntry is the
+ Data Catalog resource name of the date sharded grouped entry, for example,
+ projects/{project_id}/locations/{location}/entrygroups/{entryGroupId}/entries/{entryId}.
+ Otherwise, groupedEntry is empty.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: bigqueryDateShardedSpec
+ description: |
+ Specification for a group of BigQuery tables with name pattern [prefix]YYYYMMDD.
+ Context: https://cloud.google.com/bigquery/docs/partitioned-tables#partitioning_versus_sharding.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: dataset
+ description: |
+ The Data Catalog resource name of the dataset entry the current table belongs to, for example,
+ projects/{project_id}/locations/{location}/entrygroups/{entryGroupId}/entries/{entryId}
+ output: true
+ - !ruby/object:Api::Type::String
+ name: tablePrefix
+ description: |
+ The table name prefix of the shards. The name of any given shard is [tablePrefix]YYYYMMDD,
+ for example, for shard MyTable20180101, the tablePrefix is MyTable.
+ output: true
+ - !ruby/object:Api::Type::Integer
+ name: shardCount
+ description: |
+ Total number of shards.
+ output: true
+ - !ruby/object:Api::Resource
+ name: TagTemplate
+ base_url: projects/{{project}}/locations/{{region}}/tagTemplates
+ self_link: "{{name}}"
+ create_url: projects/{{project}}/locations/{{region}}/tagTemplates?tagTemplateId={{tag_template_id}}
+ delete_url: "{{name}}?force={{force_delete}}"
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A tag template defines a tag, which can have one or more typed fields.
+ The template is used to create and attach the tag to GCP resources.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': https://cloud.google.com/data-catalog/docs
+ api: https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.tagTemplates
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: region
+ url_param_only: true
+ input: true
+ description: |
+ Template location region.
+ - !ruby/object:Api::Type::String
+ name: tagTemplateId
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ The id of the tag template to create.
+ - !ruby/object:Api::Type::Boolean
+ name: forceDelete
+ url_param_only: true
+ description: |
+ This confirms the deletion of any possible tags using this template. Must be set to true in order to delete the tag template.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The resource name of the tag template in URL format. Example: projects/{project_id}/locations/{location}/tagTemplates/{tagTemplateId}
+ output: true
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ The display name for this template.
+ - !ruby/object:Api::Type::Map
+ name: fields
+ description: |
+ Map of tag template field IDs to the settings for the field. This map is an exhaustive list of the allowed fields. This map must contain at least one field and at most 500 fields.
+ required: true
+ input: true # TODO(danawillow): update logic
+ key_name: field_id
+ value_type: !ruby/object:Api::Type::NestedObject
+ name: field
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The resource name of the tag template field in URL format. Example: projects/{project_id}/locations/{location}/tagTemplates/{tagTemplateId}/fields/{field}
+ output: true
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ The display name for this field.
+ - !ruby/object:Api::Type::NestedObject
+ name: type
+ description: |
+ The type of value this tag field can contain.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: primitiveType
+ description: |
+ Represents primitive types - string, bool etc.
+ values:
+ - :DOUBLE
+ - :STRING
+ - :BOOL
+ - :TIMESTAMP
+ - !ruby/object:Api::Type::NestedObject
+ name: enumType
+ description: |
+ Represents an enum type.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: allowedValues
+ description: |
+ The set of allowed values for this enum. The display names of the
+ values must be case-insensitively unique within this set. Currently,
+ enum values can only be added to the list of allowed values. Deletion
+ and renaming of enum values are not supported.
+ Can have up to 500 allowed values.
+ required: true
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ The display name of the enum value.
+ required: true
+ - !ruby/object:Api::Type::Boolean
+ name: isRequired
+ description: |
+ Whether this is a required field. Defaults to false.
+ - !ruby/object:Api::Type::Integer
+ name: order
+ description: |
+ The order of this field with respect to other fields in this tag template.
+ A higher value indicates a more important field. The value can be negative.
+ Multiple fields can have the same order, and field orders within a tag do not have to be sequential.
+ - !ruby/object:Api::Resource
+ name: Tag
+ base_url: '{{parent}}/tags'
+ self_link: '{{name}}'
+ update_url: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ self_link: '{{parent}}/tags'
+ delete_url: '{{name}}'
+ nested_query: !ruby/object:Api::Resource::NestedQuery
+ keys:
+ - tags
+ description: |
+ Tags are used to attach custom metadata to Data Catalog resources. Tags conform to the specifications within their tag template.
+
+ See [Data Catalog IAM](https://cloud.google.com/data-catalog/docs/concepts/iam) for information on the permissions needed to create or view tags.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation': https://cloud.google.com/data-catalog/docs
+ api: https://cloud.google.com/data-catalog/docs/reference/rest/v1/projects.locations.entryGroups.tags
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: parent
+ url_param_only: true
+ description: |
+ The name of the parent this tag is attached to. This can be the name of an entry or an entry group. If an entry group, the tag will be attached to
+ all entries in that group.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The resource name of the tag in URL format. Example:
+ projects/{project_id}/locations/{location}/entrygroups/{entryGroupId}/entries/{entryId}/tags/{tag_id} or
+ projects/{project_id}/locations/{location}/entrygroups/{entryGroupId}/tags/{tag_id}
+ where tag_id is a system-generated identifier. Note that this Tag may not actually be stored in the location in this name.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: template
+ description: |
+ The resource name of the tag template that this tag uses. Example:
+ projects/{project_id}/locations/{location}/tagTemplates/{tagTemplateId}
+ This field cannot be modified after creation.
+ required: true
+ input: true
+ - !ruby/object:Api::Type::String
+ name: templateDisplayName
+ description: |
+ The display name of the tag template.
+ output: true
+ - !ruby/object:Api::Type::Map
+ name: fields
+ description: |
+ This maps the ID of a tag field to the value of and additional information about that field.
+ Valid field IDs are defined by the tag's template. A tag must have at least 1 field and at most 500 fields.
+ required: true
+ key_name: field_name
+ value_type: !ruby/object:Api::Type::NestedObject
+ name: field_value
+ properties:
+ - !ruby/object:Api::Type::String
+ name: display_name
+ description: |
+ The display name of this field
+ output: true
+ - !ruby/object:Api::Type::Integer
+ name: order
+ description: |
+ The order of this field with respect to other fields in this tag. For example, a higher value can indicate
+ a more important field. The value can be negative. Multiple fields can have the same order, and field orders
+ within a tag do not have to be sequential.
+ output: true
+ - !ruby/object:Api::Type::Double
+ name: doubleValue
+ description: |
+ Holds the value for a tag field with double type.
+ - !ruby/object:Api::Type::String
+ name: stringValue
+ description: |
+ Holds the value for a tag field with string type.
+ - !ruby/object:Api::Type::Boolean
+ name: boolValue
+ description: |
+ Holds the value for a tag field with boolean type.
+ - !ruby/object:Api::Type::String
+ name: timestampValue
+ description: |
+ Holds the value for a tag field with timestamp type.
+ - !ruby/object:Api::Type::NestedObject
+ name: enumValue
+ description: |
+ Holds the value for a tag field with enum type. This value must be one of the allowed values in the definition of this enum.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ The display name of the enum value.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: column
+ description: |
+ Resources like Entry can have schemas associated with them. This scope allows users to attach tags to an
+ individual column based on that schema.
+
+ For attaching a tag to a nested column, use `.` to separate the column names. Example:
+ `outer_column.inner_column`
diff --git a/products/datacatalog/terraform.yaml b/products/datacatalog/terraform.yaml
new file mode 100644
index 000000000000..4aadf710af56
--- /dev/null
+++ b/products/datacatalog/terraform.yaml
@@ -0,0 +1,179 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ EntryGroup: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_group_basic"
+ primary_resource_id: "basic_entry_group"
+ primary_resource_name: "fmt.Sprintf(\"tf_test_my_group%s\", context[\"random_suffix\"])"
+ vars:
+ entry_group_id: "my_group"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_group_full"
+ primary_resource_id: "basic_entry_group"
+ primary_resource_name: "fmt.Sprintf(\"tf_test_my_group%s\", context[\"random_suffix\"])"
+ vars:
+ entry_group_id: "my_group"
+ properties:
+ entryGroupId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[A-z_][A-z0-9_]{0,63}$'
+ region: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ required: false
+ default_from_api: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/data_catalog_entry_group.go.erb
+ Entry: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ supports_indirect_user_project_override: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_basic"
+ primary_resource_id: "basic_entry"
+ vars:
+ entry_id: "my_entry"
+ entry_group_id: "my_group"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_fileset"
+ primary_resource_id: "basic_entry"
+ vars:
+ entry_id: "my_entry"
+ entry_group_id: "my_group"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_full"
+ primary_resource_id: "basic_entry"
+ vars:
+ entry_id: "my_entry"
+ entry_group_id: "my_group"
+ properties:
+ linkedResource: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ schema: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/json_schema.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb'
+ state_func: 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }'
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.ValidateJsonString'
+ userSpecifiedSystem: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[A-z_][A-z0-9_]{0,63}$'
+ userSpecifiedType: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[A-z_][A-z0-9_]{0,63}$'
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/data_catalog_entry.go.erb
+ TagTemplate: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ skip_sweeper: true # no list endpoint plus variables in delete URL
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_tag_template_basic"
+ primary_resource_id: "basic_tag_template"
+ vars:
+ tag_template_id: "my_template"
+ force_delete: "false"
+ test_vars_overrides:
+ force_delete: "true"
+ oics_vars_overrides:
+ force_delete: "true"
+ properties:
+ tagTemplateId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[a-z_][a-z0-9_]{0,63}$'
+ fields: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ Set of tag template field IDs and the settings for the field. This set is an exhaustive list of the allowed fields. This set must contain at least one field and at most 500 fields.
+ fields.type.enumType: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ {{description}} Exactly one of `primitive_type` or `enum_type` must be set
+ fields.type.enumType.allowedValues: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ fields.type.primitiveType: !ruby/object:Overrides::Terraform::PropertyOverride
+ description: |
+ {{description}} Exactly one of `primitive_type` or `enum_type` must be set
+ region: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ required: false
+ default_from_api: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/data_catalog_tag_template.go.erb
+ Tag: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["{{name}}"]
+ id_format: "{{name}}"
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_tag_basic"
+ primary_resource_id: "basic_tag"
+ vars:
+ entry_group_id: "my_entry_group"
+ entry_id: "my_entry"
+ tag_template_id: "my_template"
+ force_delete: "false"
+ test_vars_overrides:
+ force_delete: "true"
+ oics_vars_overrides:
+ force_delete: "true"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_group_tag"
+ primary_resource_id: "entry_group_tag"
+ vars:
+ entry_group_id: "my_entry_group"
+ first_entry: "first_entry"
+ second_entry: "second_entry"
+ tag_template_id: "my_template"
+ force_delete: "false"
+ test_vars_overrides:
+ force_delete: "true"
+ oics_vars_overrides:
+ force_delete: "true"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "data_catalog_entry_tag_full"
+ primary_resource_id: "basic_tag"
+ vars:
+ entry_group_id: "my_entry_group"
+ entry_id: "my_entry"
+ tag_template_id: "my_template"
+ force_delete: "false"
+ test_vars_overrides:
+ force_delete: "true"
+ oics_vars_overrides:
+ force_delete: "true"
+ properties:
+ # Changing the name here so when mm generates methods like `flattenDataCatalogTagTemplateDisplayName`
+ # this doesn't conflict with tag template's display name methods
+ templateDisplayName: !ruby/object:Overrides::Terraform::PropertyOverride
+ name: template_displayname
+ fields.enumValue: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ # because `fields` is a set, the current generated expand code can't properly retrieve
+ # enum_value by d.Get("enum_value") without knowing the set id, however, the value
+ # `v` is the correct value and passed to expand, so this custom expand will use
+ # that as the correct `enum_value.display_name` value
+ custom_expand: templates/terraform/custom_expand/data_catalog_tag.go.erb
+ custom_flatten: templates/terraform/custom_flatten/data_catalog_tag.go.erb
+ fields.enumValue.displayName: !ruby/object:Overrides::Terraform::PropertyOverride
+ name: enum_value
+ required: false
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/data_catalog_tag.go.erb
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
\ No newline at end of file
diff --git a/products/datafusion/api.yaml b/products/datafusion/api.yaml
index 3954a63b0a77..023f1d127ee1 100644
--- a/products/datafusion/api.yaml
+++ b/products/datafusion/api.yaml
@@ -147,7 +147,7 @@ objects:
Endpoint on which the Data Fusion UI and REST APIs are accessible.
- !ruby/object:Api::Type::String
name: 'version'
- output: true
+ input: true
description: |
Current version of the Data Fusion.
- !ruby/object:Api::Type::String
diff --git a/products/datafusion/terraform.yaml b/products/datafusion/terraform.yaml
index 262fbaa838fc..2dbaabf7dfab 100644
--- a/products/datafusion/terraform.yaml
+++ b/products/datafusion/terraform.yaml
@@ -37,6 +37,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
ignore_read: true
required: false
default_from_api: true
+ version: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
name: !ruby/object:Overrides::Terraform::PropertyOverride
custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb'
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
diff --git a/products/dataproc/api.yaml b/products/dataproc/api.yaml
index f0532959a3f9..d633bceda4ad 100644
--- a/products/dataproc/api.yaml
+++ b/products/dataproc/api.yaml
@@ -13,7 +13,6 @@
--- !ruby/object:Api::Product
name: Dataproc
-display_name: Cloud Dataproc
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -32,6 +31,7 @@ objects:
name: 'AutoscalingPolicy'
base_url: "projects/{{project}}/locations/{{location}}/autoscalingPolicies"
self_link: "projects/{{project}}/locations/{{location}}/autoscalingPolicies/{{id}}"
+ collection_url_key: 'policies'
description: |
Describes an autoscaling policy for Dataproc cluster autoscaler.
parameters:
@@ -486,10 +486,13 @@ objects:
description: |
The set of optional components to activate on the cluster.
- Possible values include: COMPONENT_UNSPECIFIED, ANACONDA, HIVE_WEBHCAT, JUPYTER, ZEPPELIN
+ Possible values include: COMPONENT_UNSPECIFIED, ANACONDA, HIVE_WEBHCAT, JUPYTER, ZEPPELIN, HBASE, SOLR, and RANGER
values:
- :COMPONENT_UNSPECIFIED
- :ANACONDA
+ - :HBASE
+ - :RANGER
+ - :SOLR
- :HIVE_WEBHCAT
- :JUPYTER
- :ZEPPELIN
diff --git a/products/datastore/api.yaml b/products/datastore/api.yaml
index fb6fac991e8b..b041e7a372b0 100644
--- a/products/datastore/api.yaml
+++ b/products/datastore/api.yaml
@@ -13,7 +13,6 @@
--- !ruby/object:Api::Product
name: Datastore
-display_name: Cloud Datastore
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -74,8 +73,7 @@ objects:
- :NONE
- :ALL_ANCESTORS
description: |
- Policy for including ancestors in the index. Either `ALL_ANCESTORS` or `NONE`,
- the default is `NONE`.
+ Policy for including ancestors in the index.
- !ruby/object:Api::Type::Array
name: 'properties'
description: |
@@ -95,4 +93,4 @@ objects:
- :ASCENDING
- :DESCENDING
description: |
- The direction the index should optimize for sorting. Possible values are ASCENDING and DESCENDING.
+ The direction the index should optimize for sorting.
diff --git a/products/datastore/terraform.yaml b/products/datastore/terraform.yaml
index 2760b70867bd..e29556779c6b 100644
--- a/products/datastore/terraform.yaml
+++ b/products/datastore/terraform.yaml
@@ -16,6 +16,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
Index: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: "projects/{{project}}/indexes/{{index_id}}"
self_link: "projects/{{project}}/indexes/{{index_id}}"
+ error_retry_predicates: ["datastoreIndex409Contention"]
autogen_async: true
# TODO(ndmckinley): This resource doesn't have a name, so the current
# sweeper won't ever sweep it - might as well not have one for now,
diff --git a/products/deploymentmanager/api.yaml b/products/deploymentmanager/api.yaml
index dccd1c7c2760..42bdfb144370 100644
--- a/products/deploymentmanager/api.yaml
+++ b/products/deploymentmanager/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: DeploymentManager
-display_name: Deployment Manager
+display_name: Cloud Deployment Manager
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/deploymentmanager/terraform.yaml b/products/deploymentmanager/terraform.yaml
index 4edaa5818ae7..683d885c1e61 100644
--- a/products/deploymentmanager/terraform.yaml
+++ b/products/deploymentmanager/terraform.yaml
@@ -53,7 +53,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
properties:
preview: !ruby/object:Overrides::Terraform::PropertyOverride
description: |
- {{description}} ~>**NOTE**: Deployment Manager does not allow update
+ {{description}} ~>**NOTE:** Deployment Manager does not allow update
of a deployment in preview (unless updating to preview=false). Thus,
Terraform will force-recreate deployments if either preview is updated
to true or if other fields are updated while preview is true.
diff --git a/products/dialogflow/api.yaml b/products/dialogflow/api.yaml
index c750e9d91b5b..8ca33a365c98 100644
--- a/products/dialogflow/api.yaml
+++ b/products/dialogflow/api.yaml
@@ -60,7 +60,6 @@ objects:
The list of all languages supported by this agent (except for the defaultLanguageCode).
- !ruby/object:Api::Type::String
name: 'timeZone'
- input: true
description: |
The time zone of this agent from the [time zone database](https://www.iana.org/time-zones), e.g., America/New_York,
Europe/Paris.
@@ -253,4 +252,70 @@ objects:
name: 'parentFollowupIntentName'
description: |
The unique identifier of the followup intent's parent.
- Format: projects//agent/intents/.
\ No newline at end of file
+ Format: projects//agent/intents/.
+ - !ruby/object:Api::Resource
+ name: 'EntityType'
+ base_url: "projects/{{project}}/agent/entityTypes/"
+ self_link: "{{name}}"
+ update_verb: :PATCH
+ description: |
+ Represents an entity type. Entity types serve as a tool for extracting parameter values from natural language queries.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/dialogflow/docs/'
+ api: 'https://cloud.google.com/dialogflow/docs/reference/rest/v2/projects.agent.entityTypes'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ output: true
+ description: |
+ The unique identifier of the entity type.
+ Format: projects//agent/entityTypes/.
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ required: true
+ description: |
+ The name of this entity type to be displayed on the console.
+ - !ruby/object:Api::Type::Enum
+ name: 'kind'
+ required: true
+ description: |
+ Indicates the kind of entity type.
+ * KIND_MAP: Map entity types allow mapping of a group of synonyms to a reference value.
+ * KIND_LIST: List entity types contain a set of entries that do not map to reference values. However, list entity
+ types can contain references to other entity types (with or without aliases).
+ * KIND_REGEXP: Regexp entity types allow to specify regular expressions in entries values.
+ values:
+ - :KIND_MAP
+ - :KIND_LIST
+ - :KIND_REGEXP
+ - !ruby/object:Api::Type::Boolean
+ name: 'enableFuzzyExtraction'
+ description: |
+ Enables fuzzy entity extraction during classification.
+ - !ruby/object:Api::Type::Array
+ name: 'entities'
+ description: |
+ The collection of entity entries associated with the entity type.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'value'
+ required: true
+ description: |
+ The primary value associated with this entity entry. For example, if the entity type is vegetable, the value
+ could be scallions.
+ For KIND_MAP entity types:
+ * A reference value to be used in place of synonyms.
+ For KIND_LIST entity types:
+ * A string that can contain references to other entity types (with or without aliases).
+ - !ruby/object:Api::Type::Array
+ name: 'synonyms'
+ required: true
+ item_type: Api::Type::String
+ description: |
+ A collection of value synonyms. For example, if the entity type is vegetable, and value is scallions, a synonym
+ could be green onions.
+ For KIND_LIST entity types:
+ * This collection must contain exactly one synonym equal to value.
\ No newline at end of file
diff --git a/products/dialogflow/terraform.yaml b/products/dialogflow/terraform.yaml
index 694b21f5cdd7..d9ee953383e2 100644
--- a/products/dialogflow/terraform.yaml
+++ b/products/dialogflow/terraform.yaml
@@ -79,6 +79,21 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_code: !ruby/object:Provider::Terraform::CustomCode
custom_import: templates/terraform/custom_import/self_link_as_name_set_project.go.erb
post_create: 'templates/terraform/post_create/set_computed_name.erb'
+ EntityType: !ruby/object:Overrides::Terraform::ResourceOverride
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "dialogflow_entity_type_basic"
+ primary_resource_id: "basic_entity_type"
+ skip_test: true
+ vars:
+ intent_name: "basic-entity-type"
+ # Skip sweeper gen since this is a child resource.
+ skip_sweeper: true
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/self_link_as_name_set_project.go.erb
+ post_create: 'templates/terraform/post_create/set_computed_name.erb'
# This is for copying files over
files: !ruby/object:Provider::Config::Files
# These files have templating (ERB) code that will be run.
diff --git a/products/dns/ansible.yaml b/products/dns/ansible.yaml
index bcf41ba13942..12b8d8209f46 100644
--- a/products/dns/ansible.yaml
+++ b/products/dns/ansible.yaml
@@ -14,6 +14,8 @@
--- !ruby/object:Provider::Ansible::Config
# This is where custom code would be defined eventually.
datasources: !ruby/object:Overrides::ResourceOverrides
+ Policy: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
Project: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
ResourceRecordSet: !ruby/object:Overrides::Ansible::ResourceOverride
@@ -33,6 +35,8 @@ datasources: !ruby/object:Overrides::ResourceOverrides
query_options: false
filter_api_param: dnsName
overrides: !ruby/object:Overrides::ResourceOverrides
+ Policy: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
ResourceRecordSet: !ruby/object:Overrides::Ansible::ResourceOverride
access_api_results: true
imports:
diff --git a/products/dns/api.yaml b/products/dns/api.yaml
index 8d850318d1a3..7cd63659fb8e 100644
--- a/products/dns/api.yaml
+++ b/products/dns/api.yaml
@@ -173,7 +173,6 @@ objects:
description: |
The zone's visibility: public zones are exposed to the Internet,
while private zones are visible only to Virtual Private Cloud resources.
- Must be one of: `public`, `private`.
values:
- :private
- :public
@@ -228,9 +227,7 @@ objects:
values:
- :default
- :private
- min_version: beta
- !ruby/object:Api::Type::NestedObject
- min_version: beta
name: 'peeringConfig'
description: |
The presence of this field indicates that DNS Peering is enabled for this
@@ -259,6 +256,25 @@ objects:
Specifies if this is a managed reverse lookup zone. If true, Cloud DNS will resolve reverse
lookup queries using automatically configured records for VPC resources. This only applies
to networks listed under `private_visibility_config`.
+ - !ruby/object:Api::Type::NestedObject
+ min_version: beta
+ input: true
+ name: 'serviceDirectoryConfig'
+ description:
+ The presence of this field indicates that this zone is backed by Service Directory. The value
+ of this field contains information related to the namespace associated with the zone.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'namespace'
+ required: true
+ description: 'The namespace associated with the zone.'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'namespaceUrl'
+ required: true
+ description: |
+ The fully qualified URL of the service directory namespace that should be
+ associated with the zone. Ignored for `public` visibility zones.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Managing Zones':
@@ -352,7 +368,6 @@ objects:
'Using DNS server policies':
'https://cloud.google.com/dns/zones/#using-dns-server-policies'
api: 'https://cloud.google.com/dns/docs/reference/v1beta2/policies'
- min_version: beta
- !ruby/object:Api::Resource
name: 'Project'
kind: 'dns#project'
diff --git a/products/dns/terraform.yaml b/products/dns/terraform.yaml
index 1c6d0c14fd42..33ed5fe3e1e7 100644
--- a/products/dns/terraform.yaml
+++ b/products/dns/terraform.yaml
@@ -19,6 +19,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "dns_managed_zone_basic"
primary_resource_id: "example-zone"
+ # Randomness from random provider
+ skip_vcr: true
- !ruby/object:Provider::Terraform::Examples
name: "dns_managed_zone_private"
primary_resource_id: "private-zone"
@@ -36,12 +38,18 @@ overrides: !ruby/object:Overrides::ResourceOverrides
network_2_name: "network-2"
- !ruby/object:Provider::Terraform::Examples
name: "dns_managed_zone_private_peering"
- min_version: 'beta'
primary_resource_id: "peering-zone"
vars:
zone_name: "peering-zone"
network_source_name: "network-source"
network_target_name: "network-target"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "dns_managed_zone_service_directory"
+ min_version: 'beta'
+ primary_resource_id: "sd-zone"
+ vars:
+ zone_name: "peering-zone"
+ network_name: "network"
properties:
creationTime: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
@@ -81,7 +89,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
and apply an incorrect update to the resource. If you encounter this issue, remove all `networks`
blocks in an update and then apply another update adding all of them back simultaneously.
privateVisibilityConfig.networks.networkUrl: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/network_full_url.erb'
diff_suppress_func: 'compareSelfLinkOrResourceName'
+ description: |
+ The id or fully qualified URL of the VPC network to bind to.
+ This should be formatted like `projects/{project}/global/networks/{network}` or
+ `https://www.googleapis.com/compute/v1/projects/{project}/global/networks/{network}`
forwardingConfig.targetNameServers: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
set_hash_func: |-
@@ -94,9 +107,25 @@ overrides: !ruby/object:Overrides::ResourceOverrides
schema.SerializeResourceForHash(&buf, raw, dnsManagedZoneForwardingConfigTargetNameServersSchema())
return hashcode.String(buf.String())
}
+ serviceDirectoryConfig.namespace.namespaceUrl: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/sd_full_url.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/full_to_relative_path.erb'
+ description: |
+ The fully qualified or partial URL of the service directory namespace that should be
+ associated with the zone. This should be formatted like
+ `https://servicedirectory.googleapis.com/v1/projects/{project}/locations/{location}/namespaces/{namespace_id}`
+ or simply `projects/{project}/locations/{location}/namespaces/{namespace_id}`
+ Ignored for `public` visibility zones.
visibility: !ruby/object:Overrides::Terraform::PropertyOverride
diff_suppress_func: 'caseDiffSuppress'
custom_flatten: templates/terraform/custom_flatten/default_if_empty.erb
+ peeringConfig.targetNetwork.networkUrl: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: templates/terraform/custom_expand/network_full_url.erb
+ diff_suppress_func: 'compareSelfLinkOrResourceName'
+ description: |
+ The id or fully qualified URL of the VPC network to forward queries to.
+ This should be formatted like `projects/{project}/global/networks/{network}` or
+ `https://www.googleapis.com/compute/v1/projects/{project}/global/networks/{network}`
reverseLookup: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: templates/terraform/custom_flatten/object_to_bool.go.erb
custom_expand: templates/terraform/custom_expand/bool_to_object.go.erb
@@ -142,6 +171,13 @@ overrides: !ruby/object:Overrides::ResourceOverrides
schema.SerializeResourceForHash(&buf, raw, dnsPolicyNetworksSchema())
return hashcode.String(buf.String())
}
+ networks.networkUrl: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: templates/terraform/custom_expand/network_full_url.erb
+ diff_suppress_func: 'compareSelfLinkOrResourceName'
+ description: |
+ The id or fully qualified URL of the VPC network to forward queries to.
+ This should be formatted like `projects/{project}/global/networks/{network}` or
+ `https://www.googleapis.com/compute/v1/projects/{project}/global/networks/{network}`
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/detach_network.erb
ResourceRecordSet: !ruby/object:Overrides::Terraform::ResourceOverride
diff --git a/products/filestore/api.yaml b/products/filestore/api.yaml
index 85e277d8c75e..b7484c39bfd0 100644
--- a/products/filestore/api.yaml
+++ b/products/filestore/api.yaml
@@ -19,11 +19,13 @@
# include a small hack to rename the library - see
# templates/terraform/constants/filestore.erb.
name: Filestore
-display_name: Cloud Filestore
versions:
- !ruby/object:Api::Product::Version
name: ga
base_url: https://file.googleapis.com/v1/
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://file.googleapis.com/v1beta1/
scopes:
- https://www.googleapis.com/auth/cloud-platform
async: !ruby/object:Api::OpAsync
@@ -105,9 +107,12 @@ objects:
required: true
input: true
values:
- - TIER_UNSPECIFIED
- - STANDARD
- - PREMIUM
+ - :TIER_UNSPECIFIED
+ - :STANDARD
+ - :PREMIUM
+ - :BASIC_HDD
+ - :BASIC_SSD
+ - :HIGH_SCALE_SSD
- !ruby/object:Api::Type::KeyValuePairs
name: 'labels'
description: |
@@ -133,6 +138,51 @@ objects:
File share capacity in GiB. This must be at least 1024 GiB
for the standard tier, or 2560 GiB for the premium tier.
required: true
+ - !ruby/object:Api::Type::Array
+ name: 'nfsExportOptions'
+ description: |
+ Nfs Export Options. There is a limit of 10 export options per file share.
+ max_size: 10
+ min_version: beta
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'ipRanges'
+ description: |
+ List of either IPv4 addresses, or ranges in CIDR notation which may mount the file share.
+ Overlapping IP ranges are not allowed, both within and across NfsExportOptions. An error will be returned.
+ The limit is 64 IP ranges/addresses for each FileShareConfig among all NfsExportOptions.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Enum
+ name: 'accessMode'
+ description: |
+ Either READ_ONLY, for allowing only read requests on the exported directory,
+ or READ_WRITE, for allowing both read and write requests. The default is READ_WRITE.
+ default_value: :READ_WRITE
+ values:
+ - :READ_ONLY
+ - :READ_WRITE
+ - !ruby/object:Api::Type::Enum
+ name: 'squashMode'
+ description: |
+ Either NO_ROOT_SQUASH, for allowing root access on the exported directory, or ROOT_SQUASH,
+ for not allowing root access. The default is NO_ROOT_SQUASH.
+ default_value: :NO_ROOT_SQUASH
+ values:
+ - :NO_ROOT_SQUASH
+ - :ROOT_SQUASH
+ - !ruby/object:Api::Type::Integer
+ name: 'anonUid'
+ description: |
+ An integer representing the anonymous user id with a default value of 65534.
+ Anon_uid may only be set with squashMode of ROOT_SQUASH. An error will be returned
+ if this field is specified for other squashMode settings.
+ - !ruby/object:Api::Type::Integer
+ name: 'anonGid'
+ description: |
+ An integer representing the anonymous group id with a default value of 65534.
+ Anon_gid may only be set with squashMode of ROOT_SQUASH. An error will be returned
+ if this field is specified for other squashMode settings.
- !ruby/object:Api::Type::Array
name: 'networks'
description: |
diff --git a/products/filestore/terraform.yaml b/products/filestore/terraform.yaml
index f20a9567914f..2633995e0fea 100644
--- a/products/filestore/terraform.yaml
+++ b/products/filestore/terraform.yaml
@@ -25,6 +25,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
primary_resource_id: "instance"
vars:
instance_name: "test-instance"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "filestore_instance_full"
+ min_version: beta
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "test-instance"
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
diff --git a/products/firebase/api.yaml b/products/firebase/api.yaml
index ca1fc9b7df01..a6f84d7245d2 100644
--- a/products/firebase/api.yaml
+++ b/products/firebase/api.yaml
@@ -100,3 +100,55 @@ objects:
description: |
The ID of the default GCP resource location for the Project. The location must be one of the available GCP
resource locations.
+ - !ruby/object:Api::Resource
+ name: 'WebApp'
+ min_version: beta
+ base_url: projects/{{project}}/webApps
+ self_link: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Google Cloud Firebase web application instance
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://firebase.google.com/'
+ api: 'https://firebase.google.com/docs/projects/api/reference/rest/v1beta1/projects.webApps'
+ async: !ruby/object:Api::OpAsync
+ actions: ["create"]
+ operation: !ruby/object:Api::OpAsync::Operation
+ path: 'name'
+ base_url: '{{op_id}}'
+ wait_ms: 1000
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: true
+ allowed:
+ - true
+ - false
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The fully qualified resource name of the App, for example:
+
+ projects/projectId/webApps/appId
+ output: true
+ - !ruby/object:Api::Type::String
+ name: displayName
+ required: true
+ description: |
+ The user-assigned display name of the App.
+ - !ruby/object:Api::Type::String
+ name: appId
+ output: true
+ description: |
+ Immutable. The globally unique, Firebase-assigned identifier of the App.
+
+ This identifier should be treated as an opaque token, as the data format is not specified.
diff --git a/products/firebase/terraform.yaml b/products/firebase/terraform.yaml
index 62f8bc6d0050..a61601bd524f 100644
--- a/products/firebase/terraform.yaml
+++ b/products/firebase/terraform.yaml
@@ -17,8 +17,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
import_format: ["projects/{{project}}", "{{project}}"]
timeouts: !ruby/object:Api::Timeouts
insert_minutes: 10
- update_minutes: 10
- delete_minutes: 10
autogen_async: true
skip_delete: true
skip_sweeper: true
@@ -44,8 +42,27 @@ overrides: !ruby/object:Overrides::ResourceOverrides
primary_resource_id: "basic"
test_env_vars:
org_id: :ORG_ID
- properties:
-
+ WebApp: !ruby/object:Overrides::Terraform::ResourceOverride
+ # id_format: '{{name}}'
+ import_format: ['{{name}}']
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 10
+ update_minutes: 10
+ autogen_async: true
+ skip_delete: true #currently only able to delete a webapp through the Firebase Admin console
+ skip_sweeper: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "firebase_web_app_basic"
+ min_version: "beta"
+ primary_resource_id: "basic"
+ vars:
+ display_name: "Display Name Basic"
+ bucket_name: "fb-webapp-"
+ test_env_vars:
+ org_id: :ORG_ID
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
# This is for copying files over
files: !ruby/object:Provider::Config::Files
# These files have templating (ERB) code that will be run.
diff --git a/products/firestore/api.yaml b/products/firestore/api.yaml
index 7441f165db35..9a6afefdeb2b 100644
--- a/products/firestore/api.yaml
+++ b/products/firestore/api.yaml
@@ -13,7 +13,6 @@
--- !ruby/object:Api::Product
name: Firestore
-display_name: Cloud Firestore
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -69,8 +68,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: queryScope
description: |
- The scope at which a query is run. One of `"COLLECTION"` or
- `"COLLECTION_GROUP"`. Defaults to `"COLLECTION"`.
+ The scope at which a query is run.
default_value: :COLLECTION
values:
- :COLLECTION
diff --git a/products/gameservices/api.yaml b/products/gameservices/api.yaml
index a1d914e95b0e..024c07b07794 100644
--- a/products/gameservices/api.yaml
+++ b/products/gameservices/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: GameServices
-display_name: Google Game Services
+display_name: Game Servers
scopes:
- https://www.googleapis.com/auth/compute
versions:
diff --git a/products/healthcare/api.yaml b/products/healthcare/api.yaml
index 981cd1afee52..0a1403a98b68 100644
--- a/products/healthcare/api.yaml
+++ b/products/healthcare/api.yaml
@@ -15,6 +15,9 @@
name: Healthcare
display_name: Cloud Healthcare
versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://healthcare.googleapis.com/v1/
- !ruby/object:Api::Product::Version
name: beta
base_url: https://healthcare.googleapis.com/v1beta1/
@@ -73,7 +76,7 @@ objects:
guides:
'Creating a dataset':
'https://cloud.google.com/healthcare/docs/how-tos/datasets'
- api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1beta1/projects.locations.datasets'
+ api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets'
- !ruby/object:Api::Resource
name: 'DicomStore'
kind: "healthcare#dicomStore"
@@ -153,7 +156,7 @@ objects:
guides:
'Creating a DICOM store':
'https://cloud.google.com/healthcare/docs/how-tos/dicom'
- api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1beta1/projects.locations.datasets.dicomStores'
+ api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets.dicomStores'
- !ruby/object:Api::Resource
name: 'FhirStore'
kind: "healthcare#fhirStore"
@@ -184,17 +187,30 @@ objects:
** Changing this property may recreate the FHIR store (removing all data) **
required: true
input: true
+ # Version is duplicated because it is optional in beta but required in GA.
- !ruby/object:Api::Type::Enum
name: version
description: |
- The FHIR specification version. Supported values include DSTU2, STU3 and R4. Defaults to STU3.
- required: false # TODO: Make this field required in GA.
+ The FHIR specification version.
+ exact_version: beta
+ required: false
input: true
default_value: :STU3
values:
- :DSTU2
- :STU3
- :R4
+ - !ruby/object:Api::Type::Enum
+ name: version
+ description: |
+ The FHIR specification version.
+ exact_version: ga
+ required: true
+ input: true
+ values:
+ - :DSTU2
+ - :STU3
+ - :R4
- !ruby/object:Api::Type::Boolean
name: 'enableUpdateCreate'
description: |
@@ -288,11 +304,67 @@ objects:
description: |
The fully qualified name of this dataset
output: true
+ - !ruby/object:Api::Type::Array
+ name: streamConfigs
+ description: |-
+ A list of streaming configs that configure the destinations of streaming export for every resource mutation in
+ this FHIR store. Each store is allowed to have up to 10 streaming configs. After a new config is added, the next
+ resource mutation is streamed to the new location in addition to the existing ones. When a location is removed
+ from the list, the server stops streaming to that location. Before adding a new config, you must add the required
+ bigquery.dataEditor role to your project's Cloud Healthcare Service Agent service account. Some lag (typically on
+ the order of dozens of seconds) is expected before the results show up in the streaming destination.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'resourceTypes'
+ description: |
+ Supply a FHIR resource type (such as "Patient" or "Observation"). See
+ https://www.hl7.org/fhir/valueset-resource-types.html for a list of all FHIR resource types. The server treats
+ an empty list as an intent to stream all the supported resource types in this FHIR store.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: bigqueryDestination
+ required: true
+ description: |
+ The destination BigQuery structure that contains both the dataset location and corresponding schema config.
+ The output is organized in one table per resource type. The server reuses the existing tables (if any) that
+ are named after the resource types, e.g. "Patient", "Observation". When there is no existing table for a given
+ resource type, the server attempts to create one.
+ See the [streaming config reference](https://cloud.google.com/healthcare/docs/reference/rest/v1beta1/projects.locations.datasets.fhirStores#streamconfig) for more details.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: datasetUri
+ required: true
+ description: |
+ BigQuery URI to a dataset, up to 2000 characters long, in the format bq://projectId.bqDatasetId
+ - !ruby/object:Api::Type::NestedObject
+ name: schemaConfig
+ required: true
+ description: |
+ The configuration for the exported BigQuery schema.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: schemaType
+ description: |
+ Specifies the output schema type. Only ANALYTICS is supported at this time.
+ * ANALYTICS: Analytics schema defined by the FHIR community.
+ See https://github.com/FHIR/sql-on-fhir/blob/master/sql-on-fhir.md.
+ default_value: :ANALYTICS
+ values:
+ - :ANALYTICS
+ - !ruby/object:Api::Type::Integer
+ name: recursiveStructureDepth
+ required: true
+ description: |
+ The depth for all recursive structures in the output analytics schema. For example, concept in the CodeSystem
+ resource is a recursive structure; when the depth is 2, the CodeSystem table will have a column called
+ concept.concept but not concept.concept.concept. If not specified or set to 0, the server will use the default
+ value 2. The maximum depth allowed is 5.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Creating a FHIR store':
'https://cloud.google.com/healthcare/docs/how-tos/fhir'
- api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1beta1/projects.locations.datasets.fhirStores'
+ api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets.fhirStores'
- !ruby/object:Api::Resource
name: 'Hl7V2Store'
kind: "healthcare#hl7V2Store"
@@ -333,6 +405,7 @@ objects:
at_least_one_of:
- parser_config.0.allow_null_header
- parser_config.0.segment_terminator
+ - parser_config.0.schema
description: |
Determines whether messages with no header are allowed.
- !ruby/object:Api::Type::String
@@ -340,11 +413,20 @@ objects:
at_least_one_of:
- parser_config.0.allow_null_header
- parser_config.0.segment_terminator
+ - parser_config.0.schema
description: |
Byte(s) to be used as the segment terminator. If this is unset, '\r' will be used as segment terminator.
A base64-encoded string.
-
+ - !ruby/object:Api::Type::String
+ name: schema
+ at_least_one_of:
+ - parser_config.0.allow_null_header
+ - parser_config.0.segment_terminator
+ - parser_config.0.schema
+ description: |
+ JSON encoded string for schemas used to parse messages in this
+ store if schematized parsing is desired.
- !ruby/object:Api::Type::KeyValuePairs
name: labels
required: false
@@ -362,9 +444,62 @@ objects:
An object containing a list of "key": value pairs.
Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
+ - !ruby/object:Api::Type::Array
+ name: notificationConfigs
+ description: |-
+ A list of notification configs. Each configuration uses a filter to determine whether to publish a
+ message (both Ingest & Create) on the corresponding notification destination. Only the message name
+ is sent as part of the notification. Supplied by the client.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: pubsubTopic
+ description: |
+ The Cloud Pub/Sub topic that notifications of changes are published on. Supplied by the client.
+ PubsubMessage.Data will contain the resource name. PubsubMessage.MessageId is the ID of this message.
+ It is guaranteed to be unique within the topic. PubsubMessage.PublishTime is the time at which the message
+ was published. Notifications are only sent if the topic is non-empty. Topic names must be scoped to a
+ project. cloud-healthcare@system.gserviceaccount.com must have publisher permissions on the given
+ Cloud Pub/Sub topic. Not having adequate permissions will cause the calls that send notifications to fail.
+
+ If a notification cannot be published to Cloud Pub/Sub, errors will be logged to Stackdriver
+ required: true
+ - !ruby/object:Api::Type::String
+ name: filter
+ description: |
+ Restricts notifications sent for messages matching a filter. If this is empty, all messages
+ are matched. Syntax: https://cloud.google.com/appengine/docs/standard/python/search/query_strings
+ Fields/functions available for filtering are:
+
+ * messageType, from the MSH-9.1 field. For example, NOT messageType = "ADT".
+ * send_date or sendDate, the YYYY-MM-DD date the message was sent in the dataset's timeZone, from the MSH-7 segment. For example, send_date < "2017-01-02".
+ * sendTime, the timestamp when the message was sent, using the RFC3339 time format for comparisons, from the MSH-7 segment. For example, sendTime < "2017-01-02T00:00:00-05:00".
+ * sendFacility, the care center that the message came from, from the MSH-4 segment. For example, sendFacility = "ABC".
+ * PatientId(value, type), which matches if the message lists a patient having an ID of the given value and type in the PID-2, PID-3, or PID-4 segments. For example, PatientId("123456", "MRN").
+ * labels.x, a string value of the label with key x as set using the Message.labels map. For example, labels."priority"="high". The operator :* can be used to assert the existence of a label. For example, labels."priority":*.
- !ruby/object:Api::Type::NestedObject
name: notificationConfig
+ removed_message: This field has been replaced by notificationConfigs
+ exact_version: ga
+ required: false
+ update_url: '{{dataset}}/hl7V2Stores/{{name}}'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: pubsubTopic
+ description: |
+ The Cloud Pub/Sub topic that notifications of changes are published on. Supplied by the client.
+ PubsubMessage.Data will contain the resource name. PubsubMessage.MessageId is the ID of this message.
+ It is guaranteed to be unique within the topic. PubsubMessage.PublishTime is the time at which the message
+ was published. Notifications are only sent if the topic is non-empty. Topic names must be scoped to a
+ project. cloud-healthcare@system.gserviceaccount.com must have publisher permissions on the given
+ Cloud Pub/Sub topic. Not having adequate permissions will cause the calls that send notifications to fail.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: notificationConfig
+ # This field is duplicated because beta and ga have different behaviors.
+ deprecation_message: This field has been replaced by notificationConfigs
+ exact_version: beta
required: false
update_url: '{{dataset}}/hl7V2Stores/{{name}}'
properties:
@@ -378,7 +513,6 @@ objects:
project. cloud-healthcare@system.gserviceaccount.com must have publisher permissions on the given
Cloud Pub/Sub topic. Not having adequate permissions will cause the calls that send notifications to fail.
required: true
-
- !ruby/object:Api::Type::Time
name: 'creationTime'
description: |
@@ -394,4 +528,4 @@ objects:
guides:
'Creating a HL7v2 Store':
'https://cloud.google.com/healthcare/docs/how-tos/hl7v2'
- api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1beta1/projects.locations.datasets.hl7V2Stores'
+ api: 'https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets.hl7V2Stores'
diff --git a/products/healthcare/terraform.yaml b/products/healthcare/terraform.yaml
index 92c80245ca94..02f0eed55ae7 100644
--- a/products/healthcare/terraform.yaml
+++ b/products/healthcare/terraform.yaml
@@ -21,7 +21,6 @@ overrides: !ruby/object:Overrides::ResourceOverrides
examples:
- !ruby/object:Provider::Terraform::Examples
name: "healthcare_dataset_basic"
- skip_test: true
primary_resource_id: "default"
vars:
dataset_name: "example-dataset"
@@ -41,15 +40,24 @@ overrides: !ruby/object:Overrides::ResourceOverrides
{{description}}
id_format: "{{dataset}}/fhirStores/{{name}}"
import_format: ["{{dataset}}/fhirStores/{{name}}"]
+ # FhirStore datastores will be sweeped by the Dataset sweeper
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "healthcare_fhir_store_basic"
- skip_test: true
primary_resource_id: "default"
vars:
dataset_name: "example-dataset"
fhir_store_name: "example-fhir-store"
pubsub_topic: "fhir-notifications"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "healthcare_fhir_store_streaming_config"
+ primary_resource_id: "default"
+ vars:
+ dataset_name: "example-dataset"
+ fhir_store_name: "example-fhir-store"
+ pubsub_topic: "fhir-notifications"
+ bq_dataset_name: "bq_example_dataset"
properties:
creationTime: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
@@ -63,10 +71,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
{{description}}
id_format: "{{dataset}}/dicomStores/{{name}}"
import_format: ["{{dataset}}/dicomStores/{{name}}"]
+ # DicomStore datastores will be sweeped by the Dataset sweeper
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "healthcare_dicom_store_basic"
- skip_test: true
primary_resource_id: "default"
vars:
dataset_name: "example-dataset"
@@ -85,18 +94,32 @@ overrides: !ruby/object:Overrides::ResourceOverrides
{{description}}
id_format: "{{dataset}}/hl7V2Stores/{{name}}"
import_format: ["{{dataset}}/hl7V2Stores/{{name}}"]
+ # Hl7V2Store datastores will be sweeped by the Dataset sweeper
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "healthcare_hl7_v2_store_basic"
- skip_test: true
primary_resource_id: "default"
vars:
dataset_name: "example-dataset"
hl7_v2_store_name: "example-hl7-v2-store"
pubsub_topic: "hl7-v2-notifications"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "healthcare_hl7_v2_store_parser_config"
+ min_version: beta
+ primary_resource_id: "store"
+ vars:
+ dataset_name: "example-dataset"
+ hl7_v2_store_name: "example-hl7-v2-store"
properties:
creationTime: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
+ parserConfig.schema: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/json_schema.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/json_schema.erb'
+ state_func: 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }'
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.ValidateJsonString'
selfLink: !ruby/object:Overrides::Terraform::PropertyOverride
ignore_read: true
custom_code: !ruby/object:Provider::Terraform::CustomCode
diff --git a/products/iam/api.yaml b/products/iam/api.yaml
index dd634970b3cc..9a7b00df287b 100644
--- a/products/iam/api.yaml
+++ b/products/iam/api.yaml
@@ -97,6 +97,7 @@ objects:
- !ruby/object:Api::Resource
name: 'ServiceAccountKey'
base_url: projects/{{project}}/serviceAccounts/{{service_account}}/keys
+ collection_url_key: 'keys'
description: |
A service account in the Identity and Access Management API.
parameters:
diff --git a/products/iam/helpers/ansible/service_account_key_template.erb b/products/iam/helpers/ansible/service_account_key_template.erb
index 0c9b69a3a261..a8f57fdebe7a 100644
--- a/products/iam/helpers/ansible/service_account_key_template.erb
+++ b/products/iam/helpers/ansible/service_account_key_template.erb
@@ -3,12 +3,12 @@
#
# Copyright (C) 2017 Google
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-<%= lines(autogen_notice :python) -%>
+<%= lines(autogen_notice(:python, pwd)) -%>
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-<%= lines(compile('templates/ansible/documentation.erb'), 1) -%>
+<%= lines(compile(pwd + '/templates/ansible/documentation.erb'), 1) -%>
################################################################################
# Imports
################################################################################
@@ -48,7 +48,7 @@ import base64
def main():
"""Main function"""
-<%= lines(indent(compile('templates/ansible/module.erb'), 4)) -%>
+<%= lines(indent(compile(pwd + '/templates/ansible/module.erb'), 4)) -%>
if not module.params['scopes']:
module.params['scopes'] = <%= python_literal(object.__product.scopes) %>
diff --git a/products/iap/api.yaml b/products/iap/api.yaml
index fc1b65f12866..d4fbb8f24e91 100644
--- a/products/iap/api.yaml
+++ b/products/iap/api.yaml
@@ -182,6 +182,10 @@ objects:
input: true
description: |
Contains the data that describes an Identity Aware Proxy owned client.
+
+ ~> **Note:** Only internal org clients can be created via declarative tools. Other types of clients must be
+ manually created via the GCP console. This restriction is due to the existing APIs and not lack of support
+ in this tool.
parameters:
- !ruby/object:Api::Type::String
name: 'clientId'
diff --git a/products/iap/terraform.yaml b/products/iap/terraform.yaml
index 84a2fcb29930..d2db04e498f3 100644
--- a/products/iap/terraform.yaml
+++ b/products/iap/terraform.yaml
@@ -152,7 +152,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
primary_resource_name: "fmt.Sprintf(\"tf-test-tunnel-vm%s\", context[\"random_suffix\"])"
Brand: !ruby/object:Overrides::Terraform::ResourceOverride
async: !ruby/object:Provider::Terraform::PollAsync
- check_response_func: PollCheckForExistence
+ check_response_func_existence: PollCheckForExistence
actions: ['create']
operation: !ruby/object:Api::Async::Operation
timeouts: !ruby/object:Api::Timeouts
@@ -184,6 +184,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: '{{brand}}/identityAwareProxyClients/{{client_id}}'
self_link: '{{brand}}/identityAwareProxyClients/{{client_id}}'
import_format: ['{{brand}}/identityAwareProxyClients/{{client_id}}']
+ # Child of iap brand resource
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "iap_client"
diff --git a/products/identityplatform/terraform.yaml b/products/identityplatform/terraform.yaml
index ce93e10624a8..aa205b723850 100644
--- a/products/identityplatform/terraform.yaml
+++ b/products/identityplatform/terraform.yaml
@@ -24,6 +24,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
skip_test: true
TenantDefaultSupportedIdpConfig: !ruby/object:Overrides::Terraform::ResourceOverride
import_format: ["projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{idp_id}}"]
+ # Child of idp Tenant resource
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "identity_platform_tenant_default_supported_idp_config_basic"
@@ -41,7 +43,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
idp_entity_id: tf-idp
sp_entity_id: tf-sp
test_vars_overrides:
- name: '"saml.tf-config-" + acctest.RandString(10)'
+ name: '"saml.tf-config-" + randString(t, 10)'
TenantInboundSamlConfig: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -55,7 +57,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
idp_entity_id: tf-idp
sp_entity_id: tf-sp
test_vars_overrides:
- name: '"saml.tf-config-" + acctest.RandString(10)'
+ name: '"saml.tf-config-" + randString(t, 10)'
OauthIdpConfig: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -67,7 +69,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
name: oidc.oauth-idp-config
test_vars_overrides:
- name: '"oidc.oauth-idp-config-" + acctest.RandString(10)'
+ name: '"oidc.oauth-idp-config-" + randString(t, 10)'
TenantOauthIdpConfig: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
@@ -79,7 +81,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
vars:
name: oidc.oauth-idp-config
test_vars_overrides:
- name: '"oidc.oauth-idp-config-" + acctest.RandString(10)'
+ name: '"oidc.oauth-idp-config-" + randString(t, 10)'
Tenant: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
diff --git a/products/kms/ansible.yaml b/products/kms/ansible.yaml
index 0f7bda77214c..87d654836145 100644
--- a/products/kms/ansible.yaml
+++ b/products/kms/ansible.yaml
@@ -60,6 +60,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
Immutable purpose of CryptoKey. See
https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose
for inputs.
+ KeyRingImportJob: !ruby/object:Overrides::Ansible::ResourceOverride
+ exclude: true
SecretCiphertext: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
files: !ruby/object:Provider::Config::Files
diff --git a/products/kms/api.yaml b/products/kms/api.yaml
index bb37ac0818b7..01d8df9a2ea0 100644
--- a/products/kms/api.yaml
+++ b/products/kms/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: KMS
-display_name: Cloud KMS
+display_name: Cloud Key Management Service
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -146,6 +146,124 @@ objects:
'Creating a key':
'https://cloud.google.com/kms/docs/creating-keys#create_a_key'
api: 'https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys'
+ - !ruby/object:Api::Resource
+ name: 'KeyRingImportJob'
+ base_url: '{{key_ring}}/importJobs'
+ create_url: '{{key_ring}}/importJobs?importJobId={{import_job_id}}'
+ self_link: '{{name}}'
+ input: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Importing a key':
+ 'https://cloud.google.com/kms/docs/importing-a-key'
+ api: 'https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.importJobs'
+ description: |
+ A `KeyRingImportJob` can be used to create `CryptoKeys` and `CryptoKeyVersions` using pre-existing
+ key material, generated outside of Cloud KMS. A `KeyRingImportJob` expires 3 days after it is created.
+ Once expired, Cloud KMS will no longer be able to import or unwrap any key material that
+ was wrapped with the `KeyRingImportJob`'s public key.
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'keyRing'
+ description: |
+ The KeyRing that this import job belongs to.
+ Format: `'projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}'`.
+ required: true
+ input: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: 'importJobId'
+ required: true
+ description: |
+ It must be unique within a KeyRing and match the regular expression [a-zA-Z0-9_-]{1,63}
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource name for this ImportJob in the format projects/*/locations/*/keyRings/*/importJobs/*.
+ output: true
+ - !ruby/object:Api::Type::Enum
+ name: 'importMethod'
+ input: true
+ required: true
+ description: |
+ The wrapping method to be used for incoming key material.
+ values:
+ - :RSA_OAEP_3072_SHA1_AES_256
+ - :RSA_OAEP_4096_SHA1_AES_256
+ - !ruby/object:Api::Type::Enum
+ name: 'protectionLevel'
+ input: true
+ required: true
+ description: |
+ The protection level of the ImportJob. This must match the protectionLevel of the
+ versionTemplate on the CryptoKey you attempt to import into.
+ values:
+ - :SOFTWARE
+ - :HSM
+ - :EXTERNAL
+ - !ruby/object:Api::Type::Time
+ name: 'createTime'
+ description: |
+ The time that this resource was created on the server.
+ This is in RFC3339 text format.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: 'generateTime'
+ description: |
+ The time that this resource was generated.
+ This is in RFC3339 text format.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: 'expireTime'
+ description: |
+ The time at which this resource is scheduled for expiration and can no longer be used.
+ This is in RFC3339 text format.
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: 'expireEventTime'
+ description: |
+ The time this resource expired. Only present if state is EXPIRED.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'state'
+ description: |
+ The current state of the ImportJob, indicating if it can be used.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'publicKey'
+ description: |
+ The public key with which to wrap key material prior to import. Only returned if state is `ACTIVE`.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'pem'
+ description: |
+ The public key, encoded in PEM format. For more information, see the RFC 7468 sections
+ for General Considerations and Textual Encoding of Subject Public Key Info.
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'attestation'
+ description: |
+ Statement that was generated and signed by the key creator (for example, an HSM) at key creation time.
+ Use this statement to verify attributes of the key as stored on the HSM, independently of Google.
+ Only present if the chosen ImportMethod is one with a protection level of HSM.
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'format'
+ description: |
+ The format of the attestation data.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'content'
+ description: |
+ The attestation data provided by the HSM when the key operation was performed.
+ A base64-encoded string.
+ output: true
- !ruby/object:Api::Resource
name: 'SecretCiphertext'
base_url: '{{crypto_key}}'
diff --git a/products/kms/inspec.yaml b/products/kms/inspec.yaml
index 9eb70a924790..e9263e4d9fca 100644
--- a/products/kms/inspec.yaml
+++ b/products/kms/inspec.yaml
@@ -49,5 +49,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
base_url: 'projects/{{project}}/locations/{{location}}/keyRings/{{key_ring_name}}/cryptoKeys/{{crypto_key_name}}'
exclude: false
method_name_separator: ':'
+ KeyRingImportJob: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
SecretCiphertext: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
\ No newline at end of file
diff --git a/products/kms/terraform.yaml b/products/kms/terraform.yaml
index ab48f697aa00..6cff368ef88b 100644
--- a/products/kms/terraform.yaml
+++ b/products/kms/terraform.yaml
@@ -102,11 +102,41 @@ overrides: !ruby/object:Overrides::ResourceOverrides
encoder: templates/terraform/encoders/kms_crypto_key.go.erb
update_encoder: templates/terraform/update_encoder/kms_crypto_key.go.erb
extra_schema_entry: templates/terraform/extra_schema_entry/kms_self_link.erb
+ KeyRingImportJob: !ruby/object:Overrides::Terraform::ResourceOverride
+ description: |
+ {{description}}
+
+ ~> **Note:** KeyRingImportJobs cannot be deleted from Google Cloud Platform.
+ Destroying a Terraform-managed KeyRingImportJob will remove it from state but
+ *will not delete the resource on the server.*
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "kms_key_ring_import_job"
+ primary_resource_id: "import-job"
+ vars:
+ keyring: "keyring-example"
+ skip_test: true
+ properties:
+ createTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ keyRing: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: 'kmsCryptoKeyRingsEquivalent'
+ ignore_read: true
+ createTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ generateTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ expireEventTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/kms_key_ring_import_job.go.erb
SecretCiphertext: !ruby/object:Overrides::Terraform::ResourceOverride
description: |
{{description}}
- ~> **NOTE**: Using this resource will allow you to conceal secret data within your
+ ~> **NOTE:** Using this resource will allow you to conceal secret data within your
resource definitions, but it does not take care of protecting that data in the
logging output, plan output, or state output. Please take care to secure your secret
data outside of resource definitions.
diff --git a/products/logging/api.yaml b/products/logging/api.yaml
index 1ad1dd07ca5c..49375dddf39a 100644
--- a/products/logging/api.yaml
+++ b/products/logging/api.yaml
@@ -13,7 +13,7 @@
---
!ruby/object:Api::Product
name: Logging
-display_name: Stackdriver Logging
+display_name: Cloud (Stackdriver) Logging
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/memcache/api.yaml b/products/memcache/api.yaml
new file mode 100644
index 000000000000..a7bd2e4c69ad
--- /dev/null
+++ b/products/memcache/api.yaml
@@ -0,0 +1,152 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: Memcache
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://memcache.googleapis.com/v1beta2/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ path: 'name'
+ base_url: '{{op_id}}'
+ wait_ms: 1000
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: True
+ allowed:
+ - True
+ - False
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Instance'
+ min_version: beta
+ create_url: projects/{{project}}/locations/{{region}}/instances?instanceId={{name}}
+ self_link: projects/{{project}}/locations/{{region}}/instances/{{name}}
+ base_url: projects/{{project}}/locations/{{region}}/instances
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Google Cloud Memcache instance.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/memcache/docs/creating-instances'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'region'
+ description: |
+ The name of the Memcache region of the instance.
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource name of the instance.
+ required: true
+ input: true
+ url_param_only: true
+ pattern: projects/{{project}}/locations/{{region}}/instances/{{name}}
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ description: |
+ A user-visible name for the instance.
+ - !ruby/object:Api::Type::String
+ name: 'state'
+ description: |
+ The instance state - short description.
+ output: true
+ exclude: true
+ - !ruby/object:Api::Type::Array
+ name: 'instanceMessages'
+ description: |
+ Additional information about the instance state, if available.
+ output: true
+ exclude: true
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'code'
+ description: An error code.
+ - !ruby/object:Api::Type::String
+ name: 'message'
+ description: The message to be displayed to a user.
+ - !ruby/object:Api::Type::Time
+ name: 'createTime'
+ description: Creation timestamp in RFC3339 text format.
+ output: true
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Resource labels to represent user-provided metadata.
+ - !ruby/object:Api::Type::Array
+ name: 'zones'
+ input: true
+ description: |
+ Zones where memcache nodes should be provisioned. If not
+ provided, all zones will be used.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::String
+ name: 'authorizedNetwork'
+ input: true
+ description: |
+ The full name of the GCE network to connect the instance to. If not provided,
+ 'default' will be used.
+ - !ruby/object:Api::Type::Integer
+ name: nodeCount
+ description: |
+ Number of nodes in the memcache instance.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: nodeConfig
+ description: |
+ Configuration for memcache nodes.
+ required: true
+ input: true
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: cpuCount
+ description: |
+ Number of CPUs per node.
+ required: true
+ - !ruby/object:Api::Type::Integer
+ name: memorySizeMb
+ description: |
+ Memory size in Mebibytes for each memcache node.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: parameters
+ description: |
+ User-specified parameters for this memcache instance.
+ input: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: id
+ output: true
+ description: |
+ This is a unique ID associated with this set of parameters.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: params
+ description: |
+ User-defined set of parameters to use in the memcache process.
diff --git a/products/memcache/inspec.yaml b/products/memcache/inspec.yaml
new file mode 100644
index 000000000000..ed65c44f040a
--- /dev/null
+++ b/products/memcache/inspec.yaml
@@ -0,0 +1,17 @@
+# Copyright 2019 Google Inc.
+# 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/object:Provider::Inspec::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Instance: !ruby/object:Overrides::Inspec::ResourceOverride
+ collection_url_key: resources
\ No newline at end of file
diff --git a/products/memcache/terraform.yaml b/products/memcache/terraform.yaml
new file mode 100644
index 000000000000..85801e23b860
--- /dev/null
+++ b/products/memcache/terraform.yaml
@@ -0,0 +1,48 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Instance: !ruby/object:Overrides::Terraform::ResourceOverride
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 20
+ update_minutes: 20
+ delete_minutes: 20
+ autogen_async: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "memcache_instance_basic"
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "test-instance"
+ properties:
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ displayName: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ zones: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ is_set: true
+ region: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ parameters: !ruby/object:Overrides::Terraform::PropertyOverride
+ name: memcacheParameters
+
+
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/monitoring/api.yaml b/products/monitoring/api.yaml
index 91a41033b270..f9a37208e7bd 100644
--- a/products/monitoring/api.yaml
+++ b/products/monitoring/api.yaml
@@ -12,11 +12,11 @@
# limitations under the License.
--- !ruby/object:Api::Product
name: Monitoring
-display_name: Stackdriver Monitoring
+display_name: Cloud (Stackdriver) Monitoring
versions:
- !ruby/object:Api::Product::Version
name: ga
- base_url: https://monitoring.googleapis.com/v3/
+ base_url: https://monitoring.googleapis.com/
scopes:
- https://www.googleapis.com/auth/cloud-platform
apis_required:
@@ -26,8 +26,8 @@ apis_required:
objects:
- !ruby/object:Api::Resource
name: 'AlertPolicy'
- base_url: projects/{{project}}/alertPolicies
- self_link: "{{name}}"
+ base_url: v3/projects/{{project}}/alertPolicies
+ self_link: "v3/{{name}}"
update_verb: :PATCH
update_mask: true
description: |
@@ -739,11 +739,10 @@ objects:
The format of the content field. Presently, only the value
"text/markdown" is supported.
-
- !ruby/object:Api::Resource
name: 'Group'
- base_url: projects/{{project}}/groups
- self_link: "{{name}}"
+ base_url: v3/projects/{{project}}/groups
+ self_link: "v3/{{name}}"
update_verb: :PUT
description: |
The description of a dynamic collection of monitored resources. Each group
@@ -788,11 +787,10 @@ objects:
The filter used to determine which monitored resources
belong to this group.
-
- !ruby/object:Api::Resource
name: NotificationChannel
- base_url: projects/{{project}}/notificationChannels
- self_link: "{{name}}"
+ base_url: v3/projects/{{project}}/notificationChannels
+ self_link: "v3/{{name}}"
update_verb: :PATCH
description: |
A NotificationChannel is a medium through which an alert is delivered
@@ -918,9 +916,9 @@ objects:
- !ruby/object:Api::Resource
name: Service
- base_url: projects/{{project}}/services
- create_url: projects/{{project}}/services?serviceId={{service_id}}
- self_link: "{{name}}"
+ base_url: v3/projects/{{project}}/services
+ create_url: v3/projects/{{project}}/services?serviceId={{service_id}}
+ self_link: "v3/{{name}}"
update_verb: :PATCH
update_mask: true
description: |
@@ -963,6 +961,614 @@ objects:
Formatted as described in
https://cloud.google.com/apis/design/resource_names.
+ - !ruby/object:Api::Resource
+ name: Slo
+ base_url: v3/projects/{{project}}/services/{{service}}/serviceLevelObjectives
+ # name = projects/{{project}}/services/{{service}}/serviceLevelObjectives/{{slo_id}}
+ self_link: "v3/{{name}}"
+ create_url: v3/projects/{{project}}/services/{{service}}/serviceLevelObjectives?serviceLevelObjectiveId={{slo_id}}
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A Service-Level Objective (SLO) describes the level of desired good
+ service. It consists of a service-level indicator (SLI), a performance
+ goal, and a period over which the objective is to be evaluated against
+ that goal. The SLO can use SLIs defined in a number of different manners.
+ Typical SLOs might include "99% of requests in each rolling week have
+ latency below 200 milliseconds" or "99.5% of requests in each calendar
+ month return successfully."
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Service Monitoring': 'https://cloud.google.com/monitoring/service-monitoring'
+ 'Monitoring API Documentation': 'https://cloud.google.com/monitoring/api/v3/'
+ api: 'https://cloud.google.com/monitoring/api/ref_v3/rest/v3/services.serviceLevelObjectives'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: service
+ required: true
+ url_param_only: true
+ input: true
+ description: |
+ ID of the service to which this SLO belongs.
+ - !ruby/object:Api::Type::String
+ name: sloId
+ description: |
+ The id to use for this ServiceLevelObjective. If omitted, an id will be generated instead.
+ input: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |
+ The full resource name for this service. The syntax is:
+ projects/[PROJECT_ID_OR_NUMBER]/services/[SERVICE_ID]/serviceLevelObjectives/[SLO_NAME]
+ output: true
+ - !ruby/object:Api::Type::String
+ name: displayName
+ description: |
+ Name used for UI elements listing this SLO.
+ - !ruby/object:Api::Type::Double
+ name: goal
+ required: true
+ description: |
+ The fraction of service that must be good in order for this objective
+ to be met. 0 < goal <= 0.999
+ - !ruby/object:Api::Type::Integer
+ name: rollingPeriodDays
+ api_name: rollingPeriod
+ exactly_one_of:
+ - rolling_period_days
+ - calendar_period
+ description: |
+ A rolling time period, semantically "in the past X days".
+ Must be between 1 to 30 days, inclusive.
+ - !ruby/object:Api::Type::Enum
+ name: calendarPeriod
+ exactly_one_of:
+ - rolling_period_days
+ - calendar_period
+ description: |
+ A calendar period, semantically "since the start of the current
+ ".
+ values:
+ - DAY
+ - WEEK
+ - FORTNIGHT
+ - MONTH
+ - !ruby/object:Api::Type::NestedObject
+ name: serviceLevelIndicator
+ description: |
+ serviceLevelIndicator (SLI) describes a good service.
+ It is used to measure and calculate the quality of the Service's
+ performance with respect to a single aspect of service quality.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: basicSli
+ exactly_one_of:
+ - service_level_indicator.0.basic_sli
+ - service_level_indicator.0.request_based_sli
+ - service_level_indicator.0.windows_based_sli
+ description: |
+ Basic Service-Level Indicator (SLI) on a well-known service type.
+ Performance will be computed on the basis of pre-defined metrics.
+
+ SLIs are used to measure and calculate the quality of the Service's
+ performance with respect to a single aspect of service quality.
+
+ Exactly one of the following must be set:
+ `basic_sli`, `request_based_sli`, `windows_based_sli`
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: method
+ description: |
+ An optional set of RPCs to which this SLI is relevant.
+ Telemetry from other methods will not be used to calculate
+ performance for this SLI. If omitted, this SLI applies to all
+ the Service's methods. For service types that don't support
+ breaking down by method, setting this field will result in an
+ error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: location
+ description: |
+ An optional set of locations to which this SLI is relevant.
+ Telemetry from other locations will not be used to calculate
+ performance for this SLI. If omitted, this SLI applies to all
+ locations in which the Service has activity. For service types
+ that don't support breaking down by location, setting this
+ field will result in an error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: version
+ description: |
+ The set of API versions to which this SLI is relevant.
+ Telemetry from other API versions will not be used to
+ calculate performance for this SLI. If omitted,
+ this SLI applies to all API versions. For service types
+ that don't support breaking down by version, setting this
+ field will result in an error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: latency
+ description: |
+ Parameters for a latency threshold SLI.
+ required: true
+ properties:
+ - !ruby/object:Api::Type::String
+ required: true
+ name: threshold
+ description: |
+ A duration string, e.g. 10s.
+ Good service is defined to be the count of requests made to
+ this service that return in no more than threshold.
+ - !ruby/object:Api::Type::NestedObject
+ name: requestBasedSli
+ api_name: 'requestBased'
+ exactly_one_of:
+ - service_level_indicator.0.basic_sli
+ - service_level_indicator.0.request_based_sli
+ - service_level_indicator.0.windows_based_sli
+ description: |
+ A request-based SLI defines a SLI for which atomic units of
+ service are counted directly.
+
+ A SLI describes a good service.
+ It is used to measure and calculate the quality of the Service's
+ performance with respect to a single aspect of service quality.
+ Exactly one of the following must be set:
+ `basic_sli`, `request_based_sli`, `windows_based_sli`
+ properties:
+ # NOTE: If adding properties to requestBasedSli, remember to add to the
+ # custom updateMask fields in property overrides.
+ - !ruby/object:Api::Type::NestedObject
+ name: goodTotalRatio
+ exactly_one_of:
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio
+ - service_level_indicator.0.request_based_sli.0.distribution_cut
+ description: |
+ A means to compute a ratio of `good_service` to `total_service`.
+ Defines computing this ratio with two TimeSeries [monitoring filters](https://cloud.google.com/monitoring/api/v3/filters)
+ Must specify exactly two of good, bad, and total service filters.
+ The relationship good_service + bad_service = total_service
+ will be assumed.
+
+ Exactly one of `distribution_cut` or `good_total_ratio` can be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: goodServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying good service provided.
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+
+ Exactly two of `good_service_filter`,`bad_service_filter`,`total_service_filter`
+ must be set (good + bad = total is assumed).
+ - !ruby/object:Api::Type::String
+ name: badServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying bad service provided, either demanded service that
+ was not provided or demanded service that was of inadequate
+ quality.
+
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+
+ Exactly two of `good_service_filter`,`bad_service_filter`,`total_service_filter`
+ must be set (good + bad = total is assumed).
+ - !ruby/object:Api::Type::String
+ name: totalServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying total demanded service.
+
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+
+ Exactly two of `good_service_filter`,`bad_service_filter`,`total_service_filter`
+ must be set (good + bad = total is assumed).
+ - !ruby/object:Api::Type::NestedObject
+ name: distributionCut
+ exactly_one_of:
+ - service_level_indicator.0.request_based_sli.0.good_total_ratio
+ - service_level_indicator.0.request_based_sli.0.distribution_cut
+ description: |
+ Used when good_service is defined by a count of values aggregated in a
+ Distribution that fall into a good range. The total_service is the
+ total count of all values aggregated in the Distribution.
+ Defines a distribution TimeSeries filter and thresholds used for
+ measuring good service and total service.
+
+ Exactly one of `distribution_cut` or `good_total_ratio` can be set.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: distributionFilter
+ required: true
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ aggregating values to quantify the good service provided.
+
+ Must have ValueType = DISTRIBUTION and
+ MetricKind = DELTA or MetricKind = CUMULATIVE.
+ - !ruby/object:Api::Type::NestedObject
+ name: range
+ required: true
+ description: |
+ Range of numerical values. The computed good_service
+ will be the count of values x in the Distribution such
+ that range.min <= x < range.max. inclusive of min and
+ exclusive of max. Open ranges can be defined by setting
+ just one of min or max.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: min
+ at_least_one_of:
+ - service_level_indicator.0.request_based_sli.0.distribution_cut.0.range.0.min
+ - service_level_indicator.0.request_based_sli.0.distribution_cut.0.range.0.max
+ description: |
+ Min value for the range (inclusive). If not given,
+ will be set to "-infinity", defining an open range
+ "< range.max"
+ - !ruby/object:Api::Type::Integer
+ name: max
+ at_least_one_of:
+ - service_level_indicator.0.request_based_sli.0.distribution_cut.0.range.0.min
+ - service_level_indicator.0.request_based_sli.0.distribution_cut.0.range.0.max
+ description: |
+ max value for the range (inclusive). If not given,
+ will be set to "infinity", defining an open range
+ ">= range.min"
+ - !ruby/object:Api::Type::NestedObject
+ name: windowsBasedSli
+ api_name: 'windowsBased'
+ exactly_one_of:
+ - service_level_indicator.0.basic_sli
+ - service_level_indicator.0.request_based_sli
+ - service_level_indicator.0.windows_based_sli
+ description: |
+ A windows-based SLI defines the criteria for time windows.
+ good_service is defined based off the count of these time windows
+ for which the provided service was of good quality.
+
+ A SLI describes a good service. It is used to measure and calculate
+ the quality of the Service's performance with respect to a single
+ aspect of service quality.
+
+ Exactly one of the following must be set:
+ `basic_sli`, `request_based_sli`, `windows_based_sli`
+ properties:
+ # NOTE: If adding properties to windowsBasedSli, remember to add to the
+ # custom updateMask fields in property overrides.
+ - !ruby/object:Api::Type::String
+ name: windowPeriod
+ description: |
+ Duration over which window quality is evaluated, given as a
+ duration string "{X}s" representing X seconds. Must be an
+ integer fraction of a day and at least 60s.
+ # START window_criterion FIELDS
+ - !ruby/object:Api::Type::String
+ name: goodBadMetricFilter
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_bad_metric_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ with ValueType = BOOL. The window is good if any true values
+ appear in the window. One of `good_bad_metric_filter`,
+ `good_total_ratio_threshold`, `metric_mean_in_range`,
+ `metric_sum_in_range` must be set for `windows_based_sli`.
+ - !ruby/object:Api::Type::NestedObject
+ name: goodTotalRatioThreshold
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_bad_metric_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range
+ description: |
+ Criterion that describes a window as good if its performance is
+ high enough. One of `good_bad_metric_filter`,
+ `good_total_ratio_threshold`, `metric_mean_in_range`,
+ `metric_sum_in_range` must be set for `windows_based_sli`.
+ properties:
+ - !ruby/object:Api::Type::Double
+ name: threshold
+ description: |
+ If window performance >= threshold, the window is counted
+ as good.
+ - !ruby/object:Api::Type::NestedObject
+ name: performance
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.basic_sli_performance
+ description: |
+ Request-based SLI to evaluate to judge window quality.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: goodTotalRatio
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut
+ description: |
+ A means to compute a ratio of `good_service` to `total_service`.
+ Defines computing this ratio with two TimeSeries [monitoring filters](https://cloud.google.com/monitoring/api/v3/filters)
+ Must specify exactly two of good, bad, and total service filters.
+ The relationship good_service + bad_service = total_service
+ will be assumed.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: goodServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying good service provided. Exactly two of
+ good, bad, or total service filter must be defined (where
+ good + bad = total is assumed)
+
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+ - !ruby/object:Api::Type::String
+ name: badServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying bad service provided, either demanded service that
+ was not provided or demanded service that was of inadequate
+ quality. Exactly two of
+ good, bad, or total service filter must be defined (where
+ good + bad = total is assumed)
+
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+ - !ruby/object:Api::Type::String
+ name: totalServiceFilter
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.good_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.bad_service_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio.0.total_service_filter
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ quantifying total demanded service. Exactly two of
+ good, bad, or total service filter must be defined (where
+ good + bad = total is assumed)
+
+ Must have ValueType = DOUBLE or ValueType = INT64 and
+ must have MetricKind = DELTA or MetricKind = CUMULATIVE.
+ - !ruby/object:Api::Type::NestedObject
+ name: distributionCut
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.good_total_ratio
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut
+ description: |
+ Used when good_service is defined by a count of values aggregated in a
+ Distribution that fall into a good range. The total_service is the
+ total count of all values aggregated in the Distribution.
+ Defines a distribution TimeSeries filter and thresholds used for
+ measuring good service and total service.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: distributionFilter
+ required: true
+ description: |
+ A TimeSeries [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ aggregating values to quantify the good service provided.
+
+ Must have ValueType = DISTRIBUTION and
+ MetricKind = DELTA or MetricKind = CUMULATIVE.
+ - !ruby/object:Api::Type::NestedObject
+ name: range
+ required: true
+ description: |
+ Range of numerical values. The computed good_service
+ will be the count of values x in the Distribution such
+ that range.min <= x < range.max. inclusive of min and
+ exclusive of max. Open ranges can be defined by setting
+ just one of min or max.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: min
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut.0.range.0.max
+ description: |
+ Min value for the range (inclusive). If not given,
+ will be set to "-infinity", defining an open range
+ "< range.max"
+ - !ruby/object:Api::Type::Integer
+ name: max
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance.0.distribution_cut.0.range.0.max
+ description: |
+ max value for the range (inclusive). If not given,
+ will be set to "infinity", defining an open range
+ ">= range.min"
+ - !ruby/object:Api::Type::NestedObject
+ name: basicSliPerformance
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.performance
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold.0.basic_sli_performance
+ description: |
+ Basic SLI to evaluate to judge window quality.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: method
+ description: |
+ An optional set of RPCs to which this SLI is relevant.
+ Telemetry from other methods will not be used to calculate
+ performance for this SLI. If omitted, this SLI applies to all
+ the Service's methods. For service types that don't support
+ breaking down by method, setting this field will result in an
+ error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: location
+ description: |
+ An optional set of locations to which this SLI is relevant.
+ Telemetry from other locations will not be used to calculate
+ performance for this SLI. If omitted, this SLI applies to all
+ locations in which the Service has activity. For service types
+ that don't support breaking down by location, setting this
+ field will result in an error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: version
+ description: |
+ The set of API versions to which this SLI is relevant.
+ Telemetry from other API versions will not be used to
+ calculate performance for this SLI. If omitted,
+ this SLI applies to all API versions. For service types
+ that don't support breaking down by version, setting this
+ field will result in an error.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: latency
+ required: true
+ description: |
+ Parameters for a latency threshold SLI.
+ properties:
+ - !ruby/object:Api::Type::String
+ required: true
+ name: threshold
+ description: |
+ A duration string, e.g. 10s.
+ Good service is defined to be the count of requests made to
+ this service that return in no more than threshold.
+ - !ruby/object:Api::Type::NestedObject
+ name: metricMeanInRange
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_bad_metric_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range
+ description: |
+ Criterion that describes a window as good if the metric's value
+ is in a good range, *averaged* across returned streams.
+ One of `good_bad_metric_filter`,
+
+ `good_total_ratio_threshold`, `metric_mean_in_range`,
+ `metric_sum_in_range` must be set for `windows_based_sli`.
+ Average value X of `time_series` should satisfy
+ `range.min <= X < range.max` for a good window.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: timeSeries
+ required: true
+ description: |
+ A [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ specifying the TimeSeries to use for evaluating window
+ The provided TimeSeries must have ValueType = INT64 or
+ ValueType = DOUBLE and MetricKind = GAUGE. Mean value `X`
+ should satisfy `range.min <= X < range.max`
+ under good service.
+ - !ruby/object:Api::Type::NestedObject
+ name: range
+ required: true
+ description: |
+ Range of numerical values. The computed good_service
+ will be the count of values x in the Distribution such
+ that range.min <= x < range.max. inclusive of min and
+ exclusive of max. Open ranges can be defined by setting
+ just one of min or max. Mean value `X` of `time_series`
+ values should satisfy `range.min <= X < range.max` for a
+ good service.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: min
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.max
+ description: |
+ Min value for the range (inclusive). If not given,
+ will be set to "-infinity", defining an open range
+ "< range.max"
+ - !ruby/object:Api::Type::Integer
+ name: max
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.max
+ description: |
+ max value for the range (inclusive). If not given,
+ will be set to "infinity", defining an open range
+ ">= range.min"
+ - !ruby/object:Api::Type::NestedObject
+ name: metricSumInRange
+ exactly_one_of:
+ - service_level_indicator.0.windows_based_sli.0.good_bad_metric_filter
+ - service_level_indicator.0.windows_based_sli.0.good_total_ratio_threshold
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range
+ description: |
+ Criterion that describes a window as good if the metric's value
+ is in a good range, *summed* across returned streams.
+ Summed value `X` of `time_series` should satisfy
+ `range.min <= X < range.max` for a good window.
+
+ One of `good_bad_metric_filter`,
+ `good_total_ratio_threshold`, `metric_mean_in_range`,
+ `metric_sum_in_range` must be set for `windows_based_sli`.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: timeSeries
+ required: true
+ description: |
+ A [monitoring filter](https://cloud.google.com/monitoring/api/v3/filters)
+ specifying the TimeSeries to use for evaluating window
+ quality. The provided TimeSeries must have
+ ValueType = INT64 or ValueType = DOUBLE and
+ MetricKind = GAUGE.
+
+ Summed value `X` should satisfy
+ `range.min <= X < range.max` for a good window.
+ - !ruby/object:Api::Type::NestedObject
+ name: range
+ required: true
+ description: |
+ Range of numerical values. The computed good_service
+ will be the count of values x in the Distribution such
+ that range.min <= x < range.max. inclusive of min and
+ exclusive of max. Open ranges can be defined by setting
+ just one of min or max. Summed value `X` should satisfy
+ `range.min <= X < range.max` for a good window.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: min
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.metric_sum_in_range.0.range.0.max
+ description: |
+ Min value for the range (inclusive). If not given,
+ will be set to "-infinity", defining an open range
+ "< range.max"
+ - !ruby/object:Api::Type::Integer
+ name: max
+ at_least_one_of:
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.min
+ - service_level_indicator.0.windows_based_sli.0.metric_mean_in_range.0.range.0.max
+ description: |
+ max value for the range (inclusive). If not given,
+ will be set to "infinity", defining an open range
+ ">= range.min"
+ # END window_criterion FIELDS
- !ruby/object:Api::Resource
name: UptimeCheckConfig
update_verb: :PATCH
@@ -972,8 +1578,8 @@ objects:
'Official Documentation':
'https://cloud.google.com/monitoring/uptime-checks/'
api: 'https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.uptimeCheckConfigs'
- base_url: projects/{{project}}/uptimeCheckConfigs
- self_link: "{{name}}"
+ base_url: v3/projects/{{project}}/uptimeCheckConfigs
+ self_link: "v3/{{name}}"
description: This message configures which resources and services to monitor for
availability.
properties:
@@ -1017,6 +1623,16 @@ objects:
name: content
description: String or regex content to match (max 1024 bytes)
required: true
+ - !ruby/object:Api::Type::Enum
+ name: matcher
+ description: The type of content matcher that will be applied to the server output,
+ compared to the content string when the check is run.
+ default_value: :CONTAINS_STRING
+ values:
+ - :CONTAINS_STRING
+ - :NOT_CONTAINS_STRING
+ - :MATCHES_REGEX
+ - :NON_MATCHES_REGEX
- !ruby/object:Api::Type::Array
name: selectedRegions
description: The list of regions from which the check will be run. Some regions
@@ -1032,6 +1648,22 @@ objects:
- http_check
- tcp_check
properties:
+ - !ruby/object:Api::Type::Enum
+ name: requestMethod
+ input: true
+ description: The HTTP request method to use for the check. If set to
+ METHOD_UNSPECIFIED then requestMethod defaults to GET.
+ default_value: :GET
+ values:
+ - :METHOD_UNSPECIFIED
+ - :GET
+ - :POST
+ - !ruby/object:Api::Type::Enum
+ name: contentType
+ description: The content type to use for the check.
+ values:
+ - :TYPE_UNSPECIFIED
+ - :URL_ENCODED
- !ruby/object:Api::Type::NestedObject
name: authInfo
at_least_one_of:
@@ -1122,6 +1754,15 @@ objects:
you do not wish to be seen when retrieving the configuration. The server will
be responsible for encrypting the headers. On Get/List calls, if mask_headers
is set to True then the headers will be obscured with ******.
+ - !ruby/object:Api::Type::String
+ name: body
+ description: The request body associated with the HTTP POST request. If contentType
+ is URL_ENCODED, the body passed in must be URL-encoded. Users can provide a
+ Content-Length header via the headers field or the API will do so. If the
+ requestMethod is GET and body is not empty, the API will return an error. The
+ maximum byte size is 1 megabyte. Note - As with all bytes fields JSON
+ representations are base64 encoded. e.g. "foo=bar" in URL-encoded form is
+ "foo%3Dbar" and in base64 encoding is "Zm9vJTI1M0RiYXI=".
- !ruby/object:Api::Type::NestedObject
name: tcpCheck
description: Contains information needed to make a TCP check.
@@ -1187,4 +1828,166 @@ objects:
required: true
description: Values for all of the labels listed in the associated
monitored resource descriptor. For example, Compute Engine VM instances use
- the labels "project_id", "instance_id", and "zone".
\ No newline at end of file
+ the labels "project_id", "instance_id", and "zone".
+
+ - !ruby/object:Api::Resource
+ name: MetricDescriptor
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/monitoring/custom-metrics/'
+ api: 'https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metricDescriptors'
+ base_url: v3/projects/{{project}}/metricDescriptors
+ self_link: "v3/{{name}}"
+ update_verb: :POST
+ update_url: v3/projects/{{project}}/metricDescriptors
+ description: Defines a metric type and its schema. Once a metric descriptor is created,
+ deleting or altering it stops data collection and makes the metric type's existing data
+ unusable.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ output: true
+ description: The resource name of the metric descriptor.
+ - !ruby/object:Api::Type::String
+ name: type
+ input: true
+ required: true
+ description: The metric type, including its DNS name prefix. The type is not
+ URL-encoded. All service defined metrics must be prefixed with the service name,
+ in the format of {service name}/{relative metric name}, such as
+ cloudsql.googleapis.com/database/cpu/utilization. The relative metric name must
+ have only upper and lower-case letters, digits, '/' and underscores '_' are
+ allowed. Additionally, the maximum number of characters allowed for the
+ relative_metric_name is 100. All user-defined metric types have the DNS name
+ custom.googleapis.com, external.googleapis.com, or logging.googleapis.com/user/.
+ - !ruby/object:Api::Type::Array
+ name: labels
+ description: The set of labels that can be used to describe a specific instance of this
+ metric type. In order to delete a label, the entire resource must be deleted,
+ then created with the desired labels.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: key
+ required: true
+ description: The key for this label. The key must not exceed 100 characters. The
+ first character of the key must be an upper- or lower-case letter, the remaining
+ characters must be letters, digits or underscores, and the key must match the
+ regular expression [a-zA-Z][a-zA-Z0-9_]*
+ - !ruby/object:Api::Type::Enum
+ name: valueType
+ description: The type of data that can be assigned to the label.
+ default_value: :STRING
+ values:
+ - :STRING
+ - :BOOL
+ - :INT64
+ - !ruby/object:Api::Type::String
+ name: description
+ description: A human-readable description for the label.
+ - !ruby/object:Api::Type::Enum
+ name: metricKind
+ input: true
+ required: true
+ description: Whether the metric records instantaneous values, changes to a value, etc.
+ Some combinations of metricKind and valueType might not be supported.
+ values:
+ - :METRIC_KIND_UNSPECIFIED
+ - :GAUGE
+ - :DELTA
+ - :CUMULATIVE
+ - !ruby/object:Api::Type::Enum
+ name: valueType
+ input: true
+ required: true
+ description: Whether the measurement is an integer, a floating-point number, etc. Some
+ combinations of metricKind and valueType might not be supported.
+ values:
+ - :BOOL
+ - :INT64
+ - :DOUBLE
+ - :STRING
+ - :DISTRIBUTION
+ - !ruby/object:Api::Type::String
+ name: unit
+ input: true
+ description: |
+ The units in which the metric value is reported. It is only applicable if the
+ valueType is INT64, DOUBLE, or DISTRIBUTION. The unit defines the representation of
+ the stored metric values.
+
+ Different systems may scale the values to be more easily displayed (so a value of
+ 0.02KBy might be displayed as 20By, and a value of 3523KBy might be displayed as
+ 3.5MBy). However, if the unit is KBy, then the value of the metric is always in
+ thousands of bytes, no matter how it may be displayed.
+
+ If you want a custom metric to record the exact number of CPU-seconds used by a job,
+ you can create an INT64 CUMULATIVE metric whose unit is s{CPU} (or equivalently
+ 1s{CPU} or just s). If the job uses 12,005 CPU-seconds, then the value is written as
+ 12005.
+
+ Alternatively, if you want a custom metric to record data in a more granular way, you
+ can create a DOUBLE CUMULATIVE metric whose unit is ks{CPU}, and then write the value
+ 12.005 (which is 12005/1000), or use Kis{CPU} and write 11.723 (which is 12005/1024).
+ The supported units are a subset of The Unified Code for Units of Measure standard.
+ More info can be found in the API documentation
+ (https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metricDescriptors).
+ - !ruby/object:Api::Type::String
+ name: description
+ input: true
+ required: true
+ description: A detailed description of the metric, which can be used in documentation.
+ - !ruby/object:Api::Type::String
+ name: displayName
+ input: true
+ required: true
+ description: A concise name for the metric, which can be displayed in user interfaces.
+ Use sentence case without an ending period, for example "Request count".
+ - !ruby/object:Api::Type::NestedObject
+ name: metadata
+ input: true
+ description: Metadata which can be used to guide usage of the metric.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: samplePeriod
+ at_least_one_of:
+ - metadata.0.sample_period
+ - metadata.0.ingest_delay
+ description: The sampling period of metric data points. For metrics which are
+ written periodically, consecutive data points are stored at this time interval,
+ excluding data loss due to errors. Metrics with a higher granularity have a
+ smaller sampling period. In
+ `[duration format](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?&_ga=2.264881487.1507873253.1593446723-935052455.1591817775#google.protobuf.Duration)`.
+ - !ruby/object:Api::Type::String
+ name: ingestDelay
+ at_least_one_of:
+ - metadata.0.sample_period
+ - metadata.0.ingest_delay
+ description: The delay of data points caused by ingestion. Data points older than
+ this age are guaranteed to be ingested and available to be read, excluding data
+ loss due to errors. In
+ `[duration format](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf?&_ga=2.264881487.1507873253.1593446723-935052455.1591817775#google.protobuf.Duration)`.
+ - !ruby/object:Api::Type::Enum
+ name: launchStage
+ input: true
+ description: The launch stage of the metric definition.
+ values:
+ - :LAUNCH_STAGE_UNSPECIFIED
+ - :UNIMPLEMENTED
+ - :PRELAUNCH
+ - :EARLY_ACCESS
+ - :ALPHA
+ - :BETA
+ - :GA
+ - :DEPRECATED
+ - !ruby/object:Api::Type::Array
+ name: monitoredResourceTypes
+ output: true
+ description: If present, then a time series, which is identified partially by
+ a metric type and a MonitoredResourceDescriptor, that is associated with this metric
+ type can only be associated with one of the monitored resource types listed here.
+ This field allows time series to be associated with the intersection of this metric
+ type and the monitored resource types in this list.
+ item_type: Api::Type::String
+
diff --git a/products/monitoring/inspec.yaml b/products/monitoring/inspec.yaml
index 1f65cfd128e6..c7f0d95ff02d 100644
--- a/products/monitoring/inspec.yaml
+++ b/products/monitoring/inspec.yaml
@@ -18,7 +18,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
additional_functions: third_party/inspec/custom_functions/alert_policy.erb
singular_extra_examples: third_party/inspec/documentation/google_project_alert_policy.md
plural_extra_examples: third_party/inspec/documentation/google_project_alert_policies.md
- self_link: projects/{{project}}/alertPolicies/{{name}}
+ self_link: v3/projects/{{project}}/alertPolicies/{{name}}
properties:
name: !ruby/object:Overrides::Inspec::PropertyOverride
override_name: policy_names
@@ -32,5 +32,9 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
Service: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
+ Slo: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
UptimeCheckConfig: !ruby/object:Overrides::Inspec::ResourceOverride
- exclude: true
\ No newline at end of file
+ exclude: true
+ MetricDescriptor: !ruby/object:Overrides::Inspec::ResourceOverride
+ exclude: true
diff --git a/products/monitoring/terraform.yaml b/products/monitoring/terraform.yaml
index 190941a69742..7fb081990097 100644
--- a/products/monitoring/terraform.yaml
+++ b/products/monitoring/terraform.yaml
@@ -16,7 +16,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: "{{name}}"
import_format: ["{{name}}"]
mutex: alertPolicy/{{project}}
- error_retry_predicates: ["isMonitoringRetryableError"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
examples:
- !ruby/object:Provider::Terraform::Examples
# skipping tests because the API is full of race conditions
@@ -35,7 +35,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: "{{name}}"
import_format: ["{{name}}"]
mutex: stackdriver/groups/{{project}}
- error_retry_predicates: ["isMonitoringRetryableError"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
examples:
- !ruby/object:Provider::Terraform::Examples
name: "monitoring_group_basic"
@@ -59,7 +59,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
id_format: "{{name}}"
import_format: ["{{name}}"]
mutex: stackdriver/notifications/{{project}}
- error_retry_predicates: ["isMonitoringRetryableError"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
examples:
- !ruby/object:Provider::Terraform::Examples
name: "notification_channel_basic"
@@ -111,7 +111,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
legacy_name: 'google_monitoring_custom_service'
id_format: "{{name}}"
import_format: ["{{name}}"]
- error_retry_predicates: ["isMonitoringRetryableError"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
properties:
serviceId: !ruby/object:Overrides::Terraform::PropertyOverride
api_name: 'name'
@@ -130,10 +130,113 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_import: templates/terraform/custom_import/self_link_as_name.erb
encoder: templates/terraform/encoders/monitoring_service.go.erb
+ Slo: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ mutex: monitoring/project/{{project}}/service/{{service}}
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "monitoring_slo_appengine"
+ primary_resource_id: "appeng_slo"
+ vars:
+ slo_id: "ae-slo"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "monitoring_slo_request_based"
+ primary_resource_id: "request_based_slo"
+ test_env_vars:
+ project: :PROJECT_NAME
+ vars:
+ service_id: "custom-srv-request-slos"
+ slo_id: "consumed-api-slo"
+ - !ruby/object:Provider::Terraform::Examples
+ name: 'monitoring_slo_windows_based_good_bad_metric_filter'
+ primary_resource_id: "windows_based"
+ vars:
+ service_id: "custom-srv-windows-slos"
+ slo_id: "good-bad-metric-filter"
+ - !ruby/object:Provider::Terraform::Examples
+ name: 'monitoring_slo_windows_based_metric_mean'
+ primary_resource_id: "windows_based"
+ vars:
+ service_id: "custom-srv-windows-slos"
+ slo_id: "metric-mean-range"
+ - !ruby/object:Provider::Terraform::Examples
+ name: 'monitoring_slo_windows_based_metric_sum'
+ primary_resource_id: "windows_based"
+ vars:
+ service_id: "custom-srv-windows-slos"
+ slo_id: "metric-sum-range"
+ - !ruby/object:Provider::Terraform::Examples
+ name: 'monitoring_slo_windows_based_ratio_threshold'
+ primary_resource_id: "windows_based"
+ vars:
+ service_id: "custom-srv-windows-slos"
+ slo_id: "ratio-threshold"
+ properties:
+ rollingPeriodDays: !ruby/object:Overrides::Terraform::PropertyOverride
+ api_name: rollingPeriod
+ custom_flatten: templates/terraform/custom_expand/days_to_duration_string.go.erb
+ custom_expand: templates/terraform/custom_flatten/duration_string_to_days.go.erb
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(1, 30)'
+ sloId: !ruby/object:Overrides::Terraform::PropertyOverride
+ api_name: 'name'
+ custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
+ default_from_api: true
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[a-z0-9\-]+$'
+ goal: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: validateMonitoringSloGoal
+ serviceLevelIndicator: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ serviceLevelIndicator.basicSli.method: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ serviceLevelIndicator.basicSli.location: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ serviceLevelIndicator.basicSli.version: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ serviceLevelIndicator.requestBasedSli: !ruby/object:Overrides::Terraform::PropertyOverride
+ # Force update all nested fields to allow for unsetting values.
+ update_mask_fields:
+ - "serviceLevelIndicator.requestBased.goodTotalRatio.badServiceFilter"
+ - "serviceLevelIndicator.requestBased.goodTotalRatio.goodServiceFilter"
+ - "serviceLevelIndicator.requestBased.goodTotalRatio.totalServiceFilter"
+ - "serviceLevelIndicator.requestBased.distributionCut.range"
+ - "serviceLevelIndicator.requestBased.distributionCut.distributionFilter"
+ serviceLevelIndicator.windowsBasedSli: !ruby/object:Overrides::Terraform::PropertyOverride
+ # Force update nested fields to allow for unsetting values.
+ update_mask_fields:
+ - "serviceLevelIndicator.windowsBased.windowPeriod"
+ - "serviceLevelIndicator.windowsBased.goodBadMetricFilter"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.threshold"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.performance.goodTotalRatio.badServiceFilter"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.performance.goodTotalRatio.goodServiceFilter"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.performance.goodTotalRatio.totalServiceFilter"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.performance.distributionCut.range"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.performance.distributionCut.distributionFilter"
+ - "serviceLevelIndicator.windowsBased.goodTotalRatioThreshold.basicSliPerformance"
+ - "serviceLevelIndicator.windowsBased.metricMeanInRange.timeSeries"
+ - "serviceLevelIndicator.windowsBased.metricMeanInRange.range"
+ - "serviceLevelIndicator.windowsBased.metricSumInRange.timeSeries"
+ - "serviceLevelIndicator.windowsBased.metricSumInRange.range"
+ serviceLevelIndicator.windowsBasedSli.goodTotalRatioThreshold.basicSliPerformance.method: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ serviceLevelIndicator.windowsBasedSli.goodTotalRatioThreshold.basicSliPerformance.location: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ serviceLevelIndicator.windowsBasedSli.goodTotalRatioThreshold.basicSliPerformance.version: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ constants: templates/terraform/constants/monitoring_slo.go.erb
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
+ encoder: templates/terraform/encoders/monitoring_slo.go.erb
+
UptimeCheckConfig: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: "{{name}}"
import_format: ["{{name}}"]
- error_retry_predicates: ["isMonitoringRetryableError"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
+ mutex: stackdriver/groups/{{project}}
examples:
- !ruby/object:Provider::Terraform::Examples
name: "uptime_check_config_http"
@@ -168,10 +271,52 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_flatten: "templates/terraform/custom_flatten/uptime_check_http_password.erb"
httpCheck.port: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
+ httpCheck.headers: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
resourceGroup.groupId: !ruby/object:Overrides::Terraform::PropertyOverride
custom_expand: "templates/terraform/custom_expand/resource_from_self_link.go.erb"
custom_flatten: "templates/terraform/custom_flatten/group_id_to_name.erb"
+ MetricDescriptor: !ruby/object:Overrides::Terraform::ResourceOverride
+ async: !ruby/object:Provider::Terraform::PollAsync
+ check_response_func_existence: PollCheckForExistence
+ check_response_func_absence: PollCheckForAbsence
+ target_occurrences: 20
+ actions: ['create', 'update', 'delete']
+ operation: !ruby/object:Api::Async::Operation
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 6
+ update_minutes: 6
+ delete_minutes: 6
+ id_format: "{{name}}"
+ import_format: ["{{name}}"]
+ error_retry_predicates: ["isMonitoringConcurrentEditError"]
+ properties:
+ labels: !ruby/object:Overrides::Terraform::PropertyOverride
+ is_set: true
+ labels.valueType: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: "templates/terraform/custom_flatten/default_if_empty.erb"
+ metadata: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ launchStage: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "monitoring_metric_descriptor_basic"
+ primary_resource_id: "basic"
+ vars:
+ display_name: "metric-descriptor"
+ type: "daily_sales"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "monitoring_metric_descriptor_alert"
+ primary_resource_id: "with_alert"
+ vars:
+ display_name: "metric-descriptor"
+ type: "daily_sales"
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
+
+
files: !ruby/object:Provider::Config::Files
# These files have templating (ERB) code that will be run.
# This is usually to add licensing info, autogeneration notices, etc.
diff --git a/products/networkmanagement/api.yaml b/products/networkmanagement/api.yaml
new file mode 100644
index 000000000000..7c1781b9b9d8
--- /dev/null
+++ b/products/networkmanagement/api.yaml
@@ -0,0 +1,212 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: NetworkManagement
+display_name: NetworkManagement
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://networkmanagement.googleapis.com/v1/
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Network Management API
+ url: https://console.cloud.google.com/apis/library/networkmanagement.googleapis.com/
+async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ path: 'name'
+ base_url: '{{op_id}}'
+ wait_ms: 1000
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: true
+ allowed:
+ - true
+ - false
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+objects:
+ - !ruby/object:Api::Resource
+ name: 'ConnectivityTest'
+ base_url: projects/{{project}}/locations/global/connectivityTests
+ create_url: projects/{{project}}/locations/global/connectivityTests?testId={{name}}
+ update_verb: :PATCH
+ update_mask: true
+ description: |
+ A connectivity test are a static analysis of your resource configurations
+ that enables you to evaluate connectivity to and from Google Cloud
+ resources in your Virtual Private Cloud (VPC) network.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/network-intelligence-center/docs'
+ api: 'https://cloud.google.com/network-intelligence-center/docs/connectivity-tests/reference/networkmanagement/rest/v1/projects.locations.global.connectivityTests'
+ iam_policy: !ruby/object:Api::Resource::IamPolicy
+ exclude: true
+ method_name_separator: ':'
+ parent_resource_attribute: 'connectivityTest'
+ import_format: ["projects/{{project}}/locations/global/connectivityTests/{{connectivityTest}}", "{{connectivityTest}}"]
+ properties:
+ - !ruby/object:Api::Type::String
+ name: name
+ description: |-
+ Unique name for the connectivity test.
+ required: true
+ input: true
+ - !ruby/object:Api::Type::String
+ name: description
+ description: |-
+ The user-supplied description of the Connectivity Test.
+ Maximum of 512 characters.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'source'
+ required: true
+ description: |
+ Required. Source specification of the Connectivity Test.
+
+ You can use a combination of source IP address, virtual machine
+ (VM) instance, or Compute Engine network to uniquely identify the
+ source location.
+
+ Examples: If the source IP address is an internal IP address within
+ a Google Cloud Virtual Private Cloud (VPC) network, then you must
+ also specify the VPC network. Otherwise, specify the VM instance,
+ which already contains its internal IP address and VPC network
+ information.
+
+ If the source of the test is within an on-premises network, then
+ you must provide the destination VPC network.
+
+ If the source endpoint is a Compute Engine VM instance with multiple
+ network interfaces, the instance itself is not sufficient to
+ identify the endpoint. So, you must also specify the source IP
+ address or VPC network.
+
+ A reachability analysis proceeds even if the source location is
+ ambiguous. However, the test result may include endpoints that
+ you don't intend to test.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: ipAddress
+ description: |-
+ The IP address of the endpoint, which can be an external or
+ internal IP. An IPv6 address is only allowed when the test's
+ destination is a global load balancer VIP.
+ - !ruby/object:Api::Type::Integer
+ name: port
+ description: |-
+ The IP protocol port of the endpoint. Only applicable when
+ protocol is TCP or UDP.
+ - !ruby/object:Api::Type::String
+ name: instance
+ description: |-
+ A Compute Engine instance URI.
+ - !ruby/object:Api::Type::String
+ name: network
+ description: |-
+ A Compute Engine network URI.
+ - !ruby/object:Api::Type::Enum
+ name: networkType
+ description: |-
+ Type of the network where the endpoint is located.
+ values:
+ - :GCP_NETWORK
+ - :NON_GCP_NETWORK
+ - !ruby/object:Api::Type::String
+ name: projectId
+ description: |-
+ Project ID where the endpoint is located. The Project ID can be
+ derived from the URI if you provide a VM instance or network URI.
+ The following are two cases where you must provide the project ID:
+
+ 1. Only the IP address is specified, and the IP address is
+ within a GCP project.
+ 2. When you are using Shared VPC and the IP address
+ that you provide is from the service project. In this case,
+ the network that the IP address resides in is defined in the
+ host project.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'destination'
+ required: true
+ description: |
+ Required. Destination specification of the Connectivity Test.
+
+ You can use a combination of destination IP address, Compute
+ Engine VM instance, or VPC network to uniquely identify the
+ destination location.
+
+ Even if the destination IP address is not unique, the source IP
+ location is unique. Usually, the analysis can infer the destination
+ endpoint from route information.
+
+ If the destination you specify is a VM instance and the instance has
+ multiple network interfaces, then you must also specify either a
+ destination IP address or VPC network to identify the destination
+ interface.
+
+ A reachability analysis proceeds even if the destination location
+ is ambiguous. However, the result can include endpoints that you
+ don't intend to test.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: ipAddress
+ description: |-
+ The IP address of the endpoint, which can be an external or
+ internal IP. An IPv6 address is only allowed when the test's
+ destination is a global load balancer VIP.
+ - !ruby/object:Api::Type::Integer
+ name: port
+ description: |-
+ The IP protocol port of the endpoint. Only applicable when
+ protocol is TCP or UDP.
+ - !ruby/object:Api::Type::String
+ name: instance
+ description: |-
+ A Compute Engine instance URI.
+ - !ruby/object:Api::Type::String
+ name: network
+ description: |-
+ A Compute Engine network URI.
+ - !ruby/object:Api::Type::String
+ name: projectId
+ description: |-
+ Project ID where the endpoint is located. The Project ID can be
+ derived from the URI if you provide a VM instance or network URI.
+ The following are two cases where you must provide the project ID:
+ 1. Only the IP address is specified, and the IP address is within
+ a GCP project. 2. When you are using Shared VPC and the IP address
+ that you provide is from the service project. In this case, the
+ network that the IP address resides in is defined in the host
+ project.
+ - !ruby/object:Api::Type::String
+ name: protocol
+ description: |-
+ IP Protocol of the test. When not provided, "TCP" is assumed.
+ default_value: "TCP"
+ - !ruby/object:Api::Type::Array
+ name: relatedProjects
+ description: |-
+ Other projects that may be relevant for reachability analysis.
+ This is applicable to scenarios where a test can cross project
+ boundaries.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Resource labels to represent user-provided metadata.
diff --git a/products/networkmanagement/terraform.yaml b/products/networkmanagement/terraform.yaml
new file mode 100644
index 000000000000..2954652b4638
--- /dev/null
+++ b/products/networkmanagement/terraform.yaml
@@ -0,0 +1,55 @@
+# Copyright 2019 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ ConnectivityTest: !ruby/object:Overrides::Terraform::ResourceOverride
+ filename_override: 'connectivity_test_resource'
+ id_format: projects/{{project}}/locations/global/connectivityTests/{{name}}
+ autogen_async: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "network_management_connectivity_test_instances"
+ primary_resource_id: "instance-test"
+ vars:
+ primary_resource_name: "conn-test-instances"
+ network_name: "conn-test-net"
+ source_instance: "source-vm"
+ dest_instance: "dest-vm"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "network_management_connectivity_test_addresses"
+ primary_resource_id: "address-test"
+ vars:
+ primary_resource_name: "conn-test-addr"
+ network: "connectivity-vpc"
+ source_addr: "src-addr"
+ dest_addr: "dest-addr"
+ properties:
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_expand: 'templates/terraform/custom_expand/network_management_connectivity_test_name.go.erb'
+ custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ source: !ruby/object:Overrides::Terraform::PropertyOverride
+ update_mask_fields:
+ - "source.ipAddress"
+ - "source.port"
+ - "source.instance"
+ - "source.network"
+ - "source.networkType"
+ - "source.projectId"
+ destination: !ruby/object:Overrides::Terraform::PropertyOverride
+ update_mask_fields:
+ - "destination.ipAddress"
+ - "destination.port"
+ - "destination.instance"
+ - "destination.network"
+ - "destination.projectId"
diff --git a/products/notebooks/api.yaml b/products/notebooks/api.yaml
new file mode 100644
index 000000000000..3f5105abff77
--- /dev/null
+++ b/products/notebooks/api.yaml
@@ -0,0 +1,400 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: Notebooks
+display_name: Cloud AI Notebooks
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://notebooks.googleapis.com/v1beta1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Cloud Notebooks API
+ url: https://console.cloud.google.com/apis/api/notebooks.googleapis.com
+async: !ruby/object:Api::OpAsync
+ operation: !ruby/object:Api::OpAsync::Operation
+ base_url: '{{op_id}}'
+ path: 'name'
+ wait_ms: 1000
+ result: !ruby/object:Api::OpAsync::Result
+ path: 'response'
+ resource_inside_response: true
+ status: !ruby/object:Api::OpAsync::Status
+ path: 'done'
+ complete: True
+ allowed:
+ - True
+ - False
+ error: !ruby/object:Api::OpAsync::Error
+ path: 'error'
+ message: 'message'
+objects:
+ # Notebooks Environment
+ - !ruby/object:Api::Resource
+ name: 'Environment'
+ description: |
+ A Cloud AI Platform Notebook environment.
+ min_version: beta
+ base_url: projects/{{project}}/locations/{{location}}/environments
+ create_url: projects/{{project}}/locations/{{location}}/environments?environmentId={{name}}
+ self_link: projects/{{project}}/locations/{{location}}/environments/{{name}}
+ create_verb: :POST
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/ai-platform-notebooks'
+ api: 'https://cloud.google.com/ai-platform/notebooks/docs/reference/rest'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The name specified for the Environment instance.
+ Format: projects/{project_id}/locations/{location}/environments/{environmentId}
+ required: true
+ input: true
+ url_param_only: true
+ pattern: projects/{{project}}/locations/{{location}}/environments/{{name}}
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'location'
+ description: 'A reference to the zone where the machine resides.'
+ resource: 'Location'
+ imports: 'name'
+ required: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ description: |
+ Display name of this environment for the UI.
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ A brief description of this environment.
+ - !ruby/object:Api::Type::String
+ name: 'postStartupScript'
+ description: |
+ Path to a Bash script that automatically runs after a notebook instance fully boots up.
+ The path must be a URL or Cloud Storage path. Example: "gs://path-to-file/file-name"
+ - !ruby/object:Api::Type::Time
+ name: 'createTime'
+ description: 'Instance creation time'
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'vmImage'
+ exactly_one_of:
+ - vm_image
+ - container_image
+ description: |
+ Use a Compute Engine VM image to start the notebook instance.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'project'
+ description: |
+ The name of the Google Cloud project that this VM image belongs to.
+ Format: projects/{project_id}
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'imageName'
+ description: |
+ Use VM image name to find the image.
+ - !ruby/object:Api::Type::String
+ name: 'imageFamily'
+ description: |
+ Use this VM image family to find the image; the newest image in this family will be used.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'containerImage'
+ exactly_one_of:
+ - vm_image
+ - container_image
+ description: |
+ Use a container image to start the notebook instance.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'repository'
+ description: |
+ The path to the container image repository.
+ For example: gcr.io/{project_id}/{imageName}
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tag'
+ description: |
+ The tag of the container image. If not specified, this defaults to the latest tag.
+ # Notebooks Instance
+ - !ruby/object:Api::Resource
+ name: 'Instance'
+ description: |
+ A Cloud AI Platform Notebook instance.
+ min_version: beta
+ base_url: projects/{{project}}/locations/{{location}}/instances
+ create_url: projects/{{project}}/locations/{{location}}/instances?instanceId={{name}}
+ self_link: projects/{{project}}/locations/{{location}}/instances/{{name}}
+ create_verb: :POST
+ input: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/ai-platform-notebooks'
+ api: 'https://cloud.google.com/ai-platform/notebooks/docs/reference/rest'
+ parameters:
+ - !ruby/object:Api::Type::ResourceRef
+ name: 'location'
+ description: 'A reference to the zone where the machine resides.'
+ resource: 'Location'
+ imports: 'selfLink'
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The name specified for the Notebook instance.
+ required: true
+ input: true
+ url_param_only: true
+ pattern: projects/{{project}}/locations/{{location}}/instances/{{name}}
+ - !ruby/object:Api::Type::String
+ name: 'machineType'
+ description: |
+ A reference to a machine type which defines VM kind.
+ required: true
+ # Machine Type is updatable, but requires the instance to be stopped, just like
+ # for compute instances.
+ # TODO: Implement allow_stopping_for_update here and for acceleratorConfig
+ # update_verb: :PATCH
+ # update_url: 'projects/{{project}}/locations/{{location}}/instances/{{name}}:setMachineType'
+ pattern: projects/{{project}}/zones/{{location}}/machineTypes/{{name}}
+ - !ruby/object:Api::Type::String
+ name: 'postStartupScript'
+ description: |
+ Path to a Bash script that automatically runs after a
+ notebook instance fully boots up. The path must be a URL
+ or Cloud Storage path (gs://path-to-file/file-name).
+ - !ruby/object:Api::Type::String
+ name: 'proxyUri'
+ description: |
+ The proxy endpoint that is used to access the Jupyter notebook.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'instanceOwners'
+ description: |
+ The owner of this instance after creation.
+ Format: alias@example.com.
+ Currently supports one owner only.
+ If not specified, all of the service account users of
+ your VM instance's service account can use the instance.
+ - !ruby/object:Api::Type::String
+ name: 'serviceAccount'
+ description: |
+ The service account on this instance, giving access to other
+ Google Cloud services. You can use any service account within
+ the same project, but you must have the service account user
+ permission to use the instance. If not specified,
+ the Compute Engine default service account is used.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'acceleratorConfig'
+ description: |
+ The hardware accelerator used on this instance. If you use accelerators,
+ make sure that your configuration has enough vCPUs and memory to support the
+ machineType you have selected.
+ # AcceleratorConfig is updatable, but requires the instance to be stopped, just like
+ # for compute instances.
+ # TODO: Implement allow_stopping_for_update here and for machineType
+ # update_verb: :PATCH
+ # update_url: 'projects/{{project}}/locations/{{location}}/instances/{{name}}:setAccelerator'
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'type'
+ values:
+ - ACCELERATOR_TYPE_UNSPECIFIED
+ - NVIDIA_TESLA_K80
+ - NVIDIA_TESLA_P100
+ - NVIDIA_TESLA_V100
+ - NVIDIA_TESLA_P4
+ - NVIDIA_TESLA_T4
+ - NVIDIA_TESLA_T4_VWS
+ - NVIDIA_TESLA_P100_VWS
+ - NVIDIA_TESLA_P4_VWS
+ - TPU_V2
+ - TPU_V3
+ required: true
+ description: |
+ Type of this accelerator.
+ - !ruby/object:Api::Type::Integer
+ name: 'coreCount'
+ required: true
+ description: |
+ Count of cores of this accelerator.
+ - !ruby/object:Api::Type::Enum
+ name: 'state'
+ values:
+ - STATE_UNSPECIFIED
+ - STARTING
+ - PROVISIONING
+ - ACTIVE
+ - STOPPING
+ - STOPPED
+ - DELETED
+ description: |
+ The state of this instance.
+ output: true
+ - !ruby/object:Api::Type::Boolean
+ name: 'installGpuDriver'
+ description: |
+ Indicates that this is a boot disk. The virtual machine will
+ use the first partition of the disk for its root filesystem.
+ input: true
+ - !ruby/object:Api::Type::String
+ name: 'customGpuDriverPath'
+ description: |
+ Specify a custom Cloud Storage path where the GPU driver is stored.
+ If not specified, we'll automatically choose from official GPU drivers.
+ - !ruby/object:Api::Type::Enum
+ name: 'bootDiskType'
+ values:
+ - DISK_TYPE_UNSPECIFIED
+ - PD_STANDARD
+ - PD_SSD
+ description: |
+ Possible disk types for notebook instances.
+ - !ruby/object:Api::Type::Integer
+ name: 'bootDiskSizeGb'
+ description: |
+ The size of the boot disk in GB attached to this instance,
+ up to a maximum of 64000 GB (64 TB). The minimum recommended value is 100 GB.
+ If not specified, this defaults to 100.
+ - !ruby/object:Api::Type::Enum
+ name: 'dataDiskType'
+ values:
+ - DISK_TYPE_UNSPECIFIED
+ - PD_STANDARD
+ - PD_SSD
+ description: |
+ Possible disk types for notebook instances.
+ - !ruby/object:Api::Type::Integer
+ name: 'dataDiskSizeGb'
+ description: |
+ The size of the data disk in GB attached to this instance,
+ up to a maximum of 64000 GB (64 TB).
+ You can choose the size of the data disk based on how big your notebooks and data are.
+ If not specified, this defaults to 100.
+ - !ruby/object:Api::Type::Boolean
+ name: 'noRemoveDataDisk'
+ description: |
+ If true, the data disk will not be auto deleted when deleting the instance.
+ - !ruby/object:Api::Type::Enum
+ name: 'diskEncryption'
+ values:
+ - DISK_ENCRYPTION_UNSPECIFIED
+ - GMEK
+ - CMEK
+ description: |
+ Disk encryption method used on the boot and data disks, defaults to GMEK.
+ - !ruby/object:Api::Type::String
+ name: 'kmsKey'
+ description: |
+ The KMS key used to encrypt the disks, only applicable if diskEncryption is CMEK.
+ Format: projects/{project_id}/locations/{location}/keyRings/{key_ring_id}/cryptoKeys/{key_id}
+ - !ruby/object:Api::Type::Boolean
+ name: 'noPublicIp'
+ description: |
+ no public IP will be assigned to this instance.
+ - !ruby/object:Api::Type::Boolean
+ name: 'noProxyAccess'
+ description: |
+ the notebook instance will not register with the proxy..
+ - !ruby/object:Api::Type::String
+ name: 'network'
+ description: |
+ The name of the VPC that this instance is in.
+ Format: projects/{project_id}/global/networks/{network_id}
+ - !ruby/object:Api::Type::String
+ name: 'subnet'
+ description: |
+ The name of the subnet that this instance is in.
+ Format: projects/{project_id}/regions/{region}/subnetworks/{subnetwork_id}
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Labels to apply to this instance. These can be later modified by the setLabels method.
+ An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
+ update_verb: :PATCH
+ update_url: 'projects/{{project}}/locations/{{location}}/instances/{{name}}:setLabels'
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ Custom metadata to apply to this instance.
+ An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
+ - !ruby/object:Api::Type::Time
+ name: 'createTime'
+ description: 'Instance creation time'
+ output: true
+ - !ruby/object:Api::Type::Time
+ name: 'updateTime'
+ description: 'Instance update time.'
+ output: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'vmImage'
+ exactly_one_of:
+ - vm_image
+ - container_image
+ description: |
+ Use a Compute Engine VM image to start the notebook instance.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'project'
+ description: |
+ The name of the Google Cloud project that this VM image belongs to.
+ Format: projects/{project_id}
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'imageFamily'
+ description: |
+ Use this VM image family to find the image; the newest image in this family will be used.
+ - !ruby/object:Api::Type::String
+ name: 'imageName'
+ description: |
+ Use VM image name to find the image.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'containerImage'
+ exactly_one_of:
+ - vm_image
+ - container_image
+ description: |
+ Use a container image to start the notebook instance.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'repository'
+ description: |
+ The path to the container image repository.
+ For example: gcr.io/{project_id}/{imageName}
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'tag'
+ description: |
+ The tag of the container image. If not specified, this defaults to the latest tag.
+ # Compute Zone (Location)
+ - !ruby/object:Api::Resource
+ name: 'Location'
+ kind: 'compute#zone'
+ base_url: projects/{{project}}/locations
+ collection_url_key: 'items'
+ has_self_link: true
+ readonly: true
+ description: 'Represents a Location resource.'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: 'Name of the Location resource.'
\ No newline at end of file
diff --git a/products/notebooks/terraform.yaml b/products/notebooks/terraform.yaml
new file mode 100644
index 000000000000..e966c62b85e3
--- /dev/null
+++ b/products/notebooks/terraform.yaml
@@ -0,0 +1,113 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Environment: !ruby/object:Overrides::Terraform::ResourceOverride
+ properties:
+ location: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: 'compareSelfLinkOrResourceName'
+ custom_expand: templates/terraform/custom_expand/resource_from_self_link.go.erb
+ custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "notebook_environment_basic"
+ primary_resource_id: "environment"
+ vars:
+ environment_name: "notebooks-environment"
+ Instance: !ruby/object:Overrides::Terraform::ResourceOverride
+ timeouts: !ruby/object:Api::Timeouts
+ insert_minutes: 15
+ update_minutes: 15
+ delete_minutes: 15
+ autogen_async: true
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "notebook_instance_basic"
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "notebooks-instance"
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "notebook_instance_basic_container"
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "notebooks-instance"
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "notebook_instance_basic_gpu"
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "notebooks-instance"
+ - !ruby/object:Provider::Terraform::Examples
+ min_version: beta
+ name: "notebook_instance_full"
+ primary_resource_id: "instance"
+ vars:
+ instance_name: "notebooks-instance"
+ test_env_vars:
+ service_account: :SERVICE_ACCT
+ description: |
+ {{description}}
+
+ ~> **Note:** Due to limitations of the Notebooks Instance API, many fields
+ in this resource do not properly detect drift. These fields will also not
+ appear in state once imported.
+ properties:
+ bootDiskSizeGb: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ bootDiskType: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ createTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ containerImage: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ dataDiskSizeGb: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ instanceOwners: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ machineType: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: 'compareSelfLinkOrResourceName'
+ custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
+ metadata: !ruby/object:Overrides::Terraform::PropertyOverride
+ # This is not a traditional ignore_read. Metadata is returned from the API,
+ # but it gets merged with metadata that the server sets. This prevents us
+ # from detecting drift.
+ ignore_read: true
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ network: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: compareSelfLinkOrResourceName
+ default_from_api: true
+ serviceAccount: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ subnet: !ruby/object:Overrides::Terraform::PropertyOverride
+ diff_suppress_func: compareSelfLinkOrResourceName
+ default_from_api: true
+ updateTime: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ vmImage: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ Location: !ruby/object:Overrides::Terraform::ResourceOverride
+ properties:
+ name: !ruby/object:Overrides::Terraform::PropertyOverride
+ custom_flatten: templates/terraform/custom_flatten/name_from_self_link.erb
+
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
\ No newline at end of file
diff --git a/products/osconfig/api.yaml b/products/osconfig/api.yaml
new file mode 100644
index 000000000000..0d79cf286e15
--- /dev/null
+++ b/products/osconfig/api.yaml
@@ -0,0 +1,1544 @@
+# Copyright 2020 google Inc.
+# 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/object:Api::Product
+name: OSConfig
+display_name: OS Config
+versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://osconfig.googleapis.com/v1/
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://osconfig.googleapis.com/v1beta/
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Identity and Access Management (IAM) API
+ url: https://console.cloud.google.com/apis/library/iam.googleapis.com/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+ - https://www.googleapis.com/auth/compute
+objects:
+ - !ruby/object:Api::Resource
+ name: 'PatchDeployment'
+ base_url: "projects/{{project}}/patchDeployments"
+ create_url: "projects/{{project}}/patchDeployments?patchDeploymentId={{patch_deployment_id}}"
+ self_link: "{{name}}"
+ description: |
+ Patch deployments are configurations that individual patch jobs use to complete a patch.
+ These configurations include instance filter, package repository settings, and a schedule.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/compute/docs/os-patch-management'
+ api: 'https://cloud.google.com/compute/docs/osconfig/rest'
+ input: true
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'patchDeploymentId'
+ description: |
+ A name for the patch deployment in the project. When creating a name the following rules apply:
+ * Must contain only lowercase letters, numbers, and hyphens.
+ * Must start with a letter.
+ * Must be between 1-63 characters.
+ * Must end with a number or a letter.
+ * Must be unique within the project.
+ required: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ Unique name for the patch deployment resource in a project.
+ The patch deployment name is in the form: projects/{project_id}/patchDeployments/{patchDeploymentId}.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ Description of the patch deployment. Length of the description is limited to 1024 characters.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'instanceFilter'
+ required: true
+ description: |
+ VM instances to patch.
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'all'
+ at_least_one_of:
+ - instance_filter.0.all
+ - instance_filter.0.group_labels
+ - instance_filter.0.zones
+ - instance_filter.0.instances
+ - instance_filter.0.instance_name_prefixes
+ description: |
+ Target all VM instances in the project. If true, no other criteria is permitted.
+ - !ruby/object:Api::Type::Array
+ name: 'groupLabels'
+ at_least_one_of:
+ - instance_filter.0.all
+ - instance_filter.0.group_labels
+ - instance_filter.0.zones
+ - instance_filter.0.instances
+ - instance_filter.0.instance_name_prefixes
+ description: |
+ Targets VM instances matching ANY of these GroupLabels. This allows targeting of disparate groups of VM instances.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ required: true
+ description: |
+ Compute Engine instance labels that must be present for a VM instance to be targeted by this filter
+ - !ruby/object:Api::Type::Array
+ name: 'zones'
+ at_least_one_of:
+ - instance_filter.0.all
+ - instance_filter.0.group_labels
+ - instance_filter.0.zones
+ - instance_filter.0.instances
+ - instance_filter.0.instance_name_prefixes
+ description: |
+ Targets VM instances in ANY of these zones. Leave empty to target VM instances in any zone.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'instances'
+ at_least_one_of:
+ - instance_filter.0.all
+ - instance_filter.0.group_labels
+ - instance_filter.0.zones
+ - instance_filter.0.instances
+ - instance_filter.0.instance_name_prefixes
+ description: |
+ Targets any of the VM instances specified. Instances are specified by their URI in the `form zones/{{zone}}/instances/{{instance_name}}`,
+ `projects/{{project_id}}/zones/{{zone}}/instances/{{instance_name}}`, or
+ `https://www.googleapis.com/compute/v1/projects/{{project_id}}/zones/{{zone}}/instances/{{instance_name}}`
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'instanceNamePrefixes'
+ at_least_one_of:
+ - instance_filter.0.all
+ - instance_filter.0.group_labels
+ - instance_filter.0.zones
+ - instance_filter.0.instances
+ - instance_filter.0.instance_name_prefixes
+ description: |
+ Targets VMs whose name starts with one of these prefixes. Similar to labels, this is another way to group
+ VMs when targeting configs, for example prefix="prod-".
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'patchConfig'
+ description: |
+ Patch configuration that is applied.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'rebootConfig'
+ description: |
+ Post-patch reboot settings.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ values:
+ - :DEFAULT
+ - :ALWAYS
+ - :NEVER
+ - !ruby/object:Api::Type::NestedObject
+ name: 'apt'
+ description: |
+ Apt update settings. Use this setting to override the default apt patch rules.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'type'
+ at_least_one_of:
+ - patch_config.0.apt.type
+ - patch_config.0.apt.excludes
+ - patch_config.0.apt.exclusive_packages
+ description: |
+ By changing the type to DIST, the patching is performed using apt-get dist-upgrade instead.
+ values:
+ - :DIST
+ - :UPGRADE
+ - !ruby/object:Api::Type::Array
+ name: 'excludes'
+ at_least_one_of:
+ - patch_config.0.apt.type
+ - patch_config.0.apt.excludes
+ - patch_config.0.apt.exclusive_packages
+ description: |
+ List of packages to exclude from update. These packages will be excluded.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exclusivePackages'
+ at_least_one_of:
+ - patch_config.0.apt.type
+ - patch_config.0.apt.excludes
+ - patch_config.0.apt.exclusive_packages
+ description: |
+ An exclusive list of packages to be updated. These are the only packages that will be updated.
+ If these packages are not installed, they will be ignored. This field cannot be specified with
+ any other patch configuration fields.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'yum'
+ description: |
+ Yum update settings. Use this setting to override the default yum patch rules.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'security'
+ at_least_one_of:
+ - patch_config.0.yum.security
+ - patch_config.0.yum.minimal
+ - patch_config.0.yum.excludes
+ - patch_config.0.yum.exclusive_packages
+ description: |
+ Adds the --security flag to yum update. Not supported on all platforms.
+ - !ruby/object:Api::Type::Boolean
+ name: 'minimal'
+ at_least_one_of:
+ - patch_config.0.yum.security
+ - patch_config.0.yum.minimal
+ - patch_config.0.yum.excludes
+ - patch_config.0.yum.exclusive_packages
+ description: |
+ Will cause patch to run yum update-minimal instead.
+ - !ruby/object:Api::Type::Array
+ name: 'excludes'
+ at_least_one_of:
+ - patch_config.0.yum.security
+ - patch_config.0.yum.minimal
+ - patch_config.0.yum.excludes
+ - patch_config.0.yum.exclusive_packages
+ description: |
+ List of packages to exclude from update. These packages will be excluded.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exclusivePackages'
+ at_least_one_of:
+ - patch_config.0.yum.security
+ - patch_config.0.yum.minimal
+ - patch_config.0.yum.excludes
+ - patch_config.0.yum.exclusive_packages
+ description: |
+ An exclusive list of packages to be updated. These are the only packages that will be updated.
+ If these packages are not installed, they will be ignored. This field cannot be specified with
+ any other patch configuration fields.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'goo'
+ description: |
+ goo update settings. Use this setting to override the default goo patch rules.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: enabled
+ description: |
+ goo update settings. Use this setting to override the default goo patch rules.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'zypper'
+ description: |
+ zypper update settings. Use this setting to override the default zypper patch rules.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::Boolean
+ name: 'withOptional'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ Adds the --with-optional flag to zypper patch.
+ - !ruby/object:Api::Type::Boolean
+ name: 'withUpdate'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ Adds the --with-update flag, to zypper patch.
+ - !ruby/object:Api::Type::Array
+ name: 'categories'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ Install only patches with these categories. Common categories include security, recommended, and feature.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'severities'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ Install only patches with these severities. Common severities include critical, important, moderate, and low.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'excludes'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ List of packages to exclude from update.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exclusivePatches'
+ at_least_one_of:
+ - patch_config.0.zypper.withOptional
+ - patch_config.0.zypper.withUpdate
+ - patch_config.0.zypper.categories
+ - patch_config.0.zypper.severities
+ - patch_config.0.zypper.excludes
+ - patch_config.0.zypper.exclusive_patches
+ description: |
+ An exclusive list of patches to be updated. These are the only patches that will be installed using 'zypper patch patch:' command.
+ This field must not be used with any other patch configuration fields.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'windowsUpdate'
+ description: |
+ Windows update settings. Use this setting to override the default Windows patch rules.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'classifications'
+ at_least_one_of:
+ - patch_config.0.windowsUpdate.classifications
+ - patch_config.0.windowsUpdate.excludes
+ - patch_config.0.windowsUpdate.exclusive_patches
+ description: |
+ Only apply updates of these windows update classifications. If empty, all updates are applied.
+ values:
+ - :CRITICAL
+ - :SECURITY
+ - :DEFINITION
+ - :DRIVER
+ - :FEATURE_PACK
+ - :SERVICE_PACK
+ - :TOOL
+ - :UPDATE_ROLLUP
+ - :UPDATE
+ - !ruby/object:Api::Type::Array
+ name: 'excludes'
+ at_least_one_of:
+ - patch_config.0.windowsUpdate.classifications
+ - patch_config.0.windowsUpdate.excludes
+ - patch_config.0.windowsUpdate.exclusive_patches
+ description: |
+ List of KBs to exclude from update.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'exclusivePatches'
+ at_least_one_of:
+ - patch_config.0.windowsUpdate.classifications
+ - patch_config.0.windowsUpdate.excludes
+ - patch_config.0.windowsUpdate.exclusive_patches
+ description: |
+ An exclusive list of kbs to be updated. These are the only patches that will be updated.
+ This field must not be used with other patch configurations.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'preStep'
+ description: |
+ The ExecStep to run before the patch update.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'linuxExecStepConfig'
+ at_least_one_of:
+ - patch_config.0.preStep.linux_exec_step_config
+ - patch_config.0.preStep.windows_exec_step_config
+ description: |
+ The ExecStepConfig for all Linux VMs targeted by the PatchJob.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowedSuccessCodes'
+ description: |
+ Defaults to [0]. A list of possible return values that the execution can return to indicate a success.
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script will
+ be executed directly, which will likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ An absolute path to the executable on the VM.
+ exactly_one_of:
+ - patch_config.0.pre_step.0.linux_exec_step_config.0.local_path
+ - patch_config.0.pre_step.0.linux_exec_step_config.0.gcs_object
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gcsObject'
+ description: |
+ A Cloud Storage object containing the executable.
+ exactly_one_of:
+ - patch_config.0.pre_step.0.linux_exec_step_config.0.local_path
+ - patch_config.0.pre_step.0.linux_exec_step_config.0.gcs_object
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'bucket'
+ required: true
+ description: |
+ Bucket of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'object'
+ required: true
+ description: |
+ Name of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'generationNumber'
+ required: true
+ description: |
+ Generation number of the Cloud Storage object. This is used to ensure that the ExecStep specified by this PatchJob does not change.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'windowsExecStepConfig'
+ at_least_one_of:
+ - patch_config.0.preStep.linux_exec_step_config
+ - patch_config.0.preStep.windows_exec_step_config
+ description: |
+ The ExecStepConfig for all Windows VMs targeted by the PatchJob.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowedSuccessCodes'
+ description: |
+ Defaults to [0]. A list of possible return values that the execution can return to indicate a success.
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script will
+ be executed directly, which will likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ An absolute path to the executable on the VM.
+ exactly_one_of:
+ - patch_config.0.pre_step.0.windows_exec_step_config.0.local_path
+ - patch_config.0.pre_step.0.windows_exec_step_config.0.gcs_object
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gcsObject'
+ description: |
+ A Cloud Storage object containing the executable.
+ exactly_one_of:
+ - patch_config.0.pre_step.0.windows_exec_step_config.0.local_path
+ - patch_config.0.pre_step.0.windows_exec_step_config.0.gcs_object
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'bucket'
+ required: true
+ description: |
+ Bucket of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'object'
+ required: true
+ description: |
+ Name of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'generationNumber'
+ required: true
+ description: |
+ Generation number of the Cloud Storage object. This is used to ensure that the ExecStep specified by this PatchJob does not change.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'postStep'
+ description: |
+ The ExecStep to run after the patch update.
+ at_least_one_of:
+ - patch_config.0.reboot_config
+ - patch_config.0.apt
+ - patch_config.0.yum
+ - patch_config.0.goo
+ - patch_config.0.zypper
+ - patch_config.0.window_update
+ - patch_config.0.pre_step
+ - patch_config.0.post_step
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'linuxExecStepConfig'
+ at_least_one_of:
+ - patch_config.0.post_step.linux_exec_step_config
+ - patch_config.0.post_step.windows_exec_step_config
+ description: |
+ The ExecStepConfig for all Linux VMs targeted by the PatchJob.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowedSuccessCodes'
+ description: |
+ Defaults to [0]. A list of possible return values that the execution can return to indicate a success.
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script will
+ be executed directly, which will likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ An absolute path to the executable on the VM.
+ exactly_one_of:
+ - patch_config.0.post_step.0.linux_exec_step_config.0.local_path
+ - patch_config.0.post_step.0.linux_exec_step_config.0.gcs_object
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gcsObject'
+ description: |
+ A Cloud Storage object containing the executable.
+ exactly_one_of:
+ - patch_config.0.post_step.0.linux_exec_step_config.0.local_path
+ - patch_config.0.post_step.0.linux_exec_step_config.0.gcs_object
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'bucket'
+ required: true
+ description: |
+ Bucket of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'object'
+ required: true
+ description: |
+ Name of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'generationNumber'
+ required: true
+ description: |
+ Generation number of the Cloud Storage object. This is used to ensure that the ExecStep specified by this PatchJob does not change.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'windowsExecStepConfig'
+ at_least_one_of:
+ - patch_config.0.post_step.linux_exec_step_config
+ - patch_config.0.post_step.windows_exec_step_config
+ description: |
+ The ExecStepConfig for all Windows VMs targeted by the PatchJob.
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'allowedSuccessCodes'
+ description: |
+ Defaults to [0]. A list of possible return values that the execution can return to indicate a success.
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script will
+ be executed directly, which will likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ An absolute path to the executable on the VM.
+ exactly_one_of:
+ - patch_config.0.post_step.0.windows_exec_step_config.0.local_path
+ - patch_config.0.post_step.0.windows_exec_step_config.0.gcs_object
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gcsObject'
+ description: |
+ A Cloud Storage object containing the executable.
+ exactly_one_of:
+ - patch_config.0.post_step.0.windows_exec_step_config.0.local_path
+ - patch_config.0.post_step.0.windows_exec_step_config.0.gcs_object
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'bucket'
+ required: true
+ description: |
+ Bucket of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'object'
+ required: true
+ description: |
+ Name of the Cloud Storage object.
+ - !ruby/object:Api::Type::String
+ name: 'generationNumber'
+ required: true
+ description: |
+ Generation number of the Cloud Storage object. This is used to ensure that the ExecStep specified by this PatchJob does not change.
+ - !ruby/object:Api::Type::String
+ name: 'duration'
+ description: |
+ Duration of the patch. After the duration ends, the patch times out.
+ A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s"
+ - !ruby/object:Api::Type::String
+ name: 'createTime'
+ output: true
+ description: |
+ Time the patch deployment was created. Timestamp is in RFC3339 text format.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'updateTime'
+ output: true
+ description: |
+ Time the patch deployment was last updated. Timestamp is in RFC3339 text format.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'lastExecuteTime'
+ output: true
+ description: |
+ The last time a patch job was started by this deployment. Timestamp is in RFC3339 text format.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::NestedObject
+ name: 'oneTimeSchedule'
+ exactly_one_of:
+ - one_time_schedule
+ - recurring_schedule
+ description: |
+ Schedule a one-time execution.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'executeTime'
+ required: true
+ description: |
+ The desired patch job execution time. A timestamp in RFC3339 UTC "Zulu" format,
+ accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::NestedObject
+ name: 'recurringSchedule'
+ exactly_one_of:
+ - one_time_schedule
+ - recurring_schedule
+ description: |
+ Schedule recurring executions.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'timeZone'
+ required: true
+ description: |
+ Defines the time zone that timeOfDay is relative to. The rules for daylight saving time are
+ determined by the chosen time zone.
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ required: true
+ description: |
+ IANA Time Zone Database time zone, e.g. "America/New_York".
+ - !ruby/object:Api::Type::String
+ name: 'version'
+ description: |
+ IANA Time Zone Database version number, e.g. "2019a".
+ - !ruby/object:Api::Type::String
+ name: 'startTime'
+ description: |
+ The time that the recurring schedule becomes effective. Defaults to createTime of the patch deployment.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'endTime'
+ description: |
+ The end time at which a recurring patch deployment schedule is no longer active.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::NestedObject
+ name: 'timeOfDay'
+ required: true
+ description: |
+ Time of the day to run a recurring deployment.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'hours'
+ at_least_one_of:
+ - recurring_schedule.0.time_of_day.0.hours
+ - recurring_schedule.0.time_of_day.0.minutes
+ - recurring_schedule.0.time_of_day.0.seconds
+ - recurring_schedule.0.time_of_day.0.nanos
+ description: |
+ Hours of day in 24 hour format. Should be from 0 to 23.
+ An API may choose to allow the value "24:00:00" for scenarios like business closing time.
+ - !ruby/object:Api::Type::Integer
+ name: 'minutes'
+ at_least_one_of:
+ - recurring_schedule.0.time_of_day.0.hours
+ - recurring_schedule.0.time_of_day.0.minutes
+ - recurring_schedule.0.time_of_day.0.seconds
+ - recurring_schedule.0.time_of_day.0.nanos
+ description: |
+ Minutes of hour of day. Must be from 0 to 59.
+ - !ruby/object:Api::Type::Integer
+ name: 'seconds'
+ at_least_one_of:
+ - recurring_schedule.0.time_of_day.0.hours
+ - recurring_schedule.0.time_of_day.0.minutes
+ - recurring_schedule.0.time_of_day.0.seconds
+ - recurring_schedule.0.time_of_day.0.nanos
+ description: |
+ Seconds of minutes of the time. Must normally be from 0 to 59. An API may allow the value 60 if it allows leap-seconds.
+ - !ruby/object:Api::Type::Integer
+ name: 'nanos'
+ at_least_one_of:
+ - recurring_schedule.0.time_of_day.0.hours
+ - recurring_schedule.0.time_of_day.0.minutes
+ - recurring_schedule.0.time_of_day.0.seconds
+ - recurring_schedule.0.time_of_day.0.nanos
+ description: |
+ Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999.
+ - !ruby/object:Api::Type::Enum
+ name: 'frequency'
+ required: true
+ description: |
+ The frequency unit of this recurring schedule.
+ values:
+ - :WEEKLY
+ - :MONTHLY
+ - !ruby/object:Api::Type::String
+ name: 'lastExecuteTime'
+ output: true
+ description: |
+ The time the last patch job ran successfully.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'nextExecuteTime'
+ output: true
+ description: |
+ The time the next patch job is scheduled to run.
+ A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::NestedObject
+ name: 'weekly'
+ exactly_one_of:
+ - recurring_schedule.0.weekly
+ - recurring_schedule.0.monthly
+ description: |
+ Schedule with weekly executions.
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'dayOfWeek'
+ required: true
+ description: |
+ IANA Time Zone Database time zone, e.g. "America/New_York".
+ values:
+ - :MONDAY
+ - :TUESDAY
+ - :WEDNESDAY
+ - :THURSDAY
+ - :FRIDAY
+ - :SATURDAY
+ - :SUNDAY
+ - !ruby/object:Api::Type::NestedObject
+ name: 'monthly'
+ exactly_one_of:
+ - recurring_schedule.0.weekly
+ - recurring_schedule.0.monthly
+ description: |
+ Schedule with monthly executions.
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'weekDayOfMonth'
+ exactly_one_of:
+ - recurring_schedule.0.monthly.0.week_day_of_month
+ - recurring_schedule.0.monthly.0.month_day
+ description: |
+ Week day in a month.
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'weekOrdinal'
+ required: true
+ description: |
+ Week number in a month. 1-4 indicates the 1st to 4th week of the month. -1 indicates the last week of the month.
+ - !ruby/object:Api::Type::Enum
+ name: 'dayOfWeek'
+ required: true
+ description: |
+ A day of the week.
+ values:
+ - :MONDAY
+ - :TUESDAY
+ - :WEDNESDAY
+ - :THURSDAY
+ - :FRIDAY
+ - :SATURDAY
+ - :SUNDAY
+ - !ruby/object:Api::Type::Integer
+ name: 'monthDay'
+ exactly_one_of:
+ - recurring_schedule.0.monthly.0.week_day_of_month
+ - recurring_schedule.0.monthly.0.month_day
+ description: |
+ One day of the month. 1-31 indicates the 1st to the 31st day. -1 indicates the last day of the month.
+ Months without the target day will be skipped. For example, a schedule to run "every month on the 31st"
+ will not run in February, April, June, etc.
+ - !ruby/object:Api::Resource
+ name: 'GuestPolicies'
+ base_url: "projects/{{project}}/guestPolicies"
+ create_url: "projects/{{project}}/guestPolicies?guestPolicyId={{guest_policy_id}}"
+ update_verb: :PATCH
+ self_link: "projects/{{project}}/guestPolicies/{{guest_policy_id}}"
+ min_version: beta
+ description: |
+ An OS Config resource representing a guest configuration policy. These policies represent
+ the desired state for VM instance guest environments including packages to install or remove,
+ package repository configurations, and software to install.
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Official Documentation':
+ 'https://cloud.google.com/compute/docs/os-config-management'
+ api: 'https://cloud.google.com/compute/docs/osconfig/rest'
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'guestPolicyId'
+ description: |
+ The logical name of the guest policy in the project with the following restrictions:
+ * Must contain only lowercase letters, numbers, and hyphens.
+ * Must start with a letter.
+ * Must be between 1-63 characters.
+ * Must end with a number or a letter.
+ * Must be unique within the project.
+ required: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ Unique name of the resource in this project using one of the following forms: projects/{project_number}/guestPolicies/{guestPolicyId}.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'description'
+ description: |
+ Description of the guest policy. Length of the description is limited to 1024 characters.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'assignment'
+ required: true
+ description: |
+ Specifies the VM instances that are assigned to this policy. This allows you to target sets
+ or groups of VM instances by different parameters such as labels, names, OS, or zones.
+ If left empty, all VM instances underneath this policy are targeted.
+ At the same level in the resource hierarchy (that is within a project), the service prevents
+ the creation of multiple policies that conflict with each other.
+ For more information, see how the service
+ [handles assignment conflicts](https://cloud.google.com/compute/docs/os-config-management/create-guest-policy#handle-conflicts).
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'groupLabels'
+ at_least_one_of:
+ - assignment.0.group_labels
+ - assignment.0.zones
+ - assignment.0.instances
+ - assignment.0.instance_name_prefixes
+ - assignment.0.os_types
+ description: |
+ Targets instances matching at least one of these label sets. This allows an assignment to target disparate groups,
+ for example "env=prod or env=staging".
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ required: true
+ description: |
+ Google Compute Engine instance labels that must be present for an instance to be included in this assignment group.
+ - !ruby/object:Api::Type::Array
+ name: 'zones'
+ at_least_one_of:
+ - assignment.0.group_labels
+ - assignment.0.zones
+ - assignment.0.instances
+ - assignment.0.instance_name_prefixes
+ - assignment.0.os_types
+ description: |
+ Targets instances in any of these zones. Leave empty to target instances in any zone.
+ Zonal targeting is uncommon and is supported to facilitate the management of changes by zone.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'instances'
+ at_least_one_of:
+ - assignment.0.group_labels
+ - assignment.0.zones
+ - assignment.0.instances
+ - assignment.0.instance_name_prefixes
+ - assignment.0.os_types
+ description: |
+ Targets any of the instances specified. Instances are specified by their URI in the form
+ zones/[ZONE]/instances/[INSTANCE_NAME].
+ Instance targeting is uncommon and is supported to facilitate the management of changes
+ by the instance or to target specific VM instances for development and testing.
+ Only supported for project-level policies and must reference instances within this project.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'instanceNamePrefixes'
+ at_least_one_of:
+ - assignment.0.group_labels
+ - assignment.0.zones
+ - assignment.0.instances
+ - assignment.0.instance_name_prefixes
+ - assignment.0.os_types
+ description: |
+ Targets VM instances whose name starts with one of these prefixes.
+ Like labels, this is another way to group VM instances when targeting configs,
+ for example prefix="prod-".
+ Only supported for project-level policies.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'osTypes'
+ at_least_one_of:
+ - assignment.0.group_labels
+ - assignment.0.zones
+ - assignment.0.instances
+ - assignment.0.instance_name_prefixes
+ - assignment.0.os_types
+ description: |
+ Targets VM instances matching at least one of the following OS types.
+ VM instances must match all supplied criteria for a given OsType to be included.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'osShortName'
+ description: |
+ Targets VM instances with OS Inventory enabled and having the following OS short name, for example "debian" or "windows".
+ - !ruby/object:Api::Type::String
+ name: 'osVersion'
+ description: |
+ Targets VM instances with OS Inventory enabled and having the following following OS version.
+ - !ruby/object:Api::Type::String
+ name: 'osArchitecture'
+ description: |
+ Targets VM instances with OS Inventory enabled and having the following OS architecture.
+ - !ruby/object:Api::Type::Array
+ name: 'packages'
+ description: |
+ The software packages to be managed by this policy.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The name of the package. A package is uniquely identified for conflict validation
+ by checking the package name and the manager(s) that the package targets.
+ required: true
+ - !ruby/object:Api::Type::Enum
+ name: 'desiredState'
+ description: |
+ The desiredState the agent should maintain for this package. The default is to ensure the package is installed.
+ values:
+ - :INSTALLED
+ - :UPDATED
+ - :REMOVED
+ - !ruby/object:Api::Type::Enum
+ name: 'manager'
+ description: |
+ Type of package manager that can be used to install this package. If a system does not have the package manager,
+ the package is not installed or removed no error message is returned. By default, or if you specify ANY,
+ the agent attempts to install and remove this package using the default package manager.
+ This is useful when creating a policy that applies to different types of systems.
+ The default behavior is ANY.
+ default_value: :ANY
+ values:
+ - :ANY
+ - :APT
+ - :YUM
+ - :ZYPPER
+ - :GOO
+ - !ruby/object:Api::Type::Array
+ name: 'packageRepositories'
+ description: |
+ A list of package repositories to configure on the VM instance.
+ This is done before any other configs are applied so they can use these repos.
+ Package repositories are only configured if the corresponding package manager(s) are available.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'apt'
+ description: |
+ An Apt Repository.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::Enum
+ name: 'archiveType'
+ description: |
+ Type of archive files in this repository. The default behavior is DEB.
+ default_value: :DEB
+ values:
+ - :DEB
+ - :DEB_SRC
+ - !ruby/object:Api::Type::String
+ name: 'uri'
+ description: |
+ URI for this repository.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'distribution'
+ description: |
+ Distribution of this repository.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'components'
+ description: |
+ List of components for this repository. Must contain at least one item.
+ required: true
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::String
+ name: 'gpgKey'
+ description: |
+ URI of the key file for this repository. The agent maintains a keyring at
+ /etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg containing all the keys in any applied guest policy.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'yum'
+ description: |
+ A Yum Repository.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ description: |
+ A one word, unique name for this repository. This is the repo id in the Yum config file and also the displayName
+ if displayName is omitted. This id is also used as the unique identifier when checking for guest policy conflicts.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ description: |
+ The display name of the repository.
+ - !ruby/object:Api::Type::String
+ name: 'baseUrl'
+ description: |
+ The location of the repository directory.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'gpgKeys'
+ description: |
+ URIs of GPG keys.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'zypper'
+ description: |
+ A Zypper Repository.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ description: |
+ A one word, unique name for this repository. This is the repo id in the zypper config file and also the displayName
+ if displayName is omitted. This id is also used as the unique identifier when checking for guest policy conflicts.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'displayName'
+ description: |
+ The display name of the repository.
+ - !ruby/object:Api::Type::String
+ name: 'baseUrl'
+ description: |
+ The location of the repository directory.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'gpgKeys'
+ description: |
+ URIs of GPG keys.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::NestedObject
+ name: 'goo'
+ description: |
+ A Goo Repository.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The name of the repository.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'url'
+ description: |
+ The url of the repository.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'recipes'
+ description: |
+ A list of Recipes to install on the VM instance.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ Unique identifier for the recipe. Only one recipe with a given name is installed on an instance.
+ Names are also used to identify resources which helps to determine whether guest policies have conflicts.
+ This means that requests to create multiple recipes with the same name and version are rejected since they
+ could potentially have conflicting assignments.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'version'
+ description: |
+ The version of this software recipe. Version can be up to 4 period separated numbers (e.g. 12.34.56.78).
+ - !ruby/object:Api::Type::Array
+ name: 'artifacts'
+ description: |
+ Resources available to be used in the steps in the recipe.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'id'
+ description: |
+ Id of the artifact, which the installation and update steps of this recipe can reference.
+ Artifacts in a recipe cannot have the same id.
+ required: true
+ - !ruby/object:Api::Type::Boolean
+ name: 'allowInsecure'
+ description: |
+ Defaults to false. When false, recipes are subject to validations based on the artifact type:
+ Remote: A checksum must be specified, and only protocols with transport-layer security are permitted.
+ GCS: An object generation number must be specified.
+ default_value: false
+ - !ruby/object:Api::Type::NestedObject
+ name: 'remote'
+ description: |
+ A generic remote artifact.
+ # TODO (mbang): add conflicts_with when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'uri'
+ description: |
+ URI from which to fetch the object. It should contain both the protocol and path following the format {protocol}://{location}.
+ - !ruby/object:Api::Type::String
+ name: 'checkSum'
+ description: |
+ Must be provided if allowInsecure is false. SHA256 checksum in hex format, to compare to the checksum of the artifact.
+ If the checksum is not empty and it doesn't match the artifact then the recipe installation fails before running any
+ of the steps.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'gcs'
+ description: |
+ A Google Cloud Storage artifact.
+ # TODO (mbang): add conflicts_with when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'bucket'
+ description: |
+ Bucket of the Google Cloud Storage object. Given an example URL: https://storage.googleapis.com/my-bucket/foo/bar#1234567
+ this value would be my-bucket.
+ - !ruby/object:Api::Type::String
+ name: 'object'
+ description: |
+ Name of the Google Cloud Storage object. Given an example URL: https://storage.googleapis.com/my-bucket/foo/bar#1234567
+ this value would be foo/bar.
+ - !ruby/object:Api::Type::Integer
+ name: 'generation'
+ description: |
+ Must be provided if allowInsecure is false. Generation number of the Google Cloud Storage object.
+ https://storage.googleapis.com/my-bucket/foo/bar#1234567 this value would be 1234567.
+ - !ruby/object:Api::Type::Array
+ name: 'installSteps'
+ description: |
+ Actions to be taken for installing this recipe. On failure it stops executing steps and does not attempt another installation.
+ Any steps taken (including partially completed steps) are not rolled back.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fileCopy'
+ description: |
+ Copies a file onto the instance.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'destination'
+ description: |
+ The absolute path on the instance to put the file.
+ required: true
+ - !ruby/object:Api::Type::Boolean
+ name: 'overwrite'
+ description: |
+ Whether to allow this step to overwrite existing files.If this is false and the file already exists the file
+ is not overwritten and the step is considered a success. Defaults to false.
+ default_value: false
+ - !ruby/object:Api::Type::String
+ name: 'permissions'
+ description: |
+ Consists of three octal digits which represent, in order, the permissions of the owner, group, and other users
+ for the file (similarly to the numeric mode used in the linux chmod utility). Each digit represents a three bit
+ number with the 4 bit corresponding to the read permissions, the 2 bit corresponds to the write bit, and the one
+ bit corresponds to the execute permission. Default behavior is 755.
+
+ Below are some examples of permissions and their associated values:
+ read, write, and execute: 7 read and execute: 5 read and write: 6 read only: 4
+ - !ruby/object:Api::Type::NestedObject
+ name: 'archiveExtraction'
+ description: |
+ Extracts an archive into the specified directory.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'destination'
+ description: |
+ Directory to extract archive to. Defaults to / on Linux or C:\ on Windows.
+ - !ruby/object:Api::Type::Enum
+ name: 'type'
+ description: |
+ The type of the archive to extract.
+ required: true
+ values:
+ - :TAR
+ - :TAR_GZIP
+ - :TAR_BZIP
+ - :TAR_LZMA
+ - :TAR_XZ
+ - :ZIP
+ - !ruby/object:Api::Type::NestedObject
+ name: 'msiInstallation'
+ description: |
+ Installs an MSI file.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'flags'
+ description: |
+ The flags to use when installing the MSI. Defaults to the install flag.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowedExitCodes'
+ description: |
+ Return codes that indicate that the software installed or updated successfully. Behaviour defaults to [0]
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::NestedObject
+ name: 'dpkgInstallation'
+ description: |
+ Installs a deb file via dpkg.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'rpmInstallation'
+ description: |
+ Installs an rpm file via the rpm utility.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fileExec'
+ description: |
+ Executes an artifact or local file.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'args'
+ description: |
+ Arguments to be passed to the provided executable.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::String
+ name: 'allowedExitCodes'
+ description: |
+ A list of possible return values that the program can return to indicate a success. Defaults to [0].
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ The absolute path of the file on the local filesystem.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ - !ruby/object:Api::Type::NestedObject
+ name: 'scriptRun'
+ description: |
+ Runs commands in a shell.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'script'
+ description: |
+ The shell script to be executed.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'allowedExitCodes'
+ description: |
+ Return codes that indicate that the software installed or updated successfully. Behaviour defaults to [0]
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script is executed directly,
+ which likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::Array
+ name: 'updateSteps'
+ description: |
+ Actions to be taken for updating this recipe. On failure it stops executing steps and does not attempt another update for this recipe.
+ Any steps taken (including partially completed steps) are not rolled back.
+ item_type: !ruby/object:Api::Type::NestedObject
+ properties:
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fileCopy'
+ description: |
+ Copies a file onto the instance.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'destination'
+ description: |
+ The absolute path on the instance to put the file.
+ required: true
+ - !ruby/object:Api::Type::Boolean
+ name: 'overwrite'
+ description: |
+ Whether to allow this step to overwrite existing files.If this is false and the file already exists the file
+ is not overwritten and the step is considered a success. Defaults to false.
+ default_value: false
+ - !ruby/object:Api::Type::String
+ name: 'permissions'
+ description: |
+ Consists of three octal digits which represent, in order, the permissions of the owner, group, and other users
+ for the file (similarly to the numeric mode used in the linux chmod utility). Each digit represents a three bit
+ number with the 4 bit corresponding to the read permissions, the 2 bit corresponds to the write bit, and the one
+ bit corresponds to the execute permission. Default behavior is 755.
+
+ Below are some examples of permissions and their associated values:
+ read, write, and execute: 7 read and execute: 5 read and write: 6 read only: 4
+ - !ruby/object:Api::Type::NestedObject
+ name: 'archiveExtraction'
+ description: |
+ Extracts an archive into the specified directory.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::String
+ name: 'destination'
+ description: |
+ Directory to extract archive to. Defaults to / on Linux or C:\ on Windows.
+ - !ruby/object:Api::Type::Enum
+ name: 'type'
+ description: |
+ The type of the archive to extract.
+ required: true
+ values:
+ - :TAR
+ - :TAR_GZIP
+ - :TAR_BZIP
+ - :TAR_LZMA
+ - :TAR_XZ
+ - :ZIP
+ - !ruby/object:Api::Type::NestedObject
+ name: 'msiInstallation'
+ description: |
+ Installs an MSI file.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'flags'
+ description: |
+ The flags to use when installing the MSI. Defaults to the install flag.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowedExitCodes'
+ description: |
+ Return codes that indicate that the software installed or updated successfully. Behaviour defaults to [0]
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::NestedObject
+ name: 'dpkgInstallation'
+ description: |
+ Installs a deb file via dpkg.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'rpmInstallation'
+ description: |
+ Installs an rpm file via the rpm utility.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ required: true
+ - !ruby/object:Api::Type::NestedObject
+ name: 'fileExec'
+ description: |
+ Executes an artifact or local file.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::Array
+ name: 'args'
+ description: |
+ Arguments to be passed to the provided executable.
+ item_type: Api::Type::String
+ - !ruby/object:Api::Type::Array
+ name: 'allowedExitCodes'
+ description: |
+ A list of possible return values that the program can return to indicate a success. Defaults to [0].
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::String
+ name: 'artifactId'
+ description: |
+ The id of the relevant artifact in the recipe.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ - !ruby/object:Api::Type::String
+ name: 'localPath'
+ description: |
+ The absolute path of the file on the local filesystem.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ - !ruby/object:Api::Type::NestedObject
+ name: 'scriptRun'
+ description: |
+ Runs commands in a shell.
+ # TODO (mbang): add exactly_one_of when it can be applied to lists (https://github.com/hashicorp/terraform-plugin-sdk/issues/470)
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'script'
+ description: |
+ The shell script to be executed.
+ required: true
+ - !ruby/object:Api::Type::Array
+ name: 'allowedExitCodes'
+ description: |
+ Return codes that indicate that the software installed or updated successfully. Behaviour defaults to [0]
+ item_type: Api::Type::Integer
+ - !ruby/object:Api::Type::Enum
+ name: 'interpreter'
+ description: |
+ The script interpreter to use to run the script. If no interpreter is specified the script is executed directly,
+ which likely only succeed for scripts with shebang lines.
+ values:
+ - :SHELL
+ - :POWERSHELL
+ - !ruby/object:Api::Type::Enum
+ name: 'desiredState'
+ description: |
+ Default is INSTALLED. The desired state the agent should maintain for this recipe.
+
+ INSTALLED: The software recipe is installed on the instance but won't be updated to new versions.
+ INSTALLED_KEEP_UPDATED: The software recipe is installed on the instance. The recipe is updated to a higher version,
+ if a higher version of the recipe is assigned to this instance.
+ REMOVE: Remove is unsupported for software recipes and attempts to create or update a recipe to the REMOVE state is rejected.
+ default_value: :INSTALLED
+ values:
+ - :INSTALLED
+ - :UPDATED
+ - :REMOVED
+ - !ruby/object:Api::Type::String
+ name: 'createTime'
+ output: true
+ description: |
+ Time this guest policy was created. A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds.
+ Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'updateTime'
+ output: true
+ description: |
+ Last time this guest policy was updated. A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds.
+ Example: "2014-10-02T15:01:23.045123456Z".
+ - !ruby/object:Api::Type::String
+ name: 'etag'
+ description: |
+ The etag for this guest policy. If this is provided on update, it must match the server's etag.
diff --git a/products/osconfig/terraform.yaml b/products/osconfig/terraform.yaml
new file mode 100644
index 000000000000..913b88b85bd9
--- /dev/null
+++ b/products/osconfig/terraform.yaml
@@ -0,0 +1,120 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ PatchDeployment: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{name}}"
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_patch_deployment_basic"
+ primary_resource_id: "patch"
+ vars:
+ instance_name: "patch-deploy-inst"
+ patch_deployment_id: "patch-deploy"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_patch_deployment_instance"
+ primary_resource_id: "patch"
+ vars:
+ instance_name: "patch-deploy-inst"
+ patch_deployment_id: "patch-deploy"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_patch_deployment_full"
+ primary_resource_id: "patch"
+ vars:
+ instance_name: "patch-deploy-inst"
+ patch_deployment_id: "patch-deploy"
+ properties:
+ patchDeploymentId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))"
+ recurringSchedule.timeOfDay.hours: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0,23)'
+ recurringSchedule.timeOfDay.minutes: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0,59)'
+ recurringSchedule.timeOfDay.seconds: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0,60)'
+ recurringSchedule.timeOfDay.nanos: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0,999999999)'
+ recurringSchedule.monthly.weekDayOfMonth.weekOrdinal: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(-1,4)'
+ recurringSchedule.monthly.monthDay: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(-1,31)'
+ recurringSchedule.frequency: !ruby/object:Overrides::Terraform::PropertyOverride
+ exclude: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ post_create: templates/terraform/post_create/set_computed_name.erb
+ encoder: templates/terraform/encoders/os_config_patch_deployment.go.erb
+ decoder: templates/terraform/decoders/os_config_patch_deployment.go.erb
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
+ GuestPolicies: !ruby/object:Overrides::Terraform::ResourceOverride
+ id_format: "{{name}}"
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_guest_policies_basic"
+ primary_resource_id: "guest_policies"
+ vars:
+ instance_name: "guest-policy-inst"
+ guest_policy_id: "guest-policy"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_guest_policies_packages"
+ primary_resource_id: "guest_policies"
+ vars:
+ guest_policy_id: "guest-policy"
+ - !ruby/object:Provider::Terraform::Examples
+ name: "os_config_guest_policies_recipes"
+ primary_resource_id: "guest_policies"
+ vars:
+ guest_policy_id: "guest-policy"
+ properties:
+ guestPolicyId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))"
+ recipes.installSteps.archiveExtraction.destination: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.installSteps.msiInstallation.flags: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.installSteps.msiInstallation.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.installSteps.fileExec.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.installSteps.scriptRun.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.updateSteps.archiveExtraction.destination: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.updateSteps.msiInstallation.flags: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.updateSteps.msiInstallation.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.updateSteps.fileExec.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ recipes.updateSteps.scriptRun.allowedExitCodes: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ etag: !ruby/object:Overrides::Terraform::PropertyOverride
+ default_from_api: true
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ post_create: templates/terraform/post_create/set_computed_name.erb
+ custom_import: templates/terraform/custom_import/self_link_as_name.erb
+
+# This is for copying files over
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
\ No newline at end of file
diff --git a/products/oslogin/api.yaml b/products/oslogin/api.yaml
index fa028120e485..98c9b674d122 100644
--- a/products/oslogin/api.yaml
+++ b/products/oslogin/api.yaml
@@ -60,6 +60,7 @@ objects:
description: |
Public key text in SSH format, defined by RFC4253 section 6.6.
required: true
+ input: true
- !ruby/object:Api::Type::String
name: 'expirationTimeUsec'
description: |
diff --git a/products/pubsub/terraform.yaml b/products/pubsub/terraform.yaml
index b620ca35159b..ae05af868bf8 100644
--- a/products/pubsub/terraform.yaml
+++ b/products/pubsub/terraform.yaml
@@ -21,7 +21,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
# resource until it exists and the negative cached result goes away.
# Context: terraform-providers/terraform-provider-google#4993
async: !ruby/object:Provider::Terraform::PollAsync
- check_response_func: PollCheckForExistence
+ check_response_func_existence: PollCheckForExistence
actions: ['create']
operation: !ruby/object:Api::Async::Operation
timeouts: !ruby/object:Api::Timeouts
@@ -71,7 +71,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
# resource until it exists and the negative cached result goes away.
# Context: terraform-providers/terraform-provider-google#4993
async: !ruby/object:Provider::Terraform::PollAsync
- check_response_func: PollCheckForExistence
+ check_response_func_existence: PollCheckForExistence
actions: ['create']
operation: !ruby/object:Api::Async::Operation
timeouts: !ruby/object:Api::Timeouts
diff --git a/products/redis/api.yaml b/products/redis/api.yaml
index 52eaa1c7a88b..e9fd2e0a0075 100644
--- a/products/redis/api.yaml
+++ b/products/redis/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: Redis
-display_name: Cloud Memorystore
+display_name: Memorystore (Redis)
versions:
- !ruby/object:Api::Product::Version
name: ga
@@ -81,9 +81,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: connectMode
description: |
- The connection mode of the Redis instance. Can be either
- `DIRECT_PEERING` or `PRIVATE_SERVICE_ACCESS`. The default
- connect mode if not provided is `DIRECT_PEERING`.
+ The connection mode of the Redis instance.
input: true
values:
- :DIRECT_PEERING
diff --git a/products/redis/terraform.yaml b/products/redis/terraform.yaml
index 71a58ca5eabd..f828da1e6c5f 100644
--- a/products/redis/terraform.yaml
+++ b/products/redis/terraform.yaml
@@ -50,6 +50,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
name: !ruby/object:Overrides::Terraform::PropertyOverride
custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb'
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
+ validation: !ruby/object:Provider::Terraform::Validation
+ regex: '^[a-z][a-z0-9-]{0,39}[a-z0-9]$'
redisVersion: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
region: !ruby/object:Overrides::Terraform::PropertyOverride
diff --git a/products/runtimeconfig/api.yaml b/products/runtimeconfig/api.yaml
index 0f8d2ffd8965..4b5e51bacb2b 100644
--- a/products/runtimeconfig/api.yaml
+++ b/products/runtimeconfig/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: RuntimeConfig
-display_name: Cloud Runtime Configuration
+display_name: Runtime Configurator
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/secretmanager/api.yaml b/products/secretmanager/api.yaml
index ca3699c624c9..4ea62d22f78e 100644
--- a/products/secretmanager/api.yaml
+++ b/products/secretmanager/api.yaml
@@ -15,6 +15,9 @@
name: SecretManager
display_name: Secret Manager
versions:
+ - !ruby/object:Api::Product::Version
+ name: ga
+ base_url: https://secretmanager.googleapis.com/v1/
- !ruby/object:Api::Product::Version
name: beta
base_url: https://secretmanager.googleapis.com/v1beta1/
@@ -27,7 +30,6 @@ apis_required:
objects:
- !ruby/object:Api::Resource
name: Secret
- min_version: beta
self_link: projects/{{project}}/secrets/{{secret_id}}
base_url: projects/{{project}}/secrets
create_url: projects/{{project}}/secrets?secretId={{secret_id}}
@@ -37,8 +39,9 @@ objects:
parent_resource_attribute: secret_id
method_name_separator: ':'
exclude: false
+ allowed_iam_role: roles/secretmanager.secretAccessor
references: !ruby/object:Api::Resource::ReferenceLinks
- api: 'https://cloud.google.com/secret-manager/docs/reference/rest/v1beta1/projects.secrets'
+ api: 'https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets'
description: |
A Secret is a logical secret whose value and versions can be accessed.
parameters:
@@ -114,7 +117,6 @@ objects:
The canonical IDs of the location to replicate data. For example: "us-east1".
- !ruby/object:Api::Resource
name: SecretVersion
- min_version: beta
base_url: '{{name}}'
self_link: '{{name}}'
create_url: '{{secret}}:addVersion'
diff --git a/products/secretmanager/terraform.yaml b/products/secretmanager/terraform.yaml
index 5b1a14699bab..4afdb8ff2404 100644
--- a/products/secretmanager/terraform.yaml
+++ b/products/secretmanager/terraform.yaml
@@ -17,8 +17,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "secret_config_basic"
primary_resource_id: "secret-basic"
- primary_resource_name: "fmt.Sprintf(\"tf-test-test-secret-basic%s\", context[\"random_suffix\"])"
- min_version: beta
+ primary_resource_name: "fmt.Sprintf(\"secret%s\", context[\"random_suffix\"])"
vars:
secret_id: "secret"
import_format: ["projects/{{project}}/secrets/{{secret_id}}"]
@@ -28,11 +27,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
custom_expand: templates/terraform/custom_expand/bool_to_object.go.erb
SecretVersion: !ruby/object:Overrides::Terraform::ResourceOverride
+ # Versions will be sweeped by the Secret sweeper
+ skip_sweeper: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "secret_version_basic"
primary_resource_id: "secret-version-basic"
- min_version: beta
vars:
secret_id: "secret-version"
data: "secret-data"
diff --git a/products/securitycenter/api.yaml b/products/securitycenter/api.yaml
index 6ba463bd2a65..67d7dbc891a6 100644
--- a/products/securitycenter/api.yaml
+++ b/products/securitycenter/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: SecurityCenter
-display_name: Cloud Security Command Center
+display_name: Security Command Center (SCC)
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/servicedirectory/api.yaml b/products/servicedirectory/api.yaml
new file mode 100644
index 000000000000..3723d861410b
--- /dev/null
+++ b/products/servicedirectory/api.yaml
@@ -0,0 +1,180 @@
+# Copyright 2020 Google Inc.
+# 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/object:Api::Product
+name: ServiceDirectory
+display_name: Service Directory
+versions:
+ - !ruby/object:Api::Product::Version
+ name: beta
+ base_url: https://servicedirectory.googleapis.com/v1beta1/
+scopes:
+ - https://www.googleapis.com/auth/cloud-platform
+apis_required:
+ - !ruby/object:Api::Product::ApiReference
+ name: Service Directory API
+ url: https://console.cloud.google.com/apis/library/servicedirectory.googleapis.com/
+objects:
+ - !ruby/object:Api::Resource
+ name: 'Namespace'
+ base_url: '{{name}}'
+ create_url: 'projects/{{project}}/locations/{{location}}/namespaces?namespaceId={{namespace_id}}'
+ self_link: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Configuring a namespace': 'https://cloud.google.com/service-directory/docs/configuring-service-directory#configuring_a_namespace'
+ api: 'https://cloud.google.com/service-directory/docs/reference/rest/v1beta1/projects.locations.namespaces'
+ iam_policy: !ruby/object:Api::Resource::IamPolicy
+ exclude: false
+ parent_resource_attribute: 'name'
+ method_name_separator: ':'
+ fetch_iam_policy_verb: :POST
+ set_iam_policy_verb: :POST
+ min_version: beta
+ description: |
+ A container for `services`. Namespaces allow administrators to group services
+ together and define permissions for a collection of services.
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'location'
+ description: |
+ The location for the Namespace.
+ A full list of valid locations can be found by running
+ `gcloud beta service-directory locations list`.
+ required: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: namespaceId
+ description: |
+ The Resource ID must be 1-63 characters long, including digits,
+ lowercase letters or the hyphen character.
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource name for the namespace
+ in the format `projects/*/locations/*/namespaces/*`.
+ output: true
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Resource labels associated with this Namespace. No more than 64 user
+ labels can be associated with a given resource. Label keys and values can
+ be no longer than 63 characters.
+ - !ruby/object:Api::Resource
+ name: 'Service'
+ base_url: '{{name}}'
+ create_url: '{{namespace}}/services?serviceId={{service_id}}'
+ self_link: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Configuring a service': 'https://cloud.google.com/service-directory/docs/configuring-service-directory#configuring_a_service'
+ api: 'https://cloud.google.com/service-directory/docs/reference/rest/v1beta1/projects.locations.namespaces.services'
+ iam_policy: !ruby/object:Api::Resource::IamPolicy
+ exclude: false
+ parent_resource_attribute: 'name'
+ method_name_separator: ':'
+ fetch_iam_policy_verb: :POST
+ set_iam_policy_verb: :POST
+ min_version: beta
+ description: |
+ An individual service. A service contains a name and optional metadata.
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'namespace'
+ description: |
+ The resource name of the namespace this service will belong to.
+ required: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: serviceId
+ description: |
+ The Resource ID must be 1-63 characters long, including digits,
+ lowercase letters or the hyphen character.
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource name for the service in the
+ format `projects/*/locations/*/namespaces/*/services/*`.
+ output: true
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ Metadata for the service. This data can be consumed
+ by service clients. The entire metadata dictionary may contain
+ up to 2000 characters, spread across all key-value pairs.
+ Metadata that goes beyond any these limits will be rejected.
+ - !ruby/object:Api::Resource
+ name: 'Endpoint'
+ base_url: '{{name}}'
+ create_url: '{{service}}/endpoints?endpointId={{endpoint_id}}'
+ self_link: '{{name}}'
+ update_verb: :PATCH
+ update_mask: true
+ references: !ruby/object:Api::Resource::ReferenceLinks
+ guides:
+ 'Configuring an endpoint': 'https://cloud.google.com/service-directory/docs/configuring-service-directory#configuring_an_endpoint'
+ api: 'https://cloud.google.com/service-directory/docs/reference/rest/v1beta1/projects.locations.namespaces.services.endpoints'
+ min_version: beta
+ description: |
+ An individual endpoint that provides a service.
+ parameters:
+ - !ruby/object:Api::Type::String
+ name: 'service'
+ description: |
+ The resource name of the service that this endpoint provides.
+ required: true
+ url_param_only: true
+ - !ruby/object:Api::Type::String
+ name: endpointId
+ description: |
+ The Resource ID must be 1-63 characters long, including digits,
+ lowercase letters or the hyphen character.
+ required: true
+ input: true
+ url_param_only: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'name'
+ description: |
+ The resource name for the endpoint in the format
+ `projects/*/locations/*/namespaces/*/services/*/endpoints/*`.
+ output: true
+ - !ruby/object:Api::Type::String
+ name: 'address'
+ description: |
+ IPv4 or IPv6 address of the endpoint.
+ - !ruby/object:Api::Type::Integer
+ name: 'port'
+ description: |
+ Port that the endpoint is running on, must be in the
+ range of [0, 65535]. If unspecified, the default is 0.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'metadata'
+ description: |
+ Metadata for the endpoint. This data can be consumed
+ by service clients. The entire metadata dictionary may contain
+ up to 512 characters, spread across all key-value pairs.
+ Metadata that goes beyond any these limits will be rejected.
+
diff --git a/products/servicedirectory/terraform.yaml b/products/servicedirectory/terraform.yaml
new file mode 100644
index 000000000000..343b1d128ee8
--- /dev/null
+++ b/products/servicedirectory/terraform.yaml
@@ -0,0 +1,80 @@
+# Copyright 2020 Google Inc.
+# 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/object:Provider::Terraform::Config
+overrides: !ruby/object:Overrides::ResourceOverrides
+ Namespace: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "service_directory_namespace_basic"
+ primary_resource_id: "example"
+ vars:
+ namespace_id: "example-namespace"
+ min_version: beta
+ properties:
+ location: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ namespaceId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateRFC1035Name(2, 63)'
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/service_directory_namespace.go.erb
+ Service: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "service_directory_service_basic"
+ primary_resource_id: "example"
+ vars:
+ service_id: "example-service"
+ namespace_id: "example-namespace"
+ min_version: beta
+ properties:
+ namespace: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ serviceId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateRFC1035Name(2, 63)'
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/service_directory_service.go.erb
+ Endpoint: !ruby/object:Overrides::Terraform::ResourceOverride
+ import_format: ["projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}/endpoints/{{endpoint_id}}"]
+ examples:
+ - !ruby/object:Provider::Terraform::Examples
+ name: "service_directory_endpoint_basic"
+ primary_resource_id: "example"
+ vars:
+ service_id: "example-service"
+ namespace_id: "example-namespace"
+ endpoint_id: "example-endpoint"
+ min_version: beta
+ properties:
+ service: !ruby/object:Overrides::Terraform::PropertyOverride
+ ignore_read: true
+ endpointId: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateRFC1035Name(2, 63)'
+ address: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validateIpAddress'
+ port: !ruby/object:Overrides::Terraform::PropertyOverride
+ validation: !ruby/object:Provider::Terraform::Validation
+ function: 'validation.IntBetween(0, 65535)'
+ custom_code: !ruby/object:Provider::Terraform::CustomCode
+ custom_import: templates/terraform/custom_import/service_directory_endpoint.go.erb
+files: !ruby/object:Provider::Config::Files
+ # These files have templating (ERB) code that will be run.
+ # This is usually to add licensing info, autogeneration notices, etc.
+ compile:
+<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
diff --git a/products/servicemanagement/api.yaml b/products/servicemanagement/api.yaml
index 9b170d21aeb9..a214d516478f 100644
--- a/products/servicemanagement/api.yaml
+++ b/products/servicemanagement/api.yaml
@@ -13,7 +13,7 @@
--- !ruby/object:Api::Product
name: ServiceManagement
-display_name: Service Management
+display_name: Cloud Endpoints
versions:
- !ruby/object:Api::Product::Version
name: ga
diff --git a/products/sourcerepo/terraform.yaml b/products/sourcerepo/terraform.yaml
index 688c25f64cb7..31aa0f98a20a 100644
--- a/products/sourcerepo/terraform.yaml
+++ b/products/sourcerepo/terraform.yaml
@@ -49,9 +49,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides
A Cloud Pub/Sub topic in this repo's project. Values are of the form
`projects//topics/` or `` (where the topic will
be inferred).
+ set_hash_func: 'resourceSourceRepoRepositoryPubSubConfigsHash'
pubsubConfigs.serviceAccountEmail: !ruby/object:Overrides::Terraform::PropertyOverride
default_from_api: true
custom_code: !ruby/object:Provider::Terraform::CustomCode
+ constants: templates/terraform/constants/source_repo_repository.go.erb
update_encoder: templates/terraform/update_encoder/source_repo_repository.erb
post_create: templates/terraform/post_create/source_repo_repository_update.go.erb
# This is for copying files over
diff --git a/products/spanner/terraform.yaml b/products/spanner/terraform.yaml
index 53438b2a8f1a..73e9f7bbe016 100644
--- a/products/spanner/terraform.yaml
+++ b/products/spanner/terraform.yaml
@@ -17,6 +17,7 @@ overrides: !ruby/object:Overrides::ResourceOverrides
autogen_async: true
# This resource is a child resource
skip_sweeper: true
+ id_format: "{{instance}}/{{name}}"
import_format:
- "projects/{{project}}/instances/{{instance}}/databases/{{name}}"
- "instances/{{instance}}/databases/{{name}}"
@@ -26,6 +27,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "spanner_database_basic"
primary_resource_id: "database"
+ # Randomness due to spanner instance
+ skip_vcr: true
vars:
database_name: "my-database"
properties:
@@ -55,6 +58,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "spanner_instance_basic"
primary_resource_id: "example"
+ # Randomness
+ skip_vcr: true
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
description: |
diff --git a/products/sql/api.yaml b/products/sql/api.yaml
index ae6d8420ffea..222e4f7f9353 100644
--- a/products/sql/api.yaml
+++ b/products/sql/api.yaml
@@ -395,6 +395,10 @@ objects:
update method to make sure concurrent updates are handled properly.
During update, use the most recent settingsVersion value for this
instance and do not try to update this value.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'userLabels'
+ description: |
+ User-provided labels, represented as a dictionary where each label is a single key value pair.
- !ruby/object:Api::Type::String
name: 'gceZone'
output: true
@@ -415,6 +419,50 @@ objects:
- :PENDING_CREATE
- :MAINTENANCE
- :FAILED
+ - !ruby/object:Api::Type::NestedObject
+ name: 'diskEncryptionConfiguration'
+ description: 'Disk encyption settings'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyName'
+ description: |
+ The KMS key used to encrypt the Cloud SQL instance
+ - !ruby/object:Api::Type::NestedObject
+ name: 'diskEncryptionStatus'
+ description: 'Disk encyption status'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'kmsKeyVersionName'
+ description: |
+ The KMS key version used to encrypt the Cloud SQL instance
+ - !ruby/object:Api::Type::NestedObject
+ name: 'serverCaCert'
+ description: 'SSL configuration'
+ output: true
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'cert'
+ description: 'PEM representation of the X.509 certificate.'
+ - !ruby/object:Api::Type::String
+ name: 'certSerialNumber'
+ description: 'Serial number, as extracted from the certificate.'
+ - !ruby/object:Api::Type::String
+ name: 'commonName'
+ description: 'User supplied name. Constrained to [a-zA-Z.-_ ]+.'
+ - !ruby/object:Api::Type::Time
+ name: 'createTime'
+ description: |
+ The time when the certificate was created in RFC 3339 format, for
+ example 2012-11-15T16:19:00.094Z.
+ - !ruby/object:Api::Type::Time
+ name: 'expirationTime'
+ description: |
+ The time when the certificate expires in RFC 3339 format, for example
+ 2012-11-15T16:19:00.094Z.
+ - !ruby/object:Api::Type::String
+ name: 'sha1Fingerprint'
+ description: |
+ SHA-1 fingerprint of the certificate.
- !ruby/object:Api::Resource
name: 'Database'
kind: 'sql#database'
@@ -654,7 +702,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'databaseVersion'
description: |
- The MySQL version running on your source database server: MYSQL_5_6 or MYSQL_5_7.
+ The MySQL version running on your source database server.
required: true
values:
- :MYSQL_5_6
diff --git a/products/sql/terraform.yaml b/products/sql/terraform.yaml
index 9d64768e49be..e0cac2542390 100644
--- a/products/sql/terraform.yaml
+++ b/products/sql/terraform.yaml
@@ -16,6 +16,7 @@ client_name: 'SqlAdmin'
overrides: !ruby/object:Overrides::ResourceOverrides
Database: !ruby/object:Overrides::Terraform::ResourceOverride
mutex: "google-sql-database-instance-{{project}}-{{instance}}"
+ read_error_transform: "transformSQLDatabaseReadError"
import_format: ["projects/{{project}}/instances/{{instance}}/databases/{{name}}",
"{{project}}/{{instance}}/{{name}}",
"instances/{{instance}}/databases/{{name}}",
diff --git a/products/storage/ansible.yaml b/products/storage/ansible.yaml
index f8b4b6400267..976c6561aa92 100644
--- a/products/storage/ansible.yaml
+++ b/products/storage/ansible.yaml
@@ -25,6 +25,12 @@ datasources: !ruby/object:Overrides::ResourceOverrides
Object: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
overrides: !ruby/object:Overrides::ResourceOverrides
+ Bucket: !ruby/object:Overrides::Ansible::ResourceOverride
+ properties:
+ retentionPolicy: !ruby/object:Overrides::Ansible::PropertyOverride
+ exclude: true
+ encryption: !ruby/object:Overrides::Ansible::PropertyOverride
+ exclude: true
ObjectAccessControl: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
Object: !ruby/object:Overrides::Ansible::ResourceOverride
diff --git a/products/storage/api.yaml b/products/storage/api.yaml
index ab50fcc12258..b52ac786a957 100644
--- a/products/storage/api.yaml
+++ b/products/storage/api.yaml
@@ -407,6 +407,39 @@ objects:
object is missing, if applicable, the service will return the
named object from this bucket as the content for a 404 Not Found
result.
+ - !ruby/object:Api::Type::KeyValuePairs
+ name: 'labels'
+ description: |
+ Labels applied to this bucket. A list of key->value pairs.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'encryption'
+ description: |
+ Encryption configuration for the bucket
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'defaultKmsKeyName'
+ description: |
+ A Cloud KMS key that will be used to encrypt objects inserted into this bucket,
+ if no encryption method is specified.
+ - !ruby/object:Api::Type::NestedObject
+ name: 'retentionPolicy'
+ description: |
+ Retention policy for the bucket
+ properties:
+ - !ruby/object:Api::Type::Time
+ name: 'effectiveTime'
+ description: |
+ The time from which the retention policy was effective
+ - !ruby/object:Api::Type::Boolean
+ name: 'isLocked'
+ description: |
+ If the retention policy is locked. If true, the retention policy cannot be removed and the period cannot
+ be reduced.
+ - !ruby/object:Api::Type::Integer
+ name: 'retentionPeriod'
+ description: |
+ The period of time, in seconds, that objects in the bucket must be retained and cannot be deleted,
+ overwritten, or made noncurrent.
parameters:
- !ruby/object:Api::Type::String
name: 'project'
@@ -438,10 +471,6 @@ objects:
- :projectPrivate
- :publicRead
input: true
- - !ruby/object:Api::Type::KeyValuePairs
- name: 'labels'
- description: |
- Labels applied to this bucket. A list of key->value pairs.
- !ruby/object:Api::Resource
name: 'BucketAccessControl'
kind: 'storage#bucketAccessControl'
diff --git a/products/storage/terraform.yaml b/products/storage/terraform.yaml
index af92aaa18cf1..56fd4bfe903d 100644
--- a/products/storage/terraform.yaml
+++ b/products/storage/terraform.yaml
@@ -15,6 +15,7 @@
overrides: !ruby/object:Overrides::ResourceOverrides
Bucket: !ruby/object:Overrides::Terraform::ResourceOverride
exclude_resource: true
+ error_retry_predicates: ["isStoragePreconditionError"]
import_format: ["{{name}}"]
examples:
- !ruby/object:Provider::Terraform::Examples
diff --git a/provider/ansible.rb b/provider/ansible.rb
index 32b40ff46175..a15208919545 100644
--- a/provider/ansible.rb
+++ b/provider/ansible.rb
@@ -94,7 +94,7 @@ def module_name(object)
object.name.underscore].join('_')
end
- def build_object_data(object, output_folder, version)
+ def build_object_data(pwd, object, output_folder, version)
# Method is overridden to add Ansible example objects to the data object.
data = AnsibleProductFileTemplate.file_for_resource(
output_folder,
@@ -105,7 +105,7 @@ def build_object_data(object, output_folder, version)
)
prod_name = data.object.name.underscore
- path = ["products/#{data.product.api_name}",
+ path = [pwd + "/products/#{data.product.api_name}",
"examples/ansible/#{prod_name}.yaml"].join('/')
data.example = get_example(path) if File.file?(path)
@@ -233,19 +233,20 @@ def get_example(cfg_file)
ex
end
- def generate_resource(data)
+ def generate_resource(pwd, data)
target_folder = data.output_folder
name = module_name(data.object)
path = File.join(target_folder,
"plugins/modules/#{name}.py")
data.generate(
+ pwd,
data.object.template || 'templates/ansible/resource.erb',
path,
self
)
end
- def generate_resource_tests(data)
+ def generate_resource_tests(pwd, data)
prod_name = data.object.name.underscore
path = ["products/#{data.product.api_name}",
"examples/ansible/#{prod_name}.yaml"].join('/')
@@ -260,6 +261,7 @@ def generate_resource_tests(data)
path = File.join(target_folder,
"tests/integration/targets/#{name}/tasks/main.yml")
data.generate(
+ pwd,
'templates/ansible/tests_main.erb',
path,
self
@@ -270,6 +272,7 @@ def generate_resource_tests(data)
path = File.join(target_folder,
"tests/integration/targets/#{name}/tasks/#{t.name}.yml")
data.generate(
+ pwd,
t.path,
path,
self
@@ -280,20 +283,22 @@ def generate_resource_tests(data)
path = File.join(target_folder,
"tests/integration/targets/#{name}/defaults/main.yml")
data.generate(
+ pwd,
'templates/ansible/integration_test_variables.erb',
path,
self
)
end
- def generate_resource_sweepers(data)
+ def generate_resource_sweepers(pwd, data)
# No generated sweepers for this provider
end
- def compile_datasource(data)
+ def compile_datasource(pwd, data)
target_folder = data.output_folder
name = module_name(data.object)
- data.generate('templates/ansible/facts.erb',
+ data.generate(pwd,
+ 'templates/ansible/facts.erb',
File.join(target_folder,
"plugins/modules/#{name}_info.py"),
self)
@@ -344,7 +349,7 @@ def regex_url(url)
# Generates files on a per-resource basis.
# All paths are allowed a '%s' where the module name
# will be added.
- def generate_resource_files(data)
+ def generate_resource_files(pwd, data)
return unless @config&.files&.resource
files = @config.files.resource
@@ -358,7 +363,7 @@ def generate_resource_files(data)
data.version,
build_env
)
- compile_file_list(data.output_folder, files, file_template)
+ compile_file_list(data.output_folder, files, file_template, pwd)
end
def copy_common_files(output_folder, provider_name = 'ansible')
diff --git a/provider/ansible/example.rb b/provider/ansible/example.rb
index 6591304402a2..83fc317937e6 100644
--- a/provider/ansible/example.rb
+++ b/provider/ansible/example.rb
@@ -229,7 +229,7 @@ class NoVerifier < Verifier
attr_reader :reason
def validate() end
- def build_task(_state, _object)
+ def build_task(_state, _object, _pwd)
''
end
end
@@ -262,9 +262,9 @@ def validate
true
end
- def build_task(_state, object)
+ def build_task(_state, object, pwd)
@parameters = build_parameters(object)
- compile 'templates/ansible/verifiers/facts.yaml.erb'
+ compile(pwd + '/templates/ansible/verifiers/facts.yaml.erb')
end
private
diff --git a/provider/ansible_devel.rb b/provider/ansible_devel.rb
index 08d745a0fba6..51a3a5ae692b 100644
--- a/provider/ansible_devel.rb
+++ b/provider/ansible_devel.rb
@@ -34,22 +34,24 @@ def module_utils_import_path
'ansible.module_utils.gcp_utils'
end
- def generate_resource(data)
+ def generate_resource(pwd, data)
target_folder = data.output_folder
name = module_name(data.object)
path = File.join(target_folder,
"lib/ansible/modules/cloud/google/#{name}.py")
data.generate(
+ pwd,
data.object.template || 'templates/ansible/resource.erb',
path,
self
)
end
- def compile_datasource(data)
+ def compile_datasource(pwd, data)
target_folder = data.output_folder
name = module_name(data.object)
- data.generate('templates/ansible/facts.erb',
+ data.generate(pwd,
+ 'templates/ansible/facts.erb',
File.join(target_folder,
"lib/ansible/modules/cloud/google/#{name}_info.py"),
self)
@@ -64,7 +66,7 @@ def compile_datasource(data)
File.symlink "#{name}_info.py", deprecated_facts_path
end
- def generate_resource_tests(data)
+ def generate_resource_tests(pwd, data)
prod_name = data.object.name.underscore
path = ["products/#{data.product.api_name}",
"examples/ansible/#{prod_name}.yaml"].join('/')
@@ -79,6 +81,7 @@ def generate_resource_tests(data)
path = File.join(target_folder,
"test/integration/targets/#{name}/tasks/main.yml")
data.generate(
+ pwd,
'templates/ansible/tests_main.erb',
path,
self
@@ -89,6 +92,7 @@ def generate_resource_tests(data)
path = File.join(target_folder,
"test/integration/targets/#{name}/tasks/#{t.name}.yml")
data.generate(
+ pwd,
t.path,
path,
self
@@ -96,7 +100,7 @@ def generate_resource_tests(data)
end
end
- def generate_resource_sweepers(data) end
+ def generate_resource_sweepers(pwd, data) end
def compile_common_files(_arg1, _arg2, _arg3) end
@@ -115,7 +119,7 @@ def copy_common_files(output_folder, provider_name = nil)
copy_file_list(output_folder, files)
end
- def generate_resource_files(data)
+ def generate_resource_files(pwd, data)
return unless @config&.files&.resource
files = @config.files.resource
@@ -132,7 +136,7 @@ def generate_resource_files(data)
data.version,
build_env
)
- compile_file_list(data.output_folder, files, file_template)
+ compile_file_list(data.output_folder, files, file_template, pwd)
end
end
end
diff --git a/provider/core.rb b/provider/core.rb
index e43a5bf29fe6..a9d4361b6317 100644
--- a/provider/core.rb
+++ b/provider/core.rb
@@ -89,10 +89,14 @@ def generate(output_folder, types, product_path, dump_yaml)
compile_product_files(output_folder) \
unless @config.files.nil? || @config.files.compile.nil?
- generate_datasources(output_folder, types) \
+ FileUtils.mkpath output_folder unless Dir.exist?(output_folder)
+ pwd = Dir.pwd
+ Dir.chdir output_folder
+ generate_datasources(pwd, output_folder, types) \
unless @config.datasources.nil?
- generate_operation(output_folder, types)
+ generate_operation(pwd, output_folder, types)
+ Dir.chdir pwd
# Write a file with the final version of the api, after overrides
# have been applied.
@@ -107,7 +111,7 @@ def generate(output_folder, types, product_path, dump_yaml)
end
end
- def generate_operation(output_folder, types); end
+ def generate_operation(pwd, output_folder, types); end
def copy_files(output_folder)
copy_file_list(output_folder, @config.files.copy)
@@ -181,14 +185,16 @@ def compile_common_files(
compile_file_list(output_folder, files, file_template)
end
- def compile_file_list(output_folder, files, file_template)
+ def compile_file_list(output_folder, files, file_template, pwd = Dir.pwd)
+ FileUtils.mkpath output_folder unless Dir.exist?(output_folder)
+ Dir.chdir output_folder
files.map do |target, source|
Thread.new do
Google::LOGGER.debug "Compiling #{source} => #{target}"
- target_file = File.join(output_folder, target)
- file_template.generate(source, target_file, self)
+ file_template.generate(pwd, source, target, self)
end
end.map(&:join)
+ Dir.chdir pwd
end
def generate_objects(output_folder, types)
@@ -215,27 +221,34 @@ def generate_objects(output_folder, types)
end
def generate_object(object, output_folder, version_name)
- data = build_object_data(object, output_folder, version_name)
+ pwd = Dir.pwd
+ data = build_object_data(pwd, object, output_folder, version_name)
unless object.exclude_resource
+ FileUtils.mkpath output_folder unless Dir.exist?(output_folder)
+ Dir.chdir output_folder
Google::LOGGER.debug "Generating #{object.name} resource"
- generate_resource data.clone
+ generate_resource(pwd, data.clone)
Google::LOGGER.debug "Generating #{object.name} tests"
- generate_resource_tests data.clone
- generate_resource_sweepers data.clone
- generate_resource_files data.clone
+ generate_resource_tests(pwd, data.clone)
+ generate_resource_sweepers(pwd, data.clone)
+ generate_resource_files(pwd, data.clone)
+ Dir.chdir pwd
end
# if iam_policy is not defined or excluded, don't generate it
return if object.iam_policy.nil? || object.iam_policy.exclude
+ FileUtils.mkpath output_folder unless Dir.exist?(output_folder)
+ Dir.chdir output_folder
Google::LOGGER.debug "Generating #{object.name} IAM policy"
- generate_iam_policy data.clone
+ generate_iam_policy(pwd, data.clone)
+ Dir.chdir pwd
end
# Generate files at a per-resource basis.
- def generate_resource_files(data) end
+ def generate_resource_files(pwd, data) end
- def generate_datasources(output_folder, types)
+ def generate_datasources(pwd, output_folder, types)
# We need to apply overrides for datasources
@api = Overrides::Runner.build(@api, @config.datasources,
@config.resource_override,
@@ -257,18 +270,18 @@ def generate_datasources(output_folder, types)
"Excluding #{object.name} datasource per API version"
)
else
- generate_datasource object, output_folder
+ generate_datasource(pwd, object, output_folder)
end
end
end
- def generate_datasource(object, output_folder)
- data = build_object_data(object, output_folder, @target_version_name)
+ def generate_datasource(pwd, object, output_folder)
+ data = build_object_data(pwd, object, output_folder, @target_version_name)
- compile_datasource data.clone
+ compile_datasource(pwd, data.clone)
end
- def build_object_data(object, output_folder, version)
+ def build_object_data(_pwd, object, output_folder, version)
ProductFileTemplate.file_for_resource(output_folder, object, version, @config, build_env)
end
@@ -329,7 +342,7 @@ def update_uri(resource, url_part)
url_part
end
- def generate_iam_policy(data) end
+ def generate_iam_policy(pwd, data) end
# TODO(nelsonjr): Review all object interfaces and move to private methods
# that should not be exposed outside the object hierarchy.
diff --git a/provider/file_template.rb b/provider/file_template.rb
index 1694ca9a511a..5831be9aca0f 100644
--- a/provider/file_template.rb
+++ b/provider/file_template.rb
@@ -35,10 +35,7 @@ class FileTemplate
#
# Once the file's contents are written, set the proper [chmod] mode and
# format the file with a language-appropriate formatter.
- def generate(template, path, provider)
- folder = File.dirname(path)
- FileUtils.mkpath folder unless Dir.exist?(folder)
-
+ def generate(pwd, template, path, provider)
# If we've modified a file since starting an MM run, it's a reasonable
# assumption that it was this run that modified it.
if File.exist?(path) && File.mtime(path) > @env[:start_time]
@@ -58,17 +55,19 @@ def generate(template, path, provider)
end
# This variable is used in ansible/resource.erb
- ctx.local_variable_set('file_relative', relative_path(path, @output_folder).to_s)
+ ctx.local_variable_set('file_relative',
+ relative_path(@output_folder + '/' + path, @output_folder).to_s)
+ ctx.local_variable_set('pwd', pwd)
Google::LOGGER.debug "Generating #{path}"
- File.open(path, 'w') { |f| f.puts compile_file(ctx, template) }
+ File.open(path, 'w') { |f| f.puts compile_file(ctx, pwd + '/' + template) }
# Files are often generated in parallel.
# We can use thread-local variables to ensure that autogen checking
# stays specific to the file each thred represents.
raise "#{path} missing autogen" unless Thread.current[:autogen]
- old_file_chmod_mode = File.stat(template).mode
+ old_file_chmod_mode = File.stat(pwd + '/' + template).mode
FileUtils.chmod(old_file_chmod_mode, path)
format_output_file(path)
diff --git a/provider/inspec.rb b/provider/inspec.rb
index 00fe1a5a0c26..e6eab888dc68 100644
--- a/provider/inspec.rb
+++ b/provider/inspec.rb
@@ -61,36 +61,39 @@ class NestedObjectProductFileTemplate < Provider::ProductFileTemplate
# This function uses the resource templates to create singular and plural
# resources that can be used by InSpec
- def generate_resource(data)
+ def generate_resource(pwd, data)
target_folder = File.join(data.output_folder, 'libraries')
name = data.object.name.underscore
data.generate(
+ pwd,
'templates/inspec/singular_resource.erb',
File.join(target_folder, "#{resource_name(data.object, data.product)}.rb"),
self
)
- generate_documentation(data.clone, name, false)
+ generate_documentation(pwd, data.clone, name, false)
unless data.object.singular_only
data.generate(
+ pwd,
'templates/inspec/plural_resource.erb',
File.join(target_folder, resource_name(data.object, data.product).pluralize + '.rb'),
self
)
- generate_documentation(data.clone, name, true)
+ generate_documentation(pwd, data.clone, name, true)
end
- generate_properties(data.clone, data.object.all_user_properties)
+ generate_properties(pwd, data.clone, data.object.all_user_properties)
end
# Generate the IAM policy for this object. This is used to query and test
# IAM policies separately from the resource itself
- def generate_iam_policy(data)
+ def generate_iam_policy(pwd, data)
target_folder = File.join(data.output_folder, 'libraries')
iam_policy_resource_name = "#{resource_name(data.object, data.product)}_iam_policy"
data.generate(
+ pwd,
'templates/inspec/iam_policy/iam_policy.erb',
File.join(target_folder, "#{iam_policy_resource_name}.rb"),
self
@@ -98,21 +101,23 @@ def generate_iam_policy(data)
markdown_target_folder = File.join(data.output_folder, 'docs/resources')
data.generate(
+ pwd,
'templates/inspec/iam_policy/iam_policy.md.erb',
File.join(markdown_target_folder, "#{iam_policy_resource_name}.md"),
self
)
- generate_iam_binding(data)
+ generate_iam_binding(pwd, data)
end
# Generate the IAM binding for this object. This is used to query and test
# IAM bindings in a more convienient way than using the IAM policy resource
- def generate_iam_binding(data)
+ def generate_iam_binding(pwd, data)
target_folder = File.join(data.output_folder, 'libraries')
iam_binding_resource_name = "#{resource_name(data.object, data.product)}_iam_binding"
data.generate(
+ pwd,
'templates/inspec/iam_binding/iam_binding.erb',
File.join(target_folder, "#{iam_binding_resource_name}.rb"),
self
@@ -120,25 +125,26 @@ def generate_iam_binding(data)
markdown_target_folder = File.join(data.output_folder, 'docs/resources')
data.generate(
+ pwd,
'templates/inspec/iam_binding/iam_binding.md.erb',
File.join(markdown_target_folder, "#{iam_binding_resource_name}.md"),
self
)
end
- def generate_properties(data, props)
+ def generate_properties(pwd, data, props)
nested_objects = props.select(&:nested_properties?)
return if nested_objects.empty?
# Create property files for any nested objects.
- generate_property_files(nested_objects, data)
+ generate_property_files(pwd, nested_objects, data)
# Create property files for any deeper nested objects.
- nested_objects.each { |prop| generate_properties(data, prop.nested_properties) }
+ nested_objects.each { |prop| generate_properties(pwd, data, prop.nested_properties) }
end
# Generate the files for the properties
- def generate_property_files(properties, data)
+ def generate_property_files(pwd, properties, data)
properties.flatten.compact.each do |property|
nested_object_template = NestedObjectProductFileTemplate.new(
data.output_folder,
@@ -153,11 +159,11 @@ def generate_property_files(properties, data)
nested_object_template.output_folder,
"libraries/#{nested_object_requires(property)}.rb"
)
- nested_object_template.generate(source, target, self)
+ nested_object_template.generate(pwd, source, target, self)
end
end
- def build_object_data(object, output_folder, version)
+ def build_object_data(_pwd, object, output_folder, version)
InspecProductFileTemplate.file_for_resource(
output_folder,
object,
@@ -168,7 +174,7 @@ def build_object_data(object, output_folder, version)
end
# Generates InSpec markdown documents for the resource
- def generate_documentation(data, base_name, plural)
+ def generate_documentation(pwd, data, base_name, plural)
docs_folder = File.join(data.output_folder, 'docs', 'resources')
name = plural ? base_name.pluralize : base_name
@@ -179,6 +185,7 @@ def generate_documentation(data, base_name, plural)
file_name = resource_name(data.object, data.product)
file_name = file_name.pluralize if plural
data.generate(
+ pwd,
'templates/inspec/doc_template.md.erb',
File.join(docs_folder, "#{file_name}.md"),
self
@@ -193,28 +200,29 @@ def format_url(url)
end
# Copies InSpec tests to build folder
- def generate_resource_tests(data)
+ def generate_resource_tests(pwd, data)
target_folder = File.join(data.output_folder, 'test')
FileUtils.mkpath target_folder
- FileUtils.cp_r 'templates/inspec/tests/.', target_folder
+ FileUtils.cp_r pwd + '/templates/inspec/tests/.', target_folder
name = resource_name(data.object, data.product)
- generate_inspec_test(data.clone, name, target_folder, name)
+ generate_inspec_test(pwd, data.clone, name, target_folder, name)
# Build test for plural resource
- generate_inspec_test(data.clone, name.pluralize, target_folder, name)\
+ generate_inspec_test(pwd, data.clone, name.pluralize, target_folder, name)\
unless data.object.singular_only
end
- def generate_inspec_test(data, name, target_folder, attribute_file_name)
+ def generate_inspec_test(pwd, data, name, target_folder, attribute_file_name)
data.name = name
data.attribute_file_name = attribute_file_name
data.doc_generation = false
data.privileged = data.object.privileged
data.generate(
+ pwd,
'templates/inspec/integration_test_template.erb',
File.join(
target_folder,
@@ -225,7 +233,7 @@ def generate_inspec_test(data, name, target_folder, attribute_file_name)
)
end
- def generate_resource_sweepers(data)
+ def generate_resource_sweepers(pwd, data)
# No generated sweepers for this provider
end
@@ -306,22 +314,26 @@ def markdown_format(property, indent = 1)
description_arr += property.item_type.properties.map\
{ |prop| markdown_format(prop, indent + 1) }
description = description_arr.join("\n\n")
+ elsif property.is_a?(Api::Type::Enum)
+ description_arr = [description, "#{' ' * indent}Possible values:"]
+ description_arr += property.values.map { |v| "#{' ' * (indent + 1)}* #{v}" }
+ description = description_arr.join("\n")
end
description
end
- def grab_attributes
- YAML.load_file('templates/inspec/tests/integration/configuration/mm-attributes.yml')
+ def grab_attributes(pwd)
+ YAML.load_file(pwd + '/templates/inspec/tests/integration/configuration/mm-attributes.yml')
end
# Returns a variable name OR default value for that variable based on
# defaults from the existing inspec-gcp tests that do not exist within MM
# Default values are used within documentation to show realistic examples
- def external_attribute(attribute_name, doc_generation = false)
+ def external_attribute(pwd, attribute_name, doc_generation = false)
return attribute_name unless doc_generation
external_attribute_file = 'templates/inspec/examples/attributes/external_attributes.yml'
- "'#{YAML.load_file(external_attribute_file)[attribute_name]}'"
+ "'#{YAML.load_file(pwd + '/' + external_attribute_file)[attribute_name]}'"
end
def qualified_property_class(property)
@@ -381,8 +393,11 @@ def beta_api_url(object)
end
def ga_api_url(object)
- ga_version = object.__product.version_obj_or_closest('ga')
- object.product_url || ga_version.base_url
+ if object.__product.exists_at_version('ga')
+ ga_version = object.__product.version_obj_or_closest('ga')
+ return object.product_url || ga_version.base_url
+ end
+ beta_api_url(object)
end
end
end
diff --git a/provider/terraform.rb b/provider/terraform.rb
index e694501f30ff..671c9466b461 100644
--- a/provider/terraform.rb
+++ b/provider/terraform.rb
@@ -1,4 +1,4 @@
-# Copyright 2017 Google Inc.
+# Copyright 2020 Google Inc.
# 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
@@ -100,23 +100,48 @@ def force_new?(property, resource)
force_new?(property.parent, resource))))
end
- # Returns the property for a given Terraform field path (e.g.
+ # Returns tuples of (fieldName, list of update masks) for
+ # top-level updatable fields. Schema path refers to a given Terraform
+ # field name (e.g. d.GetChange('fieldName)')
+ def get_property_update_masks_groups(properties, mask_prefix: '')
+ mask_groups = []
+ properties.each do |prop|
+ if prop.flatten_object
+ mask_groups += get_property_update_masks_groups(
+ prop.properties, mask_prefix: "#{prop.api_name}."
+ )
+ elsif prop.update_mask_fields
+ mask_groups << [prop.name.underscore, prop.update_mask_fields]
+ else
+ mask_groups << [prop.name.underscore, [mask_prefix + prop.api_name]]
+ end
+ end
+ mask_groups
+ end
+
+ # Returns an updated path for a given Terraform field path (e.g.
# 'a_field', 'parent_field.0.child_name'). Returns nil if the property
- # is not included in the resource's properties.
- def property_for_schema_path(schema_path, resource)
+ # is not included in the resource's properties and removes keys that have
+ # been flattened
+ # TODO(emilymye): Change format of input for
+ # xactly_one_of/at_least_one_of/etc to use camelcase, MM properities and
+ # convert to snake in this method
+ def get_property_schema_path(schema_path, resource)
nested_props = resource.properties
prop = nil
-
- schema_path.split('.').each_with_index do |pname, i|
- next if i.odd?
-
- pname = pname.camelize(:lower)
- prop = nested_props.find { |p| p.name == pname }
- break if prop.nil?
+ path_tkns = schema_path.split('.0.').map do |pname|
+ camel_pname = pname.camelize(:lower)
+ prop = nested_props.find { |p| p.name == camel_pname }
+ return nil if prop.nil?
nested_props = prop.nested_properties || []
+ prop.flatten_object ? nil : pname.underscore
+ end
+ if path_tkns.empty? || path_tkns[-1].nil?
+ nil
+ else
+ path_tkns.compact.join('.0.')
end
- prop
end
# Transforms a format string with field markers to a regex string with
@@ -153,30 +178,31 @@ def folder_name(version)
# This function uses the resource.erb template to create one file
# per resource. The resource.erb template forms the basis of a single
# GCP Resource on Terraform.
- def generate_resource(data)
- target_folder = File.join(data.output_folder, folder_name(data.version))
-
- name = data.object.name.underscore
+ def generate_resource(pwd, data)
+ name = data.object.filename_override || data.object.name.underscore
product_name = data.product.name.underscore
- filepath = File.join(target_folder, "resource_#{product_name}_#{name}.go")
- data.generate('templates/terraform/resource.erb', filepath, self)
- generate_documentation(data)
+ FileUtils.mkpath folder_name(data.version) unless Dir.exist?(folder_name(data.version))
+ data.generate(pwd,
+ '/templates/terraform/resource.erb',
+ "#{folder_name(data.version)}/resource_#{product_name}_#{name}.go",
+ self)
+ generate_documentation(pwd, data)
end
- def generate_documentation(data)
+ def generate_documentation(pwd, data)
target_folder = data.output_folder
target_folder = File.join(target_folder, 'website', 'docs', 'r')
FileUtils.mkpath target_folder
- name = data.object.name.underscore
+ name = data.object.filename_override || data.object.name.underscore
product_name = @config.legacy_name || data.product.name.underscore
filepath =
File.join(target_folder, "#{product_name}_#{name}.html.markdown")
- data.generate('templates/terraform/resource.html.markdown.erb', filepath, self)
+ data.generate(pwd, 'templates/terraform/resource.html.markdown.erb', filepath, self)
end
- def generate_resource_tests(data)
+ def generate_resource_tests(pwd, data)
return if data.object.examples
.reject(&:skip_test)
.reject do |e|
@@ -185,96 +211,91 @@ def generate_resource_tests(data)
end
.empty?
- target_folder = File.join(data.output_folder, folder_name(data.version))
-
- name = data.object.name.underscore
+ name = data.object.filename_override || data.object.name.underscore
product_name = data.product.name.underscore
- filepath =
- File.join(
- target_folder,
- "resource_#{product_name}_#{name}_generated_test.go"
- )
data.product = data.product.name
data.resource_name = data.object.name.camelize(:upper)
- data.generate('templates/terraform/examples/base_configs/test_file.go.erb',
- filepath, self)
+ FileUtils.mkpath folder_name(data.version) unless Dir.exist?(folder_name(data.version))
+ data.generate(
+ pwd,
+ 'templates/terraform/examples/base_configs/test_file.go.erb',
+ "#{folder_name(data.version)}/resource_#{product_name}_#{name}_generated_test.go",
+ self
+ )
end
- def generate_resource_sweepers(data)
+ def generate_resource_sweepers(pwd, data)
return if data.object.skip_sweeper ||
data.object.custom_code.custom_delete ||
- data.object.custom_code.pre_delete
+ data.object.custom_code.pre_delete ||
+ data.object.skip_delete
- target_folder = File.join(data.output_folder, folder_name(data.version))
-
- name = data.object.name.underscore
+ name = data.object.filename_override || data.object.name.underscore
product_name = data.product.name.underscore
- filepath =
- File.join(
- target_folder,
- "resource_#{product_name}_#{name}_sweeper_test.go"
- )
data.product = data.product.name
data.resource_name = data.object.name.camelize(:upper)
- data.generate('templates/terraform/sweeper_file.go.erb',
- filepath, self)
+ FileUtils.mkpath folder_name(data.version) unless Dir.exist?(folder_name(data.version))
+ data.generate(pwd,
+ 'templates/terraform/sweeper_file.go.erb',
+ "#{folder_name(data.version)}/resource_#{product_name}_#{name}_sweeper_test.go",
+ self)
end
- def generate_operation(output_folder, _types)
+ def generate_operation(pwd, output_folder, _types)
return if @api.objects.select(&:autogen_async).empty?
product_name = @api.name.underscore
- data = build_object_data(@api.objects.first, output_folder, @target_version_name)
- target_folder = File.join(data.output_folder, folder_name(data.version))
+ data = build_object_data(pwd, @api.objects.first, output_folder, @target_version_name)
data.object = @api.objects.select(&:autogen_async).first
data.async = data.object.async
- data.generate('templates/terraform/operation.go.erb',
- File.join(target_folder,
- "#{product_name}_operation.go"),
+ FileUtils.mkpath folder_name(data.version) unless Dir.exist?(folder_name(data.version))
+ data.generate(pwd,
+ 'templates/terraform/operation.go.erb',
+ "#{folder_name(data.version)}/#{product_name}_operation.go",
self)
end
# Generate the IAM policy for this object. This is used to query and test
# IAM policies separately from the resource itself
- def generate_iam_policy(data)
- target_folder = File.join(data.output_folder, folder_name(data.version))
-
- name = data.object.name.underscore
+ def generate_iam_policy(pwd, data)
+ name = data.object.filename_override || data.object.name.underscore
product_name = data.product.name.underscore
- filepath = File.join(target_folder, "iam_#{product_name}_#{name}.go")
- data.generate('templates/terraform/iam_policy.go.erb', filepath, self)
+ FileUtils.mkpath folder_name(data.version) unless Dir.exist?(folder_name(data.version))
+ data.generate(pwd,
+ 'templates/terraform/iam_policy.go.erb',
+ "#{folder_name(data.version)}/iam_#{product_name}_#{name}.go",
+ self)
# Only generate test if testable examples exist.
unless data.object.examples.reject(&:skip_test).empty?
- generated_test_name = "iam_#{product_name}_#{name}_generated_test.go"
- filepath = File.join(target_folder, generated_test_name)
data.generate(
+ pwd,
'templates/terraform/examples/base_configs/iam_test_file.go.erb',
- filepath,
+ "#{folder_name(data.version)}/iam_#{product_name}_#{name}_generated_test.go",
self
)
end
- generate_iam_documentation(data)
+ generate_iam_documentation(pwd, data)
end
- def generate_iam_documentation(data)
+ def generate_iam_documentation(pwd, data)
target_folder = data.output_folder
target_folder = File.join(target_folder, 'website', 'docs', 'r')
FileUtils.mkpath target_folder
- name = data.object.name.underscore
+ name = data.object.filename_override || data.object.name.underscore
product_name = @config.legacy_name || data.product.name.underscore
filepath =
File.join(target_folder, "#{product_name}_#{name}_iam.html.markdown")
- data.generate('templates/terraform/resource_iam.html.markdown.erb', filepath, self)
+ data.generate(pwd, 'templates/terraform/resource_iam.html.markdown.erb', filepath, self)
end
- def build_object_data(object, output_folder, version)
+ def build_object_data(_pwd, object, output_folder, version)
TerraformProductFileTemplate.file_for_resource(
output_folder,
object,
diff --git a/provider/terraform/async.rb b/provider/terraform/async.rb
index 08b2c589ece7..33b5b36b1b7b 100644
--- a/provider/terraform/async.rb
+++ b/provider/terraform/async.rb
@@ -20,8 +20,13 @@ class Terraform < Provider::AbstractCore
class PollAsync < Api::Async
# Details how to poll for an eventually-consistent resource state.
- # Function to call for checking the Poll response
- attr_reader :check_response_func
+ # Function to call for checking the Poll response for
+ # creating and updating a resource
+ attr_reader :check_response_func_existence
+
+ # Function to call for checking the Poll response for
+ # deleting a resource
+ attr_reader :check_response_func_absence
# Custom code to get a poll response, if needed.
# Will default to same logic as Read() to get current resource
@@ -31,12 +36,18 @@ class PollAsync < Api::Async
# result of the final Read()
attr_reader :suppress_error
+ # Number of times the desired state has to occur continuously
+ # during polling before returning a success
+ attr_reader :target_occurrences
+
def validate
super
- check :check_response_func, type: String, required: true
+ check :check_response_func_existence, type: String, required: true
+ check :check_response_func_absence, type: String, default: 'PollCheckForAbsence'
check :custom_poll_read, type: String
check :suppress_error, type: :boolean, default: false
+ check :target_occurrences, type: Integer, default: 1
end
end
end
diff --git a/provider/terraform/common~compile.yaml b/provider/terraform/common~compile.yaml
index 4878b9a14490..d75b6f6a172a 100644
--- a/provider/terraform/common~compile.yaml
+++ b/provider/terraform/common~compile.yaml
@@ -15,7 +15,6 @@
<%
dir = @target_version_name == 'ga' ? 'google' : "google-#{@target_version_name}"
-%>
-'website/google.erb': 'third_party/terraform/website-compiled/google.erb'
<% Dir["third_party/terraform/tests/*.go.erb"].each do |file_path|
fname = file_path.split('/')[-1]
-%>
diff --git a/provider/terraform/custom_code.rb b/provider/terraform/custom_code.rb
index 1f46b314a411..f1b2ef4dee58 100644
--- a/provider/terraform/custom_code.rb
+++ b/provider/terraform/custom_code.rb
@@ -75,6 +75,9 @@ class CustomCode < Api::Object
# (e.g. "fooBarDiffSuppress") and regexes that are necessarily
# exported (e.g. "fooBarValidationRegex").
attr_reader :constants
+ # This code is run before the Create call happens. It's placed
+ # in the Create function, just before the Create call is made.
+ attr_reader :pre_create
# This code is run after the Create call succeeds. It's placed
# in the Create function directly without modification.
attr_reader :post_create
@@ -126,6 +129,7 @@ def validate
check :update_encoder, type: String
check :decoder, type: String
check :constants, type: String
+ check :pre_create, type: String
check :post_create, type: String
check :custom_create, type: String
check :pre_update, type: String
diff --git a/provider/terraform/examples.rb b/provider/terraform/examples.rb
index 83c0283e0f43..be8c6c379740 100644
--- a/provider/terraform/examples.rb
+++ b/provider/terraform/examples.rb
@@ -59,6 +59,8 @@ class Examples < Api::Object
# - :ORG_TARGET
# - :BILLING_ACCT
# - :SERVICE_ACCT
+ # - :CUST_ID
+ # - :IDENTITY_USER
# This list corresponds to the `get*FromEnv` methods in provider_test.go.
attr_reader :test_env_vars
@@ -81,6 +83,10 @@ class Examples < Api::Object
# }
attr_reader :test_vars_overrides
+ # Hash to provider custom override values for generating oics config
+ # See test_vars_overrides for more details
+ attr_reader :oics_vars_overrides
+
# The version name of of the example's version if it's different than the
# resource version, eg. `beta`
#
@@ -107,6 +113,9 @@ class Examples < Api::Object
# Whether to skip generating tests for this resource
attr_reader :skip_test
+ # Whether to skip generating docs for this example
+ attr_reader :skip_docs
+
# The name of the primary resource for use in IAM tests. IAM tests need
# a reference to the primary resource to create IAM policies for
attr_reader :primary_resource_name
@@ -115,7 +124,13 @@ class Examples < Api::Object
# Defaults to `templates/terraform/examples/{{name}}.tf.erb`
attr_reader :config_path
- def config_documentation
+ # If the example should be skipped during VCR testing.
+ # This is the case when something about the resource or config causes VCR to fail for example
+ # a resource with a unique identifier generated within the resource via resource.UniqueId()
+ # Or a config with two fine grained resources that have a race condition during create
+ attr_reader :skip_vcr
+
+ def config_documentation(pwd)
docs_defaults = {
PROJECT_NAME: 'my-project-name',
FIRESTORE_PROJECT_NAME: 'my-project-name',
@@ -125,7 +140,9 @@ def config_documentation
ORG_DOMAIN: 'example.com',
ORG_TARGET: '123456789',
BILLING_ACCT: '000000-0000000-0000000-000000',
- SERVICE_ACCT: 'emailAddress:my@service-account.com'
+ SERVICE_ACCT: 'emailAddress:my@service-account.com',
+ CUST_ID: 'A01b123xz',
+ IDENTITY_USER: 'cloud_identity_user'
}
@vars ||= {}
@test_env_vars ||= {}
@@ -135,26 +152,26 @@ def config_documentation
test_env_vars: test_env_vars.map { |k, v| [k, docs_defaults[v]] }.to_h,
primary_resource_id: primary_resource_id
},
- config_path
+ pwd + '/' + config_path
))
lines(compile_file(
{ content: body },
- 'templates/terraform/examples/base_configs/documentation.tf.erb'
+ pwd + '/templates/terraform/examples/base_configs/documentation.tf.erb'
))
end
- def config_test
- body = config_test_body
+ def config_test(pwd)
+ body = config_test_body(pwd)
lines(compile_file(
{
content: body
},
- 'templates/terraform/examples/base_configs/test_body.go.erb'
+ pwd + '/templates/terraform/examples/base_configs/test_body.go.erb'
))
end
# rubocop:disable Style/FormatStringToken
- def config_test_body
+ def config_test_body(pwd)
@vars ||= {}
@test_env_vars ||= {}
@test_vars_overrides ||= {}
@@ -185,21 +202,25 @@ def config_test_body
test_env_vars: test_env_vars.map { |k, _| [k, "%{#{k}}"] }.to_h,
primary_resource_id: primary_resource_id
},
- config_path
+ pwd + '/' + config_path
))
substitute_test_paths body
end
- def config_example
+ def config_example(pwd)
@vars ||= []
+ @oics_vars_overrides ||= {}
+
+ rand_vars = vars.map { |k, str| [k, "#{str}-${local.name_suffix}"] }.to_h
+
# Examples with test_env_vars are skipped elsewhere
body = lines(compile_file(
{
- vars: vars.map { |k, str| [k, "#{str}-${local.name_suffix}"] }.to_h,
+ vars: rand_vars.merge(oics_vars_overrides),
primary_resource_id: primary_resource_id
},
- config_path
+ pwd + '/' + config_path
))
substitute_example_paths body
@@ -253,7 +274,9 @@ def validate
check :ignore_read_extra, type: Array, item_type: String, default: []
check :primary_resource_name, type: String
check :skip_test, type: TrueClass
+ check :skip_docs, type: TrueClass
check :config_path, type: String, default: "templates/terraform/examples/#{name}.tf.erb"
+ check :skip_vcr, type: TrueClass
end
end
end
diff --git a/provider/terraform/sub_template.rb b/provider/terraform/sub_template.rb
index a4e38113d3d6..03c58ab37139 100644
--- a/provider/terraform/sub_template.rb
+++ b/provider/terraform/sub_template.rb
@@ -17,51 +17,62 @@ module Provider
class Terraform < Provider::AbstractCore
# Functions to compile sub-templates.
module SubTemplate
- def build_schema_property(property, object)
- compile_template'templates/terraform/schema_property.erb',
- property: property,
- object: object
+ def build_schema_property(property, object, pwd)
+ compile_template pwd + '/templates/terraform/schema_property.erb',
+ property: property,
+ object: object,
+ pwd: pwd
end
- def build_subresource_schema(property, object)
- compile_template'templates/terraform/schema_subresource.erb',
- property: property,
- object: object
+ def build_subresource_schema(property, object, pwd)
+ compile_template pwd + '/templates/terraform/schema_subresource.erb',
+ property: property,
+ object: object,
+ pwd: pwd
end
# Transforms a Cloud API representation of a property into a Terraform
# schema representation.
- def build_flatten_method(prefix, property, object)
- compile_template 'templates/terraform/flatten_property_method.erb',
+ def build_flatten_method(prefix, property, object, pwd)
+ compile_template pwd + '/templates/terraform/flatten_property_method.erb',
prefix: prefix,
property: property,
- object: object
+ object: object,
+ pwd: pwd
end
# Transforms a Terraform schema representation of a property into a
# representation used by the Cloud API.
- def build_expand_method(prefix, property, object)
- compile_template 'templates/terraform/expand_property_method.erb',
+ def build_expand_method(prefix, property, object, pwd)
+ compile_template pwd + '/templates/terraform/expand_property_method.erb',
prefix: prefix,
property: property,
- object: object
+ object: object,
+ pwd: pwd
end
- def build_expand_resource_ref(var_name, property)
- compile_template 'templates/terraform/expand_resource_ref.erb',
+ def build_expand_resource_ref(var_name, property, pwd)
+ compile_template pwd + '/templates/terraform/expand_resource_ref.erb',
var_name: var_name,
- property: property
+ property: property,
+ pwd: pwd
end
- def build_property_documentation(property)
- compile_template 'templates/terraform/property_documentation.erb',
- property: property
+ def build_property_documentation(property, pwd)
+ return if property.removed?
+
+ compile_template pwd + '/templates/terraform/property_documentation.erb',
+ property: property,
+ pwd: pwd
end
- def build_nested_property_documentation(property)
+ def build_nested_property_documentation(property, pwd)
+ return if property.removed?
+
compile_template(
- 'templates/terraform/nested_property_documentation.erb',
- property: property
+ pwd + '/templates/terraform/nested_property_documentation.erb',
+ property: property,
+ pwd: pwd
)
end
diff --git a/provider/terraform/virtual_fields.rb b/provider/terraform/virtual_fields.rb
index 12a0b2673c92..e81bdbffe52e 100644
--- a/provider/terraform/virtual_fields.rb
+++ b/provider/terraform/virtual_fields.rb
@@ -43,10 +43,18 @@ class VirtualFields < Api::Object
# The description / docs for the field.
attr_reader :description
+ # The API type of the field (defaults to boolean)
+ attr_reader :type
+
+ # The default value for the field (defaults to false)
+ attr_reader :default_value
+
def validate
super
check :name, type: String, required: true
check :description, type: String, required: true
+ check :type, type: Class, default: Api::Type::Boolean
+ check :default_value, default: false
end
end
end
diff --git a/provider/terraform_object_library.rb b/provider/terraform_object_library.rb
index bc4ccb0f0dc6..46ac2058cb1f 100644
--- a/provider/terraform_object_library.rb
+++ b/provider/terraform_object_library.rb
@@ -30,11 +30,12 @@ def generate_object(object, output_folder, version_name)
super(object, output_folder, version_name)
end
- def generate_resource(data)
+ def generate_resource(pwd, data)
target_folder = data.output_folder
product_ns = data.object.__product.name
- data.generate('templates/terraform/objectlib/base.go.erb',
+ data.generate(pwd,
+ 'templates/terraform/objectlib/base.go.erb',
File.join(target_folder,
"google/#{product_ns.downcase}_#{data.object.name.underscore}.go"),
self)
@@ -115,7 +116,7 @@ def copy_common_files(output_folder)
['google/compute_shared_operation.go',
'third_party/terraform/utils/compute_shared_operation.go'],
['google/compute_instance_helpers.go',
- 'third_party/terraform/utils/compute_instance_helpers.go'],
+ 'third_party/terraform/utils/compute_instance_helpers.go.erb'],
['google/convert.go',
'third_party/terraform/utils/convert.go'],
['google/metadata.go',
@@ -137,10 +138,10 @@ def copy_common_files(output_folder)
])
end
- def generate_resource_tests(data) end
+ def generate_resource_tests(pwd, data) end
- def generate_iam_policy(data) end
+ def generate_iam_policy(pwd, data) end
- def generate_resource_sweepers(data) end
+ def generate_resource_sweepers(pwd, data) end
end
end
diff --git a/provider/terraform_oics.rb b/provider/terraform_oics.rb
index c7590169e404..f4fba172e7fe 100644
--- a/provider/terraform_oics.rb
+++ b/provider/terraform_oics.rb
@@ -24,7 +24,7 @@ def generate(output_folder, types, _product_path, _dump_yaml)
end
# Create a directory of examples per resource
- def generate_resource(data)
+ def generate_resource(pwd, data)
examples = data.object.examples
.reject(&:skip_test)
.reject { |e| !e.test_env_vars.nil? && e.test_env_vars.any? }
@@ -37,41 +37,37 @@ def generate_resource(data)
data.example = example
- data.generate(
- 'templates/terraform/examples/base_configs/example_file.tf.erb',
- File.join(target_folder, 'main.tf'),
- self
- )
+ data.generate(pwd,
+ 'templates/terraform/examples/base_configs/example_file.tf.erb',
+ File.join(target_folder, 'main.tf'),
+ self)
- data.generate(
- 'templates/terraform/examples/base_configs/tutorial.md.erb',
- File.join(target_folder, 'tutorial.md'),
- self
- )
+ data.generate(pwd,
+ 'templates/terraform/examples/base_configs/tutorial.md.erb',
+ File.join(target_folder, 'tutorial.md'),
+ self)
- data.generate(
- 'templates/terraform/examples/base_configs/example_backing_file.tf.erb',
- File.join(target_folder, 'backing_file.tf'),
- self
- )
+ data.generate(pwd,
+ 'templates/terraform/examples/base_configs/example_backing_file.tf.erb',
+ File.join(target_folder, 'backing_file.tf'),
+ self)
- data.generate(
- 'templates/terraform/examples/static/motd',
- File.join(target_folder, 'motd'),
- self
- )
+ data.generate(pwd,
+ 'templates/terraform/examples/static/motd',
+ File.join(target_folder, 'motd'),
+ self)
end
end
# We don't want to generate anything but the resource.
- def generate_resource_tests(data) end
+ def generate_resource_tests(pwd, data) end
- def generate_resource_sweepers(data) end
+ def generate_resource_sweepers(pwd, data) end
def compile_common_files(output_folder, products, common_compile_file) end
def copy_common_files(output_folder) end
- def generate_iam_policy(data) end
+ def generate_iam_policy(pwd, data) end
end
end
diff --git a/spec/compiler_spec.rb b/spec/compiler_spec.rb
index 43bc8e6d7b37..e3a8627f0599 100644
--- a/spec/compiler_spec.rb
+++ b/spec/compiler_spec.rb
@@ -48,7 +48,7 @@
it { is_expected.to be_instance_of Api::Product }
it { is_expected.to have_attributes(api_name: 'myproduct') }
- it { is_expected.to have_attribute_of_length(objects: 4) }
+ it { is_expected.to have_attribute_of_length(objects: 5) }
end
context 'should only accept product' do
diff --git a/spec/data/good-file.yaml b/spec/data/good-file.yaml
index 98d2d34a6b74..eb4683e127c0 100644
--- a/spec/data/good-file.yaml
+++ b/spec/data/good-file.yaml
@@ -114,6 +114,43 @@ objects:
- !ruby/object:Api::Type::String
name: 'nv-prop1'
description: 'the first property in my namevalues'
+ - !ruby/object:Api::Resource
+ name: 'ResourceWithTerraformOverride'
+ kind: 'terraform#resourceWithTerraformOverride'
+ base_url: 'resourceWithTerraformOverride'
+ description: 'a description'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'stringOne'
+ description: 'a string property (depth 0)'
+ - !ruby/object:Api::Type::NestedObject
+ name: 'objectOne'
+ description: 'a NestedObject property (depth 0)'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'objectOneString'
+ description: 'a string property (depth 1)'
+ - !ruby/object:Api::Type::NestedObject
+ name: 'objectOneFlattenedObject'
+ description: 'a nested NestedObject (depth 1)'
+ properties:
+ - !ruby/object:Api::Type::Integer
+ name: 'objectOneNestedNestedInteger'
+ description: 'a nested integer (depth 2)'
+ - !ruby/object:Api::Type::NestedObject
+ name: 'objectTwoFlattened'
+ description: 'a NestedObject property that is flattened (depth 0)'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'objectTwoString'
+ description: 'a nested string (depth 1)'
+ - !ruby/object:Api::Type::NestedObject
+ name: 'objectTwoNestedObject'
+ description: 'a nested NestedObject (depth 1)'
+ properties:
+ - !ruby/object:Api::Type::String
+ name: 'objectTwoNestedNestedString'
+ description: 'a nested String (depth 2)'
- !ruby/object:Api::Resource
name: 'TerraformImportIdTest'
description: 'Used for spec/provider_terraform_import_spec'
diff --git a/spec/data/good-file-config.yaml b/spec/data/good-tf-override.yaml
similarity index 57%
rename from spec/data/good-file-config.yaml
rename to spec/data/good-tf-override.yaml
index fff83f0f2b5f..83180541b559 100644
--- a/spec/data/good-file-config.yaml
+++ b/spec/data/good-tf-override.yaml
@@ -12,13 +12,12 @@
# limitations under the License.
--- !ruby/object:Provider::Terraform::Config
-overrides: !ruby/object:Provider::ResourceOverrides
- AnotherResource: !ruby/object:Provider::Terraform::ResourceOverride
- description: '{{description}} bar'
+overrides: !ruby/object:Overrides::ResourceOverrides
+ ResourceWithTerraformOverride: !ruby/object:Overrides::Terraform::ResourceOverride
properties:
- property1: !ruby/object:Provider::Terraform::PropertyOverride
- description: 'foo'
- nested-property.property1: !ruby/object:Provider::Terraform::PropertyOverride
- description: 'bar'
- array-property.property1: !ruby/object:Provider::Terraform::PropertyOverride
- description: 'baz'
+ objectTwoFlattened: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ objectTwoFlattened.objectTwoNestedObject: !ruby/object:Overrides::Terraform::PropertyOverride
+ update_mask_fields:
+ - 'overrideFoo'
+ - 'nested.overrideBar'
diff --git a/spec/data/terraform-config.yaml b/spec/data/terraform-config.yaml
index 9aea0ef12e01..76dcb92477d0 100644
--- a/spec/data/terraform-config.yaml
+++ b/spec/data/terraform-config.yaml
@@ -13,3 +13,13 @@
--- !ruby/object:Provider::Terraform::Config
overrides: !ruby/object:Overrides::ResourceOverrides
+ ResourceWithTerraformOverride: !ruby/object:Overrides::Terraform::ResourceOverride
+ properties:
+ objectOne.objectOneFlattenedObject: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ objectTwoFlattened: !ruby/object:Overrides::Terraform::PropertyOverride
+ flatten_object: true
+ objectTwoFlattened.objectTwoString: !ruby/object:Overrides::Terraform::PropertyOverride
+ update_mask_fields:
+ - 'overrideFoo'
+ - 'nested.overrideBar'
diff --git a/spec/provider_terraform_spec.rb b/spec/provider_terraform_spec.rb
index 76fdff0f9e17..13e30f5c16cc 100644
--- a/spec/provider_terraform_spec.rb
+++ b/spec/provider_terraform_spec.rb
@@ -23,11 +23,14 @@ class << self
describe Provider::Terraform do
context 'good file product' do
let(:product) { Api::Compiler.new(File.read('spec/data/good-file.yaml')).run }
- let(:config) do
- Provider::Config.parse('spec/data/terraform-config.yaml', product)[1]
- end
+ let(:parsed) { Provider::Config.parse('spec/data/terraform-config.yaml', product) }
+ let(:config) { parsed[1] }
+ let(:override_product) { parsed[0] }
let(:provider) { Provider::Terraform.new(config, product, 'ga', Time.now) }
let(:resource) { product.objects[0] }
+ let(:override_resource) do
+ override_product.objects.find { |o| o.name == 'ResourceWithTerraformOverride' }
+ end
before do
allow_open 'spec/data/good-file.yaml'
@@ -139,6 +142,94 @@ class << self
)
end
end
+
+ describe '#get_property_update_masks_groups' do
+ subject do
+ provider.get_property_update_masks_groups(override_resource.properties)
+ end
+
+ it do
+ is_expected.to eq(
+ [
+ ['string_one', ['stringOne']],
+ ['object_one', ['objectOne']],
+ ['object_two_string', ['overrideFoo', 'nested.overrideBar']],
+ [
+ 'object_two_nested_object', [
+ 'objectTwoFlattened.objectTwoNestedObject'
+ ]
+ ]
+ ]
+ )
+ end
+ end
+
+ describe '#get_property_schema_path nonexistant' do
+ let(:test_paths) do
+ [
+ 'not_a_field',
+ 'object_one.0.not_a_field',
+ 'object_one.0.object_one_nested_object.0.not_a_field'
+ ]
+ end
+ subject do
+ test_paths.map do |test_path|
+ provider.get_property_schema_path(test_path, override_resource)
+ end
+ end
+
+ it do
+ is_expected.to eq([nil] * test_paths.size)
+ end
+ end
+
+ describe '#get_property_schema_path no changes' do
+ let(:test_paths) do
+ [
+ 'string_one',
+ 'object_one',
+ 'object_one.0.object_one_string'
+ ]
+ end
+ subject do
+ test_paths.map do |test_path|
+ provider.get_property_schema_path(test_path, override_resource)
+ end
+ end
+
+ it do
+ is_expected.to eq(test_paths)
+ end
+ end
+
+ describe '#get_property_schema_path flattened objects' do
+ let(:test_paths) do
+ [
+ 'object_one.0.object_one_flattened_object',
+ 'object_one.0.object_one_flattened_object.0.object_one_nested_nested_integer',
+ 'object_two_flattened.0.object_two_string',
+ 'object_two_flattened.0.object_two_nested_object',
+ 'object_two_flattened.0.object_two_nested_object.0.object_two_nested_nested_string'
+ ]
+ end
+ subject do
+ test_paths.map do |test_path|
+ provider.get_property_schema_path(test_path, override_resource)
+ end
+ end
+
+ it do
+ is_expected.to eq(
+ [
+ nil,
+ 'object_one.0.object_one_nested_nested_integer',
+ 'object_two_string',
+ 'object_two_nested_object',
+ 'object_two_nested_object.0.object_two_nested_nested_string'
+ ]
+ )
+ end
+ end
end
def allow_open(file_name)
diff --git a/templates/ansible/facts.erb b/templates/ansible/facts.erb
index c7d7506672c4..ceb233356088 100644
--- a/templates/ansible/facts.erb
+++ b/templates/ansible/facts.erb
@@ -3,7 +3,7 @@
#
# Copyright (C) 2017 Google
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-<%= lines(autogen_notice :python) -%>
+<%= lines(autogen_notice(:python, pwd)) -%>
from __future__ import absolute_import, division, print_function
__metaclass__ = type
diff --git a/templates/ansible/integration_test.erb b/templates/ansible/integration_test.erb
index 6cb30d90812e..0cf793faa2cb 100644
--- a/templates/ansible/integration_test.erb
+++ b/templates/ansible/integration_test.erb
@@ -1,5 +1,5 @@
---
-<%= lines(autogen_notice :yaml) -%>
+<%= lines(autogen_notice(:yaml, pwd)) -%>
# Pre-test setup
<% unless example.dependencies.nil? -%>
<% example.dependencies.each do |depend| -%>
@@ -25,7 +25,7 @@
- result.changed == true
<% end # if object.readonly -%>
<% unless example.verifier.nil? -%>
-<%= lines(example.verifier.build_task('present', object)) -%>
+<%= lines(example.verifier.build_task('present', object, pwd)) -%>
<% end -%>
<% unless object.readonly -%>
# ----------------------------------------------------------------------------
@@ -43,7 +43,7 @@
that:
- result.changed == true
<% unless example.verifier.nil? -%>
-<%= lines(example.verifier.build_task('absent', object)) -%>
+<%= lines(example.verifier.build_task('absent', object, pwd)) -%>
<% end -%>
# ----------------------------------------------------------------------------
<%= lines(example.task.build_test('absent', object, true)) -%>
diff --git a/templates/ansible/provider_helpers.erb b/templates/ansible/provider_helpers.erb
index db854570bd65..34380b2ef8bf 100644
--- a/templates/ansible/provider_helpers.erb
+++ b/templates/ansible/provider_helpers.erb
@@ -4,9 +4,9 @@
<%=
object.provider_helpers.map do |f|
if f == object.provider_helpers.last
- lines(compile(f))
+ lines(compile(pwd + '/' + f))
else
- lines(compile(f), 2)
+ lines(compile(pwd + '/' + f), 2)
end
end.join
-%>
diff --git a/templates/ansible/resource.erb b/templates/ansible/resource.erb
index 51ecd909b5e4..801cf167353c 100644
--- a/templates/ansible/resource.erb
+++ b/templates/ansible/resource.erb
@@ -3,12 +3,12 @@
#
# Copyright (C) 2017 Google
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-<%= lines(autogen_notice :python) -%>
+<%= lines(autogen_notice(:python, pwd)) -%>
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-<%= lines(compile('templates/ansible/documentation.erb'), 1) -%>
+<%= lines(compile(pwd + '/templates/ansible/documentation.erb'), 1) -%>
################################################################################
# Imports
################################################################################
@@ -44,7 +44,7 @@ import json
def main():
"""Main function"""
-<%= lines(indent(compile('templates/ansible/module.erb'), 4)) -%>
+<%= lines(indent(compile(pwd + '/templates/ansible/module.erb'), 4)) -%>
if not module.params['scopes']:
module.params['scopes'] = <%= python_literal(object.__product.scopes) %>
@@ -295,7 +295,7 @@ def <%= func_name -%>(module, request, response):
<% end -%>
<% end # unless update_props.empty? -%>
<% if object.update_mask -%>
-<%= lines(compile('templates/ansible/update_mask.erb')) -%>
+<%= lines(compile(pwd + '/templates/ansible/update_mask.erb')) -%>
<% end # if update_mask -%>
<%=
lines(method_decl('delete', ['module', 'link', ('kind' if object.kind?),
@@ -378,7 +378,7 @@ def unwrap_resource(result, module):
<% end -%>
-<%= lines(compile('templates/ansible/transport.erb'), 2) -%>
+<%= lines(compile(pwd + '/templates/ansible/transport.erb'), 2) -%>
<%= lines(emit_link('self_link', build_url(object.self_link_url), object), 2) -%>
<%= lines(emit_link('collection', build_url(object.collection_url), object), 2) -%>
<%- unless object.create_url.nil? -%>
@@ -446,7 +446,7 @@ def is_different(module, response):
def response_to_hash(module, response):
return <%= lines(python_literal(response_properties(object.properties), use_hash_brackets: true)) -%>
<% if object.all_user_properties.any?(&:pattern) -%>
-<%= lines(compile('templates/ansible/pattern.py.erb')) -%>
+<%= lines(compile(pwd + '/templates/ansible/pattern.py.erb')) -%>
<% end -%>
<% readonly_selflink_rrefs.each do |resource| -%>
@@ -459,9 +459,9 @@ def <%= resource.name.underscore -%>_selflink(name, params):
name = <%= build_url(resource.self_link_url).gsub('{name}', '%s') -%>.format(**params) % name
return name
<% end -%>
-<%= lines_before(compile('templates/ansible/async.erb'), 1) -%>
-<%= lines_before(compile('templates/ansible/provider_helpers.erb'), 1) -%>
-<%= lines_before(compile('templates/ansible/properties.erb'), 1) -%>
+<%= lines_before(compile(pwd + '/templates/ansible/async.erb'), 1) -%>
+<%= lines_before(compile(pwd + '/templates/ansible/provider_helpers.erb'), 1) -%>
+<%= lines_before(compile(pwd + '/templates/ansible/properties.erb'), 1) -%>
if __name__ == '__main__':
diff --git a/templates/inspec/doc_template.md.erb b/templates/inspec/doc_template.md.erb
index 8c78c74d5eee..937912f3657f 100644
--- a/templates/inspec/doc_template.md.erb
+++ b/templates/inspec/doc_template.md.erb
@@ -30,17 +30,17 @@ This resource has beta fields available. To retrieve these fields, include `beta
<% end -%>
## Examples
```
-<%= compile("templates/inspec/examples/#{resource_name(object, product)}/#{resource_underscored_name}.erb") -%>
+<%= compile(pwd + "/templates/inspec/examples/#{resource_name(object, product)}/#{resource_underscored_name}.erb") -%>
```
<% if object.singular_extra_examples && !plural -%>
-<%= compile(object.singular_extra_examples) -%>
+<%= compile(pwd + '/' + object.singular_extra_examples) -%>
<% end -%>
<% if object.plural_extra_examples && plural -%>
-<%= compile(object.plural_extra_examples) -%>
+<%= compile(pwd + '/' + object.plural_extra_examples) -%>
<% end -%>
diff --git a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policies.erb b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policies.erb
index 2ecb2957f474..93894243caa5 100644
--- a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policies.erb
+++ b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policies.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% service_perimeter = grab_attributes['service_perimeter'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% service_perimeter = grab_attributes(pwd)['service_perimeter'] -%>
describe google_access_context_manager_access_policies(org_id: <%= gcp_organization_id %>) do
its('count') { should be >= 1 }
diff --git a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy.erb b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy.erb
index b26f00b8863d..d85d846714dd 100644
--- a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy.erb
+++ b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% service_perimeter = grab_attributes['service_perimeter'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% service_perimeter = grab_attributes(pwd)['service_perimeter'] -%>
describe.one do
google_access_context_manager_access_policies(org_id: <%= gcp_organization_id %>).names.each do |policy_name|
diff --git a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy_attributes.erb b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy_attributes.erb
index 4ef4a50d8d00..d7eb5a975b1c 100644
--- a/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy_attributes.erb
+++ b/templates/inspec/examples/google_access_context_manager_access_policy/google_access_context_manager_access_policy_attributes.erb
@@ -1,3 +1,3 @@
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the perimeter')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the perimeter')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-service_perimeter = attribute('service_perimeter', default: <%= JSON.pretty_generate(grab_attributes['service_perimeter']) -%>, description: 'Service perimeter definition')
\ No newline at end of file
+service_perimeter = attribute('service_perimeter', default: <%= JSON.pretty_generate(grab_attributes(pwd)['service_perimeter']) -%>, description: 'Service perimeter definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter.erb b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter.erb
index e93362478d83..e23dca2d8df3 100644
--- a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter.erb
+++ b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% service_perimeter = grab_attributes['service_perimeter'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% service_perimeter = grab_attributes(pwd)['service_perimeter'] -%>
describe.one do
google_access_context_manager_access_policies(org_id: <%= gcp_organization_id %>).names.each do |policy_name|
diff --git a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter_attributes.erb b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter_attributes.erb
index 4ef4a50d8d00..d7eb5a975b1c 100644
--- a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter_attributes.erb
+++ b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeter_attributes.erb
@@ -1,3 +1,3 @@
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the perimeter')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the perimeter')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-service_perimeter = attribute('service_perimeter', default: <%= JSON.pretty_generate(grab_attributes['service_perimeter']) -%>, description: 'Service perimeter definition')
\ No newline at end of file
+service_perimeter = attribute('service_perimeter', default: <%= JSON.pretty_generate(grab_attributes(pwd)['service_perimeter']) -%>, description: 'Service perimeter definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeters.erb b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeters.erb
index ed65843deb61..5ed933bff520 100644
--- a/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeters.erb
+++ b/templates/inspec/examples/google_access_context_manager_service_perimeter/google_access_context_manager_service_perimeters.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% service_perimeter = grab_attributes['service_perimeter'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% service_perimeter = grab_attributes(pwd)['service_perimeter'] -%>
describe.one do
google_access_context_manager_access_policies(org_id: <%= gcp_organization_id %>).names.each do |policy_name|
diff --git a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version.erb b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version.erb
index c53e464c7c70..cdb414532564 100644
--- a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version.erb
+++ b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% standardappversion = grab_attributes['standardappversion'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% standardappversion = grab_attributes(pwd)['standardappversion'] -%>
describe google_appengine_standard_app_version(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>, version_id: <%= doc_generation ? "'#{standardappversion['version_id']}'" : "standardappversion['version_id']" -%>, service: <%= doc_generation ? "'#{standardappversion['service']}'" : "standardappversion['service']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version_attributes.erb b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version_attributes.erb
index 425ce2537a4f..47f6338b6dc5 100644
--- a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version_attributes.erb
+++ b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_version_attributes.erb
@@ -1,5 +1,5 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project location.')
-standardappversion = attribute('standardappversion', default: <%= JSON.pretty_generate(grab_attributes['standardappversion']) -%>, description: 'Cloud App Engine definition')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project location.')
+standardappversion = attribute('standardappversion', default: <%= JSON.pretty_generate(grab_attributes(pwd)['standardappversion']) -%>, description: 'Cloud App Engine definition')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_versions.erb b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_versions.erb
index 3ecf79e4469f..485a69908c25 100644
--- a/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_versions.erb
+++ b/templates/inspec/examples/google_appengine_standard_app_version/google_appengine_standard_app_versions.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% standardappversion = grab_attributes['standardappversion'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% standardappversion = grab_attributes(pwd)['standardappversion'] -%>
describe google_appengine_standard_app_versions(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>,service: <%= doc_generation ? "'#{standardappversion['service']}'" : "standardappversion['service']" -%>) do
its('runtimes') { should include <%= doc_generation ? "'#{standardappversion['runtime']}'" : "standardappversion['runtime']" -%> }
diff --git a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset.erb b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset.erb
index 1fa49e1f1bc2..f8be9fe14eb6 100644
--- a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset.erb
+++ b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% dataset = grab_attributes['dataset'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% dataset = grab_attributes(pwd)['dataset'] -%>
describe google_bigquery_dataset(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{dataset['dataset_id']}'" : "dataset['dataset_id']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset_attributes.erb b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset_attributes.erb
index 24d9298e551f..874450396a53 100644
--- a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset_attributes.erb
+++ b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_dataset_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-dataset = attribute('dataset', default: <%= JSON.pretty_generate(grab_attributes['dataset']) -%>, description: 'BigQuery dataset definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+dataset = attribute('dataset', default: <%= JSON.pretty_generate(grab_attributes(pwd)['dataset']) -%>, description: 'BigQuery dataset definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_datasets.erb b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_datasets.erb
index 326afb3e0ae7..a293484ca1a3 100644
--- a/templates/inspec/examples/google_bigquery_dataset/google_bigquery_datasets.erb
+++ b/templates/inspec/examples/google_bigquery_dataset/google_bigquery_datasets.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% dataset = grab_attributes['dataset'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% dataset = grab_attributes(pwd)['dataset'] -%>
describe google_bigquery_datasets(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('count') { should be >= 1 }
its('friendly_names') { should include <%= doc_generation ? "'#{dataset['friendly_name']}'" : "dataset['friendly_name']" -%> }
diff --git a/templates/inspec/examples/google_bigquery_table/google_bigquery_table.erb b/templates/inspec/examples/google_bigquery_table/google_bigquery_table.erb
index 770313f62ea3..32e42aca5389 100644
--- a/templates/inspec/examples/google_bigquery_table/google_bigquery_table.erb
+++ b/templates/inspec/examples/google_bigquery_table/google_bigquery_table.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% bigquery_table = grab_attributes['bigquery_table'] -%>
-<% dataset = grab_attributes['dataset'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% bigquery_table = grab_attributes(pwd)['bigquery_table'] -%>
+<% dataset = grab_attributes(pwd)['dataset'] -%>
describe google_bigquery_table(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, dataset: <%= doc_generation ? "'#{dataset['dataset_id']}'" : "dataset['dataset_id']" -%>, name: <%= doc_generation ? "'#{bigquery_table['table_id']}'" : "bigquery_table['table_id']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_bigquery_table/google_bigquery_table_attributes.erb b/templates/inspec/examples/google_bigquery_table/google_bigquery_table_attributes.erb
index cadbae7d6ce1..adbb802ba3ce 100644
--- a/templates/inspec/examples/google_bigquery_table/google_bigquery_table_attributes.erb
+++ b/templates/inspec/examples/google_bigquery_table/google_bigquery_table_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-bigquery_table = attribute('bigquery_table', default: <%= JSON.pretty_generate(grab_attributes['bigquery_table']) -%>, description: 'BigQuery table definition')
-dataset = attribute('dataset', default: <%= JSON.pretty_generate(grab_attributes['dataset']) -%>, description: 'BigQuery dataset definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+bigquery_table = attribute('bigquery_table', default: <%= JSON.pretty_generate(grab_attributes(pwd)['bigquery_table']) -%>, description: 'BigQuery table definition')
+dataset = attribute('dataset', default: <%= JSON.pretty_generate(grab_attributes(pwd)['dataset']) -%>, description: 'BigQuery dataset definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_bigquery_table/google_bigquery_tables.erb b/templates/inspec/examples/google_bigquery_table/google_bigquery_tables.erb
index 9071803b6104..bf256a6a96ac 100644
--- a/templates/inspec/examples/google_bigquery_table/google_bigquery_tables.erb
+++ b/templates/inspec/examples/google_bigquery_table/google_bigquery_tables.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% bigquery_table = grab_attributes['bigquery_table'] -%>
-<% dataset = grab_attributes['dataset'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% bigquery_table = grab_attributes(pwd)['bigquery_table'] -%>
+<% dataset = grab_attributes(pwd)['dataset'] -%>
describe.one do
google_bigquery_tables(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, dataset: <%= doc_generation ? "'#{dataset['dataset_id']}'" : "dataset['dataset_id']" -%>).table_references.each do |table_reference|
describe google_bigquery_table(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, dataset: <%= doc_generation ? "'#{dataset['dataset_id']}'" : "dataset['dataset_id']" -%>, name: table_reference.table_id) do
diff --git a/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info.erb b/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info.erb
index 7e300f5bf870..e62897471a67 100644
--- a/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info.erb
+++ b/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_billing_account = "#{external_attribute('gcp_billing_account', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_billing_account = "#{external_attribute(pwd, 'gcp_billing_account', doc_generation)}" -%>
describe google_billing_project_billing_info(project_id: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info_attributes.erb b/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info_attributes.erb
index 7e92ede4c630..d99baef0d604 100644
--- a/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info_attributes.erb
+++ b/templates/inspec/examples/google_billing_project_billing_info/google_billing_project_billing_info_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_billing_account = attribute(:gcp_billing_account, default: '<%= external_attribute('gcp_billing_account') -%>', description: 'The GCP billing account name.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_billing_account = attribute(:gcp_billing_account, default: '<%= external_attribute(pwd, 'gcp_billing_account') -%>', description: 'The GCP billing account name.')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job.erb b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job.erb
index 5b73eb3fb4d0..de9fc2f37ca9 100644
--- a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job.erb
+++ b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% scheduler_job = grab_attributes['scheduler_job'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% scheduler_job = grab_attributes(pwd)['scheduler_job'] -%>
describe google_cloud_scheduler_job(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, region: <%= doc_generation ? "#{scheduler_job['region']}" : "scheduler_job['region']" -%>, name: <%= doc_generation ? "'#{scheduler_job['name']}'" : "scheduler_job['name']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job_attributes.erb b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job_attributes.erb
index 3a89f2879e3b..d11ee01546a4 100644
--- a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job_attributes.erb
+++ b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_job_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-scheduler_job = attribute('scheduler_job', default: <%= JSON.pretty_generate(grab_attributes['scheduler_job']) -%>, description: 'Cloud Scheduler Job configuration')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+scheduler_job = attribute('scheduler_job', default: <%= JSON.pretty_generate(grab_attributes(pwd)['scheduler_job']) -%>, description: 'Cloud Scheduler Job configuration')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_jobs.erb b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_jobs.erb
index 4406cf0a2311..945af3861a02 100644
--- a/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_jobs.erb
+++ b/templates/inspec/examples/google_cloud_scheduler_job/google_cloud_scheduler_jobs.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% scheduler_job = grab_attributes['scheduler_job'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% scheduler_job = grab_attributes(pwd)['scheduler_job'] -%>
google_cloud_scheduler_jobs(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, region: <%= doc_generation ? "#{scheduler_job['location']}" : "scheduler_job['location']" -%>).names.each do |name|
describe google_cloud_scheduler_job(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, region: <%= doc_generation ? "#{scheduler_job['region']}" : "scheduler_job['region']" -%>, name: name) do
it { should exist }
diff --git a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger.erb b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger.erb
index 3e85fc74ff3c..2658bfa017ef 100644
--- a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger.erb
+++ b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% trigger = grab_attributes['trigger'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% trigger = grab_attributes(pwd)['trigger'] -%>
describe google_cloudbuild_triggers(project: <%= gcp_project_id -%>) do
its('count') { should eq 1 }
end
diff --git a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger_attributes.erb b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger_attributes.erb
index c96172035e84..32243cf57e81 100644
--- a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger_attributes.erb
+++ b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_trigger_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-trigger = attribute('trigger', default: <%= JSON.pretty_generate(grab_attributes['trigger']) -%>, description: 'CloudBuild trigger definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+trigger = attribute('trigger', default: <%= JSON.pretty_generate(grab_attributes(pwd)['trigger']) -%>, description: 'CloudBuild trigger definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_triggers.erb b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_triggers.erb
index 3e85fc74ff3c..2658bfa017ef 100644
--- a/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_triggers.erb
+++ b/templates/inspec/examples/google_cloudbuild_trigger/google_cloudbuild_triggers.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% trigger = grab_attributes['trigger'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% trigger = grab_attributes(pwd)['trigger'] -%>
describe google_cloudbuild_triggers(project: <%= gcp_project_id -%>) do
its('count') { should eq 1 }
end
diff --git a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function.erb b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function.erb
index 6a31a1bf46a7..e88608a51cdd 100644
--- a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function.erb
+++ b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function.erb
@@ -1,11 +1,11 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_cloud_function_region = "#{external_attribute('gcp_cloud_function_region', doc_generation)}" -%>
-<% cloudfunction = grab_attributes['cloudfunction'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_cloud_function_region = "#{external_attribute(pwd, 'gcp_cloud_function_region', doc_generation)}" -%>
+<% cloudfunction = grab_attributes(pwd)['cloudfunction'] -%>
describe google_cloudfunctions_cloud_function(project: <%= gcp_project_id -%>, location: <%= gcp_cloud_function_region -%>, name: <%= doc_generation ? "'#{cloudfunction['name']}'" : "cloudfunction['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{cloudfunction['description']}'" : "cloudfunction['description']" -%> }
its('available_memory_mb') { should eq <%= doc_generation ? "'#{cloudfunction['available_memory_mb']}'" : "cloudfunction['available_memory_mb']" -%> }
- its('https_trigger.url') { should match /\/<%= "#{grab_attributes['cloudfunction']['name']}" -%>$/ }
+ its('https_trigger.url') { should match /\/<%= "#{grab_attributes(pwd)['cloudfunction']['name']}" -%>$/ }
its('entry_point') { should eq <%= doc_generation ? "'#{cloudfunction['entry_point']}'" : "cloudfunction['entry_point']" -%> }
its('environment_variables') { should include('MY_ENV_VAR' => <%= doc_generation ? "'#{cloudfunction['env_var_value']}'" : "cloudfunction['env_var_value']" -%>) }
end
diff --git a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function_attributes.erb b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function_attributes.erb
index 7665cfa9ee65..d16cc55b34d8 100644
--- a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function_attributes.erb
+++ b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_function_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_cloud_function_region = attribute(:gcp_cloud_function_region, default: '<%= external_attribute('gcp_cloud_function_region') -%>', description: 'The Cloud Function region.')
-cloudfunction = attribute('cloudfunction', default: <%= JSON.pretty_generate(grab_attributes['cloudfunction']) -%>, description: 'Cloud Function definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_cloud_function_region = attribute(:gcp_cloud_function_region, default: '<%= external_attribute(pwd, 'gcp_cloud_function_region') -%>', description: 'The Cloud Function region.')
+cloudfunction = attribute('cloudfunction', default: <%= JSON.pretty_generate(grab_attributes(pwd)['cloudfunction']) -%>, description: 'Cloud Function definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_functions.erb b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_functions.erb
index 687c59436314..acecfacba322 100644
--- a/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_functions.erb
+++ b/templates/inspec/examples/google_cloudfunctions_cloud_function/google_cloudfunctions_cloud_functions.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_cloud_function_region = "#{external_attribute('gcp_cloud_function_region', doc_generation)}" -%>
-<% cloudfunction = grab_attributes['cloudfunction'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_cloud_function_region = "#{external_attribute(pwd, 'gcp_cloud_function_region', doc_generation)}" -%>
+<% cloudfunction = grab_attributes(pwd)['cloudfunction'] -%>
describe google_cloudfunctions_cloud_functions(project: <%= gcp_project_id -%>, location: <%= gcp_cloud_function_region -%>) do
its('descriptions') { should include <%= doc_generation ? "'#{cloudfunction['description']}'" : "cloudfunction['description']" -%> }
its('entry_points') { should include <%= doc_generation ? "'#{cloudfunction['entry_point']}'" : "cloudfunction['entry_point']" -%> }
diff --git a/templates/inspec/examples/google_compute_address/google_compute_address.erb b/templates/inspec/examples/google_compute_address/google_compute_address.erb
index 446d4ff7cc9d..0cee97fb8549 100644
--- a/templates/inspec/examples/google_compute_address/google_compute_address.erb
+++ b/templates/inspec/examples/google_compute_address/google_compute_address.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% address = grab_attributes['address'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% address = grab_attributes(pwd)['address'] -%>
describe google_compute_address(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>, name: <%= doc_generation ? "'#{address['name']}'" : "address['name']" -%>) do
it { should exist }
its('address') { should eq <%= doc_generation ? "'#{address['address']}'" : "address['address']" -%> }
diff --git a/templates/inspec/examples/google_compute_address/google_compute_address_attributes.erb b/templates/inspec/examples/google_compute_address/google_compute_address_attributes.erb
index b73f6a88cc98..fcb18e906c5e 100644
--- a/templates/inspec/examples/google_compute_address/google_compute_address_attributes.erb
+++ b/templates/inspec/examples/google_compute_address/google_compute_address_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-address = attribute('address', default: <%= JSON.pretty_generate(grab_attributes['address']) -%>, description: 'Address definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+address = attribute('address', default: <%= JSON.pretty_generate(grab_attributes(pwd)['address']) -%>, description: 'Address definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_address/google_compute_addresses.erb b/templates/inspec/examples/google_compute_address/google_compute_addresses.erb
index 49075598d54f..264a7bf03ba3 100644
--- a/templates/inspec/examples/google_compute_address/google_compute_addresses.erb
+++ b/templates/inspec/examples/google_compute_address/google_compute_addresses.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% address = grab_attributes['address'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% address = grab_attributes(pwd)['address'] -%>
describe google_compute_addresses(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>) do
its('addresses') { should include <%= doc_generation ? "'#{address['address']}'" : "address['address']" -%> }
its('names') { should include <%= doc_generation ? "'#{address['name']}'" : "address['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler.erb b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler.erb
index b5c47a0a8498..1f58db41928e 100644
--- a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler.erb
+++ b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler.erb
@@ -1,10 +1,10 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" -%>
-<% autoscaler = grab_attributes['autoscaler'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>
+<% autoscaler = grab_attributes(pwd)['autoscaler'] -%>
describe google_compute_autoscaler(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, zone: <%= doc_generation ? "#{gcp_zone}" : "gcp_zone" -%>, name: <%= doc_generation ? "'#{autoscaler['name']}'" : "autoscaler['name']" -%>) do
it { should exist }
- its('target') { should match /\/<%= "#{grab_attributes['instance_group_manager']['name']}" -%>$/ }
+ its('target') { should match /\/<%= "#{grab_attributes(pwd)['instance_group_manager']['name']}" -%>$/ }
its('autoscaling_policy.max_num_replicas') { should eq <%= doc_generation ? "'#{autoscaler['max_replicas']}'" : "autoscaler['max_replicas']" -%> }
its('autoscaling_policy.min_num_replicas') { should eq <%= doc_generation ? "'#{autoscaler['min_replicas']}'" : "autoscaler['min_replicas']" -%> }
its('autoscaling_policy.cool_down_period_sec') { should eq <%= doc_generation ? "'#{autoscaler['cooldown_period']}'" : "autoscaler['cooldown_period']" -%> }
diff --git a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler_attributes.erb b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler_attributes.erb
index f478953f4152..5d6315ede0bb 100644
--- a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler_attributes.erb
+++ b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscaler_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'The GCP project zone.')
-instance_group_manager = attribute('instance_group_manager', default: <%= JSON.pretty_generate(grab_attributes['instance_group_manager']) -%>, description: 'Instance group manager definition')
-autoscaler = attribute('autoscaler', default: <%= JSON.pretty_generate(grab_attributes['autoscaler']) -%>, description: 'Autoscaler definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'The GCP project zone.')
+instance_group_manager = attribute('instance_group_manager', default: <%= JSON.pretty_generate(grab_attributes(pwd)['instance_group_manager']) -%>, description: 'Instance group manager definition')
+autoscaler = attribute('autoscaler', default: <%= JSON.pretty_generate(grab_attributes(pwd)['autoscaler']) -%>, description: 'Autoscaler definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscalers.erb b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscalers.erb
index fc9d3bd4656e..3c889c152a88 100644
--- a/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscalers.erb
+++ b/templates/inspec/examples/google_compute_autoscaler/google_compute_autoscalers.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" -%>
-<% autoscaler = grab_attributes['autoscaler'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>
+<% autoscaler = grab_attributes(pwd)['autoscaler'] -%>
autoscalers = google_compute_autoscalers(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, zone: <%= doc_generation ? "#{gcp_zone}" : "gcp_zone" -%>)
describe.one do
autoscalers.autoscaling_policies.each do |autoscaling_policy|
diff --git a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket.erb b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket.erb
index 67d8f0798112..9c7d881256bc 100644
--- a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket.erb
+++ b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_name = "#{external_attribute('gcp_storage_bucket_name', doc_generation)}" -%>
-<% backend_bucket = grab_attributes['backend_bucket'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_name = "#{external_attribute(pwd, 'gcp_storage_bucket_name', doc_generation)}" -%>
+<% backend_bucket = grab_attributes(pwd)['backend_bucket'] -%>
describe google_compute_backend_bucket(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{backend_bucket['name']}'" : "backend_bucket['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{backend_bucket['description']}'" : "backend_bucket['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket_attributes.erb b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket_attributes.erb
index 2a46730a8143..e1b6caaee2ef 100644
--- a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket_attributes.erb
+++ b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_bucket_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_storage_bucket_name = attribute(:gcp_storage_bucket_name, default: '<%= external_attribute('gcp_storage_bucket_name') -%>', description: 'The GCS bucket name to use for the backend bucket.')
-backend_bucket = attribute('backend_bucket', default: <%= JSON.pretty_generate(grab_attributes['backend_bucket']) -%>, description: 'Backend bucket definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_storage_bucket_name = attribute(:gcp_storage_bucket_name, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_name') -%>', description: 'The GCS bucket name to use for the backend bucket.')
+backend_bucket = attribute('backend_bucket', default: <%= JSON.pretty_generate(grab_attributes(pwd)['backend_bucket']) -%>, description: 'Backend bucket definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_buckets.erb b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_buckets.erb
index 2d5fd5a9c5fc..7306eaffe1bd 100644
--- a/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_buckets.erb
+++ b/templates/inspec/examples/google_compute_backend_bucket/google_compute_backend_buckets.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_name = "#{external_attribute('gcp_storage_bucket_name', doc_generation)}" -%>
-<% backend_bucket = grab_attributes['backend_bucket'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_name = "#{external_attribute(pwd, 'gcp_storage_bucket_name', doc_generation)}" -%>
+<% backend_bucket = grab_attributes(pwd)['backend_bucket'] -%>
describe google_compute_backend_buckets(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{backend_bucket['name']}'" : "backend_bucket['name']" -%>) do
its('descriptions') { should include <%= doc_generation ? "'#{backend_bucket['description']}'" : "backend_bucket['description']" -%> }
<% if doc_generation # bucket name is partially random, this ruins VCR in integration tests -%>
diff --git a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service.erb b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service.erb
index 7fcd87046cf4..68635ea8dd11 100644
--- a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service.erb
+++ b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% backend_service = grab_attributes['backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% backend_service = grab_attributes(pwd)['backend_service'] -%>
describe google_compute_backend_service(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{backend_service['name']}'" : "backend_service['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{backend_service['description']}'" : "backend_service['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service_attributes.erb b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service_attributes.erb
index a672702c6a72..8a62223696f1 100644
--- a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service_attributes.erb
+++ b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_service_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-backend_service = attribute('backend_service', default: <%= JSON.pretty_generate(grab_attributes['backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+backend_service = attribute('backend_service', default: <%= JSON.pretty_generate(grab_attributes(pwd)['backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_services.erb b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_services.erb
index 7c7e7cc29d58..8462d7df9045 100644
--- a/templates/inspec/examples/google_compute_backend_service/google_compute_backend_services.erb
+++ b/templates/inspec/examples/google_compute_backend_service/google_compute_backend_services.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% backend_service = grab_attributes['backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% backend_service = grab_attributes(pwd)['backend_service'] -%>
describe google_compute_backend_services(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
its('names') { should include <%= doc_generation ? "'#{backend_service['name']}'" : "backend_service['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_disk/google_compute_disk.erb b/templates/inspec/examples/google_compute_disk/google_compute_disk.erb
index d00ed63614b0..a9cc19a9811f 100644
--- a/templates/inspec/examples/google_compute_disk/google_compute_disk.erb
+++ b/templates/inspec/examples/google_compute_disk/google_compute_disk.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
-<% snapshot = grab_attributes['snapshot'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
+<% snapshot = grab_attributes(pwd)['snapshot'] -%>
<% gcp_compute_disk_name = snapshot["disk_name"] -%>
<% gcp_compute_disk_image = snapshot["disk_image"] -%>
<% gcp_compute_disk_type = snapshot["disk_type"] -%>
diff --git a/templates/inspec/examples/google_compute_disk/google_compute_disk_attributes.erb b/templates/inspec/examples/google_compute_disk/google_compute_disk_attributes.erb
index 9de6cdaa0312..b426d63eebf8 100644
--- a/templates/inspec/examples/google_compute_disk/google_compute_disk_attributes.erb
+++ b/templates/inspec/examples/google_compute_disk/google_compute_disk_attributes.erb
@@ -1,6 +1,6 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'The GCP project zone.')
-snapshot = attribute('snapshot', default: <%= JSON.pretty_generate(grab_attributes['snapshot']) -%>, description: 'Disk snapshot description')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'The GCP project zone.')
+snapshot = attribute('snapshot', default: <%= JSON.pretty_generate(grab_attributes(pwd)['snapshot']) -%>, description: 'Disk snapshot description')
gcp_compute_disk_name = snapshot["disk_name"]
gcp_compute_disk_image = snapshot["disk_image"]
gcp_compute_disk_type = snapshot["disk_type"]
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_disk/google_compute_disks.erb b/templates/inspec/examples/google_compute_disk/google_compute_disks.erb
index f09c940b9de2..5e2196b501a1 100644
--- a/templates/inspec/examples/google_compute_disk/google_compute_disks.erb
+++ b/templates/inspec/examples/google_compute_disk/google_compute_disks.erb
@@ -1,7 +1,7 @@
-<% snapshot = grab_attributes['snapshot'] -%>
+<% snapshot = grab_attributes(pwd)['snapshot'] -%>
<% gcp_compute_disk_image = "#{snapshot["disk_image"].gsub('\'', '')}" -%>
most_recent_image = google_compute_image(project: <%= doc_generation ? "'#{gcp_compute_disk_image.split('/').first}'" : "gcp_compute_disk_image.split('/').first" -%>, name: <%= doc_generation ? "'#{gcp_compute_disk_image.split('/').last}'" : "gcp_compute_disk_image.split('/').last" -%>)
-describe google_compute_disks(project: <%= "#{external_attribute('gcp_project_id', doc_generation)}" -%>, zone: <%= "#{external_attribute('gcp_zone', doc_generation)}" -%>) do
+describe google_compute_disks(project: <%= "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>, zone: <%= "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>) do
it { should exist }
its('names') { should include <%= doc_generation ? "'#{snapshot['disk_name']}'" : "snapshot['disk_name']" -%> }
its('source_images') { should include most_recent_image.self_link }
diff --git a/templates/inspec/examples/google_compute_firewall/google_compute_firewall.erb b/templates/inspec/examples/google_compute_firewall/google_compute_firewall.erb
index 0b21ca50971a..000738d3b490 100644
--- a/templates/inspec/examples/google_compute_firewall/google_compute_firewall.erb
+++ b/templates/inspec/examples/google_compute_firewall/google_compute_firewall.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% firewall = grab_attributes['firewall'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% firewall = grab_attributes(pwd)['firewall'] -%>
describe google_compute_firewall(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{firewall['name']}'" : "firewall['name']" -%>) do
its('direction') { should cmp 'INGRESS' }
its('log_config_enabled?') { should be true }
diff --git a/templates/inspec/examples/google_compute_firewall/google_compute_firewall_attributes.erb b/templates/inspec/examples/google_compute_firewall/google_compute_firewall_attributes.erb
index 018e6e33fd4a..35324e120e66 100644
--- a/templates/inspec/examples/google_compute_firewall/google_compute_firewall_attributes.erb
+++ b/templates/inspec/examples/google_compute_firewall/google_compute_firewall_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-firewall = attribute('firewall', default: <%= JSON.pretty_generate(grab_attributes['firewall']) -%>, description: 'Firewall rule definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+firewall = attribute('firewall', default: <%= JSON.pretty_generate(grab_attributes(pwd)['firewall']) -%>, description: 'Firewall rule definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_firewall/google_compute_firewalls.erb b/templates/inspec/examples/google_compute_firewall/google_compute_firewalls.erb
index 32f52b6350e2..eaba7efcb441 100644
--- a/templates/inspec/examples/google_compute_firewall/google_compute_firewalls.erb
+++ b/templates/inspec/examples/google_compute_firewall/google_compute_firewalls.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% firewall = grab_attributes['firewall'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% firewall = grab_attributes(pwd)['firewall'] -%>
describe google_compute_firewalls(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
its('firewall_names') { should include <%= doc_generation ? "'#{firewall['name']}'" : "firewall['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule.erb b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule.erb
index ff1bbd869e27..42b81d8dd856 100644
--- a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule.erb
+++ b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_lb_region = "#{external_attribute('gcp_lb_region', doc_generation)}" -%>
-<% gcp_fr_udp_name = "#{external_attribute('gcp_fr_udp_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_lb_region = "#{external_attribute(pwd, 'gcp_lb_region', doc_generation)}" -%>
+<% gcp_fr_udp_name = "#{external_attribute(pwd, 'gcp_fr_udp_name', doc_generation)}" -%>
describe google_compute_forwarding_rule(project: <%= gcp_project_id -%>, region: <%= gcp_lb_region -%>, name: <%= doc_generation ? gcp_fr_udp_name : "\"\#{gcp_fr_udp_name}-500\"" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule_attributes.erb b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule_attributes.erb
index d9f39a586f8d..e6aa0dab921f 100644
--- a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule_attributes.erb
+++ b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rule_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_lb_region = attribute(:gcp_lb_region, default: '<%= external_attribute('gcp_lb_region') -%>', description: 'The region used for the forwarding rule.')
-gcp_fr_udp_name = attribute(:gcp_fr_udp_name, default: '<%= external_attribute('gcp_fr_udp_name') -%>', description: 'The forwarding rule name.')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_lb_region = attribute(:gcp_lb_region, default: '<%= external_attribute(pwd, 'gcp_lb_region') -%>', description: 'The region used for the forwarding rule.')
+gcp_fr_udp_name = attribute(:gcp_fr_udp_name, default: '<%= external_attribute(pwd, 'gcp_fr_udp_name') -%>', description: 'The forwarding rule name.')
diff --git a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rules.erb b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rules.erb
index 1054439a7ae1..4663581f0f5b 100644
--- a/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rules.erb
+++ b/templates/inspec/examples/google_compute_forwarding_rule/google_compute_forwarding_rules.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_lb_region = "#{external_attribute('gcp_lb_region', doc_generation)}" -%>
-<% gcp_fr_udp_name = "#{external_attribute('gcp_fr_udp_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_lb_region = "#{external_attribute(pwd, 'gcp_lb_region', doc_generation)}" -%>
+<% gcp_fr_udp_name = "#{external_attribute(pwd, 'gcp_fr_udp_name', doc_generation)}" -%>
describe google_compute_forwarding_rules(project: <%= gcp_project_id -%>, region: <%= gcp_lb_region -%>) do
its('forwarding_rule_names') { should include <%= doc_generation ? gcp_fr_udp_name : "\"\#{gcp_fr_udp_name}-500\"" -%> }
diff --git a/templates/inspec/examples/google_compute_global_address/google_compute_global_address.erb b/templates/inspec/examples/google_compute_global_address/google_compute_global_address.erb
index 56ed5d7d1ea9..7be07c5888aa 100644
--- a/templates/inspec/examples/google_compute_global_address/google_compute_global_address.erb
+++ b/templates/inspec/examples/google_compute_global_address/google_compute_global_address.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% global_address = grab_attributes['global_address'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% global_address = grab_attributes(pwd)['global_address'] -%>
describe google_compute_global_address(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{global_address['name']}'" : "global_address['name']" -%>) do
it { should exist }
its('ip_version') { should eq <%= doc_generation ? "'#{global_address['ip_version']}'" : "global_address['ip_version']" -%> }
diff --git a/templates/inspec/examples/google_compute_global_address/google_compute_global_address_attributes.erb b/templates/inspec/examples/google_compute_global_address/google_compute_global_address_attributes.erb
index 6649541bc771..9f8b152276e7 100644
--- a/templates/inspec/examples/google_compute_global_address/google_compute_global_address_attributes.erb
+++ b/templates/inspec/examples/google_compute_global_address/google_compute_global_address_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-global_address = attribute('global_address', default: <%= JSON.pretty_generate(grab_attributes['global_address']) -%>, description: 'Compute Global Address definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+global_address = attribute('global_address', default: <%= JSON.pretty_generate(grab_attributes(pwd)['global_address']) -%>, description: 'Compute Global Address definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_global_address/google_compute_global_addresses.erb b/templates/inspec/examples/google_compute_global_address/google_compute_global_addresses.erb
index 9d2facd88721..b241e0f7e9f9 100644
--- a/templates/inspec/examples/google_compute_global_address/google_compute_global_addresses.erb
+++ b/templates/inspec/examples/google_compute_global_address/google_compute_global_addresses.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% global_address = grab_attributes['global_address'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% global_address = grab_attributes(pwd)['global_address'] -%>
describe google_compute_global_addresses(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{global_address['name']}'" : "global_address['name']" -%>) do
its('count') { should be >= 1 }
its('names') { should include <%= doc_generation ? "'#{global_address['name']}'" : "global_address['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule.erb b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule.erb
index 451617be56bd..379e7ef49d02 100644
--- a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule.erb
+++ b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule.erb
@@ -1,9 +1,9 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% global_forwarding_rule = grab_attributes['global_forwarding_rule'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% global_forwarding_rule = grab_attributes(pwd)['global_forwarding_rule'] -%>
describe google_compute_global_forwarding_rule(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{global_forwarding_rule['name']}'" : "global_forwarding_rule['name']" -%>) do
it { should exist }
its('port_range') { should eq <%= doc_generation ? "'#{global_forwarding_rule['port_range']}'" : "global_forwarding_rule['port_range']" -%> }
- its('target') { should match /\/<%= "#{grab_attributes['http_proxy']['name']}" -%>$/ }
+ its('target') { should match /\/<%= "#{grab_attributes(pwd)['http_proxy']['name']}" -%>$/ }
end
describe google_compute_global_forwarding_rule(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: 'nonexistent') do
diff --git a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule_attributes.erb b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule_attributes.erb
index b28de737a3de..afb45a68c4c5 100644
--- a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule_attributes.erb
+++ b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rule_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-global_forwarding_rule = attribute('global_forwarding_rule', default: <%= JSON.pretty_generate(grab_attributes['global_forwarding_rule']) -%>, description: 'Compute global forwarding rule definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+global_forwarding_rule = attribute('global_forwarding_rule', default: <%= JSON.pretty_generate(grab_attributes(pwd)['global_forwarding_rule']) -%>, description: 'Compute global forwarding rule definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rules.erb b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rules.erb
index 109c4857056a..a74d39ead5ee 100644
--- a/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rules.erb
+++ b/templates/inspec/examples/google_compute_global_forwarding_rule/google_compute_global_forwarding_rules.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% global_forwarding_rule = grab_attributes['global_forwarding_rule'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% global_forwarding_rule = grab_attributes(pwd)['global_forwarding_rule'] -%>
describe google_compute_global_forwarding_rules(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('count') { should be >= 1 }
its('port_ranges') { should include <%= doc_generation ? "'#{global_forwarding_rule['port_range']}'" : "global_forwarding_rule['port_range']" -%> }
diff --git a/templates/inspec/examples/google_compute_health_check/google_compute_health_check.erb b/templates/inspec/examples/google_compute_health_check/google_compute_health_check.erb
index 30931f44ceca..562caa826e16 100644
--- a/templates/inspec/examples/google_compute_health_check/google_compute_health_check.erb
+++ b/templates/inspec/examples/google_compute_health_check/google_compute_health_check.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% health_check = grab_attributes['health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% health_check = grab_attributes(pwd)['health_check'] -%>
describe google_compute_health_check(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{health_check['name']}'" : "health_check['name']" -%>) do
it { should exist }
its('timeout_sec') { should eq <%= doc_generation ? "'#{health_check['timeout_sec']}'" : "health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_health_check/google_compute_health_check_attributes.erb b/templates/inspec/examples/google_compute_health_check/google_compute_health_check_attributes.erb
index 7b601264bd64..9a4940ad4fe0 100644
--- a/templates/inspec/examples/google_compute_health_check/google_compute_health_check_attributes.erb
+++ b/templates/inspec/examples/google_compute_health_check/google_compute_health_check_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-health_check = attribute('health_check', default: <%= JSON.pretty_generate(grab_attributes['health_check']) -%>, description: 'Health check definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+health_check = attribute('health_check', default: <%= JSON.pretty_generate(grab_attributes(pwd)['health_check']) -%>, description: 'Health check definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_health_check/google_compute_health_checks.erb b/templates/inspec/examples/google_compute_health_check/google_compute_health_checks.erb
index c367e583701c..1abe9f3c5b9d 100644
--- a/templates/inspec/examples/google_compute_health_check/google_compute_health_checks.erb
+++ b/templates/inspec/examples/google_compute_health_check/google_compute_health_checks.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% health_check = grab_attributes['health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% health_check = grab_attributes(pwd)['health_check'] -%>
describe google_compute_health_checks(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{health_check['name']}'" : "health_check['name']" -%> }
its('timeout_secs') { should include <%= doc_generation ? "'#{health_check['timeout_sec']}'" : "health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check.erb b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check.erb
index b8e7b5d6c652..fd8d25a2c163 100644
--- a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check.erb
+++ b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% http_health_check = grab_attributes['http_health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% http_health_check = grab_attributes(pwd)['http_health_check'] -%>
describe google_compute_http_health_check(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{http_health_check['name']}'" : "http_health_check['name']" -%>) do
it { should exist }
its('timeout_sec') { should eq <%= doc_generation ? "'#{http_health_check['timeout_sec']}'" : "http_health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check_attributes.erb b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check_attributes.erb
index 80e5c6a6a9b8..3a8648e846aa 100644
--- a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check_attributes.erb
+++ b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_check_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-http_health_check = attribute('http_health_check', default: <%= JSON.pretty_generate(grab_attributes['http_health_check']) -%>, description: 'HTTP health check definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+http_health_check = attribute('http_health_check', default: <%= JSON.pretty_generate(grab_attributes(pwd)['http_health_check']) -%>, description: 'HTTP health check definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_checks.erb b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_checks.erb
index 7e19b4f967e0..afc9f3f7cffe 100644
--- a/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_checks.erb
+++ b/templates/inspec/examples/google_compute_http_health_check/google_compute_http_health_checks.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% http_health_check = grab_attributes['http_health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% http_health_check = grab_attributes(pwd)['http_health_check'] -%>
describe google_compute_http_health_checks(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{http_health_check['name']}'" : "http_health_check['name']" -%> }
its('timeout_secs') { should include <%= doc_generation ? "'#{http_health_check['timeout_sec']}'" : "http_health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check.erb b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check.erb
index aa8a2440eb3c..d23793ace65c 100644
--- a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check.erb
+++ b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% https_health_check = grab_attributes['https_health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% https_health_check = grab_attributes(pwd)['https_health_check'] -%>
describe google_compute_https_health_check(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{https_health_check['name']}'" : "https_health_check['name']" -%>) do
it { should exist }
its('timeout_sec') { should eq <%= doc_generation ? "'#{https_health_check['timeout_sec']}'" : "https_health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check_attributes.erb b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check_attributes.erb
index 45e945adfb91..515e2be4f1c9 100644
--- a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check_attributes.erb
+++ b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_check_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-https_health_check = attribute('https_health_check', default: <%= JSON.pretty_generate(grab_attributes['https_health_check']) -%>, description: 'HTTPS health check definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+https_health_check = attribute('https_health_check', default: <%= JSON.pretty_generate(grab_attributes(pwd)['https_health_check']) -%>, description: 'HTTPS health check definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_checks.erb b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_checks.erb
index 3d88ada99330..2e034c04f66d 100644
--- a/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_checks.erb
+++ b/templates/inspec/examples/google_compute_https_health_check/google_compute_https_health_checks.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% https_health_check = grab_attributes['https_health_check'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% https_health_check = grab_attributes(pwd)['https_health_check'] -%>
describe google_compute_https_health_checks(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{https_health_check['name']}'" : "https_health_check['name']" -%> }
its('timeout_secs') { should include <%= doc_generation ? "'#{https_health_check['timeout_sec']}'" : "https_health_check['timeout_sec']" -%> }
diff --git a/templates/inspec/examples/google_compute_image/google_compute_image.erb b/templates/inspec/examples/google_compute_image/google_compute_image.erb
index 34a3d6fe7e83..93e3d1b2ae15 100644
--- a/templates/inspec/examples/google_compute_image/google_compute_image.erb
+++ b/templates/inspec/examples/google_compute_image/google_compute_image.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% compute_image = grab_attributes['compute_image'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% compute_image = grab_attributes(pwd)['compute_image'] -%>
describe google_compute_image(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{compute_image['name']}'" : "compute_image['name']" -%>) do
it { should exist }
its('disk_size_gb') { should cmp 3 }
diff --git a/templates/inspec/examples/google_compute_image/google_compute_image_attributes.erb b/templates/inspec/examples/google_compute_image/google_compute_image_attributes.erb
index 146c3fefc2a3..fb038a9af531 100644
--- a/templates/inspec/examples/google_compute_image/google_compute_image_attributes.erb
+++ b/templates/inspec/examples/google_compute_image/google_compute_image_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-compute_image = attribute('compute_image', default: <%= JSON.pretty_generate(grab_attributes['compute_image']) -%>, description: 'Compute image description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+compute_image = attribute('compute_image', default: <%= JSON.pretty_generate(grab_attributes(pwd)['compute_image']) -%>, description: 'Compute image description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance/google_compute_instance.erb b/templates/inspec/examples/google_compute_instance/google_compute_instance.erb
index 90492b58ead5..d5cd1612cc13 100644
--- a/templates/inspec/examples/google_compute_instance/google_compute_instance.erb
+++ b/templates/inspec/examples/google_compute_instance/google_compute_instance.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
-<% instance = grab_attributes['instance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
+<% instance = grab_attributes(pwd)['instance'] -%>
describe google_compute_instance(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>, name: <%= doc_generation ? "'#{instance['name']}'" : "instance['name']" -%>) do
it { should exist }
its('machine_type') { should match <%= doc_generation ? "'#{instance['machine_type']}'" : "instance['machine_type']" -%> }
@@ -8,6 +8,8 @@ describe google_compute_instance(project: <%= gcp_project_id -%>, zone: <%= gcp_
its('tags.items') { should include <%= doc_generation ? "'#{instance['tag_2']}'" : "instance['tag_2']" -%> }
its('tag_count') { should cmp 2 }
its('service_account_scopes') { should include <%= doc_generation ? "'#{instance['sa_scope']}'" : "instance['sa_scope']" -%> }
+ its('metadata_keys') { should include <%= doc_generation ? "'#{instance['metadata_key']}'" : "instance['metadata_key']" -%> }
+ its('metadata_values') { should include <%= doc_generation ? "'#{instance['metadata_value']}'" : "instance['metadata_value']" -%> }
end
describe google_compute_instance(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>, name: 'nonexistent') do
diff --git a/templates/inspec/examples/google_compute_instance/google_compute_instance_attributes.erb b/templates/inspec/examples/google_compute_instance/google_compute_instance_attributes.erb
index 293e916a8baa..ff87256cf185 100644
--- a/templates/inspec/examples/google_compute_instance/google_compute_instance_attributes.erb
+++ b/templates/inspec/examples/google_compute_instance/google_compute_instance_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'GCP zone name of the compute disk')
-instance = attribute('instance', default: <%= JSON.pretty_generate(grab_attributes['instance']) -%>, description: 'Compute instance description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'GCP zone name of the compute disk')
+instance = attribute('instance', default: <%= JSON.pretty_generate(grab_attributes(pwd)['instance']) -%>, description: 'Compute instance description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance/google_compute_instances.erb b/templates/inspec/examples/google_compute_instance/google_compute_instances.erb
index cb05c7971485..7d2472b3e5ad 100644
--- a/templates/inspec/examples/google_compute_instance/google_compute_instances.erb
+++ b/templates/inspec/examples/google_compute_instance/google_compute_instances.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
-<% instance = grab_attributes['instance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
+<% instance = grab_attributes(pwd)['instance'] -%>
describe google_compute_instances(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>) do
its('instance_names') { should include <%= doc_generation ? "'#{instance['name']}'" : "instance['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group.erb b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group.erb
index f8d2da23c6f5..e8624744dd93 100644
--- a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group.erb
+++ b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
-<% instance_group = grab_attributes['instance_group'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
+<% instance_group = grab_attributes(pwd)['instance_group'] -%>
describe google_compute_instance_group(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>, name: <%= doc_generation ? "'#{instance_group['name']}'" : "instance_group['name']" -%>) do
it { should exist }
its('description') { should cmp <%= doc_generation ? "'#{instance_group['description']}'" : "instance_group['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group_attributes.erb b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group_attributes.erb
index 048964c15651..392989d3f94e 100644
--- a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group_attributes.erb
+++ b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_group_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'GCP zone name')
-instance_group = attribute('instance_group', default: <%= JSON.pretty_generate(grab_attributes['instance_group']) -%>, description: 'Instance group')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'GCP zone name')
+instance_group = attribute('instance_group', default: <%= JSON.pretty_generate(grab_attributes(pwd)['instance_group']) -%>, description: 'Instance group')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_groups.erb b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_groups.erb
index c4340cfa99ce..e83fcf0d7e85 100644
--- a/templates/inspec/examples/google_compute_instance_group/google_compute_instance_groups.erb
+++ b/templates/inspec/examples/google_compute_instance_group/google_compute_instance_groups.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
-<% instance_group = grab_attributes['instance_group'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
+<% instance_group = grab_attributes(pwd)['instance_group'] -%>
describe google_compute_instance_groups(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>) do
its('instance_group_names') { should include <%= doc_generation ? "'#{instance_group['name']}'" : "instance_group['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager.erb b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager.erb
index e16516c1e30c..739979dbb39b 100644
--- a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager.erb
+++ b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" -%>
-<% gcp_lb_mig1_name = "#{external_attribute('gcp_lb_mig1_name', doc_generation)}" -%>
-<% instance_group_manager = grab_attributes['instance_group_manager'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>
+<% gcp_lb_mig1_name = "#{external_attribute(pwd, 'gcp_lb_mig1_name', doc_generation)}" -%>
+<% instance_group_manager = grab_attributes(pwd)['instance_group_manager'] -%>
describe google_compute_instance_group_manager(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, zone: <%= doc_generation ? "#{gcp_zone}" : "gcp_zone" -%>, name: <%= doc_generation ? "'#{instance_group_manager['name']}'" : "instance_group_manager['name']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager_attributes.erb b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager_attributes.erb
index c69f8feb36af..7e7a7eee553e 100644
--- a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager_attributes.erb
+++ b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_manager_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'The GCP project zone.')
-instance_group_manager = attribute('instance_group_manager', default: <%= JSON.pretty_generate(grab_attributes['instance_group_manager']) -%>, description: 'Instance group manager definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'The GCP project zone.')
+instance_group_manager = attribute('instance_group_manager', default: <%= JSON.pretty_generate(grab_attributes(pwd)['instance_group_manager']) -%>, description: 'Instance group manager definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_managers.erb b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_managers.erb
index d774663ccec5..5ec0875ac2d5 100644
--- a/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_managers.erb
+++ b/templates/inspec/examples/google_compute_instance_group_manager/google_compute_instance_group_managers.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" -%>
-<% gcp_lb_mig1_name = "#{external_attribute('gcp_lb_mig1_name', doc_generation)}" -%>
-<% instance_group_manager = grab_attributes['instance_group_manager'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>
+<% gcp_lb_mig1_name = "#{external_attribute(pwd, 'gcp_lb_mig1_name', doc_generation)}" -%>
+<% instance_group_manager = grab_attributes(pwd)['instance_group_manager'] -%>
describe google_compute_instance_group_managers(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, zone: <%= doc_generation ? "#{gcp_zone}" : "gcp_zone" -%>) do
its('base_instance_names') { should include <%= doc_generation ? "'#{instance_group_manager['base_instance_name']}'" : "instance_group_manager['base_instance_name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template.erb b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template.erb
index ad95cb041b4d..0dc861ba1e62 100644
--- a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template.erb
+++ b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% instance_template = grab_attributes['instance_template'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% instance_template = grab_attributes(pwd)['instance_template'] -%>
describe google_compute_instance_template(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{instance_template['name']}'" : "instance_template['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{instance_template['description']}'" : "instance_template['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template_attributes.erb b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template_attributes.erb
index ccc90bb07712..43ee62466cb8 100644
--- a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template_attributes.erb
+++ b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_template_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-instance_template = attribute('instance_template', default: <%= JSON.pretty_generate(grab_attributes['instance_template']) -%>, description: 'An instance template definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+instance_template = attribute('instance_template', default: <%= JSON.pretty_generate(grab_attributes(pwd)['instance_template']) -%>, description: 'An instance template definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_templates.erb b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_templates.erb
index dd968bfbf06a..a6691a2c2661 100644
--- a/templates/inspec/examples/google_compute_instance_template/google_compute_instance_templates.erb
+++ b/templates/inspec/examples/google_compute_instance_template/google_compute_instance_templates.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% instance_template = grab_attributes['instance_template'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% instance_template = grab_attributes(pwd)['instance_template'] -%>
describe google_compute_instance_templates(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{instance_template['name']}'" : "instance_template['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_network/google_compute_network.erb b/templates/inspec/examples/google_compute_network/google_compute_network.erb
index 66f9c910a0c4..b24f523a9cec 100644
--- a/templates/inspec/examples/google_compute_network/google_compute_network.erb
+++ b/templates/inspec/examples/google_compute_network/google_compute_network.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% network = grab_attributes['network'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% network = grab_attributes(pwd)['network'] -%>
describe google_compute_network(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{network['name']}'" : "network['name']" -%>) do
it { should exist }
its('routing_config.routing_mode') { should cmp <%= doc_generation ? "'#{network['routing_mode']}'" : "network['routing_mode']" -%> }
diff --git a/templates/inspec/examples/google_compute_network/google_compute_network_attributes.erb b/templates/inspec/examples/google_compute_network/google_compute_network_attributes.erb
index 205e68a34291..96f6dab07361 100644
--- a/templates/inspec/examples/google_compute_network/google_compute_network_attributes.erb
+++ b/templates/inspec/examples/google_compute_network/google_compute_network_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-network = attribute('network', default: <%= JSON.pretty_generate(grab_attributes['network']) -%>, description: 'Network description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+network = attribute('network', default: <%= JSON.pretty_generate(grab_attributes(pwd)['network']) -%>, description: 'Network description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_network/google_compute_networks.erb b/templates/inspec/examples/google_compute_network/google_compute_networks.erb
index ea617bf94aff..c77f9b4eefec 100644
--- a/templates/inspec/examples/google_compute_network/google_compute_networks.erb
+++ b/templates/inspec/examples/google_compute_network/google_compute_networks.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% network = grab_attributes['network'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% network = grab_attributes(pwd)['network'] -%>
describe google_compute_networks(project: <%= gcp_project_id -%>) do
its('network_names') { should include <%= doc_generation ? "'#{network['name']}'" : "network['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group.erb b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group.erb
index 6034a69db465..dcd80daaa106 100644
--- a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group.erb
+++ b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% network_endpoint_group = grab_attributes['network_endpoint_group'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% network_endpoint_group = grab_attributes(pwd)['network_endpoint_group'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_network_endpoint_group(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>, name: <%= doc_generation ? "'#{network_endpoint_group['name']}'" : "network_endpoint_group['name']" -%>) do
it { should exist }
its('default_port') { should cmp <%= doc_generation ? "'#{network_endpoint_group['default_port']}'" : "network_endpoint_group['default_port']" -%> }
diff --git a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group_attributes.erb b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group_attributes.erb
index e6fe6011cafe..c2827e4a70a5 100644
--- a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group_attributes.erb
+++ b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_group_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-network_endpoint_group = attribute('network_endpoint_group', default: <%= JSON.pretty_generate(grab_attributes['network_endpoint_group']) -%>, description: 'Network endpoint group description')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'GCP zone name')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+network_endpoint_group = attribute('network_endpoint_group', default: <%= JSON.pretty_generate(grab_attributes(pwd)['network_endpoint_group']) -%>, description: 'Network endpoint group description')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'GCP zone name')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_groups.erb b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_groups.erb
index b416a5075442..24ea8c229dc3 100644
--- a/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_groups.erb
+++ b/templates/inspec/examples/google_compute_network_endpoint_group/google_compute_network_endpoint_groups.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% network_endpoint_group = grab_attributes['network_endpoint_group'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% network_endpoint_group = grab_attributes(pwd)['network_endpoint_group'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_network_endpoint_groups(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>) do
its('default_ports') { should include <%= doc_generation ? "'#{network_endpoint_group['default_port']}'" : "network_endpoint_group['default_port']" -%> }
its('names') { should include <%= doc_generation ? "'#{network_endpoint_group['name']}'" : "network_endpoint_group['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_node_group/google_compute_node_group.erb b/templates/inspec/examples/google_compute_node_group/google_compute_node_group.erb
index a4567eaa3e9c..aa6a57057f64 100644
--- a/templates/inspec/examples/google_compute_node_group/google_compute_node_group.erb
+++ b/templates/inspec/examples/google_compute_node_group/google_compute_node_group.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% node_group = grab_attributes['node_group'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% node_group = grab_attributes(pwd)['node_group'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_node_group(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>, name: <%= doc_generation ? "'#{node_group['name']}'" : "node_group['name']" -%>) do
it { should exist }
its('description') { should cmp <%= doc_generation ? "'#{node_group['description']}'" : "node_group['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_node_group/google_compute_node_group_attributes.erb b/templates/inspec/examples/google_compute_node_group/google_compute_node_group_attributes.erb
index 5d11c86bc48e..5f8d7f99f5bc 100644
--- a/templates/inspec/examples/google_compute_node_group/google_compute_node_group_attributes.erb
+++ b/templates/inspec/examples/google_compute_node_group/google_compute_node_group_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-node_group = attribute('node_group', default: <%= JSON.pretty_generate(grab_attributes['node_group']) -%>, description: 'Node group description')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'GCP zone name')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+node_group = attribute('node_group', default: <%= JSON.pretty_generate(grab_attributes(pwd)['node_group']) -%>, description: 'Node group description')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'GCP zone name')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_node_group/google_compute_node_groups.erb b/templates/inspec/examples/google_compute_node_group/google_compute_node_groups.erb
index 4eea2831b019..a6f7c5352fa5 100644
--- a/templates/inspec/examples/google_compute_node_group/google_compute_node_groups.erb
+++ b/templates/inspec/examples/google_compute_node_group/google_compute_node_groups.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% node_group = grab_attributes['node_group'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% node_group = grab_attributes(pwd)['node_group'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_node_groups(project: <%= gcp_project_id -%>, zone: <%= gcp_zone -%>) do
it { should exist }
its('descriptions') { should include <%= doc_generation ? "'#{node_group['description']}'" : "node_group['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_node_template/google_compute_node_template.erb b/templates/inspec/examples/google_compute_node_template/google_compute_node_template.erb
index 574227febdff..5fc714c79fc8 100644
--- a/templates/inspec/examples/google_compute_node_template/google_compute_node_template.erb
+++ b/templates/inspec/examples/google_compute_node_template/google_compute_node_template.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% node_template = grab_attributes['node_template'] -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% node_template = grab_attributes(pwd)['node_template'] -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" %>
describe google_compute_node_template(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{node_template['name']}'" : "node_template['name']" -%>) do
it { should exist }
its('node_affinity_labels') { should include(<%= doc_generation ? "'#{node_template['label_key']}'" : "node_template['label_key']" -%> => <%= doc_generation ? "'#{node_template['label_value']}'" : "node_template['label_value']" -%>) }
diff --git a/templates/inspec/examples/google_compute_node_template/google_compute_node_template_attributes.erb b/templates/inspec/examples/google_compute_node_template/google_compute_node_template_attributes.erb
index 7ecffbee4933..9e4022c57d63 100644
--- a/templates/inspec/examples/google_compute_node_template/google_compute_node_template_attributes.erb
+++ b/templates/inspec/examples/google_compute_node_template/google_compute_node_template_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-node_template = attribute('node_template', default: <%= JSON.pretty_generate(grab_attributes['node_template']) -%>, description: 'Node template description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+node_template = attribute('node_template', default: <%= JSON.pretty_generate(grab_attributes(pwd)['node_template']) -%>, description: 'Node template description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_node_template/google_compute_node_templates.erb b/templates/inspec/examples/google_compute_node_template/google_compute_node_templates.erb
index aaa36f94d300..9904f65a728c 100644
--- a/templates/inspec/examples/google_compute_node_template/google_compute_node_templates.erb
+++ b/templates/inspec/examples/google_compute_node_template/google_compute_node_templates.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% node_template = grab_attributes['node_template'] -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% node_template = grab_attributes(pwd)['node_template'] -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" %>
describe google_compute_node_templates(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('names') { should include <%= doc_generation ? "'#{node_template['name']}'" : "node_template['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_project_info/google_compute_project_info.erb b/templates/inspec/examples/google_compute_project_info/google_compute_project_info.erb
index f101eaf31e58..0bdc41f0eaec 100644
--- a/templates/inspec/examples/google_compute_project_info/google_compute_project_info.erb
+++ b/templates/inspec/examples/google_compute_project_info/google_compute_project_info.erb
@@ -1,4 +1,4 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
describe google_compute_project_info(project: <%= gcp_project_id -%>) do
it { should exist }
its('default_service_account') { should match "developer.gserviceaccount.com" }
diff --git a/templates/inspec/examples/google_compute_project_info/google_compute_project_info_attributes.erb b/templates/inspec/examples/google_compute_project_info/google_compute_project_info_attributes.erb
index a2863dfa3703..9e434667ef77 100644
--- a/templates/inspec/examples/google_compute_project_info/google_compute_project_info_attributes.erb
+++ b/templates/inspec/examples/google_compute_project_info/google_compute_project_info_attributes.erb
@@ -1 +1 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_region/google_compute_region.erb b/templates/inspec/examples/google_compute_region/google_compute_region.erb
index 5ca45d827c3f..d47c7a9a551c 100644
--- a/templates/inspec/examples/google_compute_region/google_compute_region.erb
+++ b/templates/inspec/examples/google_compute_region/google_compute_region.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
describe google_compute_region(project: <%= gcp_project_id -%>, name: <%= gcp_location -%>) do
it { should exist }
it { should be_up }
diff --git a/templates/inspec/examples/google_compute_region/google_compute_region_attributes.erb b/templates/inspec/examples/google_compute_region/google_compute_region_attributes.erb
index 8241a8af352d..7a694ac5cb22 100644
--- a/templates/inspec/examples/google_compute_region/google_compute_region_attributes.erb
+++ b/templates/inspec/examples/google_compute_region/google_compute_region_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_region/google_compute_regions.erb b/templates/inspec/examples/google_compute_region/google_compute_regions.erb
index 05bf6392abd4..8c3193d9f05c 100644
--- a/templates/inspec/examples/google_compute_region/google_compute_regions.erb
+++ b/templates/inspec/examples/google_compute_region/google_compute_regions.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
describe google_compute_regions(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
its('region_names') { should include "#{gcp_location}" }
diff --git a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service.erb b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service.erb
index 8ceca054d24c..064154375feb 100644
--- a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service.erb
+++ b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% region_backend_service = grab_attributes['region_backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% region_backend_service = grab_attributes(pwd)['region_backend_service'] -%>
describe google_compute_region_backend_service(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{region_backend_service['name']}'" : "region_backend_service['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{region_backend_service['description']}'" : "region_backend_service['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service_attributes.erb b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service_attributes.erb
index 4b6866b7922d..298773c5f630 100644
--- a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service_attributes.erb
+++ b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_service_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-region_backend_service = attribute('region_backend_service', default: <%= JSON.pretty_generate(grab_attributes['region_backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+region_backend_service = attribute('region_backend_service', default: <%= JSON.pretty_generate(grab_attributes(pwd)['region_backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_services.erb b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_services.erb
index 3d6224dc4960..5707d919233a 100644
--- a/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_services.erb
+++ b/templates/inspec/examples/google_compute_region_backend_service/google_compute_region_backend_services.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% region_backend_service = grab_attributes['region_backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% region_backend_service = grab_attributes(pwd)['region_backend_service'] -%>
describe google_compute_region_backend_services(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('count') { should be >= 1 }
its('names') { should include <%= doc_generation ? "'#{region_backend_service['name']}'" : "region_backend_service['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager.erb b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager.erb
index 2231b0c0f0e8..4269de5aca53 100644
--- a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager.erb
+++ b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% rigm = grab_attributes['rigm'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% rigm = grab_attributes(pwd)['rigm'] -%>
describe google_compute_region_instance_group_manager(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{rigm['name']}'" : "rigm['name']" -%>) do
it { should exist }
its('base_instance_name') { should eq <%= doc_generation ? "'#{rigm['base_instance_name']}'" : "rigm['base_instance_name']" -%> }
diff --git a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager_attributes.erb b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager_attributes.erb
index 3d1f22a10758..5799971ab6b2 100644
--- a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager_attributes.erb
+++ b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_manager_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-rigm = attribute('rigm', default: <%= JSON.pretty_generate(grab_attributes['rigm']) -%>, description: 'Compute region instance group manager description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+rigm = attribute('rigm', default: <%= JSON.pretty_generate(grab_attributes(pwd)['rigm']) -%>, description: 'Compute region instance group manager description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_managers.erb b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_managers.erb
index 318fc5b07199..be3faf38ac69 100644
--- a/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_managers.erb
+++ b/templates/inspec/examples/google_compute_region_instance_group_manager/google_compute_region_instance_group_managers.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% rigm = grab_attributes['rigm'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% rigm = grab_attributes(pwd)['rigm'] -%>
describe google_compute_region_instance_group_managers(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('instance_group_manager_names') { should include <%= doc_generation ? "'#{rigm['name']}'" : "rigm['name']" -%> }
its('base_instance_names') { should include <%= doc_generation ? "'#{rigm['base_instance_name']}'" : "rigm['base_instance_name']" -%> }
diff --git a/templates/inspec/examples/google_compute_route/google_compute_route.erb b/templates/inspec/examples/google_compute_route/google_compute_route.erb
index 2dfa1fed280c..61fd4cbea81f 100644
--- a/templates/inspec/examples/google_compute_route/google_compute_route.erb
+++ b/templates/inspec/examples/google_compute_route/google_compute_route.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% route = grab_attributes['route'] -%>
-<% gcp_network_name = "#{external_attribute('gcp_network_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% route = grab_attributes(pwd)['route'] -%>
+<% gcp_network_name = "#{external_attribute(pwd, 'gcp_network_name', doc_generation)}" -%>
describe google_compute_route(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{route['name']}'" : "route['name']" -%>) do
it { should exist }
its('dest_range') { should eq <%= doc_generation ? "'#{route['dest_range']}'" : "route['dest_range']" -%> }
diff --git a/templates/inspec/examples/google_compute_route/google_compute_route_attributes.erb b/templates/inspec/examples/google_compute_route/google_compute_route_attributes.erb
index 31eb5dbf7302..4912798bb9d8 100644
--- a/templates/inspec/examples/google_compute_route/google_compute_route_attributes.erb
+++ b/templates/inspec/examples/google_compute_route/google_compute_route_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-route = attribute('route', default: <%= JSON.pretty_generate(grab_attributes['route']) -%>, description: 'Compute route description')
-gcp_network_name = attribute(:gcp_network_name, default: '<%= external_attribute('gcp_network_name') -%>', description: 'GCP network name')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+route = attribute('route', default: <%= JSON.pretty_generate(grab_attributes(pwd)['route']) -%>, description: 'Compute route description')
+gcp_network_name = attribute(:gcp_network_name, default: '<%= external_attribute(pwd, 'gcp_network_name') -%>', description: 'GCP network name')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_route/google_compute_routes.erb b/templates/inspec/examples/google_compute_route/google_compute_routes.erb
index 0da181373ea7..413789b35fc2 100644
--- a/templates/inspec/examples/google_compute_route/google_compute_routes.erb
+++ b/templates/inspec/examples/google_compute_route/google_compute_routes.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% route = grab_attributes['route'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% route = grab_attributes(pwd)['route'] -%>
describe google_compute_routes(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
its('dest_ranges') { should include <%= doc_generation ? "'#{route['dest_range']}'" : "route['dest_range']" -%> }
diff --git a/templates/inspec/examples/google_compute_router/google_compute_router.erb b/templates/inspec/examples/google_compute_router/google_compute_router.erb
index b4f0467e637d..fecb0bcfcf67 100644
--- a/templates/inspec/examples/google_compute_router/google_compute_router.erb
+++ b/templates/inspec/examples/google_compute_router/google_compute_router.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% router = grab_attributes['router'] -%>
-<% gcp_network_name = "#{external_attribute('gcp_network_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% router = grab_attributes(pwd)['router'] -%>
+<% gcp_network_name = "#{external_attribute(pwd, 'gcp_network_name', doc_generation)}" -%>
describe google_compute_router(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{router['name']}'" : "router['name']" -%>) do
it { should exist }
its('bgp.asn') { should eq <%= doc_generation ? "'#{router['bgp_asn']}'" : "router['bgp_asn']" -%> }
diff --git a/templates/inspec/examples/google_compute_router/google_compute_router_attributes.erb b/templates/inspec/examples/google_compute_router/google_compute_router_attributes.erb
index 6319dea87fa0..9d7e97fc6da4 100644
--- a/templates/inspec/examples/google_compute_router/google_compute_router_attributes.erb
+++ b/templates/inspec/examples/google_compute_router/google_compute_router_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-router = attribute('router', default: <%= JSON.pretty_generate(grab_attributes['router']) -%>, description: 'Compute router description')
-gcp_network_name = attribute(:gcp_network_name, default: '<%= external_attribute('gcp_network_name') -%>', description: 'GCP network name')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+router = attribute('router', default: <%= JSON.pretty_generate(grab_attributes(pwd)['router']) -%>, description: 'Compute router description')
+gcp_network_name = attribute(:gcp_network_name, default: '<%= external_attribute(pwd, 'gcp_network_name') -%>', description: 'GCP network name')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_router/google_compute_routers.erb b/templates/inspec/examples/google_compute_router/google_compute_routers.erb
index 3adf63690476..9b02a8421407 100644
--- a/templates/inspec/examples/google_compute_router/google_compute_routers.erb
+++ b/templates/inspec/examples/google_compute_router/google_compute_routers.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% router = grab_attributes['router'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% router = grab_attributes(pwd)['router'] -%>
describe google_compute_routers(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('names') { should include <%= doc_generation ? "'#{router['name']}'" : "router['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat.erb b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat.erb
index 89f3a5539cd6..192462efbf7f 100644
--- a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat.erb
+++ b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% router = grab_attributes['router'] -%>
-<% router_nat = grab_attributes['router_nat'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% router = grab_attributes(pwd)['router'] -%>
+<% router_nat = grab_attributes(pwd)['router_nat'] -%>
describe google_compute_router_nat(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, router: <%= doc_generation ? "'#{router['name']}'" : "router['name']" -%>, name: <%= doc_generation ? "'#{router_nat['name']}'" : "router_nat['name']" -%>) do
it { should exist }
its('nat_ip_allocate_option') { should cmp <%= doc_generation ? "'#{router_nat['nat_ip_allocate_option']}'" : "router_nat['nat_ip_allocate_option']" -%> }
diff --git a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat_attributes.erb b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat_attributes.erb
index bfada640e1dc..9316bb528181 100644
--- a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat_attributes.erb
+++ b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nat_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-router = attribute('router', default: <%= JSON.pretty_generate(grab_attributes['router']) -%>, description: 'Compute router description')
-router_nat = attribute('router_nat', default: <%= JSON.pretty_generate(grab_attributes['router_nat']) -%>, description: 'Compute router NAT description')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+router = attribute('router', default: <%= JSON.pretty_generate(grab_attributes(pwd)['router']) -%>, description: 'Compute router description')
+router_nat = attribute('router_nat', default: <%= JSON.pretty_generate(grab_attributes(pwd)['router_nat']) -%>, description: 'Compute router NAT description')
diff --git a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nats.erb b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nats.erb
index 13e0e53ad843..e655821801df 100644
--- a/templates/inspec/examples/google_compute_router_nat/google_compute_router_nats.erb
+++ b/templates/inspec/examples/google_compute_router_nat/google_compute_router_nats.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% router = grab_attributes['router'] -%>
-<% router_nat = grab_attributes['router_nat'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% router = grab_attributes(pwd)['router'] -%>
+<% router_nat = grab_attributes(pwd)['router_nat'] -%>
describe google_compute_router_nats(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, router: <%= doc_generation ? "'#{router['name']}'" : "router['name']" -%>) do
its('names') { should include <%= doc_generation ? "'#{router_nat['name']}'" : "router_nat['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_security_policy/google_compute_security_policies.erb b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policies.erb
new file mode 100644
index 000000000000..54f336d392da
--- /dev/null
+++ b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policies.erb
@@ -0,0 +1,6 @@
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% security_policy = grab_attributes(pwd)['security_policy'] -%>
+describe google_compute_security_policies(project: <%= gcp_project_id -%>) do
+ its('count') { should be >= 1 }
+ its('names') { should include <%= doc_generation ? "'#{security_policy['name']}'" : "security_policy['name']" -%> }
+end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy.erb b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy.erb
new file mode 100644
index 000000000000..8487a9deb68f
--- /dev/null
+++ b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy.erb
@@ -0,0 +1,12 @@
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% security_policy = grab_attributes(pwd)['security_policy'] -%>
+describe google_compute_security_policy(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{security_policy['name']}'" : "security_policy['name']" -%>) do
+ it { should exist }
+ its('rules.size') { should cmp 2 }
+ its('rules.first.priority') { should cmp <%= doc_generation ? "'#{security_policy['priority']}'" : "security_policy['priority']" -%> }
+ its('rules.first.match.config.src_ip_ranges.first') { should cmp <%= doc_generation ? "'#{security_policy['ip_range']}'" : "security_policy['ip_range']" -%> }
+end
+
+describe google_compute_security_policy(project: <%= gcp_project_id -%>, name: 'nonexistent') do
+ it { should_not exist }
+end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy_attributes.erb b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy_attributes.erb
new file mode 100644
index 000000000000..ba9ba34bfce3
--- /dev/null
+++ b/templates/inspec/examples/google_compute_security_policy/google_compute_security_policy_attributes.erb
@@ -0,0 +1,2 @@
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+security_policy = attribute('security_policy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['security_policy']) -%>, description: 'Security Policy description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot.erb b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot.erb
index 233f7f4e3b4a..8c74c1f1c34c 100644
--- a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot.erb
+++ b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% snapshot = grab_attributes['snapshot'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% snapshot = grab_attributes(pwd)['snapshot'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_snapshot(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{snapshot['name']}'" : "snapshot['name']" -%>) do
it { should exist }
its('source_disk') { should match <%= doc_generation ? "'#{snapshot['disk_name']}'" : "snapshot['disk_name']" -%> }
diff --git a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot_attributes.erb b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot_attributes.erb
index 03a36fba93c1..4de08ded0b22 100644
--- a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot_attributes.erb
+++ b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshot_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'GCP zone name of the compute disk')
-snapshot = attribute('snapshot', default: <%= JSON.pretty_generate(grab_attributes['snapshot']) -%>, description: 'Compute disk snapshot description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'GCP zone name of the compute disk')
+snapshot = attribute('snapshot', default: <%= JSON.pretty_generate(grab_attributes(pwd)['snapshot']) -%>, description: 'Compute disk snapshot description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshots.erb b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshots.erb
index a5e7f9c982c4..63aaef15581c 100644
--- a/templates/inspec/examples/google_compute_snapshot/google_compute_snapshots.erb
+++ b/templates/inspec/examples/google_compute_snapshot/google_compute_snapshots.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% snapshot = grab_attributes['snapshot'] -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" %>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% snapshot = grab_attributes(pwd)['snapshot'] -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" %>
describe google_compute_snapshots(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
end
diff --git a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate.erb b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate.erb
index 0ab4c66bfcba..cb20905fdefd 100644
--- a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate.erb
+++ b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% ssl_certificate = grab_attributes['ssl_certificate'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% ssl_certificate = grab_attributes(pwd)['ssl_certificate'] -%>
describe google_compute_ssl_certificate(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{ssl_certificate['name']}'" : "ssl_certificate['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{ssl_certificate['description']}'" : "ssl_certificate['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate_attributes.erb b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate_attributes.erb
index 469761ce7b14..33fffe66ec75 100644
--- a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate_attributes.erb
+++ b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificate_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-ssl_certificate = attribute('ssl_certificate', default: <%= JSON.pretty_generate(grab_attributes['ssl_certificate']) -%>, description: 'A GCP SSL certificate definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+ssl_certificate = attribute('ssl_certificate', default: <%= JSON.pretty_generate(grab_attributes(pwd)['ssl_certificate']) -%>, description: 'A GCP SSL certificate definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificates.erb b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificates.erb
index fea38dd0962b..533f4f533fd6 100644
--- a/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificates.erb
+++ b/templates/inspec/examples/google_compute_ssl_certificate/google_compute_ssl_certificates.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% ssl_certificate = grab_attributes['ssl_certificate'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% ssl_certificate = grab_attributes(pwd)['ssl_certificate'] -%>
describe google_compute_ssl_certificates(project: <%= gcp_project_id -%>) do
its('names') { should include <%= doc_generation ? "'#{ssl_certificate['name']}'" : "ssl_certificate['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policies.erb b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policies.erb
index e37ae469ebd0..f34d533eda63 100644
--- a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policies.erb
+++ b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policies.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% ssl_policy = grab_attributes['ssl_policy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% ssl_policy = grab_attributes(pwd)['ssl_policy'] -%>
describe google_compute_ssl_policies(project: <%= gcp_project_id -%>) do
it { should exist }
its('names') { should include <%= doc_generation ? "'#{ssl_policy['name']}'" : "ssl_policy['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy.erb b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy.erb
index 1caa810b5c53..ccc5f477add0 100644
--- a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy.erb
+++ b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy.erb
@@ -1,5 +1,5 @@
-<% ssl_policy = grab_attributes['ssl_policy'] -%>
-describe google_compute_ssl_policy(project: <%= "#{external_attribute('gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{ssl_policy['name']}'" : "ssl_policy['name']" -%>) do
+<% ssl_policy = grab_attributes(pwd)['ssl_policy'] -%>
+describe google_compute_ssl_policy(project: <%= "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{ssl_policy['name']}'" : "ssl_policy['name']" -%>) do
it { should exist }
its('min_tls_version') { should eq <%= doc_generation ? "'#{ssl_policy['min_tls_version']}'" : "ssl_policy['min_tls_version']" -%> }
its('profile') { should eq <%= doc_generation ? "'#{ssl_policy['profile']}'" : "ssl_policy['profile']" -%> }
@@ -7,6 +7,6 @@ describe google_compute_ssl_policy(project: <%= "#{external_attribute('gcp_proje
its('custom_features') { should include <%= doc_generation ? "'#{ssl_policy['custom_feature2']}'" : "ssl_policy['custom_feature2']" -%> }
end
-describe google_compute_ssl_policy(project: <%= "#{external_attribute('gcp_project_id', doc_generation)}" -%>, name: 'nonexistent') do
+describe google_compute_ssl_policy(project: <%= "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>, name: 'nonexistent') do
it { should_not exist }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy_attributes.erb b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy_attributes.erb
index 8d9d8728df95..c8766b09bae3 100644
--- a/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy_attributes.erb
+++ b/templates/inspec/examples/google_compute_ssl_policy/google_compute_ssl_policy_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-ssl_policy = attribute('ssl_policy', default: <%= JSON.pretty_generate(grab_attributes['ssl_policy']) -%>)
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+ssl_policy = attribute('ssl_policy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['ssl_policy']) -%>)
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork.erb b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork.erb
index b2de1f6a0924..849ae695ebb6 100644
--- a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork.erb
+++ b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% subnetwork = grab_attributes['subnetwork'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% subnetwork = grab_attributes(pwd)['subnetwork'] -%>
describe google_compute_subnetwork(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{subnetwork['name']}'" : "subnetwork['name']" -%>) do
it { should exist }
its('ip_cidr_range') { should eq <%= doc_generation ? "'#{subnetwork['ip_cidr_range']}'" : "subnetwork['ip_cidr_range']" -%> }
diff --git a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork_attributes.erb b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork_attributes.erb
index 0ab67d9c7a01..dd4489bdc090 100644
--- a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork_attributes.erb
+++ b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetwork_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-subnetwork = attribute('subnetwork', default: <%= JSON.pretty_generate(grab_attributes['subnetwork']) -%>, description: 'Compute subnetwork description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+subnetwork = attribute('subnetwork', default: <%= JSON.pretty_generate(grab_attributes(pwd)['subnetwork']) -%>, description: 'Compute subnetwork description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetworks.erb b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetworks.erb
index 82adb03df3d9..5b53106795cb 100644
--- a/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetworks.erb
+++ b/templates/inspec/examples/google_compute_subnetwork/google_compute_subnetworks.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% subnetwork = grab_attributes['subnetwork'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% subnetwork = grab_attributes(pwd)['subnetwork'] -%>
describe google_compute_subnetworks(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('ip_cidr_ranges') { should include <%= doc_generation ? "'#{subnetwork['ip_cidr_range']}'" : "subnetwork['ip_cidr_range']" -%> }
its('subnetwork_names') { should include <%= doc_generation ? "'#{subnetwork['name']}'" : "subnetwork['name']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxies.erb b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxies.erb
index c9827e42d975..cf7393d3c47f 100644
--- a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxies.erb
+++ b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxies.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% http_proxy = grab_attributes['http_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% http_proxy = grab_attributes(pwd)['http_proxy'] -%>
describe google_compute_target_http_proxies(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{http_proxy['name']}'" : "http_proxy['name']" -%> }
its('descriptions') { should include <%= doc_generation ? "'#{http_proxy['description']}'" : "http_proxy['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy.erb b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy.erb
index dd58cf30094e..672e331eab85 100644
--- a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy.erb
+++ b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy.erb
@@ -1,9 +1,9 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% http_proxy = grab_attributes['http_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% http_proxy = grab_attributes(pwd)['http_proxy'] -%>
describe google_compute_target_http_proxy(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{http_proxy['name']}'" : "http_proxy['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{http_proxy['description']}'" : "http_proxy['description']" -%> }
- its('url_map') { should match /\/<%= "#{grab_attributes['url_map']['name']}" -%>$/ }
+ its('url_map') { should match /\/<%= "#{grab_attributes(pwd)['url_map']['name']}" -%>$/ }
end
describe google_compute_target_http_proxy(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: 'nonexistent') do
diff --git a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy_attributes.erb b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy_attributes.erb
index 0d67e44aad7e..c22a4ccdc5a9 100644
--- a/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy_attributes.erb
+++ b/templates/inspec/examples/google_compute_target_http_proxy/google_compute_target_http_proxy_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-http_proxy = attribute('http_proxy', default: <%= JSON.pretty_generate(grab_attributes['http_proxy']) -%>, description: 'Compute HTTP proxy definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+http_proxy = attribute('http_proxy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['http_proxy']) -%>, description: 'Compute HTTP proxy definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxies.erb b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxies.erb
index 9725d667a03a..c0fd2c13db94 100644
--- a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxies.erb
+++ b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxies.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% https_proxy = grab_attributes['https_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% https_proxy = grab_attributes(pwd)['https_proxy'] -%>
describe google_compute_target_https_proxies(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{https_proxy['name']}'" : "https_proxy['name']" -%> }
its('descriptions') { should include <%= doc_generation ? "'#{https_proxy['description']}'" : "https_proxy['description']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy.erb b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy.erb
index 1c15594fd533..4d4314ac1a19 100644
--- a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy.erb
+++ b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy.erb
@@ -1,8 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% https_proxy = grab_attributes['https_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% https_proxy = grab_attributes(pwd)['https_proxy'] -%>
describe google_compute_target_https_proxy(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{https_proxy['name']}'" : "https_proxy['name']" -%>) do
it { should exist }
- its('url_map') { should match /\/<%= "#{grab_attributes['url_map']['name']}" -%>$/ }
+ its('url_map') { should match /\/<%= "#{grab_attributes(pwd)['url_map']['name']}" -%>$/ }
its('description') { should eq <%= doc_generation ? "'#{https_proxy['description']}'" : "https_proxy['description']" -%> }
end
diff --git a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy_attributes.erb b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy_attributes.erb
index db9531e0f747..6456f0f0171f 100644
--- a/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy_attributes.erb
+++ b/templates/inspec/examples/google_compute_target_https_proxy/google_compute_target_https_proxy_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-https_proxy = attribute('https_proxy', default: <%= JSON.pretty_generate(grab_attributes['https_proxy']) -%>, description: 'Compute HTTPS proxy definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+https_proxy = attribute('https_proxy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['https_proxy']) -%>, description: 'Compute HTTPS proxy definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool.erb b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool.erb
index 9a1de14a8043..bd45ee4c2deb 100644
--- a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool.erb
+++ b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool.erb
@@ -1,8 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_ext_vm_name = "#{external_attribute('gcp_ext_vm_name', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_zone = "#{external_attribute('gcp_zone', doc_generation)}" -%>
-<% target_pool = grab_attributes['target_pool'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_ext_vm_name = "#{external_attribute(pwd, 'gcp_ext_vm_name', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_zone = "#{external_attribute(pwd, 'gcp_zone', doc_generation)}" -%>
+<% target_pool = grab_attributes(pwd)['target_pool'] -%>
describe google_compute_target_pool(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{target_pool['name']}'" : "target_pool['name']" -%>) do
it { should exist }
its('session_affinity') { should eq <%= doc_generation ? "'#{target_pool['session_affinity']}'" : "target_pool['session_affinity']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool_attributes.erb b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool_attributes.erb
index d0a8f64fafd2..0a5c482b570e 100644
--- a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool_attributes.erb
+++ b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pool_attributes.erb
@@ -1,5 +1,5 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-gcp_ext_vm_name = attribute(:gcp_ext_vm_name, default: '<%= external_attribute('gcp_ext_vm_name') -%>', description: 'The name of a VM instance.')
-target_pool = attribute('target_pool', default: <%= JSON.pretty_generate(grab_attributes['target_pool']) -%>, description: 'Target pool definition')
-gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute('gcp_zone') -%>', description: 'The GCP zone.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+gcp_ext_vm_name = attribute(:gcp_ext_vm_name, default: '<%= external_attribute(pwd, 'gcp_ext_vm_name') -%>', description: 'The name of a VM instance.')
+target_pool = attribute('target_pool', default: <%= JSON.pretty_generate(grab_attributes(pwd)['target_pool']) -%>, description: 'Target pool definition')
+gcp_zone = attribute(:gcp_zone, default: '<%= external_attribute(pwd, 'gcp_zone') -%>', description: 'The GCP zone.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pools.erb b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pools.erb
index ab2f526f5bfa..c62ad3783d5c 100644
--- a/templates/inspec/examples/google_compute_target_pool/google_compute_target_pools.erb
+++ b/templates/inspec/examples/google_compute_target_pool/google_compute_target_pools.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_ext_vm_name = "#{external_attribute('gcp_ext_vm_name', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% target_pool = grab_attributes['target_pool'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_ext_vm_name = "#{external_attribute(pwd, 'gcp_ext_vm_name', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% target_pool = grab_attributes(pwd)['target_pool'] -%>
describe google_compute_target_pools(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('names') { should include <%= doc_generation ? "'#{target_pool['name']}'" : "target_pool['name']" -%> }
its('session_affinities') { should include <%= doc_generation ? "'#{target_pool['session_affinity']}'" : "target_pool['session_affinity']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxies.erb b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxies.erb
index 8f7611821908..43d110e4ed2b 100644
--- a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxies.erb
+++ b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxies.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% target_tcp_proxy = grab_attributes['target_tcp_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% target_tcp_proxy = grab_attributes(pwd)['target_tcp_proxy'] -%>
describe google_compute_target_tcp_proxies(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>) do
its('names') { should include <%= doc_generation ? "'#{target_tcp_proxy['name']}'" : "target_tcp_proxy['name']" -%> }
its('proxy_headers') { should include <%= doc_generation ? "'#{target_tcp_proxy['proxy_header']}'" : "target_tcp_proxy['proxy_header']" -%> }
diff --git a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy.erb b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy.erb
index 83559e32eeec..778255958f68 100644
--- a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy.erb
+++ b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy.erb
@@ -1,9 +1,9 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% target_tcp_proxy = grab_attributes['target_tcp_proxy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% target_tcp_proxy = grab_attributes(pwd)['target_tcp_proxy'] -%>
describe google_compute_target_tcp_proxy(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: <%= doc_generation ? "'#{target_tcp_proxy['name']}'" : "target_tcp_proxy['name']" -%>) do
it { should exist }
its('proxy_header') { should eq <%= doc_generation ? "'#{target_tcp_proxy['proxy_header']}'" : "target_tcp_proxy['proxy_header']" -%> }
- its('service') { should match /\/<%= "#{grab_attributes['target_tcp_proxy']['tcp_backend_service_name']}" -%>$/ }
+ its('service') { should match /\/<%= "#{grab_attributes(pwd)['target_tcp_proxy']['tcp_backend_service_name']}" -%>$/ }
end
describe google_compute_target_tcp_proxy(project: <%= doc_generation ? "#{gcp_project_id}" : "gcp_project_id" -%>, name: 'nonexistent') do
diff --git a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy_attributes.erb b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy_attributes.erb
index 549aba6f34d5..c1fc11c82636 100644
--- a/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy_attributes.erb
+++ b/templates/inspec/examples/google_compute_target_tcp_proxy/google_compute_target_tcp_proxy_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-target_tcp_proxy = attribute('target_tcp_proxy', default: <%= JSON.pretty_generate(grab_attributes['target_tcp_proxy']) -%>, description: 'Compute TCP proxy definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+target_tcp_proxy = attribute('target_tcp_proxy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['target_tcp_proxy']) -%>, description: 'Compute TCP proxy definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_url_map/google_compute_url_map.erb b/templates/inspec/examples/google_compute_url_map/google_compute_url_map.erb
index aa7bd6c24723..4e2a476964e6 100644
--- a/templates/inspec/examples/google_compute_url_map/google_compute_url_map.erb
+++ b/templates/inspec/examples/google_compute_url_map/google_compute_url_map.erb
@@ -1,14 +1,14 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% url_map = grab_attributes['url_map'] -%>
-<% backend_service = grab_attributes['backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% url_map = grab_attributes(pwd)['url_map'] -%>
+<% backend_service = grab_attributes(pwd)['backend_service'] -%>
describe google_compute_url_map(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{url_map['name']}'" : "url_map['name']" -%>) do
it { should exist }
its('description') { should eq <%= doc_generation ? "'#{url_map['description']}'" : "url_map['description']" -%> }
- its('default_service') { should match /\/<%= "#{grab_attributes['backend_service']['name']}" -%>$/ }
+ its('default_service') { should match /\/<%= "#{grab_attributes(pwd)['backend_service']['name']}" -%>$/ }
its('host_rules.count') { should eq 1 }
its('host_rules.first.hosts') { should include <%= doc_generation ? "'#{url_map['host_rule_host']}'" : "url_map['host_rule_host']" -%> }
its('path_matchers.count') { should eq 1 }
- its('path_matchers.first.default_service') { should match /\/<%= "#{grab_attributes['backend_service']['name']}" -%>$/ }
+ its('path_matchers.first.default_service') { should match /\/<%= "#{grab_attributes(pwd)['backend_service']['name']}" -%>$/ }
its('tests.count') { should eq 1 }
its('tests.first.host') { should eq <%= doc_generation ? "'#{url_map['test_host']}'" : "url_map['test_host']" -%> }
its('tests.first.path') { should eq <%= doc_generation ? "'#{url_map['test_path']}'" : "url_map['test_path']" -%> }
diff --git a/templates/inspec/examples/google_compute_url_map/google_compute_url_map_attributes.erb b/templates/inspec/examples/google_compute_url_map/google_compute_url_map_attributes.erb
index 7af8bba0b9d3..eff3291ab96e 100644
--- a/templates/inspec/examples/google_compute_url_map/google_compute_url_map_attributes.erb
+++ b/templates/inspec/examples/google_compute_url_map/google_compute_url_map_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-url_map = attribute('url_map', default: <%= JSON.pretty_generate(grab_attributes['url_map']) -%>, description: 'Compute URL map definition')
-backend_service = attribute('backend_service', default: <%= JSON.pretty_generate(grab_attributes['backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+url_map = attribute('url_map', default: <%= JSON.pretty_generate(grab_attributes(pwd)['url_map']) -%>, description: 'Compute URL map definition')
+backend_service = attribute('backend_service', default: <%= JSON.pretty_generate(grab_attributes(pwd)['backend_service']) -%>, description: 'Backend service definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_url_map/google_compute_url_maps.erb b/templates/inspec/examples/google_compute_url_map/google_compute_url_maps.erb
index c62b0e148c0a..1bbae986c8bc 100644
--- a/templates/inspec/examples/google_compute_url_map/google_compute_url_maps.erb
+++ b/templates/inspec/examples/google_compute_url_map/google_compute_url_maps.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% url_map = grab_attributes['url_map'] -%>
-<% backend_service = grab_attributes['backend_service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% url_map = grab_attributes(pwd)['url_map'] -%>
+<% backend_service = grab_attributes(pwd)['backend_service'] -%>
describe google_compute_url_maps(project: <%= gcp_project_id -%>) do
its('names') { should include <%= doc_generation ? "'#{url_map['name']}'" : "url_map['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel.erb b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel.erb
index c143581ba957..d19d23bbba8d 100644
--- a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel.erb
+++ b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% vpn_tunnel = grab_attributes['vpn_tunnel'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% vpn_tunnel = grab_attributes(pwd)['vpn_tunnel'] -%>
describe google_compute_vpn_tunnel(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, name: <%= doc_generation ? "'#{vpn_tunnel['name']}'" : "vpn_tunnel['name']" -%>) do
it { should exist }
its('peer_ip') { should eq <%= doc_generation ? "'#{vpn_tunnel['peer_ip']}'" : "vpn_tunnel['peer_ip']" -%> }
diff --git a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel_attributes.erb b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel_attributes.erb
index e1bb650b7f1e..cb78252b3ae4 100644
--- a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel_attributes.erb
+++ b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnel_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-vpn_tunnel = attribute('vpn_tunnel', default: <%= JSON.pretty_generate(grab_attributes['vpn_tunnel']) -%>, description: 'Compute VPN tunnel description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+vpn_tunnel = attribute('vpn_tunnel', default: <%= JSON.pretty_generate(grab_attributes(pwd)['vpn_tunnel']) -%>, description: 'Compute VPN tunnel description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnels.erb b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnels.erb
index 51b4759aaccb..a7fced882e4f 100644
--- a/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnels.erb
+++ b/templates/inspec/examples/google_compute_vpn_tunnel/google_compute_vpn_tunnels.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% vpn_tunnel = grab_attributes['vpn_tunnel'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% vpn_tunnel = grab_attributes(pwd)['vpn_tunnel'] -%>
describe google_compute_vpn_tunnels(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('vpn_tunnel_names') { should include <%= doc_generation ? "'#{vpn_tunnel['name']}'" : "vpn_tunnel['name']" -%> }
its('peer_ips') { should include <%= doc_generation ? "'#{vpn_tunnel['peer_ip']}'" : "vpn_tunnel['peer_ip']" -%> }
diff --git a/templates/inspec/examples/google_compute_zone/google_compute_zone.erb b/templates/inspec/examples/google_compute_zone/google_compute_zone.erb
index d9c1b73625d7..e28f451d9145 100644
--- a/templates/inspec/examples/google_compute_zone/google_compute_zone.erb
+++ b/templates/inspec/examples/google_compute_zone/google_compute_zone.erb
@@ -1,4 +1,4 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
describe google_compute_zone(project: <%= gcp_project_id -%>, name: "us-central1-a") do
it { should exist }
it { should be_up }
diff --git a/templates/inspec/examples/google_compute_zone/google_compute_zone_attributes.erb b/templates/inspec/examples/google_compute_zone/google_compute_zone_attributes.erb
index a2863dfa3703..9e434667ef77 100644
--- a/templates/inspec/examples/google_compute_zone/google_compute_zone_attributes.erb
+++ b/templates/inspec/examples/google_compute_zone/google_compute_zone_attributes.erb
@@ -1 +1 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_compute_zone/google_compute_zones.erb b/templates/inspec/examples/google_compute_zone/google_compute_zones.erb
index 3b0b0b5695bb..9c3187b81c81 100644
--- a/templates/inspec/examples/google_compute_zone/google_compute_zones.erb
+++ b/templates/inspec/examples/google_compute_zone/google_compute_zones.erb
@@ -1,4 +1,4 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
google_compute_zones(project: <%= gcp_project_id -%>).zone_names.each do |zone_name|
describe google_compute_zone(project: <%= gcp_project_id -%>, name: zone_name) do
it { should exist }
diff --git a/templates/inspec/examples/google_container_cluster/google_container_cluster.erb b/templates/inspec/examples/google_container_cluster/google_container_cluster.erb
index bbd98deaed4a..5464efe90d4d 100644
--- a/templates/inspec/examples/google_container_cluster/google_container_cluster.erb
+++ b/templates/inspec/examples/google_container_cluster/google_container_cluster.erb
@@ -1,10 +1,10 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_kube_cluster_name = "#{external_attribute('gcp_kube_cluster_name', doc_generation)}" -%>
-<% gcp_kube_cluster_zone = "#{external_attribute('gcp_kube_cluster_zone', doc_generation)}" -%>
-<% gcp_kube_cluster_size = "#{external_attribute('gcp_kube_cluster_size', doc_generation)}" -%>
-<% gcp_kube_cluster_zone_extra1 = "#{external_attribute('gcp_kube_cluster_zone_extra1', doc_generation)}" -%>
-<% gcp_kube_cluster_zone_extra2 = "#{external_attribute('gcp_kube_cluster_zone_extra2', doc_generation)}" -%>
-<% gcp_kube_cluster_master_user = "#{external_attribute('gcp_kube_cluster_master_user', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_kube_cluster_name = "#{external_attribute(pwd, 'gcp_kube_cluster_name', doc_generation)}" -%>
+<% gcp_kube_cluster_zone = "#{external_attribute(pwd, 'gcp_kube_cluster_zone', doc_generation)}" -%>
+<% gcp_kube_cluster_size = "#{external_attribute(pwd, 'gcp_kube_cluster_size', doc_generation)}" -%>
+<% gcp_kube_cluster_zone_extra1 = "#{external_attribute(pwd, 'gcp_kube_cluster_zone_extra1', doc_generation)}" -%>
+<% gcp_kube_cluster_zone_extra2 = "#{external_attribute(pwd, 'gcp_kube_cluster_zone_extra2', doc_generation)}" -%>
+<% gcp_kube_cluster_master_user = "#{external_attribute(pwd, 'gcp_kube_cluster_master_user', doc_generation)}" -%>
describe google_container_cluster(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>, name: <%= gcp_kube_cluster_name -%>) do
it { should exist }
its('locations.sort'){ should cmp [ <%= gcp_kube_cluster_zone -%>, <%= gcp_kube_cluster_zone_extra1 -%>, <%= gcp_kube_cluster_zone_extra2 -%> ].sort }
@@ -14,4 +14,9 @@ end
describe google_container_cluster(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>, name: 'nonexistent') do
it { should_not exist }
+end
+
+describe google_container_cluster(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>, name: <%= gcp_kube_cluster_name -%>, beta: true) do
+ it { should exist }
+ its('release_channel.channel') { should cmp "RAPID" }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_container_cluster/google_container_cluster_attributes.erb b/templates/inspec/examples/google_container_cluster/google_container_cluster_attributes.erb
index c0a43756537c..2305faa0df95 100644
--- a/templates/inspec/examples/google_container_cluster/google_container_cluster_attributes.erb
+++ b/templates/inspec/examples/google_container_cluster/google_container_cluster_attributes.erb
@@ -1,7 +1,7 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_kube_cluster_name = attribute(:gcp_kube_cluster_name, default: '<%= external_attribute('gcp_kube_cluster_name') -%>', description: 'GCP container cluster name')
-gcp_kube_cluster_zone = attribute(:gcp_kube_cluster_zone, default: '<%= external_attribute('gcp_kube_cluster_zone') -%>', description: 'GCP container cluster zone')
-gcp_kube_cluster_size = attribute(:gcp_kube_cluster_size, default: '<%= external_attribute('gcp_kube_cluster_size') -%>', description: 'GCP container cluster size')
-gcp_kube_cluster_zone_extra1 = attribute(:gcp_kube_cluster_zone_extra1, default: '<%= external_attribute('gcp_kube_cluster_zone_extra1') -%>', description: 'First extra zone for the cluster')
-gcp_kube_cluster_zone_extra2 = attribute(:gcp_kube_cluster_zone_extra2, default: '<%= external_attribute('gcp_kube_cluster_zone_extra2') -%>', description: 'Second extra zone for the cluster')
-gcp_kube_cluster_master_user = attribute(:gcp_kube_cluster_master_user, default: '<%= external_attribute('gcp_kube_cluster_master_user') -%>', description: 'GCP container cluster admin username')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_kube_cluster_name = attribute(:gcp_kube_cluster_name, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_name') -%>', description: 'GCP container cluster name')
+gcp_kube_cluster_zone = attribute(:gcp_kube_cluster_zone, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_zone') -%>', description: 'GCP container cluster zone')
+gcp_kube_cluster_size = attribute(:gcp_kube_cluster_size, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_size') -%>', description: 'GCP container cluster size')
+gcp_kube_cluster_zone_extra1 = attribute(:gcp_kube_cluster_zone_extra1, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_zone_extra1') -%>', description: 'First extra zone for the cluster')
+gcp_kube_cluster_zone_extra2 = attribute(:gcp_kube_cluster_zone_extra2, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_zone_extra2') -%>', description: 'Second extra zone for the cluster')
+gcp_kube_cluster_master_user = attribute(:gcp_kube_cluster_master_user, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_master_user') -%>', description: 'GCP container cluster admin username')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_container_cluster/google_container_clusters.erb b/templates/inspec/examples/google_container_cluster/google_container_clusters.erb
index 0015fc63a5e9..0bdeb62af514 100644
--- a/templates/inspec/examples/google_container_cluster/google_container_clusters.erb
+++ b/templates/inspec/examples/google_container_cluster/google_container_clusters.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_kube_cluster_name = "#{external_attribute('gcp_kube_cluster_name', doc_generation)}" -%>
-<% gcp_kube_cluster_zone = "#{external_attribute('gcp_kube_cluster_zone', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_kube_cluster_name = "#{external_attribute(pwd, 'gcp_kube_cluster_name', doc_generation)}" -%>
+<% gcp_kube_cluster_zone = "#{external_attribute(pwd, 'gcp_kube_cluster_zone', doc_generation)}" -%>
describe google_container_clusters(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>) do
its('cluster_names') { should include <%= gcp_kube_cluster_name -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_container_node_pool/google_container_node_pool.erb b/templates/inspec/examples/google_container_node_pool/google_container_node_pool.erb
index 1696c4e039ee..92888408e356 100644
--- a/templates/inspec/examples/google_container_node_pool/google_container_node_pool.erb
+++ b/templates/inspec/examples/google_container_node_pool/google_container_node_pool.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_kube_cluster_zone = "#{external_attribute('gcp_kube_cluster_zone', doc_generation)}" -%>
-<% gcp_kube_cluster_name = "#{external_attribute('gcp_kube_cluster_name', doc_generation)}" -%>
-<% regional_node_pool = grab_attributes['regional_node_pool'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_kube_cluster_zone = "#{external_attribute(pwd, 'gcp_kube_cluster_zone', doc_generation)}" -%>
+<% gcp_kube_cluster_name = "#{external_attribute(pwd, 'gcp_kube_cluster_name', doc_generation)}" -%>
+<% regional_node_pool = grab_attributes(pwd)['regional_node_pool'] -%>
describe google_container_node_pool(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>, cluster_name: <%= gcp_kube_cluster_name -%>, nodepool_name: <%= doc_generation ? "'#{regional_node_pool['name']}'" : "regional_node_pool['name']" -%>) do
it { should exist }
its('initial_node_count') { should eq <%= doc_generation ? "'#{regional_node_pool['initial_node_count']}'" : "regional_node_pool['initial_node_count']" -%>}
diff --git a/templates/inspec/examples/google_container_node_pool/google_container_node_pool_attributes.erb b/templates/inspec/examples/google_container_node_pool/google_container_node_pool_attributes.erb
index c7f6605ecf02..9e87d0275330 100644
--- a/templates/inspec/examples/google_container_node_pool/google_container_node_pool_attributes.erb
+++ b/templates/inspec/examples/google_container_node_pool/google_container_node_pool_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_kube_cluster_zone = attribute(:gcp_kube_cluster_zone, default: '<%= external_attribute('gcp_kube_cluster_zone') -%>', description: 'The zone that the kube cluster resides in.')
-gcp_kube_cluster_name = attribute(:gcp_kube_cluster_name, default: '<%= external_attribute('gcp_kube_cluster_name') -%>', description: 'The parent container clusters name.')
-regional_node_pool = attribute('regional_node_pool', default: <%= JSON.pretty_generate(grab_attributes['regional_node_pool']) -%>, description: 'Regional Node Pool definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_kube_cluster_zone = attribute(:gcp_kube_cluster_zone, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_zone') -%>', description: 'The zone that the kube cluster resides in.')
+gcp_kube_cluster_name = attribute(:gcp_kube_cluster_name, default: '<%= external_attribute(pwd, 'gcp_kube_cluster_name') -%>', description: 'The parent container clusters name.')
+regional_node_pool = attribute('regional_node_pool', default: <%= JSON.pretty_generate(grab_attributes(pwd)['regional_node_pool']) -%>, description: 'Regional Node Pool definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_container_node_pool/google_container_node_pools.erb b/templates/inspec/examples/google_container_node_pool/google_container_node_pools.erb
index ee69dd74f731..143676e83699 100644
--- a/templates/inspec/examples/google_container_node_pool/google_container_node_pools.erb
+++ b/templates/inspec/examples/google_container_node_pool/google_container_node_pools.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_kube_cluster_zone = "#{external_attribute('gcp_kube_cluster_zone', doc_generation)}" -%>
-<% gcp_kube_cluster_name = "#{external_attribute('gcp_kube_cluster_name', doc_generation)}" -%>
-<% regional_node_pool = grab_attributes['regional_node_pool'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_kube_cluster_zone = "#{external_attribute(pwd, 'gcp_kube_cluster_zone', doc_generation)}" -%>
+<% gcp_kube_cluster_name = "#{external_attribute(pwd, 'gcp_kube_cluster_name', doc_generation)}" -%>
+<% regional_node_pool = grab_attributes(pwd)['regional_node_pool'] -%>
describe google_container_node_pools(project: <%= gcp_project_id -%>, location: <%= gcp_kube_cluster_zone -%>, cluster_name: <%= gcp_kube_cluster_name -%>) do
its('initial_node_counts') { should include <%= doc_generation ? "'#{regional_node_pool['initial_node_count']}'" : "regional_node_pool['initial_node_count']" -%>}
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster.erb b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster.erb
index 2ca9b6559a6f..b0bc5f65c1b6 100644
--- a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster.erb
+++ b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% dataproc_cluster = grab_attributes['dataproc_cluster'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% dataproc_cluster = grab_attributes(pwd)['dataproc_cluster'] -%>
describe google_dataproc_cluster(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>, cluster_name: <%= doc_generation ? "'#{dataproc_cluster['name']}'" : "dataproc_cluster['name']" -%>) do
it { should exist }
its('labels') { should include(<%= doc_generation ? "'#{dataproc_cluster['label_key']}'" : "dataproc_cluster['label_key']" -%> => <%= doc_generation ? "'#{dataproc_cluster['label_value']}'" : "dataproc_cluster['label_value']" -%>) }
diff --git a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster_attributes.erb b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster_attributes.erb
index be9eb6d44303..d264472ff326 100644
--- a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster_attributes.erb
+++ b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_cluster_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-dataproc_cluster = attribute('dataproc_cluster', default: <%= JSON.pretty_generate(grab_attributes['dataproc_cluster']) -%>, description: 'Dataproc cluster definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+dataproc_cluster = attribute('dataproc_cluster', default: <%= JSON.pretty_generate(grab_attributes(pwd)['dataproc_cluster']) -%>, description: 'Dataproc cluster definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_clusters.erb b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_clusters.erb
index 72f6ded703dc..fd46d12cf017 100644
--- a/templates/inspec/examples/google_dataproc_cluster/google_dataproc_clusters.erb
+++ b/templates/inspec/examples/google_dataproc_cluster/google_dataproc_clusters.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% dataproc_cluster = grab_attributes['dataproc_cluster'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% dataproc_cluster = grab_attributes(pwd)['dataproc_cluster'] -%>
describe google_dataproc_clusters(project: <%= gcp_project_id -%>, region: <%= gcp_location -%>) do
its('count') { should be >= 1 }
its('cluster_names') { should include <%= doc_generation ? "'#{dataproc_cluster['name']}'" : "dataproc_cluster['name']" -%> }
diff --git a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone.erb b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone.erb
index e8bfb724cc0e..fc3e0a0d34cc 100644
--- a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone.erb
+++ b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_dns_zone_name = "#{external_attribute('gcp_dns_zone_name', doc_generation)}" -%>
-<% dns_managed_zone = grab_attributes['dns_managed_zone'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_dns_zone_name = "#{external_attribute(pwd, 'gcp_dns_zone_name', doc_generation)}" -%>
+<% dns_managed_zone = grab_attributes(pwd)['dns_managed_zone'] -%>
describe google_dns_managed_zone(project: <%= gcp_project_id -%>, zone: <%= doc_generation ? "'#{dns_managed_zone['name']}'" : "dns_managed_zone['name']" -%>) do
it { should exist }
its('dns_name') { should cmp <%= gcp_dns_zone_name -%> }
diff --git a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone_attributes.erb b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone_attributes.erb
index 880ff948b058..bcb68a6122d0 100644
--- a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone_attributes.erb
+++ b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zone_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_dns_zone_name = attribute(:gcp_dns_zone_name, default: '<%= external_attribute('gcp_dns_zone_name') -%>', description: 'The DNS name of the DNS zone.')
-dns_managed_zone = attribute('dns_managed_zone', default: <%= grab_attributes['dns_managed_zone'] -%>)
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_dns_zone_name = attribute(:gcp_dns_zone_name, default: '<%= external_attribute(pwd, 'gcp_dns_zone_name') -%>', description: 'The DNS name of the DNS zone.')
+dns_managed_zone = attribute('dns_managed_zone', default: <%= grab_attributes(pwd)['dns_managed_zone'] -%>)
\ No newline at end of file
diff --git a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zones.erb b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zones.erb
index 81fbbaf38d5f..49413c899ee0 100644
--- a/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zones.erb
+++ b/templates/inspec/examples/google_dns_managed_zone/google_dns_managed_zones.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_dns_zone_name = "#{external_attribute('gcp_dns_zone_name', doc_generation)}" -%>
-<% dns_managed_zone = grab_attributes['dns_managed_zone'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_dns_zone_name = "#{external_attribute(pwd, 'gcp_dns_zone_name', doc_generation)}" -%>
+<% dns_managed_zone = grab_attributes(pwd)['dns_managed_zone'] -%>
describe google_dns_managed_zones(project: <%= gcp_project_id -%>) do
it { should exist }
its('zone_names') { should include <%= doc_generation ? "'#{dns_managed_zone['name']}'" : "dns_managed_zone['name']" -%> }
diff --git a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set.erb b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set.erb
index 2860e3877e03..6684b8a4dbb7 100644
--- a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set.erb
+++ b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set.erb
@@ -1,6 +1,6 @@
-<% record_set = grab_attributes['record_set'] -%>
-<% managed_zone = grab_attributes['managed_zone'] -%>
-describe google_dns_resource_record_set(project: <%= "#{external_attribute('gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{record_set['name']}'" : "record_set['name']" -%>, type: <%= doc_generation ? "'#{record_set['type']}'" : "record_set['type']" -%>, managed_zone: <%= doc_generation ? "'#{managed_zone['name']}'" : "managed_zone['name']" -%>) do
+<% record_set = grab_attributes(pwd)['record_set'] -%>
+<% managed_zone = grab_attributes(pwd)['managed_zone'] -%>
+describe google_dns_resource_record_set(project: <%= "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{record_set['name']}'" : "record_set['name']" -%>, type: <%= doc_generation ? "'#{record_set['type']}'" : "record_set['type']" -%>, managed_zone: <%= doc_generation ? "'#{managed_zone['name']}'" : "managed_zone['name']" -%>) do
it { should exist }
its('type') { should eq <%= doc_generation ? "'#{record_set['type']}'" : "record_set['type']" -%> }
its('ttl') { should eq <%= doc_generation ? "'#{record_set['ttl']}'" : "record_set['ttl']" -%> }
diff --git a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set_attributes.erb b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set_attributes.erb
index ffd8dfb667a4..7813cc172a26 100644
--- a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set_attributes.erb
+++ b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_set_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-record_set = attribute('record_set', default: <%= JSON.pretty_generate(grab_attributes['record_set']) -%>)
-managed_zone = attribute('managed_zone', default: <%= JSON.pretty_generate(grab_attributes['managed_zone']) -%>)
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+record_set = attribute('record_set', default: <%= JSON.pretty_generate(grab_attributes(pwd)['record_set']) -%>)
+managed_zone = attribute('managed_zone', default: <%= JSON.pretty_generate(grab_attributes(pwd)['managed_zone']) -%>)
\ No newline at end of file
diff --git a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_sets.erb b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_sets.erb
index cb2f186f4f4f..4a121c13165f 100644
--- a/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_sets.erb
+++ b/templates/inspec/examples/google_dns_resource_record_set/google_dns_resource_record_sets.erb
@@ -1,6 +1,6 @@
-<% record_set = grab_attributes['record_set'] -%>
-<% managed_zone = grab_attributes['managed_zone'] -%>
-describe google_dns_resource_record_sets(project: <%= "#{external_attribute('gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{record_set['name']}'" : "record_set['name']" -%>, managed_zone: <%= doc_generation ? "'#{managed_zone['name']}'" : "managed_zone['name']" -%>) do
+<% record_set = grab_attributes(pwd)['record_set'] -%>
+<% managed_zone = grab_attributes(pwd)['managed_zone'] -%>
+describe google_dns_resource_record_sets(project: <%= "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>, name: <%= doc_generation ? "'#{record_set['name']}'" : "record_set['name']" -%>, managed_zone: <%= doc_generation ? "'#{managed_zone['name']}'" : "managed_zone['name']" -%>) do
its('count') { should eq 3 }
its('types') { should include <%= doc_generation ? "'#{record_set['type']}'" : "record_set['type']" -%> }
its('ttls') { should include <%= doc_generation ? "'#{record_set['ttl']}'" : "record_set['ttl']" -%> }
diff --git a/templates/inspec/examples/google_filestore_instance/google_filestore_instance.erb b/templates/inspec/examples/google_filestore_instance/google_filestore_instance.erb
index 10a5a7c1d596..7c09bc70125d 100644
--- a/templates/inspec/examples/google_filestore_instance/google_filestore_instance.erb
+++ b/templates/inspec/examples/google_filestore_instance/google_filestore_instance.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% filestore_instance = grab_attributes['filestore_instance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% filestore_instance = grab_attributes(pwd)['filestore_instance'] -%>
describe google_filestore_instance(project: <%= gcp_project_id -%>, zone: <%= doc_generation ? "'#{filestore_instance['zone']}'" : "filestore_instance['zone']" -%>, name: <%= doc_generation ? "'#{filestore_instance['name']}'" : "filestore_instance['name']" -%>) do
it { should exist }
its('tier') { should cmp <%= doc_generation ? "'#{filestore_instance['tier']}'" : "filestore_instance['tier']" -%> }
diff --git a/templates/inspec/examples/google_filestore_instance/google_filestore_instance_attributes.erb b/templates/inspec/examples/google_filestore_instance/google_filestore_instance_attributes.erb
index 455ff911c660..e2aa864df739 100644
--- a/templates/inspec/examples/google_filestore_instance/google_filestore_instance_attributes.erb
+++ b/templates/inspec/examples/google_filestore_instance/google_filestore_instance_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-filestore_instance = attribute('filestore_instance', default: <%= grab_attributes['filestore_instance'] -%>)
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+filestore_instance = attribute('filestore_instance', default: <%= grab_attributes(pwd)['filestore_instance'] -%>)
\ No newline at end of file
diff --git a/templates/inspec/examples/google_filestore_instance/google_filestore_instances.erb b/templates/inspec/examples/google_filestore_instance/google_filestore_instances.erb
index 2d0937151334..81a4fbe3e5b1 100644
--- a/templates/inspec/examples/google_filestore_instance/google_filestore_instances.erb
+++ b/templates/inspec/examples/google_filestore_instance/google_filestore_instances.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% filestore_instance = grab_attributes['filestore_instance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% filestore_instance = grab_attributes(pwd)['filestore_instance'] -%>
describe google_filestore_instances(project: <%= gcp_project_id -%>, zone: <%= doc_generation ? "'#{filestore_instance['zone']}'" : "filestore_instance['zone']" -%>) do
its('tiers') { should include <%= doc_generation ? "'#{filestore_instance['tier']}'" : "filestore_instance['tier']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role.erb b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role.erb
index f22abe83d203..c3c1ff1eb05d 100644
--- a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role.erb
+++ b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% gcp_organization_iam_custom_role_id = "#{external_attribute('gcp_organization_iam_custom_role_id', doc_generation)}" -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% gcp_organization_iam_custom_role_id = "#{external_attribute(pwd, 'gcp_organization_iam_custom_role_id', doc_generation)}" -%>
describe google_iam_organization_custom_role(org_id: <%= doc_generation ? "'12345'" : "gcp_organization_id" -%>, name: <%= gcp_organization_iam_custom_role_id -%>) do
it { should exist }
its('stage') { should eq 'GA' }
diff --git a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role_attributes.erb b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role_attributes.erb
index cf9ae4c17e6a..47bf93a86119 100644
--- a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role_attributes.erb
+++ b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_role_attributes.erb
@@ -1,3 +1,3 @@
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
-gcp_organization_iam_custom_role_id = attribute(:gcp_organization_iam_custom_role_id, default: '<%= external_attribute('gcp_organization_iam_custom_role_id') -%>', description: 'The IAM custom role identifier.')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
+gcp_organization_iam_custom_role_id = attribute(:gcp_organization_iam_custom_role_id, default: '<%= external_attribute(pwd, 'gcp_organization_iam_custom_role_id') -%>', description: 'The IAM custom role identifier.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_roles.erb b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_roles.erb
index 2cd25f40250d..743c59acbd7c 100644
--- a/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_roles.erb
+++ b/templates/inspec/examples/google_iam_organization_custom_role/google_iam_organization_custom_roles.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% gcp_organization_iam_custom_role_id = "#{external_attribute('gcp_organization_iam_custom_role_id', doc_generation)}" -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% gcp_organization_iam_custom_role_id = "#{external_attribute(pwd, 'gcp_organization_iam_custom_role_id', doc_generation)}" -%>
describe google_iam_organization_custom_roles(org_id: <%= gcp_organization_id -%>) do
its('names') { should include "organizations/<%= doc_generation ? "123456" : "\#{gcp_organization_id}" -%>/roles/<%= doc_generation ? "role-id" : "\#{gcp_organization_iam_custom_role_id}" -%>" }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key.erb b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key.erb
index 900a5bd51281..55fd13a5474e 100644
--- a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key.erb
+++ b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_kms_key_ring_policy_name = "#{external_attribute('gcp_kms_key_ring_policy_name', doc_generation)}" -%>
-<% gcp_kms_crypto_key_name_policy = "#{external_attribute('gcp_kms_crypto_key_name_policy', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_kms_key_ring_policy_name = "#{external_attribute(pwd, 'gcp_kms_key_ring_policy_name', doc_generation)}" -%>
+<% gcp_kms_crypto_key_name_policy = "#{external_attribute(pwd, 'gcp_kms_crypto_key_name_policy', doc_generation)}" -%>
describe google_kms_crypto_key(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>, key_ring_name: <%= gcp_kms_key_ring_policy_name -%>, name: <%= gcp_kms_crypto_key_name_policy -%>) do
it { should exist }
its('crypto_key_name') { should cmp <%= gcp_kms_crypto_key_name_policy -%> }
diff --git a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key_attributes.erb b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key_attributes.erb
index 1cb85513506e..3c3fd43f8123 100644
--- a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key_attributes.erb
+++ b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_key_attributes.erb
@@ -1,6 +1,6 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'GCP location')
-gcp_kms_key_ring_policy_name = attribute(:gcp_kms_key_ring_policy_name, default: '<%= external_attribute('gcp_kms_key_ring_policy_name') -%>', description: 'Key ring name')
-gcp_kms_crypto_key_name_policy = attribute(:gcp_kms_crypto_key_name_policy, default: '<%= external_attribute('gcp_kms_crypto_key_name_policy') -%>', description: 'Key name')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'GCP location')
+gcp_kms_key_ring_policy_name = attribute(:gcp_kms_key_ring_policy_name, default: '<%= external_attribute(pwd, 'gcp_kms_key_ring_policy_name') -%>', description: 'Key ring name')
+gcp_kms_crypto_key_name_policy = attribute(:gcp_kms_crypto_key_name_policy, default: '<%= external_attribute(pwd, 'gcp_kms_crypto_key_name_policy') -%>', description: 'Key name')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_keys.erb b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_keys.erb
index 97a25781bbaa..da66280eb1cd 100644
--- a/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_keys.erb
+++ b/templates/inspec/examples/google_kms_crypto_key/google_kms_crypto_keys.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_kms_key_ring_policy_name = "#{external_attribute('gcp_kms_key_ring_policy_name', doc_generation)}" -%>
-<% gcp_kms_crypto_key_name_policy = "#{external_attribute('gcp_kms_crypto_key_name_policy', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_kms_key_ring_policy_name = "#{external_attribute(pwd, 'gcp_kms_key_ring_policy_name', doc_generation)}" -%>
+<% gcp_kms_crypto_key_name_policy = "#{external_attribute(pwd, 'gcp_kms_crypto_key_name_policy', doc_generation)}" -%>
describe google_kms_crypto_keys(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>, key_ring_name: <%= gcp_kms_key_ring_policy_name -%>) do
its('count') { should be >= 1 }
its('crypto_key_names') { should include <%= gcp_kms_crypto_key_name_policy -%> }
diff --git a/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring.erb b/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring.erb
index 4648cbe70bfb..8667bc6d2e2a 100644
--- a/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring.erb
+++ b/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_kms_key_ring_policy_name = "#{external_attribute('gcp_kms_key_ring_policy_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_kms_key_ring_policy_name = "#{external_attribute(pwd, 'gcp_kms_key_ring_policy_name', doc_generation)}" -%>
describe google_kms_key_ring(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>, name: <%= gcp_kms_key_ring_policy_name -%>) do
it { should exist }
its('create_time') { should be > Time.now - 365*60*60*24*10 }
diff --git a/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring_attributes.erb b/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring_attributes.erb
index 13f1c1fd66c1..7dbcf06ad173 100644
--- a/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring_attributes.erb
+++ b/templates/inspec/examples/google_kms_key_ring/google_kms_key_ring_attributes.erb
@@ -1,5 +1,5 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'GCP location')
-gcp_kms_key_ring_policy_name = attribute(:gcp_kms_key_ring_policy_name, default: '<%= external_attribute('gcp_kms_key_ring_policy_name') -%>', description: 'Key ring name')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'GCP location')
+gcp_kms_key_ring_policy_name = attribute(:gcp_kms_key_ring_policy_name, default: '<%= external_attribute(pwd, 'gcp_kms_key_ring_policy_name') -%>', description: 'Key ring name')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_kms_key_ring/google_kms_key_rings.erb b/templates/inspec/examples/google_kms_key_ring/google_kms_key_rings.erb
index 7c904825d9fb..fa4bfa94abf7 100644
--- a/templates/inspec/examples/google_kms_key_ring/google_kms_key_rings.erb
+++ b/templates/inspec/examples/google_kms_key_ring/google_kms_key_rings.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_kms_key_ring_policy_name = "#{external_attribute('gcp_kms_key_ring_policy_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_kms_key_ring_policy_name = "#{external_attribute(pwd, 'gcp_kms_key_ring_policy_name', doc_generation)}" -%>
describe google_kms_key_rings(project: <%= gcp_project_id -%>, location: <%= gcp_location -%>) do
its('key_ring_names'){ should include <%= gcp_kms_key_ring_policy_name -%> }
end
diff --git a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion.erb b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion.erb
index 8970222e1d72..2b729b2a3127 100644
--- a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion.erb
+++ b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% folder_exclusion = grab_attributes['folder_exclusion'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% folder_exclusion = grab_attributes(pwd)['folder_exclusion'] -%>
# Getting folder exclusions is complicated due to the name being generated by the server.
# This can be drastically simplified if you have the name when writing the test
describe.one do
diff --git a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion_attributes.erb b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion_attributes.erb
index 0a91d7605666..4e5581f1b1c5 100644
--- a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion_attributes.erb
+++ b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusion_attributes.erb
@@ -1,3 +1,3 @@
-folder_exclusion = attribute('folder_exclusion', default: <%= grab_attributes['folder_exclusion'] -%>)
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
+folder_exclusion = attribute('folder_exclusion', default: <%= grab_attributes(pwd)['folder_exclusion'] -%>)
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusions.erb b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusions.erb
index fed3a9f22d13..d90b0d09131d 100644
--- a/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusions.erb
+++ b/templates/inspec/examples/google_logging_folder_exclusion/google_logging_folder_exclusions.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% folder_exclusion = grab_attributes['folder_exclusion'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% folder_exclusion = grab_attributes(pwd)['folder_exclusion'] -%>
# Getting folder exclusions is complicated due to the name being generated by the server.
# This can be drastically simplified if you have the name when writing the test
describe.one do
diff --git a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink.erb b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink.erb
index cccb000e3c6f..7952632ccf2b 100644
--- a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink.erb
+++ b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% folder_sink = grab_attributes['folder_sink'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% folder_sink = grab_attributes(pwd)['folder_sink'] -%>
# Getting folder sinks is complicated due to the name being generated by the server.
# This can be drastically simplified if you have the folder name when writing the test
describe.one do
diff --git a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink_attributes.erb b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink_attributes.erb
index 8d148423dd73..d0087bce3601 100644
--- a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink_attributes.erb
+++ b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sink_attributes.erb
@@ -1,3 +1,3 @@
-folder_sink = attribute('folder_sink', default: <%= grab_attributes['folder_sink'] -%>)
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
+folder_sink = attribute('folder_sink', default: <%= grab_attributes(pwd)['folder_sink'] -%>)
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of the folder')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sinks.erb b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sinks.erb
index cd016eea01a3..e6a247bf46c9 100644
--- a/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sinks.erb
+++ b/templates/inspec/examples/google_logging_folder_log_sink/google_logging_folder_log_sinks.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% folder_sink = grab_attributes['folder_sink'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% folder_sink = grab_attributes(pwd)['folder_sink'] -%>
# Getting folder sinks is complicated due to the name being generated by the server.
# This can be drastically simplified if you have the folder name when writing the test
describe.one do
diff --git a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink.erb b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink.erb
index 0210d6976c93..1217591d71d1 100644
--- a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink.erb
+++ b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% org_sink = grab_attributes['org_sink'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% org_sink = grab_attributes(pwd)['org_sink'] -%>
describe google_logging_organization_log_sink(organization: <%= gcp_organization_id -%>, name: <%= doc_generation ? "'#{org_sink['name']}'" : "org_sink['name']" -%>) do
it { should exist }
its('filter') { should cmp <%= doc_generation ? "'#{org_sink['filter']}'" : "org_sink['filter']" -%> }
diff --git a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink_attributes.erb b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink_attributes.erb
index 082ea57f55a3..d90fc842b908 100644
--- a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink_attributes.erb
+++ b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sink_attributes.erb
@@ -1,3 +1,3 @@
-org_sink = attribute('org_sink', default: <%= grab_attributes['org_sink'] -%>)
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
+org_sink = attribute('org_sink', default: <%= grab_attributes(pwd)['org_sink'] -%>)
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sinks.erb b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sinks.erb
index d3d3c21ebd1a..7bb879a01b58 100644
--- a/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sinks.erb
+++ b/templates/inspec/examples/google_logging_organization_log_sink/google_logging_organization_log_sinks.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% org_sink = grab_attributes['org_sink'] -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% org_sink = grab_attributes(pwd)['org_sink'] -%>
describe google_logging_organization_log_sinks(organization: <%= gcp_organization_id -%>) do
its('names') { should include <%= doc_generation ? "'#{org_sink['name']}'" : "org_sink['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion.erb b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion.erb
index 6db10667dce5..6b8e23505f55 100644
--- a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion.erb
+++ b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% project_exclusion = grab_attributes['project_exclusion'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% project_exclusion = grab_attributes(pwd)['project_exclusion'] -%>
describe google_logging_project_exclusion(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{project_exclusion['name']}'" : "project_exclusion['name']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion_attributes.erb b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion_attributes.erb
index 02c2fc6b43bb..4e5e29cb1c98 100644
--- a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion_attributes.erb
+++ b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusion_attributes.erb
@@ -1,4 +1,4 @@
-project_exclusion = attribute('project_exclusion', default: <%= grab_attributes['project_exclusion'] -%>)
-gcp_project_id = attribute(:gcp_project_id, default: <%= external_attribute('gcp_project_id') -%>, description: 'The project identifier')
+project_exclusion = attribute('project_exclusion', default: <%= grab_attributes(pwd)['project_exclusion'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: <%= external_attribute(pwd, 'gcp_project_id') -%>, description: 'The project identifier')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusions.erb b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusions.erb
index fe5a979a6c82..489a8c3e1e83 100644
--- a/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusions.erb
+++ b/templates/inspec/examples/google_logging_project_exclusion/google_logging_project_exclusions.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% project_exclusion = grab_attributes['folder_exclusion'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% project_exclusion = grab_attributes(pwd)['folder_exclusion'] -%>
describe google_logging_project_exclusions(project: <%= gcp_project_id -%>) do
its('names'){ should include <%= doc_generation ? "'#{project_exclusion['name']}'" : "project_exclusion['name']" -%> }
diff --git a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink.erb b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink.erb
index 779931415c16..2d1cf7ad91fb 100644
--- a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink.erb
+++ b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% project_sink = grab_attributes['project_sink'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% project_sink = grab_attributes(pwd)['project_sink'] -%>
describe google_logging_project_sink(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{project_sink['name']}'" : "project_sink['name']" -%>) do
it { should exist }
its('filter') { should cmp <%= doc_generation ? "'#{project_sink['filter']}'" : "project_sink['filter']" -%> }
diff --git a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink_attributes.erb b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink_attributes.erb
index 82457f0d454c..2361137989bf 100644
--- a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink_attributes.erb
+++ b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sink_attributes.erb
@@ -1,4 +1,4 @@
-project_sink = attribute('project_sink', default: <%= grab_attributes['project_sink'] -%>)
-gcp_project_id = attribute(:gcp_project_id, default: <%= external_attribute('gcp_project_id') -%>, description: 'The project id.')
+project_sink = attribute('project_sink', default: <%= grab_attributes(pwd)['project_sink'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: <%= external_attribute(pwd, 'gcp_project_id') -%>, description: 'The project id.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sinks.erb b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sinks.erb
index e20bcb6d95b7..0aff061cd876 100644
--- a/templates/inspec/examples/google_logging_project_sink/google_logging_project_sinks.erb
+++ b/templates/inspec/examples/google_logging_project_sink/google_logging_project_sinks.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% project_sink = grab_attributes['project_sink'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% project_sink = grab_attributes(pwd)['project_sink'] -%>
describe google_logging_project_sinks(project: <%= gcp_project_id -%>) do
its('names') { should include <%= doc_generation ? "'#{project_sink['name']}'" : "project_sink['name']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_memcache_instance/google_memcache_instance.erb b/templates/inspec/examples/google_memcache_instance/google_memcache_instance.erb
new file mode 100644
index 000000000000..6dd3f038cbd8
--- /dev/null
+++ b/templates/inspec/examples/google_memcache_instance/google_memcache_instance.erb
@@ -0,0 +1,11 @@
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% memcache_instance = grab_attributes(pwd)['memcache_instance'] -%>
+describe google_memcache_instance(project: <%= gcp_project_id -%>, region: <%= gcp_location %>, name: <%= doc_generation ? "'#{memcache_instance['name']}'" : "memcache_instance['name']" -%>) do
+ it { should exist }
+ its('node_count') { should cmp 1 }
+end
+
+describe google_memcache_instance(project: <%= gcp_project_id -%>, region: <%= gcp_location %>, name: "nonexistent") do
+ it { should_not exist }
+end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_memcache_instance/google_memcache_instance_attributes.erb b/templates/inspec/examples/google_memcache_instance/google_memcache_instance_attributes.erb
new file mode 100644
index 000000000000..795917fcc5a0
--- /dev/null
+++ b/templates/inspec/examples/google_memcache_instance/google_memcache_instance_attributes.erb
@@ -0,0 +1,3 @@
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+memcache_instance = attribute('memcache_instance', default: <%= JSON.pretty_generate(grab_attributes(pwd)['memcache_instance']) -%>, description: 'Memcache settings')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_memcache_instance/google_memcache_instances.erb b/templates/inspec/examples/google_memcache_instance/google_memcache_instances.erb
new file mode 100644
index 000000000000..9ae45434a1e6
--- /dev/null
+++ b/templates/inspec/examples/google_memcache_instance/google_memcache_instances.erb
@@ -0,0 +1,7 @@
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% memcache_instance = grab_attributes(pwd)['memcache_instance'] -%>
+describe google_memcache_instances(project: <%= gcp_project_id -%>, region: <%= gcp_location %>) do
+ its('count') { should be >= 1 }
+ its('node_counts') { should include 1 }
+end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model.erb b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model.erb
index bc42beafdc4e..c4f25f3477c9 100644
--- a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model.erb
+++ b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% ml_model = grab_attributes['ml_model'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% ml_model = grab_attributes(pwd)['ml_model'] -%>
describe google_ml_engine_model(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{ml_model['name']}'" : "ml_model['name']" -%>) do
it { should exist }
its('description') { should cmp <%= doc_generation ? "'#{ml_model['description']}'" : "ml_model['description']" -%> }
diff --git a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model_attributes.erb b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model_attributes.erb
index bfbbdabf66e9..1020108510eb 100644
--- a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model_attributes.erb
+++ b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_model_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project region.')
-ml_model = attribute('ml_model', default: <%= JSON.pretty_generate(grab_attributes['ml_model']) -%>, description: 'Machine learning model definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project region.')
+ml_model = attribute('ml_model', default: <%= JSON.pretty_generate(grab_attributes(pwd)['ml_model']) -%>, description: 'Machine learning model definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_models.erb b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_models.erb
index c1ff8750517c..41c01626400a 100644
--- a/templates/inspec/examples/google_ml_engine_model/google_ml_engine_models.erb
+++ b/templates/inspec/examples/google_ml_engine_model/google_ml_engine_models.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% ml_model = grab_attributes['ml_model'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% ml_model = grab_attributes(pwd)['ml_model'] -%>
describe google_ml_engine_models(project: <%= gcp_project_id -%>) do
its('descriptions') { should include <%= doc_generation ? "'#{ml_model['description']}'" : "ml_model['description']" -%> }
its('online_prediction_loggings') { should include <%= doc_generation ? "'#{ml_model['online_prediction_logging']}'" : "ml_model['online_prediction_logging']" -%> }
diff --git a/templates/inspec/examples/google_organization/google_organization.erb b/templates/inspec/examples/google_organization/google_organization.erb
index e47486ca67c8..8bf19875f501 100644
--- a/templates/inspec/examples/google_organization/google_organization.erb
+++ b/templates/inspec/examples/google_organization/google_organization.erb
@@ -1,4 +1,4 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
describe google_organization(name: "organizations/<%= doc_generation ? '123456' : "\#{gcp_organization_id}" -%>") do
its('name') { should eq "organizations/<%= doc_generation ? '123456' : "\#{gcp_organization_id}" -%>" }
diff --git a/templates/inspec/examples/google_organization/google_organization_attributes.erb b/templates/inspec/examples/google_organization/google_organization_attributes.erb
index 1d55f221dbde..8eca5f43aaf7 100644
--- a/templates/inspec/examples/google_organization/google_organization_attributes.erb
+++ b/templates/inspec/examples/google_organization/google_organization_attributes.erb
@@ -1,2 +1,2 @@
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_organization/google_organizations.erb b/templates/inspec/examples/google_organization/google_organizations.erb
index ac1a89f2a7ec..9468ac1695a2 100644
--- a/templates/inspec/examples/google_organization/google_organizations.erb
+++ b/templates/inspec/examples/google_organization/google_organizations.erb
@@ -1,5 +1,5 @@
-<% gcp_organization_id = "#{external_attribute('gcp_organization_id', doc_generation)}" -%>
-<% gcp_organization_display_name = "#{external_attribute('gcp_organization_display_name', doc_generation)}" -%>
+<% gcp_organization_id = "#{external_attribute(pwd, 'gcp_organization_id', doc_generation)}" -%>
+<% gcp_organization_display_name = "#{external_attribute(pwd, 'gcp_organization_display_name', doc_generation)}" -%>
describe google_organizations do
its('names') { should include "organizations/<%= doc_generation ? '123456' : "\#{gcp_organization_id}" -%>" }
diff --git a/templates/inspec/examples/google_project/google_project.erb b/templates/inspec/examples/google_project/google_project.erb
index 36aa988624e4..1066abd2a61f 100644
--- a/templates/inspec/examples/google_project/google_project.erb
+++ b/templates/inspec/examples/google_project/google_project.erb
@@ -1,4 +1,4 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
describe google_project(project: <%= gcp_project_id -%>) do
it { should exist }
its('project_id') { should cmp <%= gcp_project_id -%> }
diff --git a/templates/inspec/examples/google_project/google_project_attributes.erb b/templates/inspec/examples/google_project/google_project_attributes.erb
index a2863dfa3703..9e434667ef77 100644
--- a/templates/inspec/examples/google_project/google_project_attributes.erb
+++ b/templates/inspec/examples/google_project/google_project_attributes.erb
@@ -1 +1 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project/google_projects.erb b/templates/inspec/examples/google_project/google_projects.erb
index 15a4a36bf583..e28d01579b35 100644
--- a/templates/inspec/examples/google_project/google_projects.erb
+++ b/templates/inspec/examples/google_project/google_projects.erb
@@ -1,4 +1,4 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
describe google_projects() do
its('count') { should be >= 1 }
its('project_ids') { should include <%= gcp_project_id -%> }
diff --git a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policies.erb b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policies.erb
index eeca2f996aa2..341771ebd46c 100644
--- a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policies.erb
+++ b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policies.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% alert_policy = grab_attributes['alert_policy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% alert_policy = grab_attributes(pwd)['alert_policy'] -%>
describe google_project_alert_policies(project: <%= gcp_project_id -%>) do
it { should exist }
its('policy_display_names') { should include <%= doc_generation ? "'#{alert_policy['display_name']}'" : "alert_policy['display_name']" -%>}
diff --git a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy.erb b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy.erb
index 19ce1f0be671..c8e898daefc7 100644
--- a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy.erb
+++ b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% alert_policy = grab_attributes['alert_policy'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% alert_policy = grab_attributes(pwd)['alert_policy'] -%>
describe.one do
google_project_alert_policies(project: <%= gcp_project_id -%>).policy_names do |policy_name|
describe google_project_alert_policy(project: <%= gcp_project_id -%>, name: policy_name) do
diff --git a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy_attributes.erb b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy_attributes.erb
index 4df0922e7a5b..d68387f2452b 100644
--- a/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy_attributes.erb
+++ b/templates/inspec/examples/google_project_alert_policy/google_project_alert_policy_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-alert_policy = attribute('alert_policy', default: <%= JSON.pretty_generate(grab_attributes['alert_policy']) -%>, description: 'Alert Policy description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+alert_policy = attribute('alert_policy', default: <%= JSON.pretty_generate(grab_attributes(pwd)['alert_policy']) -%>, description: 'Alert Policy description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role.erb b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role.erb
index f5129ebaa952..8f523d0733b5 100644
--- a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role.erb
+++ b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_project_iam_custom_role_id = "#{external_attribute('gcp_project_iam_custom_role_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_project_iam_custom_role_id = "#{external_attribute(pwd, 'gcp_project_iam_custom_role_id', doc_generation)}" -%>
describe google_project_iam_custom_role(project: <%= gcp_project_id -%>, name: <%= gcp_project_iam_custom_role_id -%>) do
it { should exist }
its('stage') { should eq 'GA' }
diff --git a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role_attributes.erb b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role_attributes.erb
index 3238df07fe9c..a27a02e66a28 100644
--- a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role_attributes.erb
+++ b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_role_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_project_iam_custom_role_id = attribute(:gcp_project_iam_custom_role_id, default: '<%= external_attribute('gcp_project_iam_custom_role_id') -%>', description: 'The IAM custom role identifier.')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_project_iam_custom_role_id = attribute(:gcp_project_iam_custom_role_id, default: '<%= external_attribute(pwd, 'gcp_project_iam_custom_role_id') -%>', description: 'The IAM custom role identifier.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_roles.erb b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_roles.erb
index db14e31ea613..26f1fee6203f 100644
--- a/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_roles.erb
+++ b/templates/inspec/examples/google_project_iam_custom_role/google_project_iam_custom_roles.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_project_iam_custom_role_id = "#{external_attribute('gcp_project_iam_custom_role_id', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_project_iam_custom_role_id = "#{external_attribute(pwd, 'gcp_project_iam_custom_role_id', doc_generation)}" -%>
describe google_project_iam_custom_roles(project: <%= gcp_project_id -%>) do
its('names') { should include "projects/<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>/roles/<%= doc_generation ? "role-id" : "\#{gcp_project_iam_custom_role_id}" -%>" }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project_metric/google_project_metric.erb b/templates/inspec/examples/google_project_metric/google_project_metric.erb
index 24569fcfbc0e..a3bc78606f56 100644
--- a/templates/inspec/examples/google_project_metric/google_project_metric.erb
+++ b/templates/inspec/examples/google_project_metric/google_project_metric.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% logging_metric = grab_attributes['logging_metric'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% logging_metric = grab_attributes(pwd)['logging_metric'] -%>
describe google_project_metric(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{logging_metric['name']}'" : "logging_metric['name']" -%>) do
it { should exist }
its('filter') { should cmp <%= doc_generation ? "'#{logging_metric['filter']}'" : "logging_metric['filter']" -%> }
diff --git a/templates/inspec/examples/google_project_metric/google_project_metric_attributes.erb b/templates/inspec/examples/google_project_metric/google_project_metric_attributes.erb
index 22313211290d..74e822ad83a1 100644
--- a/templates/inspec/examples/google_project_metric/google_project_metric_attributes.erb
+++ b/templates/inspec/examples/google_project_metric/google_project_metric_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-logging_metric = attribute('logging_metric', default: <%= JSON.pretty_generate(grab_attributes['logging_metric']) -%>, description: 'Logging metric definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+logging_metric = attribute('logging_metric', default: <%= JSON.pretty_generate(grab_attributes(pwd)['logging_metric']) -%>, description: 'Logging metric definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project_metric/google_project_metrics.erb b/templates/inspec/examples/google_project_metric/google_project_metrics.erb
index e00776c14c05..6f53f5ae9840 100644
--- a/templates/inspec/examples/google_project_metric/google_project_metrics.erb
+++ b/templates/inspec/examples/google_project_metric/google_project_metrics.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% logging_metric = grab_attributes['logging_metric'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% logging_metric = grab_attributes(pwd)['logging_metric'] -%>
describe google_project_metrics(project: <%= gcp_project_id -%>) do
it { should exist }
its('metric_filters') { should include <%= doc_generation ? "'#{logging_metric['filter']}'" : "logging_metric['filter']" -%> }
diff --git a/templates/inspec/examples/google_project_service/google_project_service.erb b/templates/inspec/examples/google_project_service/google_project_service.erb
index 7e5e67045fc1..f2a20336d408 100644
--- a/templates/inspec/examples/google_project_service/google_project_service.erb
+++ b/templates/inspec/examples/google_project_service/google_project_service.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% service = grab_attributes['service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% service = grab_attributes(pwd)['service'] -%>
describe google_project_service(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{service['name']}'" : "service['name']" -%>) do
it { should exist }
its('state') { should cmp "ENABLED" }
diff --git a/templates/inspec/examples/google_project_service/google_project_service_attributes.erb b/templates/inspec/examples/google_project_service/google_project_service_attributes.erb
index f7b5ec33a865..a0fc0c587797 100644
--- a/templates/inspec/examples/google_project_service/google_project_service_attributes.erb
+++ b/templates/inspec/examples/google_project_service/google_project_service_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-service = attribute('service', default: <%= JSON.pretty_generate(grab_attributes['service']) -%>, description: 'Service description')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+service = attribute('service', default: <%= JSON.pretty_generate(grab_attributes(pwd)['service']) -%>, description: 'Service description')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_project_service/google_project_services.erb b/templates/inspec/examples/google_project_service/google_project_services.erb
index 4494e84fc468..5eef0819ae9f 100644
--- a/templates/inspec/examples/google_project_service/google_project_services.erb
+++ b/templates/inspec/examples/google_project_service/google_project_services.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% service = grab_attributes['service'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% service = grab_attributes(pwd)['service'] -%>
describe.one do
google_project_services(project: <%= gcp_project_id -%>).names.each do |name|
describe name do
diff --git a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription.erb b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription.erb
index 8748a88cea45..e6f79dc05774 100644
--- a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription.erb
+++ b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% subscription = grab_attributes['subscription'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% subscription = grab_attributes(pwd)['subscription'] -%>
describe google_pubsub_subscription(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{subscription['name']}'" : "subscription['name']" -%>) do
it { should exist }
end
diff --git a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription_attributes.erb b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription_attributes.erb
index a4fc9b29b37d..336577f3407c 100644
--- a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription_attributes.erb
+++ b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscription_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-subscription = attribute('subscription', default: <%= grab_attributes['subscription'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+subscription = attribute('subscription', default: <%= grab_attributes(pwd)['subscription'] -%>)
diff --git a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscriptions.erb b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscriptions.erb
index 3c062ba63735..a934744ac1e3 100644
--- a/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscriptions.erb
+++ b/templates/inspec/examples/google_pubsub_subscription/google_pubsub_subscriptions.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% subscription = grab_attributes['subscription'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% subscription = grab_attributes(pwd)['subscription'] -%>
describe google_pubsub_subscriptions(project: <%= gcp_project_id -%>) do
its('count') { should be >= 1 }
end
diff --git a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic.erb b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic.erb
index c3c761e71c81..b773b8ee83cf 100644
--- a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic.erb
+++ b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% topic = grab_attributes['topic'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% topic = grab_attributes(pwd)['topic'] -%>
describe google_pubsub_topic(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{topic['name']}'" : "topic['name']" -%>) do
it { should exist }
end
diff --git a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic_attributes.erb b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic_attributes.erb
index f0628e0d3d22..961a6d248b72 100644
--- a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic_attributes.erb
+++ b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topic_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-topic = attribute('topic', default: <%= grab_attributes['topic'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+topic = attribute('topic', default: <%= grab_attributes(pwd)['topic'] -%>)
diff --git a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topics.erb b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topics.erb
index 0e722b93a536..ffa3b8d07497 100644
--- a/templates/inspec/examples/google_pubsub_topic/google_pubsub_topics.erb
+++ b/templates/inspec/examples/google_pubsub_topic/google_pubsub_topics.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% topic = grab_attributes['topic'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% topic = grab_attributes(pwd)['topic'] -%>
describe google_pubsub_topics(project: <%= gcp_project_id -%>) do
it { should exist }
its('names') { should include <%= doc_generation ? "'#{topic['name']}'" : "topic['name']" -%> }
diff --git a/templates/inspec/examples/google_redis_instance/google_redis_instance.erb b/templates/inspec/examples/google_redis_instance/google_redis_instance.erb
index 352b8fbbe600..3684e715611b 100644
--- a/templates/inspec/examples/google_redis_instance/google_redis_instance.erb
+++ b/templates/inspec/examples/google_redis_instance/google_redis_instance.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% redis = grab_attributes['redis'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% redis = grab_attributes(pwd)['redis'] -%>
describe google_redis_instance(project: <%= gcp_project_id -%>, region: <%= doc_generation ? "'#{redis['region']}'" : "redis['region']" -%>, name: <%= doc_generation ? "'#{redis['name']}'" : "redis['name']" -%>) do
it { should exist }
its('tier') { should cmp <%= doc_generation ? "'#{redis['tier']}'" : "redis['tier']" -%> }
diff --git a/templates/inspec/examples/google_redis_instance/google_redis_instance_attributes.erb b/templates/inspec/examples/google_redis_instance/google_redis_instance_attributes.erb
index 006e5a5d0593..47e7bd056295 100644
--- a/templates/inspec/examples/google_redis_instance/google_redis_instance_attributes.erb
+++ b/templates/inspec/examples/google_redis_instance/google_redis_instance_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-redis = attribute('redis', default: <%= grab_attributes['redis'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+redis = attribute('redis', default: <%= grab_attributes(pwd)['redis'] -%>)
diff --git a/templates/inspec/examples/google_redis_instance/google_redis_instances.erb b/templates/inspec/examples/google_redis_instance/google_redis_instances.erb
index 549e71f7b8f9..21e6d5cd9186 100644
--- a/templates/inspec/examples/google_redis_instance/google_redis_instances.erb
+++ b/templates/inspec/examples/google_redis_instance/google_redis_instances.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% redis = grab_attributes['redis'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% redis = grab_attributes(pwd)['redis'] -%>
describe google_redis_instances(project: <%= gcp_project_id -%>, region: <%= doc_generation ? "'#{redis['region']}'" : "redis['region']" -%>) do
its('tiers') { should include <%= doc_generation ? "'#{redis['tier']}'" : "redis['tier']" -%> }
its('memory_size_gbs') { should include <%= doc_generation ? "'#{redis['memory_size_gb']}'" : "redis['memory_size_gb']" -%> }
diff --git a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder.erb b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder.erb
index 53e80492d88c..b24306bc65e5 100644
--- a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder.erb
+++ b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder.erb
@@ -1,4 +1,4 @@
-<% folder = grab_attributes['folder'] -%>
+<% folder = grab_attributes(pwd)['folder'] -%>
describe.one do
google_resourcemanager_folders(parent: <%= doc_generation ? "'organizations/12345'" : "\"organizations/\#{gcp_organization_id}\"" -%>).names.each do |name|
describe google_resourcemanager_folder(name: name) do
diff --git a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder_attributes.erb b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder_attributes.erb
index 2676d1ca4f6b..bb0eff2865fd 100644
--- a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder_attributes.erb
+++ b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folder_attributes.erb
@@ -1,3 +1,3 @@
-folder = attribute('folder', default: <%= grab_attributes['folder'] -%>)
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
+folder = attribute('folder', default: <%= grab_attributes(pwd)['folder'] -%>)
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization that is the parent of this folder')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folders.erb b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folders.erb
index 7b7b4c9c8c4c..d0ce2596ddba 100644
--- a/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folders.erb
+++ b/templates/inspec/examples/google_resourcemanager_folder/google_resourcemanager_folders.erb
@@ -1,4 +1,4 @@
-<% folder = grab_attributes['folder'] -%>
+<% folder = grab_attributes(pwd)['folder'] -%>
describe.one do
google_resourcemanager_folders(parent: <%= doc_generation ? "'organizations/12345'" : "\"organizations/\#{gcp_organization_id}\"" -%>).display_names.each do |display_name|
describe display_name do
diff --git a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config.erb b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config.erb
index 1a51cf193be4..9be54812764d 100644
--- a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config.erb
+++ b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% runtimeconfig_config = grab_attributes['runtimeconfig_config'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% runtimeconfig_config = grab_attributes(pwd)['runtimeconfig_config'] -%>
describe google_runtime_config_config(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{runtimeconfig_config['name']}'" : "runtimeconfig_config['name']" -%>) do
it { should exist }
its('description') { should cmp <%= doc_generation ? "'#{runtimeconfig_config['description']}'" : "runtimeconfig_config['description']" -%> }
diff --git a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config_attributes.erb b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config_attributes.erb
index 5e80fedc0e38..dd6c245f54b7 100644
--- a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config_attributes.erb
+++ b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_config_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-runtimeconfig_config = attribute('runtimeconfig_config', default: <%= grab_attributes['runtimeconfig_config'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+runtimeconfig_config = attribute('runtimeconfig_config', default: <%= grab_attributes(pwd)['runtimeconfig_config'] -%>)
diff --git a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_configs.erb b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_configs.erb
index 478c554a2b8f..7879479232d1 100644
--- a/templates/inspec/examples/google_runtime_config_config/google_runtime_config_configs.erb
+++ b/templates/inspec/examples/google_runtime_config_config/google_runtime_config_configs.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% runtimeconfig_config = grab_attributes['runtimeconfig_config'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% runtimeconfig_config = grab_attributes(pwd)['runtimeconfig_config'] -%>
describe google_runtime_config_configs(project: <%= gcp_project_id -%>) do
its('descriptions') { should include <%= doc_generation ? "'#{runtimeconfig_config['description']}'" : "runtimeconfig_config['description']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable.erb b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable.erb
index cdc396302d0a..d530f48413b3 100644
--- a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable.erb
+++ b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% runtimeconfig_config = grab_attributes['runtimeconfig_config'] -%>
-<% runtimeconfig_variable = grab_attributes['runtimeconfig_variable'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% runtimeconfig_config = grab_attributes(pwd)['runtimeconfig_config'] -%>
+<% runtimeconfig_variable = grab_attributes(pwd)['runtimeconfig_variable'] -%>
describe google_runtime_config_variable(project: <%= gcp_project_id -%>, config: <%= doc_generation ? "'#{runtimeconfig_config['name']}'" : "runtimeconfig_config['name']" -%>, name: <%= doc_generation ? "'#{runtimeconfig_variable['name']}'" : "runtimeconfig_variable['name']" -%>) do
it { should exist }
its('text') { should cmp <%= doc_generation ? "'#{runtimeconfig_variable['text']}'" : "runtimeconfig_variable['text']" -%> }
diff --git a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable_attributes.erb b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable_attributes.erb
index eb4cf653d070..8fe1e21ecc0e 100644
--- a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable_attributes.erb
+++ b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variable_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-runtimeconfig_config = attribute('runtimeconfig_config', default: <%= grab_attributes['runtimeconfig_config'] -%>)
-runtimeconfig_variable = attribute('runtimeconfig_variable', default: <%= grab_attributes['runtimeconfig_variable'] -%>)
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+runtimeconfig_config = attribute('runtimeconfig_config', default: <%= grab_attributes(pwd)['runtimeconfig_config'] -%>)
+runtimeconfig_variable = attribute('runtimeconfig_variable', default: <%= grab_attributes(pwd)['runtimeconfig_variable'] -%>)
diff --git a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variables.erb b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variables.erb
index a34007a185f2..611d15a77f2d 100644
--- a/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variables.erb
+++ b/templates/inspec/examples/google_runtime_config_variable/google_runtime_config_variables.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% runtimeconfig_config = grab_attributes['runtimeconfig_config'] -%>
-<% runtimeconfig_variable = grab_attributes['runtimeconfig_variable'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% runtimeconfig_config = grab_attributes(pwd)['runtimeconfig_config'] -%>
+<% runtimeconfig_variable = grab_attributes(pwd)['runtimeconfig_variable'] -%>
describe google_runtime_config_variables(project: <%= gcp_project_id -%>, config: <%= doc_generation ? "'#{runtimeconfig_config['name']}'" : "runtimeconfig_config['name']" -%>) do
its('texts') { should include <%= doc_generation ? "'#{runtimeconfig_variable['text']}'" : "runtimeconfig_variable['text']" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_service_account/google_service_account.erb b/templates/inspec/examples/google_service_account/google_service_account.erb
index 724fa9bdf614..6027fde92248 100644
--- a/templates/inspec/examples/google_service_account/google_service_account.erb
+++ b/templates/inspec/examples/google_service_account/google_service_account.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
describe google_service_account(project: <%= gcp_project_id -%>, name: "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com") do
it { should exist }
its('display_name') { should cmp <%= gcp_service_account_display_name -%> }
diff --git a/templates/inspec/examples/google_service_account/google_service_account_attributes.erb b/templates/inspec/examples/google_service_account/google_service_account_attributes.erb
index ea7e09771830..0ec35cfa0e64 100644
--- a/templates/inspec/examples/google_service_account/google_service_account_attributes.erb
+++ b/templates/inspec/examples/google_service_account/google_service_account_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The IAM service account display name.')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The IAM service account display name.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_service_account/google_service_accounts.erb b/templates/inspec/examples/google_service_account/google_service_accounts.erb
index a882be63d2ed..72ff1a464f85 100644
--- a/templates/inspec/examples/google_service_account/google_service_accounts.erb
+++ b/templates/inspec/examples/google_service_account/google_service_accounts.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
describe google_service_accounts(project: <%= gcp_project_id -%>, name: "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com") do
its('service_account_emails') { should include "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com" }
its('count') { should be <= 1000 }
diff --git a/templates/inspec/examples/google_service_account_key/google_service_account_key.erb b/templates/inspec/examples/google_service_account_key/google_service_account_key.erb
index 86286b87c5af..fc5b5c137f93 100644
--- a/templates/inspec/examples/google_service_account_key/google_service_account_key.erb
+++ b/templates/inspec/examples/google_service_account_key/google_service_account_key.erb
@@ -1,5 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
google_service_account_keys(project: <%= gcp_project_id -%>, service_account: "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com").key_names.each do |sa_key_name|
- describe
+ describe google_service_account_key(project: <%= gcp_project_id -%>, service_account: "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com", name: sa_key_name.split('/').last) do
+ it { should exist }
+ its('key_type') { should_not cmp 'USER_MANAGED' }
+ end
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_service_account_key/google_service_account_key_attributes.erb b/templates/inspec/examples/google_service_account_key/google_service_account_key_attributes.erb
index ea7e09771830..0ec35cfa0e64 100644
--- a/templates/inspec/examples/google_service_account_key/google_service_account_key_attributes.erb
+++ b/templates/inspec/examples/google_service_account_key/google_service_account_key_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The IAM service account display name.')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The IAM service account display name.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default:0, description:'Flag to enable privileged resources requiring elevated privileges in GCP.')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_service_account_key/google_service_account_keys.erb b/templates/inspec/examples/google_service_account_key/google_service_account_keys.erb
index 363d7a6056f0..052d62f3ee30 100644
--- a/templates/inspec/examples/google_service_account_key/google_service_account_keys.erb
+++ b/templates/inspec/examples/google_service_account_key/google_service_account_keys.erb
@@ -1,5 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
describe google_service_account_keys(project: <%= gcp_project_id -%>, service_account: "<%= doc_generation ? "display-name" : "\#{gcp_service_account_display_name}" -%>@<%= doc_generation ? "project-id" : "\#{gcp_project_id}" -%>.iam.gserviceaccount.com") do
its('count') { should be <= 1000 }
+ its('key_types') { should_not include 'USER_MANAGED' }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repositories.erb b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repositories.erb
index 2f85226d9ad3..0c3e3adf3f99 100644
--- a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repositories.erb
+++ b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repositories.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% repository = grab_attributes['repository'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% repository = grab_attributes(pwd)['repository'] -%>
repo_name = <%= doc_generation ? "'#{repository['name']}'" : "repository['name']" %>
describe.one do
google_sourcerepo_repositories(project: <%= gcp_project_id -%>).names.each do |name|
diff --git a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository.erb b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository.erb
index b4c9bbc6193f..469e77755211 100644
--- a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository.erb
+++ b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% repository = grab_attributes['repository'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% repository = grab_attributes(pwd)['repository'] -%>
describe google_sourcerepo_repository(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{repository['name']}'" : "repository['name']" -%>) do
it { should exist }
end
diff --git a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository_attributes.erb b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository_attributes.erb
index eb1280931aee..027498314e4d 100644
--- a/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository_attributes.erb
+++ b/templates/inspec/examples/google_sourcerepo_repository/google_sourcerepo_repository_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-repository = attribute('repository', default: <%= JSON.pretty_generate(grab_attributes['repository']) -%>, description: 'Source Repository definition')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+repository = attribute('repository', default: <%= JSON.pretty_generate(grab_attributes(pwd)['repository']) -%>, description: 'Source Repository definition')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_spanner_database/google_spanner_database.erb b/templates/inspec/examples/google_spanner_database/google_spanner_database.erb
index 487ce68cc262..62db1c769db2 100644
--- a/templates/inspec/examples/google_spanner_database/google_spanner_database.erb
+++ b/templates/inspec/examples/google_spanner_database/google_spanner_database.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% spannerdatabase = grab_attributes['spannerdatabase'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% spannerdatabase = grab_attributes(pwd)['spannerdatabase'] -%>
describe google_spanner_database(project: <%= gcp_project_id -%>, instance: <%= doc_generation ? "'#{spannerdatabase['instance']}'" : "spannerdatabase['instance']" -%>, name: <%= doc_generation ? "'#{spannerdatabase['name']}'" : "spannerdatabase['name']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_spanner_database/google_spanner_database_attributes.erb b/templates/inspec/examples/google_spanner_database/google_spanner_database_attributes.erb
index 93a24ba09df1..a31c01b02921 100644
--- a/templates/inspec/examples/google_spanner_database/google_spanner_database_attributes.erb
+++ b/templates/inspec/examples/google_spanner_database/google_spanner_database_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-spannerdatabase = attribute('spannerdatabase', default: <%= JSON.pretty_generate(grab_attributes['spannerdatabase']) -%>, description: 'Cloud Spanner definition')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+spannerdatabase = attribute('spannerdatabase', default: <%= JSON.pretty_generate(grab_attributes(pwd)['spannerdatabase']) -%>, description: 'Cloud Spanner definition')
diff --git a/templates/inspec/examples/google_spanner_database/google_spanner_databases.erb b/templates/inspec/examples/google_spanner_database/google_spanner_databases.erb
index c29f3cb3c7ab..064ec0622361 100644
--- a/templates/inspec/examples/google_spanner_database/google_spanner_databases.erb
+++ b/templates/inspec/examples/google_spanner_database/google_spanner_databases.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% spannerdatabase = grab_attributes['spannerdatabase'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% spannerdatabase = grab_attributes(pwd)['spannerdatabase'] -%>
describe.one do
google_spanner_databases(project: <%= gcp_project_id -%>, instance: <%= doc_generation ? "'#{spannerdatabase['instance']}'" : "spannerdatabase['instance']" -%>).names.each do |name|
diff --git a/templates/inspec/examples/google_spanner_instance/google_spanner_instance.erb b/templates/inspec/examples/google_spanner_instance/google_spanner_instance.erb
index bb488d5eaee0..714f04240248 100644
--- a/templates/inspec/examples/google_spanner_instance/google_spanner_instance.erb
+++ b/templates/inspec/examples/google_spanner_instance/google_spanner_instance.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% spannerinstance = grab_attributes['spannerinstance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% spannerinstance = grab_attributes(pwd)['spannerinstance'] -%>
describe google_spanner_instance(project: <%= gcp_project_id -%>, name: <%= doc_generation ? "'#{spannerinstance['name']}'" : "spannerinstance['name']" -%>, config: <%= doc_generation ? "'#{spannerinstance['config']}'" : "spannerinstance['config']" -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_spanner_instance/google_spanner_instance_attributes.erb b/templates/inspec/examples/google_spanner_instance/google_spanner_instance_attributes.erb
index ba0396d56f0e..1c8ab339e0c8 100644
--- a/templates/inspec/examples/google_spanner_instance/google_spanner_instance_attributes.erb
+++ b/templates/inspec/examples/google_spanner_instance/google_spanner_instance_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-spannerinstance = attribute('spannerinstance', default: <%= JSON.pretty_generate(grab_attributes['spannerinstance']) -%>, description: 'Cloud Spanner definition')
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+spannerinstance = attribute('spannerinstance', default: <%= JSON.pretty_generate(grab_attributes(pwd)['spannerinstance']) -%>, description: 'Cloud Spanner definition')
diff --git a/templates/inspec/examples/google_spanner_instance/google_spanner_instances.erb b/templates/inspec/examples/google_spanner_instance/google_spanner_instances.erb
index 3ddaa51ab622..0b11a9afddca 100644
--- a/templates/inspec/examples/google_spanner_instance/google_spanner_instances.erb
+++ b/templates/inspec/examples/google_spanner_instance/google_spanner_instances.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% spannerinstance = grab_attributes['spannerinstance'] -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% spannerinstance = grab_attributes(pwd)['spannerinstance'] -%>
describe.one do
google_spanner_instances(project: <%= gcp_project_id -%>, config: <%= doc_generation ? "'#{spannerinstance['config']}'" : "spannerinstance['config']" -%>).configs.each do |config|
diff --git a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance.erb b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance.erb
index f2e28abcf105..728842daa274 100644
--- a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance.erb
+++ b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_db_instance_name = "#{external_attribute('gcp_db_instance_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_db_instance_name = "#{external_attribute(pwd, 'gcp_db_instance_name', doc_generation)}" -%>
describe google_sql_database_instance(project: <%= gcp_project_id -%>, database: <%= gcp_db_instance_name -%>) do
it { should exist }
diff --git a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance_attributes.erb b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance_attributes.erb
index a1a3b190f72e..d5b9382713c6 100644
--- a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance_attributes.erb
+++ b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instance_attributes.erb
@@ -1,3 +1,3 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project location.')
-gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '<%= external_attribute('gcp_db_instance_name') -%>', description: 'Database instance name.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project location.')
+gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '<%= external_attribute(pwd, 'gcp_db_instance_name') -%>', description: 'Database instance name.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instances.erb b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instances.erb
index e67dc17344e9..6d9fd569ef8a 100644
--- a/templates/inspec/examples/google_sql_database_instance/google_sql_database_instances.erb
+++ b/templates/inspec/examples/google_sql_database_instance/google_sql_database_instances.erb
@@ -1,6 +1,6 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_db_instance_name = "#{external_attribute('gcp_db_instance_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_db_instance_name = "#{external_attribute(pwd, 'gcp_db_instance_name', doc_generation)}" -%>
describe google_sql_database_instances(project: <%= gcp_project_id -%>) do
its('instance_states') { should include 'RUNNABLE' }
diff --git a/templates/inspec/examples/google_sql_user/google_sql_user.erb b/templates/inspec/examples/google_sql_user/google_sql_user.erb
index cb5fff46f9e5..df867ff15c8e 100644
--- a/templates/inspec/examples/google_sql_user/google_sql_user.erb
+++ b/templates/inspec/examples/google_sql_user/google_sql_user.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_db_instance_name = "#{external_attribute('gcp_db_instance_name', doc_generation)}" -%>
-<% gcp_db_user_name = "#{external_attribute('gcp_db_user_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_db_instance_name = "#{external_attribute(pwd, 'gcp_db_instance_name', doc_generation)}" -%>
+<% gcp_db_user_name = "#{external_attribute(pwd, 'gcp_db_user_name', doc_generation)}" -%>
describe google_sql_user(project: <%= gcp_project_id -%>, database: <%= gcp_db_instance_name -%>, name: <%= gcp_db_user_name -%>, host: "example.com") do
it { should exist }
diff --git a/templates/inspec/examples/google_sql_user/google_sql_user_attributes.erb b/templates/inspec/examples/google_sql_user/google_sql_user_attributes.erb
index 0586a7363233..58477507e9a1 100644
--- a/templates/inspec/examples/google_sql_user/google_sql_user_attributes.erb
+++ b/templates/inspec/examples/google_sql_user/google_sql_user_attributes.erb
@@ -1,4 +1,4 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'The GCP project location.')
-gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '<%= external_attribute('gcp_db_instance_name') -%>', description: 'Database instance name.')
-gcp_db_user_name = attribute(:gcp_db_user_name, default: '<%= external_attribute('gcp_db_user_name') -%>', description: 'SQL database user name.')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'The GCP project location.')
+gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '<%= external_attribute(pwd, 'gcp_db_instance_name') -%>', description: 'Database instance name.')
+gcp_db_user_name = attribute(:gcp_db_user_name, default: '<%= external_attribute(pwd, 'gcp_db_user_name') -%>', description: 'SQL database user name.')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_sql_user/google_sql_users.erb b/templates/inspec/examples/google_sql_user/google_sql_users.erb
index 004c03fbce49..b5c3dad3ffdb 100644
--- a/templates/inspec/examples/google_sql_user/google_sql_users.erb
+++ b/templates/inspec/examples/google_sql_user/google_sql_users.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
-<% gcp_db_instance_name = "#{external_attribute('gcp_db_instance_name', doc_generation)}" -%>
-<% gcp_db_user_name = "#{external_attribute('gcp_db_user_name', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
+<% gcp_db_instance_name = "#{external_attribute(pwd, 'gcp_db_instance_name', doc_generation)}" -%>
+<% gcp_db_user_name = "#{external_attribute(pwd, 'gcp_db_user_name', doc_generation)}" -%>
describe google_sql_users(project: <%= gcp_project_id -%>, database: <%= gcp_db_instance_name -%>) do
its('user_names') { should include <%= gcp_db_user_name -%> }
diff --git a/templates/inspec/examples/google_storage_bucket/google_storage_bucket.erb b/templates/inspec/examples/google_storage_bucket/google_storage_bucket.erb
index 2e4ba4e8ed03..5cb98f6ee78b 100644
--- a/templates/inspec/examples/google_storage_bucket/google_storage_bucket.erb
+++ b/templates/inspec/examples/google_storage_bucket/google_storage_bucket.erb
@@ -1,11 +1,12 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
describe google_storage_bucket(name: <%= doc_generation ? "bucket-name" : "\"inspec-gcp-static-\#{gcp_project_id}\"" -%>) do
it { should exist }
its('location') { should cmp <%= gcp_location -%>.upcase }
its('storage_class') { should eq "STANDARD" }
its('labels') { should include("key" => "value") }
+ its('retention_policy.retention_period') { should cmp 1000 }
end
describe google_storage_bucket(name: "nonexistent") do
diff --git a/templates/inspec/examples/google_storage_bucket/google_storage_bucket_attributes.erb b/templates/inspec/examples/google_storage_bucket/google_storage_bucket_attributes.erb
index fab87fb26e8a..447e1ec7dbf9 100644
--- a/templates/inspec/examples/google_storage_bucket/google_storage_bucket_attributes.erb
+++ b/templates/inspec/examples/google_storage_bucket/google_storage_bucket_attributes.erb
@@ -1,2 +1,2 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_location = attribute(:gcp_location, default: '<%= external_attribute('gcp_location') -%>', description: 'GCP location')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_location = attribute(:gcp_location, default: '<%= external_attribute(pwd, 'gcp_location') -%>', description: 'GCP location')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_storage_bucket/google_storage_buckets.erb b/templates/inspec/examples/google_storage_bucket/google_storage_buckets.erb
index 234d7f8a1760..b3dba11223f5 100644
--- a/templates/inspec/examples/google_storage_bucket/google_storage_buckets.erb
+++ b/templates/inspec/examples/google_storage_bucket/google_storage_buckets.erb
@@ -1,5 +1,5 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_location = "#{external_attribute('gcp_location', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_location = "#{external_attribute(pwd, 'gcp_location', doc_generation)}" -%>
describe google_storage_buckets(project: <%= gcp_project_id -%>) do
its('bucket_names') { should include <%= doc_generation ? "bucket-name" : "\"inspec-gcp-static-\#{gcp_project_id}\"" -%> }
end
\ No newline at end of file
diff --git a/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl.erb b/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl.erb
index 00bf6af334e9..699ba5f199b1 100644
--- a/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl.erb
+++ b/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_acl = "#{external_attribute('gcp_storage_bucket_acl', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
-<% gcp_enable_privileged_resources = "#{external_attribute('gcp_enable_privileged_resources', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_acl = "#{external_attribute(pwd, 'gcp_storage_bucket_acl', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_enable_privileged_resources = "#{external_attribute(pwd, 'gcp_enable_privileged_resources', doc_generation)}" -%>
describe google_storage_bucket_acl(bucket: <%= gcp_storage_bucket_acl -%>, entity: <%= doc_generation ? "user-email" : "\"user-\#{gcp_service_account_display_name}@\#{gcp_project_id}.iam.gserviceaccount.com\"" -%>) do
it { should exist }
its('role') { should cmp "OWNER" }
diff --git a/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl_attributes.erb b/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl_attributes.erb
index 9067ed2710b6..deaa5d4869ae 100644
--- a/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl_attributes.erb
+++ b/templates/inspec/examples/google_storage_bucket_acl/google_storage_bucket_acl_attributes.erb
@@ -1,5 +1,5 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_storage_bucket_acl = attribute(:gcp_storage_bucket_acl, default: '<%= external_attribute('gcp_storage_bucket_acl') -%>', description: 'The name of the storage bucket with ACLs attached')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_storage_bucket_acl = attribute(:gcp_storage_bucket_acl, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_acl') -%>', description: 'The name of the storage bucket with ACLs attached')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object.erb b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object.erb
index 54c7b928837e..56ee2223cae4 100644
--- a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object.erb
+++ b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object.erb
@@ -1,8 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_object = "#{external_attribute('gcp_storage_bucket_object', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
-<% gcp_storage_bucket_object_name = "#{external_attribute('gcp_storage_bucket_object_name', doc_generation)}" -%>
-<% gcp_enable_privileged_resources = "#{external_attribute('gcp_enable_privileged_resources', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_object = "#{external_attribute(pwd, 'gcp_storage_bucket_object', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_storage_bucket_object_name = "#{external_attribute(pwd, 'gcp_storage_bucket_object_name', doc_generation)}" -%>
+<% gcp_enable_privileged_resources = "#{external_attribute(pwd, 'gcp_enable_privileged_resources', doc_generation)}" -%>
describe google_storage_bucket_object(bucket: <%= gcp_storage_bucket_object -%>, object: <%= gcp_storage_bucket_object_name -%>) do
it { should exist }
its('size.to_i') { should be > 0 }
diff --git a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object_attributes.erb b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object_attributes.erb
index 325d3112c7d7..1a74e108fac9 100644
--- a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object_attributes.erb
+++ b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_object_attributes.erb
@@ -1,6 +1,6 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_storage_bucket_object = attribute(:gcp_storage_bucket_object, default: '<%= external_attribute('gcp_storage_bucket_object') -%>', description: 'The name of the storage bucket with an object')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_storage_bucket_object_name = attribute(:gcp_storage_bucket_object_name, default: '<%= external_attribute('gcp_storage_bucket_object_name') -%>', description: 'The name of the object')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_storage_bucket_object = attribute(:gcp_storage_bucket_object, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_object') -%>', description: 'The name of the storage bucket with an object')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_storage_bucket_object_name = attribute(:gcp_storage_bucket_object_name, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_object_name') -%>', description: 'The name of the object')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_objects.erb b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_objects.erb
index b64afeba2b2a..24721f9a0139 100644
--- a/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_objects.erb
+++ b/templates/inspec/examples/google_storage_bucket_object/google_storage_bucket_objects.erb
@@ -1,8 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_object = "#{external_attribute('gcp_storage_bucket_object', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
-<% gcp_storage_bucket_object_name = "#{external_attribute('gcp_storage_bucket_object_name', doc_generation)}" -%>
-<% gcp_enable_privileged_resources = "#{external_attribute('gcp_enable_privileged_resources', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_object = "#{external_attribute(pwd, 'gcp_storage_bucket_object', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_storage_bucket_object_name = "#{external_attribute(pwd, 'gcp_storage_bucket_object_name', doc_generation)}" -%>
+<% gcp_enable_privileged_resources = "#{external_attribute(pwd, 'gcp_enable_privileged_resources', doc_generation)}" -%>
describe google_storage_bucket_objects(bucket: <%= gcp_storage_bucket_object -%>) do
its('object_names') { should include <%= gcp_storage_bucket_object_name -%> }
its('count') { should be <= 10 }
diff --git a/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl.erb b/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl.erb
index ff8e0785d1d3..87340b7b0642 100644
--- a/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl.erb
+++ b/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl.erb
@@ -1,7 +1,7 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_name = "#{external_attribute('gcp_storage_bucket_name', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
-<% gcp_enable_privileged_resources = "#{external_attribute('gcp_enable_privileged_resources', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_name = "#{external_attribute(pwd, 'gcp_storage_bucket_name', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_enable_privileged_resources = "#{external_attribute(pwd, 'gcp_enable_privileged_resources', doc_generation)}" -%>
describe google_storage_default_object_acl(bucket: <%= gcp_storage_bucket_name -%>, entity: <%= doc_generation ? "user-email" : "\"user-\#{gcp_service_account_display_name}@\#{gcp_project_id}.iam.gserviceaccount.com\"" -%>) do
it { should exist }
its('role') { should cmp "OWNER" }
diff --git a/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl_attributes.erb b/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl_attributes.erb
index beaea827ad37..dc05a00799a1 100644
--- a/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl_attributes.erb
+++ b/templates/inspec/examples/google_storage_default_object_acl/google_storage_default_object_acl_attributes.erb
@@ -1,5 +1,5 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_storage_bucket_name = attribute(:gcp_storage_bucket_name, default: '<%= external_attribute('gcp_storage_bucket_name') -%>', description: 'The name of the storage bucket with the default object ACL')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_storage_bucket_name = attribute(:gcp_storage_bucket_name, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_name') -%>', description: 'The name of the storage bucket with the default object ACL')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl.erb b/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl.erb
index 1a183f728e93..8642e26fc994 100644
--- a/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl.erb
+++ b/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl.erb
@@ -1,8 +1,8 @@
-<% gcp_project_id = "#{external_attribute('gcp_project_id', doc_generation)}" -%>
-<% gcp_storage_bucket_object = "#{external_attribute('gcp_storage_bucket_object', doc_generation)}" -%>
-<% gcp_service_account_display_name = "#{external_attribute('gcp_service_account_display_name', doc_generation)}" -%>
-<% gcp_storage_bucket_object_name = "#{external_attribute('gcp_storage_bucket_object_name', doc_generation)}" -%>
-<% gcp_enable_privileged_resources = "#{external_attribute('gcp_enable_privileged_resources', doc_generation)}" -%>
+<% gcp_project_id = "#{external_attribute(pwd, 'gcp_project_id', doc_generation)}" -%>
+<% gcp_storage_bucket_object = "#{external_attribute(pwd, 'gcp_storage_bucket_object', doc_generation)}" -%>
+<% gcp_service_account_display_name = "#{external_attribute(pwd, 'gcp_service_account_display_name', doc_generation)}" -%>
+<% gcp_storage_bucket_object_name = "#{external_attribute(pwd, 'gcp_storage_bucket_object_name', doc_generation)}" -%>
+<% gcp_enable_privileged_resources = "#{external_attribute(pwd, 'gcp_enable_privileged_resources', doc_generation)}" -%>
describe google_storage_object_acl(bucket: <%= gcp_storage_bucket_object -%>, object: <%= gcp_storage_bucket_object_name -%>, entity: <%= doc_generation ? "user-email" : "\"user-\#{gcp_service_account_display_name}@\#{gcp_project_id}.iam.gserviceaccount.com\"" -%>) do
it { should exist }
its('role') { should cmp "OWNER" }
diff --git a/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl_attributes.erb b/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl_attributes.erb
index 3e738dbe025e..410358a1f54a 100644
--- a/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl_attributes.erb
+++ b/templates/inspec/examples/google_storage_object_acl/google_storage_object_acl_attributes.erb
@@ -1,6 +1,6 @@
-gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute('gcp_project_id') -%>', description: 'The GCP project identifier.')
-gcp_storage_bucket_object = attribute(:gcp_storage_bucket_object, default: '<%= external_attribute('gcp_storage_bucket_object') -%>', description: 'The name of the storage bucket with ACLs attached')
-gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute('gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
-gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute('gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
-gcp_storage_bucket_object_name = attribute(:gcp_storage_bucket_object_name, default: '<%= external_attribute('gcp_storage_bucket_object_name') -%>', description: 'The name of the object with ACLs')
-gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute('gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
+gcp_project_id = attribute(:gcp_project_id, default: '<%= external_attribute(pwd, 'gcp_project_id') -%>', description: 'The GCP project identifier.')
+gcp_storage_bucket_object = attribute(:gcp_storage_bucket_object, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_object') -%>', description: 'The name of the storage bucket with ACLs attached')
+gcp_service_account_display_name = attribute(:gcp_service_account_display_name, default: '<%= external_attribute(pwd, 'gcp_service_account_display_name') -%>', description: 'The name of the service account assigned permissions')
+gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources, default: '<%= external_attribute(pwd, 'gcp_enable_privileged_resources') -%>', description: 'If we are running tests with escalated permissions(required for this test)')
+gcp_storage_bucket_object_name = attribute(:gcp_storage_bucket_object_name, default: '<%= external_attribute(pwd, 'gcp_storage_bucket_object_name') -%>', description: 'The name of the object with ACLs')
+gcp_organization_id = attribute(:gcp_organization_id, default: <%= external_attribute(pwd, 'gcp_organization_id') -%>, description: 'The identifier of the organization')
\ No newline at end of file
diff --git a/templates/inspec/iam_binding/iam_binding.erb b/templates/inspec/iam_binding/iam_binding.erb
index 70279a97df70..bf22e29ac5fa 100644
--- a/templates/inspec/iam_binding/iam_binding.erb
+++ b/templates/inspec/iam_binding/iam_binding.erb
@@ -1,10 +1,10 @@
# frozen_string_literal: false
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby,pwd)) -%>
require 'gcp_backend'
require 'google/iam/property/iam_policy_bindings'
-# A provider to manage <%= @api.product_full_name -%> IAM Binding resources.
+# A provider to manage <%= @api.display_name -%> IAM Binding resources.
class <%= object.name -%>IamBinding < GcpResourceBase
name '<%= resource_name(object, product) -%>_iam_binding'
desc '<%= object.name -%> Iam Binding'
diff --git a/templates/inspec/iam_policy/iam_policy.erb b/templates/inspec/iam_policy/iam_policy.erb
index 984d202c81dc..62e249de1295 100644
--- a/templates/inspec/iam_policy/iam_policy.erb
+++ b/templates/inspec/iam_policy/iam_policy.erb
@@ -1,11 +1,11 @@
# frozen_string_literal: false
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby,pwd)) -%>
require 'gcp_backend'
require 'google/iam/property/iam_policy_audit_configs'
require 'google/iam/property/iam_policy_bindings'
-# A provider to manage <%= @api.product_full_name -%> IAM Policy resources.
+# A provider to manage <%= @api.display_name -%> IAM Policy resources.
class <%= object.name -%>IamPolicy < GcpResourceBase
name '<%= resource_name(object, product) -%>_iam_policy'
desc '<%= object.name -%> Iam Policy'
diff --git a/templates/inspec/integration_test_template.erb b/templates/inspec/integration_test_template.erb
index 1646ca707468..06209f1229d7 100644
--- a/templates/inspec/integration_test_template.erb
+++ b/templates/inspec/integration_test_template.erb
@@ -1,4 +1,4 @@
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby, pwd)) -%>
<% vcr_mode = ENV['VCR_MODE'] -%>
<% raise "Bad VCR_MODE environment variable set. Should be nil, 'none' or 'all'" unless vcr_mode.nil? || vcr_mode == 'all' || vcr_mode == 'none' -%>
<% if vcr_mode -%>
@@ -8,7 +8,7 @@
title 'Test GCP <%= name -%> resource.'
-<%= compile("templates/inspec/examples/#{attribute_file_name}/#{attribute_file_name}_attributes.erb") -%>
+<%= compile(pwd + "/templates/inspec/examples/#{attribute_file_name}/#{attribute_file_name}_attributes.erb") -%>
control '<%= name -%>-1.0' do
impact 1.0
@@ -20,7 +20,7 @@ control '<%= name -%>-1.0' do
<% if vcr_mode -%>
VCR.use_cassette('<%= name -%>', :record => :<%= vcr_mode -%>) do
<% end # if vcr_mode -%>
-<%= indent(compile("templates/inspec/examples/#{attribute_file_name}/#{name}.erb"), vcr_mode ? 4 : 2) %>
+<%= indent(compile(pwd + "/templates/inspec/examples/#{attribute_file_name}/#{name}.erb"), vcr_mode ? 4 : 2) %>
<% if vcr_mode -%>
end
<% end # if vcr_mode -%>
diff --git a/templates/inspec/nested_object.erb b/templates/inspec/nested_object.erb
index 4a3d3e48eb55..05a4382b2e05 100644
--- a/templates/inspec/nested_object.erb
+++ b/templates/inspec/nested_object.erb
@@ -24,7 +24,7 @@
-%>
# frozen_string_literal: false
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby, pwd)) -%>
<%
requires = generate_requires(nested_property.nested_properties)
-%>
diff --git a/templates/inspec/plural_resource.erb b/templates/inspec/plural_resource.erb
index 9d764db159b5..a067301ea831 100644
--- a/templates/inspec/plural_resource.erb
+++ b/templates/inspec/plural_resource.erb
@@ -14,7 +14,7 @@
-%>
# frozen_string_literal: false
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby, pwd)) -%>
require 'gcp_backend'
class <%= object.__product.name.camelize(:upper) -%><%= object.name -%>s < GcpResourceBase
<%
@@ -64,7 +64,7 @@ link_query_items = object&.nested_query&.keys&.first || object.collection_url_ke
hash_with_symbols[name] = value
end
<% if object.plural_custom_logic -%>
-<%= lines(indent(compile(object.plural_custom_logic), 8)) -%>
+<%= lines(indent(compile(pwd + '/' + object.plural_custom_logic), 8)) -%>
<% end -%>
converted.push(hash_with_symbols)
end
@@ -96,7 +96,7 @@ link_query_items = object&.nested_query&.keys&.first || object.collection_url_ke
private
-<%= compile('templates/inspec/product_url.erb') -%>
+<%= compile(pwd + '/templates/inspec/product_url.erb') -%>
def resource_base_url
'<%= object.base_url %>'
diff --git a/templates/inspec/singular_resource.erb b/templates/inspec/singular_resource.erb
index 572a8827be53..2283382f4cda 100644
--- a/templates/inspec/singular_resource.erb
+++ b/templates/inspec/singular_resource.erb
@@ -14,9 +14,9 @@
-%>
# frozen_string_literal: false
-<%= lines(autogen_notice :ruby) -%>
+<%= lines(autogen_notice(:ruby, pwd)) -%>
<%
- require 'google/string_utils'
+ require pwd + '/google/string_utils'
inside_indent = 8
@@ -26,7 +26,7 @@
-%>
<%= lines(emit_requires(requires)) -%>
-# A provider to manage <%= @api.product_full_name -%> resources.
+# A provider to manage <%= @api.display_name -%> resources.
class <%= object.__product.name.camelize(:upper) -%><%= object.name -%> < GcpResourceBase
name '<%= resource_name(object, product) -%>'
desc '<%= object.name -%>'
@@ -39,7 +39,7 @@ class <%= object.__product.name.camelize(:upper) -%><%= object.name -%> < GcpRes
<% end -%>
<% if !object.singular_custom_constructor.nil? -%>
-<%= indent(compile(object.singular_custom_constructor), 2) -%>
+<%= indent(compile(pwd + '/' + object.singular_custom_constructor), 2) -%>
<% elsif object.nested_query.nil? -%>
def initialize(params)
@@ -100,12 +100,12 @@ best_guess_identifier = extract_identifiers(individual_url).last
end
<% unless object&.additional_functions.nil? -%>
-<%= lines(indent(compile(object.additional_functions), 2)) -%>
+<%= lines(indent(compile(pwd + '/' + object.additional_functions), 2)) -%>
<% end -%>
private
-<%= compile('templates/inspec/product_url.erb') -%>
+<%= compile(pwd + '/templates/inspec/product_url.erb') -%>
<% url = object.self_link || object.base_url + '/{{name}}' -%>
<% url_params = extract_identifiers(individual_url) -%>
diff --git a/templates/inspec/tests/integration/build/gcp-mm.tf b/templates/inspec/tests/integration/build/gcp-mm.tf
index 3e77c33cb4cd..feba1dff37de 100644
--- a/templates/inspec/tests/integration/build/gcp-mm.tf
+++ b/templates/inspec/tests/integration/build/gcp-mm.tf
@@ -656,6 +656,10 @@ resource "google_storage_bucket" "bucket" {
labels = {
"key" = "value"
}
+
+ retention_policy {
+ retention_period = 1000
+ }
}
resource "google_storage_bucket_object" "object" {
@@ -906,6 +910,11 @@ resource "google_service_account" "spanner_service_account" {
display_name = "${var.gcp_service_account_display_name}-sp"
}
+resource "google_service_account_key" "userkey" {
+ service_account_id = google_service_account.spanner_service_account.name
+ public_key_type = "TYPE_X509_PEM_FILE"
+}
+
resource "google_spanner_instance" "spanner_instance" {
project = var.gcp_project_id
config = var.spannerinstance["config"]
@@ -1215,3 +1224,77 @@ resource "google_organization_iam_custom_role" "generic_org_iam_custom_role" {
description = "Custom role allowing to list IAM roles only"
permissions = ["iam.roles.list"]
}
+
+variable "security_policy" {
+ type = any
+}
+
+resource "google_compute_security_policy" "policy" {
+ project = var.gcp_project_id
+ name = var.security_policy["name"]
+
+ rule {
+ action = var.security_policy["action"]
+ priority = var.security_policy["priority"]
+ match {
+ versioned_expr = "SRC_IPS_V1"
+ config {
+ src_ip_ranges = [var.security_policy["ip_range"]]
+ }
+ }
+ description = var.security_policy["description"]
+ }
+
+ rule {
+ action = "allow"
+ priority = "2147483647"
+ match {
+ versioned_expr = "SRC_IPS_V1"
+ config {
+ src_ip_ranges = ["*"]
+ }
+ }
+ description = "default rule"
+ }
+}
+
+variable "memcache_instance" {
+ type = any
+}
+
+resource "google_compute_network" "memcache_network" {
+ provider = google-beta
+ project = var.gcp_project_id
+ name = "inspec-gcp-memcache"
+}
+
+resource "google_compute_global_address" "service_range" {
+ provider = google-beta
+ project = var.gcp_project_id
+ name = "inspec-gcp-memcache"
+ purpose = "VPC_PEERING"
+ address_type = "INTERNAL"
+ prefix_length = 16
+ network = google_compute_network.memcache_network.id
+}
+
+resource "google_service_networking_connection" "private_service_connection" {
+ provider = google-beta
+ network = google_compute_network.memcache_network.id
+ service = "servicenetworking.googleapis.com"
+ reserved_peering_ranges = [google_compute_global_address.service_range.name]
+}
+
+resource "google_memcache_instance" "instance" {
+ provider = google-beta
+ name = var.memcache_instance["name"]
+ project = var.gcp_project_id
+ region = var.gcp_location
+ authorized_network = google_service_networking_connection.private_service_connection.network
+
+ node_config {
+ cpu_count = 1
+ memory_size_mb = 1024
+ }
+ node_count = 1
+}
diff --git a/templates/inspec/tests/integration/configuration/mm-attributes.yml b/templates/inspec/tests/integration/configuration/mm-attributes.yml
index ab78ff156af9..faf675d00529 100644
--- a/templates/inspec/tests/integration/configuration/mm-attributes.yml
+++ b/templates/inspec/tests/integration/configuration/mm-attributes.yml
@@ -437,4 +437,13 @@ logging_metric:
compute_image:
name: inspec-image
source: https://storage.googleapis.com/bosh-cpi-artifacts/bosh-stemcell-3262.4-google-kvm-ubuntu-trusty-go_agent-raw.tar.gz
-
\ No newline at end of file
+
+security_policy:
+ name: sec-policy
+ action: deny(403)
+ priority: "1000"
+ ip_range: "9.9.9.0/24"
+ description: my description
+
+memcache_instance:
+ name: mem-instance
diff --git a/templates/stackdriver.json b/templates/stackdriver.json
new file mode 100644
index 000000000000..33430fbacff5
--- /dev/null
+++ b/templates/stackdriver.json
@@ -0,0 +1,421 @@
+{
+ "parameters": {
+ "key": {
+ "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
+ "type": "string",
+ "location": "query"
+ },
+ "access_token": {
+ "location": "query",
+ "description": "OAuth access token.",
+ "type": "string"
+ },
+ "upload_protocol": {
+ "location": "query",
+ "description": "Upload protocol for media (e.g. \"raw\", \"multipart\").",
+ "type": "string"
+ },
+ "prettyPrint": {
+ "location": "query",
+ "description": "Returns response with indentations and line breaks.",
+ "type": "boolean",
+ "default": "true"
+ },
+ "quotaUser": {
+ "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.",
+ "type": "string",
+ "location": "query"
+ },
+ "uploadType": {
+ "location": "query",
+ "description": "Legacy upload protocol for media (e.g. \"media\", \"multipart\").",
+ "type": "string"
+ },
+ "fields": {
+ "type": "string",
+ "location": "query",
+ "description": "Selector specifying which fields to include in a partial response."
+ },
+ "$.xgafv": {
+ "description": "V1 error format.",
+ "type": "string",
+ "enumDescriptions": [
+ "v1 error format",
+ "v2 error format"
+ ],
+ "location": "query",
+ "enum": [
+ "1",
+ "2"
+ ]
+ },
+ "oauth_token": {
+ "description": "OAuth 2.0 token for the current user.",
+ "type": "string",
+ "location": "query"
+ },
+ "callback": {
+ "description": "JSONP",
+ "type": "string",
+ "location": "query"
+ },
+ "alt": {
+ "default": "json",
+ "enum": [
+ "json",
+ "media",
+ "proto"
+ ],
+ "type": "string",
+ "enumDescriptions": [
+ "Responses with Content-Type of application/json",
+ "Media download with context-dependent Content-Type",
+ "Responses with Content-Type of application/x-protobuf"
+ ],
+ "location": "query",
+ "description": "Data format for response."
+ }
+ },
+ "version": "v2",
+ "baseUrl": "https://stackdriver.googleapis.com/",
+ "kind": "discovery#restDescription",
+ "description": "Provides users with programmatic access to Stackdriver endpoints that allow putting VM instances and other resources into maintenance mode.",
+ "servicePath": "",
+ "basePath": "",
+ "revision": "20200323",
+ "documentationLink": "https://cloud.google.com/stackdriver/docs/",
+ "id": "stackdriver:v2",
+ "discoveryVersion": "v1",
+ "version_module": true,
+ "schemas": {
+ "Status": {
+ "description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors).",
+ "type": "object",
+ "properties": {
+ "details": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "any",
+ "description": "Properties of the object. Contains field @type with type URL."
+ }
+ },
+ "description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use."
+ },
+ "code": {
+ "description": "The status code, which should be an enum value of google.rpc.Code.",
+ "format": "int32",
+ "type": "integer"
+ },
+ "message": {
+ "description": "A developer-facing error message, which should be in English. Any\nuser-facing error message should be localized and sent in the\ngoogle.rpc.Status.details field, or localized by the client.",
+ "type": "string"
+ }
+ },
+ "id": "Status"
+ },
+ "Operation": {
+ "id": "Operation",
+ "description": "This resource represents a long-running operation that is the result of a\nnetwork API call.",
+ "type": "object",
+ "properties": {
+ "response": {
+ "description": "The normal response of the operation in case of success. If the original\nmethod returns no data on success, such as `Delete`, the response is\n`google.protobuf.Empty`. If the original method is standard\n`Get`/`Create`/`Update`, the response should be the resource. For other\nmethods, the response should have the type `XxxResponse`, where `Xxx`\nis the original method name. For example, if the original method name\nis `TakeSnapshot()`, the inferred response type is\n`TakeSnapshotResponse`.",
+ "type": "object",
+ "additionalProperties": {
+ "description": "Properties of the object. Contains field @type with type URL.",
+ "type": "any"
+ }
+ },
+ "name": {
+ "description": "The server-assigned name, which is only unique within the same service that\noriginally returns it. If you use the default HTTP mapping, the\n`name` should be a resource name ending with `operations/{unique_id}`.",
+ "type": "string"
+ },
+ "error": {
+ "$ref": "Status",
+ "description": "The error result of the operation in case of failure or cancellation."
+ },
+ "metadata": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "any",
+ "description": "Properties of the object. Contains field @type with type URL."
+ },
+ "description": "Service-specific metadata associated with the operation. It typically\ncontains progress information and common metadata such as create time.\nSome services might not provide such metadata. Any method that returns a\nlong-running operation should document the metadata type, if any."
+ },
+ "done": {
+ "description": "If the value is `false`, it means the operation is still in progress.\nIf `true`, the operation is completed, and either `error` or `response` is\navailable.",
+ "type": "boolean"
+ }
+ }
+ },
+ "OperationMetadata": {
+ "id": "OperationMetadata",
+ "description": "Contains metadata for longrunning operations in the Stackdriver API.",
+ "type": "object",
+ "properties": {
+ "state": {
+ "enum": [
+ "STATE_UNSPECIFIED",
+ "CREATED",
+ "RUNNING",
+ "DONE",
+ "CANCELLED"
+ ],
+ "description": "Current state of the batch operation.",
+ "type": "string",
+ "enumDescriptions": [
+ "Invalid.",
+ "Request is received.",
+ "Request is actively being processed.",
+ "The batch processing is done.",
+ "The batch processing was cancelled."
+ ]
+ },
+ "updateTime": {
+ "type": "string",
+ "description": "The time when the operation result was last updated.",
+ "format": "google-datetime"
+ },
+ "createTime": {
+ "description": "The time when the batch request was received.",
+ "format": "google-datetime",
+ "type": "string"
+ }
+ }
+ },
+ "MonitoredProject": {
+ "description": "A single cloud account being monitored within a Stackdriver account.",
+ "type": "object",
+ "properties": {
+ "projectNumber": {
+ "description": "Output only. The GCP-assigned project number.",
+ "format": "int64",
+ "type": "string"
+ },
+ "createTime": {
+ "description": "Output only. The instant when this monitored project was created.",
+ "format": "google-datetime",
+ "type": "string"
+ },
+ "updateTime": {
+ "description": "Output only. The instant when this monitored project was last updated.",
+ "format": "google-datetime",
+ "type": "string"
+ },
+ "name": {
+ "description": "The resource name of the monitored project within a Stackdriver account.\nIncludes the host project id and monitored project id. On output it\nwill always contain the project number.\nExample: \u003ccode\u003eaccounts/my-project/projects/my-other-project\u003c/code\u003e",
+ "type": "string"
+ },
+ "projectId": {
+ "description": "Output only. The GCP-assigned project id.\nExample: \u003ccode\u003eprojecty-project-101\u003c/code\u003e",
+ "type": "string"
+ },
+ "organizationId": {
+ "description": "Optional, input only. The Id of the organization to hold the GCP Project\nfor a newly created monitored project.\nThis field is ignored if the GCP project already exists.",
+ "type": "string"
+ }
+ },
+ "id": "MonitoredProject"
+ },
+ "StackdriverAccount": {
+ "id": "StackdriverAccount",
+ "description": "A Workspace in Stackdriver Monitoring, which specifies one or more GCP\nprojects and zero or more AWS accounts to monitor together.\nOne GCP project acts as the Workspace's host.\nGCP projects and AWS accounts cannot be monitored until they are associated\nwith a Workspace.",
+ "type": "object",
+ "properties": {
+ "monitoredProjects": {
+ "description": "Output only. The GCP projects monitored in this Stackdriver account.",
+ "type": "array",
+ "items": {
+ "$ref": "MonitoredProject"
+ }
+ },
+ "createTime": {
+ "type": "string",
+ "description": "Output only. The instant when this account was created.",
+ "format": "google-datetime"
+ },
+ "hostProjectId": {
+ "description": "Output only. The GCP project id for the host project of this account.",
+ "type": "string"
+ },
+ "updateTime": {
+ "description": "Output only. The instant when this account record was last updated.",
+ "format": "google-datetime",
+ "type": "string"
+ },
+ "hostProjectNumber": {
+ "description": "Output only. The GCP project number for the host project of this account.",
+ "format": "int64",
+ "type": "string"
+ },
+ "name": {
+ "description": "The resource name of the Stackdriver account, including the host project\nid or number. On output it will always be the host project number.\nExample: \u003ccode\u003eaccounts/[PROJECT_ID]\u003c/code\u003e or\n\u003ccode\u003eaccounts/[PROJECT_NUMBER]\u003c/code\u003e",
+ "type": "string"
+ },
+ "organizationId": {
+ "description": "Optional, input only. The Id of the organization to hold the GCP Project\nfor a newly created Stackdriver account.\nThis field is ignored if the GCP project already exists.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "protocol": "rest",
+ "icons": {
+ "x32": "http://www.google.com/images/icons/product/search-32.gif",
+ "x16": "http://www.google.com/images/icons/product/search-16.gif"
+ },
+ "canonicalName": "Stackdriver",
+ "auth": {
+ "oauth2": {
+ "scopes": {
+ "https://www.googleapis.com/auth/monitoring": {
+ "description": "View and write monitoring data for all of your Google and third-party Cloud and API projects"
+ },
+ "https://www.googleapis.com/auth/monitoring.write": {
+ "description": "Publish metric data to your Google Cloud projects"
+ },
+ "https://www.googleapis.com/auth/cloud-platform": {
+ "description": "View and manage your data across Google Cloud Platform services"
+ },
+ "https://www.googleapis.com/auth/monitoring.read": {
+ "description": "View monitoring data for all of your Google Cloud and third-party projects"
+ }
+ }
+ }
+ },
+ "rootUrl": "https://stackdriver.googleapis.com/",
+ "ownerDomain": "google.com",
+ "name": "stackdriver",
+ "batchPath": "batch",
+ "mtlsRootUrl": "https://stackdriver.mtls.googleapis.com/",
+ "fullyEncodeReservedExpansion": true,
+ "title": "Stackdriver API",
+ "ownerName": "Google",
+ "resources": {
+ "accounts": {
+ "methods": {
+ "get": {
+ "httpMethod": "GET",
+ "parameterOrder": [
+ "name"
+ ],
+ "response": {
+ "$ref": "StackdriverAccount"
+ },
+ "parameters": {
+ "name": {
+ "location": "path",
+ "description": "The unique name of the Stackdriver account.\nCaller needs stackdriver.projects.get permission on the host project.",
+ "required": true,
+ "type": "string",
+ "pattern": "^accounts/[^/]+$"
+ },
+ "includeProjects": {
+ "type": "boolean",
+ "location": "query",
+ "description": "If true the monitored_projects collection will be populated with any\nentries, if false it will be empty."
+ }
+ },
+ "scopes": [
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/monitoring",
+ "https://www.googleapis.com/auth/monitoring.read"
+ ],
+ "flatPath": "v2/accounts/{accountsId}",
+ "id": "stackdriver.accounts.get",
+ "path": "v2/{+name}",
+ "description": "Fetches a specific Stackdriver account."
+ },
+ "create": {
+ "response": {
+ "$ref": "Operation"
+ },
+ "parameterOrder": [],
+ "httpMethod": "POST",
+ "scopes": [
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/monitoring",
+ "https://www.googleapis.com/auth/monitoring.write"
+ ],
+ "parameters": {},
+ "flatPath": "v2/accounts",
+ "path": "v2/accounts",
+ "id": "stackdriver.accounts.create",
+ "request": {
+ "$ref": "StackdriverAccount"
+ },
+ "description": "Creates a new Stackdriver account with a given host project.\nA MonitoredProject for that project will be attached to it if successful.\n\nOperation\u003cresponse: StackdriverAccount\u003e"
+ }
+ },
+ "resources": {
+ "projects": {
+ "methods": {
+ "create": {
+ "response": {
+ "$ref": "Operation"
+ },
+ "parameterOrder": [
+ "parent"
+ ],
+ "httpMethod": "POST",
+ "parameters": {
+ "parent": {
+ "description": "The unique name of the Stackdriver account that will host this project.\nCaller needs stackdriver.projects.edit permission on the host project.",
+ "required": true,
+ "type": "string",
+ "pattern": "^accounts/[^/]+$",
+ "location": "path"
+ }
+ },
+ "scopes": [
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/monitoring",
+ "https://www.googleapis.com/auth/monitoring.write"
+ ],
+ "flatPath": "v2/accounts/{accountsId}/projects",
+ "path": "v2/{+parent}/projects",
+ "id": "stackdriver.accounts.projects.create",
+ "description": "Creates a new monitored project in a Stackdriver account.\nOperation\u003cresponse: MonitoredProject\u003e",
+ "request": {
+ "$ref": "MonitoredProject"
+ }
+ }
+ }
+ }
+ }
+ },
+ "operations": {
+ "methods": {
+ "get": {
+ "httpMethod": "GET",
+ "response": {
+ "$ref": "Operation"
+ },
+ "parameterOrder": [
+ "name"
+ ],
+ "parameters": {
+ "name": {
+ "pattern": "^operations/.*$",
+ "location": "path",
+ "description": "The name of the operation resource.",
+ "required": true,
+ "type": "string"
+ }
+ },
+ "scopes": [
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/monitoring",
+ "https://www.googleapis.com/auth/monitoring.read"
+ ],
+ "flatPath": "v2/operations/{operationsId}",
+ "id": "stackdriver.operations.get",
+ "path": "v2/{+name}",
+ "description": "Gets the latest state of a long-running operation. Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice."
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/constants/bigquery_dataset_access.go b/templates/terraform/constants/bigquery_dataset_access.go
new file mode 100644
index 000000000000..fcf90d4c1d60
--- /dev/null
+++ b/templates/terraform/constants/bigquery_dataset_access.go
@@ -0,0 +1,12 @@
+var bigqueryAccessRoleToPrimitiveMap = map[string]string {
+ "roles/bigquery.dataOwner": "OWNER",
+ "roles/bigquery.dataEditor": "WRITER",
+ "roles/bigquery.dataViewer": "READER",
+}
+
+func resourceBigQueryDatasetAccessRoleDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
+ if primitiveRole, ok := bigqueryAccessRoleToPrimitiveMap[new]; ok {
+ return primitiveRole == old
+ }
+ return false
+}
diff --git a/templates/terraform/constants/bigquery_job.go b/templates/terraform/constants/bigquery_job.go
new file mode 100644
index 000000000000..2a9923e099a9
--- /dev/null
+++ b/templates/terraform/constants/bigquery_job.go
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+var (
+ bigqueryDatasetRegexp = regexp.MustCompile("projects/(.+)/datasets/(.+)")
+ bigqueryTableRegexp = regexp.MustCompile("projects/(.+)/datasets/(.+)/tables/(.+)")
+)
\ No newline at end of file
diff --git a/templates/terraform/constants/cloudiot.go.erb b/templates/terraform/constants/cloudiot.go.erb
new file mode 100644
index 000000000000..94bd4f5abb2b
--- /dev/null
+++ b/templates/terraform/constants/cloudiot.go.erb
@@ -0,0 +1,241 @@
+func expandCloudIotDeviceRegistryHTTPConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedHTTPEnabledState, err := expandCloudIotDeviceRegistryHTTPEnabledState(original["http_enabled_state"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedHTTPEnabledState); val.IsValid() && !isEmptyValue(val) {
+ transformed["httpEnabledState"] = transformedHTTPEnabledState
+ }
+
+ return transformed, nil
+}
+
+func expandCloudIotDeviceRegistryHTTPEnabledState(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandCloudIotDeviceRegistryMqttConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedMqttEnabledState, err := expandCloudIotDeviceRegistryMqttEnabledState(original["mqtt_enabled_state"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedMqttEnabledState); val.IsValid() && !isEmptyValue(val) {
+ transformed["mqttEnabledState"] = transformedMqttEnabledState
+ }
+
+ return transformed, nil
+}
+
+func expandCloudIotDeviceRegistryMqttEnabledState(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandCloudIotDeviceRegistryStateNotificationConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedPubsubTopicName, err := expandCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(original["pubsub_topic_name"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedPubsubTopicName); val.IsValid() && !isEmptyValue(val) {
+ transformed["pubsubTopicName"] = transformedPubsubTopicName
+ }
+
+ return transformed, nil
+}
+
+func expandCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandCloudIotDeviceRegistryCredentials(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ l := v.([]interface{})
+ req := make([]interface{}, 0, len(l))
+
+ for _, raw := range l {
+ if raw == nil {
+ continue
+ }
+ original := raw.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedPublicKeyCertificate, err := expandCloudIotDeviceRegistryCredentialsPublicKeyCertificate(original["public_key_certificate"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedPublicKeyCertificate); val.IsValid() && !isEmptyValue(val) {
+ transformed["publicKeyCertificate"] = transformedPublicKeyCertificate
+ }
+
+ req = append(req, transformed)
+ }
+
+ return req, nil
+}
+
+func expandCloudIotDeviceRegistryCredentialsPublicKeyCertificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedFormat, err := expandCloudIotDeviceRegistryPublicKeyCertificateFormat(original["format"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedFormat); val.IsValid() && !isEmptyValue(val) {
+ transformed["format"] = transformedFormat
+ }
+
+ transformedCertificate, err := expandCloudIotDeviceRegistryPublicKeyCertificateCertificate(original["certificate"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedCertificate); val.IsValid() && !isEmptyValue(val) {
+ transformed["certificate"] = transformedCertificate
+ }
+
+ return transformed, nil
+}
+
+func expandCloudIotDeviceRegistryPublicKeyCertificateFormat(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandCloudIotDeviceRegistryPublicKeyCertificateCertificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ return v, nil
+}
+
+func flattenCloudIotDeviceRegistryCredentials(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ log.Printf("[DEBUG] Flattening device resitry credentials: %q", d.Id())
+ if v == nil {
+ log.Printf("[DEBUG] The credentials array is nil: %q", d.Id())
+ return v
+ }
+ l := v.([]interface{})
+ transformed := make([]interface{}, 0, len(l))
+ for _, raw := range l {
+ original := raw.(map[string]interface{})
+ log.Printf("[DEBUG] Original credential: %+v", original)
+ if len(original) < 1 {
+ log.Printf("[DEBUG] Excluding empty credential that the API returned. %q", d.Id())
+ continue
+ }
+ log.Printf("[DEBUG] Credentials array before appending a new credential: %+v", transformed)
+ transformed = append(transformed, map[string]interface{}{
+ "public_key_certificate": flattenCloudIotDeviceRegistryCredentialsPublicKeyCertificate(original["publicKeyCertificate"], d, config),
+ })
+ log.Printf("[DEBUG] Credentials array after appending a new credential: %+v", transformed)
+ }
+ return transformed
+}
+
+func flattenCloudIotDeviceRegistryCredentialsPublicKeyCertificate(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ log.Printf("[DEBUG] Flattening device resitry credentials public key certificate: %q", d.Id())
+ if v == nil {
+ log.Printf("[DEBUG] The public key certificate is nil: %q", d.Id())
+ return v
+ }
+
+ original := v.(map[string]interface{})
+ log.Printf("[DEBUG] Original public key certificate: %+v", original)
+ transformed := make(map[string]interface{})
+
+ transformedPublicKeyCertificateFormat := flattenCloudIotDeviceRegistryPublicKeyCertificateFormat(original["format"], d, config)
+ transformed["format"] = transformedPublicKeyCertificateFormat
+
+ transformedPublicKeyCertificateCertificate := flattenCloudIotDeviceRegistryPublicKeyCertificateCertificate(original["certificate"], d, config)
+ transformed["certificate"] = transformedPublicKeyCertificateCertificate
+
+ log.Printf("[DEBUG] Transformed public key certificate: %+v", transformed)
+
+ return transformed
+}
+
+func flattenCloudIotDeviceRegistryPublicKeyCertificateFormat(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return v
+}
+
+func flattenCloudIotDeviceRegistryPublicKeyCertificateCertificate(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return v
+}
+
+func flattenCloudIotDeviceRegistryHTTPConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return v
+ }
+
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedHTTPEnabledState := flattenCloudIotDeviceRegistryHTTPConfigHTTPEnabledState(original["httpEnabledState"], d, config)
+ transformed["http_enabled_state"] = transformedHTTPEnabledState
+
+ return transformed
+}
+
+func flattenCloudIotDeviceRegistryHTTPConfigHTTPEnabledState(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return v
+}
+
+func flattenCloudIotDeviceRegistryMqttConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return v
+ }
+
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedMqttEnabledState := flattenCloudIotDeviceRegistryMqttConfigMqttEnabledState(original["mqttEnabledState"], d, config)
+ transformed["mqtt_enabled_state"] = transformedMqttEnabledState
+
+ return transformed
+}
+
+func flattenCloudIotDeviceRegistryMqttConfigMqttEnabledState(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return v
+}
+
+func flattenCloudIotDeviceRegistryStateNotificationConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ log.Printf("[DEBUG] Flattening state notification config: %+v", v)
+ if v == nil {
+ return v
+ }
+
+ original := v.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedPubsubTopicName := flattenCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(original["pubsubTopicName"], d, config)
+ if val := reflect.ValueOf(transformedPubsubTopicName); val.IsValid() && !isEmptyValue(val) {
+ log.Printf("[DEBUG] pubsub topic name is not null: %v", d.Get("pubsub_topic_name"))
+ transformed["pubsub_topic_name"] = transformedPubsubTopicName
+ }
+
+
+ return transformed
+}
+
+func flattenCloudIotDeviceRegistryStateNotificationConfigPubsubTopicName(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return v
+}
+
+func validateCloudIotDeviceRegistryID(v interface{}, k string) (warnings []string, errors []error) {
+ value := v.(string)
+ if strings.HasPrefix(value, "goog") {
+ errors = append(errors, fmt.Errorf(
+ "%q (%q) can not start with \"goog\"", k, value))
+ }
+ if !regexp.MustCompile(CloudIoTIdRegex).MatchString(value) {
+ errors = append(errors, fmt.Errorf(
+ "%q (%q) doesn't match regexp %q", k, value, CloudIoTIdRegex))
+ }
+ return
+}
+
+func validateCloudIotDeviceRegistrySubfolderMatch(v interface{}, k string) (warnings []string, errors []error) {
+ value := v.(string)
+ if strings.HasPrefix(value, "/") {
+ errors = append(errors, fmt.Errorf(
+ "%q (%q) can not start with '/'", k, value))
+ }
+ return
+}
diff --git a/templates/terraform/constants/firewall.erb b/templates/terraform/constants/firewall.erb
index aaac9f436038..1f949a416c02 100644
--- a/templates/terraform/constants/firewall.erb
+++ b/templates/terraform/constants/firewall.erb
@@ -34,3 +34,27 @@ func resourceComputeFirewallRuleHash(v interface{}) int {
func compareCaseInsensitive(k, old, new string, d *schema.ResourceData) bool {
return strings.ToLower(old) == strings.ToLower(new)
}
+
+func diffSuppressEnableLogging(k, old, new string, d *schema.ResourceData) bool {
+ if k == "log_config.#" {
+ if new == "0" && d.Get("enable_logging").(bool) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func resourceComputeFirewallEnableLoggingCustomizeDiff(diff *schema.ResourceDiff, v interface{}) error {
+ enableLogging, enableExists := diff.GetOkExists("enable_logging")
+ if !enableExists {
+ return nil
+ }
+
+ logConfigExists := diff.Get("log_config.#").(int) != 0
+ if logConfigExists && enableLogging == false {
+ return fmt.Errorf("log_config cannot be defined when enable_logging is false")
+ }
+
+ return nil
+}
\ No newline at end of file
diff --git a/templates/terraform/constants/monitoring_slo.go.erb b/templates/terraform/constants/monitoring_slo.go.erb
new file mode 100644
index 000000000000..23b42305d7ae
--- /dev/null
+++ b/templates/terraform/constants/monitoring_slo.go.erb
@@ -0,0 +1,7 @@
+func validateMonitoringSloGoal(v interface{}, k string) (warnings []string, errors []error) {
+ goal := v.(float64)
+ if goal <= 0 || goal > 0.999 {
+ errors = append(errors, fmt.Errorf("goal %f must be > 0 and <= 0.999", goal))
+ }
+ return
+}
\ No newline at end of file
diff --git a/templates/terraform/constants/source_repo_repository.go.erb b/templates/terraform/constants/source_repo_repository.go.erb
new file mode 100644
index 000000000000..d523a7869673
--- /dev/null
+++ b/templates/terraform/constants/source_repo_repository.go.erb
@@ -0,0 +1,30 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2019 Google Inc.
+ # 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.
+-%>
+func resourceSourceRepoRepositoryPubSubConfigsHash(v interface{}) int {
+ if v == nil {
+ return 0
+ }
+
+ var buf bytes.Buffer
+ m := v.(map[string]interface{})
+
+ buf.WriteString(fmt.Sprintf("%s-", GetResourceNameFromSelfLink(m["topic"].(string))))
+ buf.WriteString(fmt.Sprintf("%s-", m["message_format"].(string)))
+ if v, ok := m["service_account_email"]; ok {
+ buf.WriteString(fmt.Sprintf("%s-", v.(string)))
+ }
+
+ return hashcode.String(buf.String())
+}
diff --git a/templates/terraform/custom_check_destroy/storage_hmac_key.go.erb b/templates/terraform/custom_check_destroy/storage_hmac_key.go.erb
index c7208fbdd1fc..1677f4c44b7d 100644
--- a/templates/terraform/custom_check_destroy/storage_hmac_key.go.erb
+++ b/templates/terraform/custom_check_destroy/storage_hmac_key.go.erb
@@ -1,4 +1,4 @@
-config := testAccProvider.Meta().(*Config)
+config := googleProviderConfig(t)
url, err := replaceVarsForTest(config, rs, "{{StorageBasePath}}projects/{{project}}/hmacKeys/{{access_id}}")
if err != nil {
diff --git a/templates/terraform/custom_delete/appversion_delete.go.erb b/templates/terraform/custom_delete/appversion_delete.go.erb
index d3e6aa0a9bfd..ad11d36ffb92 100644
--- a/templates/terraform/custom_delete/appversion_delete.go.erb
+++ b/templates/terraform/custom_delete/appversion_delete.go.erb
@@ -30,7 +30,7 @@ if d.Get("delete_service_on_destroy") == true {
}
err = appEngineOperationWaitTime(
config, res, project, "Deleting Service",
- int(d.Timeout(schema.TimeoutDelete).Minutes()))
+ d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
@@ -50,7 +50,7 @@ if d.Get("delete_service_on_destroy") == true {
}
err = appEngineOperationWaitTime(
config, res, project, "Deleting AppVersion",
- int(d.Timeout(schema.TimeoutDelete).Minutes()))
+ d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
diff --git a/templates/terraform/custom_delete/per_instance_config.go.erb b/templates/terraform/custom_delete/per_instance_config.go.erb
new file mode 100644
index 000000000000..59d9096f9c0c
--- /dev/null
+++ b/templates/terraform/custom_delete/per_instance_config.go.erb
@@ -0,0 +1,78 @@
+ config := meta.(*Config)
+
+ project, err := getProject(d, config)
+ if err != nil {
+ return err
+ }
+
+ lockName, err := replaceVars(d, config, "instanceGroupManager/{{project}}/{{zone}}/{{instance_group_manager}}")
+ if err != nil {
+ return err
+ }
+ mutexKV.Lock(lockName)
+ defer mutexKV.Unlock(lockName)
+
+ url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/deletePerInstanceConfigs")
+ if err != nil {
+ return err
+ }
+
+ var obj map[string]interface{}
+ obj = map[string]interface{}{
+ "names": [1]string{d.Get("name").(string)},
+ }
+ log.Printf("[DEBUG] Deleting PerInstanceConfig %q", d.Id())
+
+ res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutDelete))
+ if err != nil {
+ return handleNotFoundError(err, d, "PerInstanceConfig")
+ }
+
+ err = computeOperationWaitTime(
+ config, res, project, "Deleting PerInstanceConfig",
+ d.Timeout(schema.TimeoutDelete))
+
+ if err != nil {
+ return err
+ }
+
+ // Potentially delete the state managed by this config
+ if d.Get("remove_instance_state_on_destroy").(bool) {
+ // Instance name in applyUpdatesToInstances request must include zone
+ instanceName, err := replaceVars(d, config, "zones/{{zone}}/instances/{{name}}")
+ if err != nil {
+ return err
+ }
+
+ obj = make(map[string]interface{})
+ obj["instances"] = []string{instanceName}
+
+ // The deletion must be applied to the instance after the PerInstanceConfig is deleted
+ url, err = replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/applyUpdatesToInstances")
+ if err != nil {
+ return err
+ }
+
+ log.Printf("[DEBUG] Applying updates to PerInstanceConfig %q: %#v", d.Id(), obj)
+ res, err = sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutUpdate))
+
+ if err != nil {
+ return fmt.Errorf("Error deleting PerInstanceConfig %q: %s", d.Id(), err)
+ }
+
+ err = computeOperationWaitTime(
+ config, res, project, "Applying update to PerInstanceConfig",
+ d.Timeout(schema.TimeoutUpdate))
+ if err != nil {
+ return fmt.Errorf("Error deleting PerInstanceConfig %q: %s", d.Id(), err)
+ }
+
+ // PerInstanceConfig goes into "DELETING" state while the instance is actually deleted
+ err = PollingWaitTime(resourceComputePerInstanceConfigPollRead(d, meta), PollCheckInstanceConfigDeleted, "Deleting PerInstanceConfig", d.Timeout(schema.TimeoutDelete), 1)
+ if err != nil {
+ return fmt.Errorf("Error waiting for delete on PerInstanceConfig %q: %s", d.Id(), err)
+ }
+ }
+
+ log.Printf("[DEBUG] Finished deleting PerInstanceConfig %q: %#v", d.Id(), res)
+ return nil
\ No newline at end of file
diff --git a/templates/terraform/custom_delete/region_per_instance_config.go.erb b/templates/terraform/custom_delete/region_per_instance_config.go.erb
new file mode 100644
index 000000000000..4daf052f733a
--- /dev/null
+++ b/templates/terraform/custom_delete/region_per_instance_config.go.erb
@@ -0,0 +1,79 @@
+ config := meta.(*Config)
+
+ project, err := getProject(d, config)
+ if err != nil {
+ return err
+ }
+
+ lockName, err := replaceVars(d, config, "instanceGroupManager/{{project}}/{{region}}/{{region_instance_group_manager}}")
+ if err != nil {
+ return err
+ }
+ mutexKV.Lock(lockName)
+ defer mutexKV.Unlock(lockName)
+
+ url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/deletePerInstanceConfigs")
+ if err != nil {
+ return err
+ }
+
+ var obj map[string]interface{}
+ obj = map[string]interface{}{
+ "names": [1]string{d.Get("name").(string)},
+ }
+ log.Printf("[DEBUG] Deleting RegionPerInstanceConfig %q", d.Id())
+
+ res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutDelete))
+ if err != nil {
+ return handleNotFoundError(err, d, "RegionPerInstanceConfig")
+ }
+
+ err = computeOperationWaitTime(
+ config, res, project, "Deleting RegionPerInstanceConfig",
+ d.Timeout(schema.TimeoutDelete))
+
+ if err != nil {
+ return err
+ }
+
+ // Potentially delete the state managed by this config
+ if d.Get("remove_instance_state_on_destroy").(bool) {
+ // Instance name in applyUpdatesToInstances request must include zone
+ instanceName, err := findInstanceName(d, config)
+ if err != nil {
+ return err
+ }
+
+ obj = make(map[string]interface{})
+ obj["instances"] = []string{instanceName}
+
+ // Updates must be applied to the instance after deleting the PerInstanceConfig
+ url, err = replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/applyUpdatesToInstances")
+ if err != nil {
+ return err
+ }
+
+ log.Printf("[DEBUG] Applying updates to PerInstanceConfig %q: %#v", d.Id(), obj)
+ res, err = sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutUpdate))
+
+ if err != nil {
+ return fmt.Errorf("Error updating PerInstanceConfig %q: %s", d.Id(), err)
+ }
+
+ err = computeOperationWaitTime(
+ config, res, project, "Applying update to PerInstanceConfig",
+ d.Timeout(schema.TimeoutUpdate))
+
+ if err != nil {
+ return fmt.Errorf("Error deleting PerInstanceConfig %q: %s", d.Id(), err)
+ }
+
+ // RegionPerInstanceConfig goes into "DELETING" state while the instance is actually deleted
+ err = PollingWaitTime(resourceComputeRegionPerInstanceConfigPollRead(d, meta), PollCheckInstanceConfigDeleted, "Deleting RegionPerInstanceConfig", d.Timeout(schema.TimeoutDelete), 1)
+ if err != nil {
+ return fmt.Errorf("Error waiting for delete on RegionPerInstanceConfig %q: %s", d.Id(), err)
+ }
+ }
+
+ log.Printf("[DEBUG] Finished deleting RegionPerInstanceConfig %q: %#v", d.Id(), res)
+ return nil
\ No newline at end of file
diff --git a/templates/terraform/custom_expand/bigquery_access_role.go.erb b/templates/terraform/custom_expand/bigquery_access_role.go.erb
new file mode 100644
index 000000000000..5a5aae5115c9
--- /dev/null
+++ b/templates/terraform/custom_expand/bigquery_access_role.go.erb
@@ -0,0 +1,24 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ if v == nil {
+ return nil, nil
+ }
+
+ if primitiveRole, ok := bigqueryAccessRoleToPrimitiveMap[v.(string)]; ok {
+ return primitiveRole, nil
+ }
+ return v, nil
+}
diff --git a/templates/terraform/custom_expand/bigquery_dataset_ref.go.erb b/templates/terraform/custom_expand/bigquery_dataset_ref.go.erb
new file mode 100644
index 000000000000..a0f45311c80f
--- /dev/null
+++ b/templates/terraform/custom_expand/bigquery_dataset_ref.go.erb
@@ -0,0 +1,40 @@
+<%# # the license inside this if block pertains to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+#%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ l := v.([]interface{})
+ if len(l) == 0 || l[0] == nil {
+ return nil, nil
+ }
+ raw := l[0]
+ original := raw.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedProjectId := original["project_id"]
+ if val := reflect.ValueOf(transformedProjectId); val.IsValid() && !isEmptyValue(val) {
+ transformed["projectId"] = transformedProjectId
+ }
+
+ transformedDatasetId := original["dataset_id"]
+ if val := reflect.ValueOf(transformedDatasetId); val.IsValid() && !isEmptyValue(val) {
+ transformed["datasetId"] = transformedDatasetId
+ }
+
+ if parts := bigqueryDatasetRegexp.FindStringSubmatch(transformedDatasetId.(string)); parts != nil {
+ transformed["projectId"] = parts[1]
+ transformed["datasetId"] = parts[2]
+ }
+
+ return transformed, nil
+}
diff --git a/templates/terraform/custom_expand/bigquery_table_ref.go.erb b/templates/terraform/custom_expand/bigquery_table_ref.go.erb
new file mode 100644
index 000000000000..817dc252aa6a
--- /dev/null
+++ b/templates/terraform/custom_expand/bigquery_table_ref.go.erb
@@ -0,0 +1,46 @@
+<%# # the license inside this if block pertains to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+#%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ l := v.([]interface{})
+ if len(l) == 0 || l[0] == nil {
+ return nil, nil
+ }
+ raw := l[0]
+ original := raw.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedProjectId := original["project_id"]
+ if val := reflect.ValueOf(transformedProjectId); val.IsValid() && !isEmptyValue(val) {
+ transformed["projectId"] = transformedProjectId
+ }
+
+ transformedDatasetId := original["dataset_id"]
+ if val := reflect.ValueOf(transformedDatasetId); val.IsValid() && !isEmptyValue(val) {
+ transformed["datasetId"] = transformedDatasetId
+ }
+
+ transformedTableId := original["table_id"]
+ if val := reflect.ValueOf(transformedTableId); val.IsValid() && !isEmptyValue(val) {
+ transformed["tableId"] = transformedTableId
+ }
+
+ if parts := bigqueryTableRegexp.FindStringSubmatch(transformedTableId.(string)); parts != nil {
+ transformed["projectId"] = parts[1]
+ transformed["datasetId"] = parts[2]
+ transformed["tableId"] = parts[3]
+ }
+
+ return transformed, nil
+}
diff --git a/templates/terraform/custom_expand/bigquery_table_ref_array.go.erb b/templates/terraform/custom_expand/bigquery_table_ref_array.go.erb
new file mode 100644
index 000000000000..ce30ad84fe3b
--- /dev/null
+++ b/templates/terraform/custom_expand/bigquery_table_ref_array.go.erb
@@ -0,0 +1,50 @@
+<%# # the license inside this if block pertains to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+#%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ l := v.([]interface{})
+ req := make([]interface{}, 0, len(l))
+ for _, raw := range l {
+ if raw == nil {
+ continue
+ }
+ original := raw.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedProjectId := original["project_id"]
+ if val := reflect.ValueOf(transformedProjectId); val.IsValid() && !isEmptyValue(val) {
+ transformed["projectId"] = transformedProjectId
+ }
+
+ transformedDatasetId := original["dataset_id"]
+ if val := reflect.ValueOf(transformedDatasetId); val.IsValid() && !isEmptyValue(val) {
+ transformed["datasetId"] = transformedDatasetId
+ }
+
+ transformedTableId := original["table_id"]
+ if val := reflect.ValueOf(transformedTableId); val.IsValid() && !isEmptyValue(val) {
+ transformed["tableId"] = transformedTableId
+ }
+
+ tableRef := regexp.MustCompile("projects/(.+)/datasets/(.+)/tables/(.+)")
+ if parts := tableRef.FindStringSubmatch(transformedTableId.(string)); parts != nil {
+ transformed["projectId"] = parts[1]
+ transformed["datasetId"] = parts[2]
+ transformed["tableId"] = parts[3]
+ }
+
+ req = append(req, transformed)
+ }
+ return req, nil
+}
diff --git a/templates/terraform/custom_expand/compute_full_url.erb b/templates/terraform/custom_expand/compute_full_url.erb
index 32dbb4da8be5..637528d1adf8 100644
--- a/templates/terraform/custom_expand/compute_full_url.erb
+++ b/templates/terraform/custom_expand/compute_full_url.erb
@@ -16,7 +16,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T
if v == nil || v.(string) == "" {
return "", nil
}
- f, err := <%= build_expand_resource_ref('v.(string)', property) %>
+ f, err := <%= build_expand_resource_ref('v.(string)', property, pwd) %>
if err != nil {
return nil, fmt.Errorf("Invalid value for <%= property.name.underscore -%>: %s", err)
}
diff --git a/templates/terraform/custom_expand/data_catalog_tag.go.erb b/templates/terraform/custom_expand/data_catalog_tag.go.erb
new file mode 100644
index 000000000000..667da5a756ca
--- /dev/null
+++ b/templates/terraform/custom_expand/data_catalog_tag.go.erb
@@ -0,0 +1,24 @@
+<%# # the license inside this if block pertains to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+#%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ // we flattened the original["enum_value"]["display_name"] object to be just original["enum_value"] so here,
+ // v is the value we want from the config
+ transformed := make(map[string]interface{})
+ if val := reflect.ValueOf(v); val.IsValid() && !isEmptyValue(val) {
+ transformed["displayName"] = v
+ }
+
+ return transformed, nil
+}
diff --git a/templates/terraform/custom_expand/days_to_duration_string.go.erb b/templates/terraform/custom_expand/days_to_duration_string.go.erb
new file mode 100644
index 000000000000..694efb7334d9
--- /dev/null
+++ b/templates/terraform/custom_expand/days_to_duration_string.go.erb
@@ -0,0 +1,28 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ if v == nil {
+ return nil, nil
+ }
+ i, ok := v.(int)
+ if !ok {
+ return nil, fmt.Errorf("unexpected value is not int: %v", v)
+ }
+ if i == 0 {
+ return "", nil
+ }
+ // Day = 86400s
+ return fmt.Sprintf("%ds", i * 86400), nil
+}
diff --git a/templates/terraform/custom_expand/firewall_log_config.go.erb b/templates/terraform/custom_expand/firewall_log_config.go.erb
new file mode 100644
index 000000000000..9db2f00592f5
--- /dev/null
+++ b/templates/terraform/custom_expand/firewall_log_config.go.erb
@@ -0,0 +1,33 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ l := v.([]interface{})
+ transformed := make(map[string]interface{})
+
+ if len(l) == 0 || l[0] == nil {
+ // send enable = enable_logging value to ensure correct logging status if there is no config
+ transformed["enable"] = d.Get("enable_logging").(bool)
+ return transformed, nil
+ }
+
+ raw := l[0]
+ original := raw.(map[string]interface{})
+
+ // The log_config block is specified, so logging should be enabled
+ transformed["enable"] = true
+ transformed["metadata"] = original["metadata"]
+
+ return transformed, nil
+}
diff --git a/templates/terraform/custom_expand/json_schema.erb b/templates/terraform/custom_expand/json_schema.erb
new file mode 100644
index 000000000000..ef3f0dec09e3
--- /dev/null
+++ b/templates/terraform/custom_expand/json_schema.erb
@@ -0,0 +1,25 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ b := []byte(v.(string))
+ if len(b) == 0 {
+ return nil, nil
+ }
+ m := make(map[string]interface{})
+ if err := json.Unmarshal(b, &m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
diff --git a/templates/terraform/custom_expand/network_full_url.erb b/templates/terraform/custom_expand/network_full_url.erb
new file mode 100644
index 000000000000..befc8e314a47
--- /dev/null
+++ b/templates/terraform/custom_expand/network_full_url.erb
@@ -0,0 +1,12 @@
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ if v == nil || v.(string) == "" {
+ return "", nil
+ } else if strings.HasPrefix(v.(string), "https://") {
+ return v, nil
+ }
+ url, err := replaceVars(d, config, "{{ComputeBasePath}}" + v.(string))
+ if err != nil {
+ return "", err
+ }
+ return ConvertSelfLinkToV1(url), nil
+}
diff --git a/templates/terraform/custom_expand/network_management_connectivity_test_name.go.erb b/templates/terraform/custom_expand/network_management_connectivity_test_name.go.erb
new file mode 100644
index 000000000000..2fd5a83ffe4e
--- /dev/null
+++ b/templates/terraform/custom_expand/network_management_connectivity_test_name.go.erb
@@ -0,0 +1,22 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ // projects/X/tests/Y - note not "connectivityTests"
+ f, err := parseGlobalFieldValue("tests", v.(string), "project", d, config, true)
+ if err != nil {
+ return nil, fmt.Errorf("Invalid value for zone: %s", err)
+ }
+ return f.RelativeLink(), nil
+}
diff --git a/templates/terraform/custom_expand/preserved_state_disks.go.erb b/templates/terraform/custom_expand/preserved_state_disks.go.erb
new file mode 100644
index 000000000000..dacc8d489e08
--- /dev/null
+++ b/templates/terraform/custom_expand/preserved_state_disks.go.erb
@@ -0,0 +1,43 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ if v == nil {
+ return map[string]interface{}{}, nil
+ }
+ l := v.(*schema.Set).List()
+ req := make(map[string]interface{})
+ for _, raw := range l {
+ if raw == nil {
+ continue
+ }
+ original := raw.(map[string]interface{})
+ deviceName := original["device_name"].(string)
+ diskObj := make(map[string]interface{})
+ deleteRule := original["delete_rule"].(string)
+ if deleteRule != "" {
+ diskObj["autoDelete"] = deleteRule
+ }
+ source := original["source"]
+ if source != "" {
+ diskObj["source"] = source
+ }
+ mode := original["mode"]
+ if source != "" {
+ diskObj["mode"] = mode
+ }
+ req[deviceName] = diskObj
+ }
+ return req, nil
+}
diff --git a/templates/terraform/custom_expand/sd_full_url.erb b/templates/terraform/custom_expand/sd_full_url.erb
new file mode 100644
index 000000000000..71543d60488c
--- /dev/null
+++ b/templates/terraform/custom_expand/sd_full_url.erb
@@ -0,0 +1,12 @@
+func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
+ if v == nil || v.(string) == "" {
+ return "", nil
+ } else if strings.HasPrefix(v.(string), "https://") {
+ return v, nil
+ }
+ url, err := replaceVars(d, config, "{{ServiceDirectoryBasePath}}" + v.(string))
+ if err != nil {
+ return "", err
+ }
+ return url, nil
+}
diff --git a/templates/terraform/custom_flatten/bigquery_connection_flatten.go.erb b/templates/terraform/custom_flatten/bigquery_connection_flatten.go.erb
new file mode 100644
index 000000000000..62b67471440b
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_connection_flatten.go.erb
@@ -0,0 +1,22 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ return []interface{}{
+ map[string]interface{}{
+ "username": d.Get("cloud_sql.0.credential.0.username"),
+ "password": d.Get("cloud_sql.0.credential.0.password"),
+ },
+ }
+}
diff --git a/templates/terraform/custom_flatten/bigquery_dataset_ref.go.erb b/templates/terraform/custom_flatten/bigquery_dataset_ref.go.erb
new file mode 100644
index 000000000000..d3d56745ea69
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_dataset_ref.go.erb
@@ -0,0 +1,32 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+ original := v.(map[string]interface{})
+ if len(original) == 0 {
+ return nil
+ }
+ transformed := make(map[string]interface{})
+ transformed["project_id"] = original["projectId"]
+ transformed["dataset_id"] = original["datasetId"]
+
+ if bigqueryDatasetRegexp.MatchString(d.Get("query.0.default_dataset.0.dataset_id").(string)) {
+ // The user specified the dataset_id as a URL, so store it in state that way
+ transformed["dataset_id"] = fmt.Sprintf("projects/%s/datasets/%s", transformed["project_id"], transformed["dataset_id"])
+ }
+ return []interface{}{transformed}
+}
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref.go.erb
new file mode 100644
index 000000000000..ba39eac461eb
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref.go.erb
@@ -0,0 +1,33 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+ original := v.(map[string]interface{})
+ if len(original) == 0 {
+ return nil
+ }
+ transformed := make(map[string]interface{})
+ transformed["project_id"] = original["projectId"]
+ transformed["dataset_id"] = original["datasetId"]
+ transformed["table_id"] = original["tableId"]
+
+ if bigqueryTableRegexp.MatchString(d.Get("<%= prop_path -%>").(string)) {
+ // The user specified the table_id as a URL, so store it in state that way
+ transformed["table_id"] = fmt.Sprintf("projects/%s/datasets/%s/tables/%s", transformed["project_id"], transformed["dataset_id"], transformed["table_id"])
+ }
+ return []interface{}{transformed}
+}
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref_copy_destinationtable.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref_copy_destinationtable.go.erb
new file mode 100644
index 000000000000..fc4d6f3f55bc
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref_copy_destinationtable.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<%= lines(compile_template(pwd + '/templates/terraform/custom_flatten/bigquery_table_ref.go.erb',
+ prefix: prefix,
+ property: property,
+ prop_path: 'copy.0.destination_table.0.table_id')) -%>
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref_copy_sourcetables.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref_copy_sourcetables.go.erb
new file mode 100644
index 000000000000..98132a5e5271
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref_copy_sourcetables.go.erb
@@ -0,0 +1,41 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return v
+ }
+ l := v.([]interface{})
+ transformed := make([]interface{}, 0, len(l))
+ for i, raw := range l {
+ original := raw.(map[string]interface{})
+ if len(original) < 1 {
+ // Do not include empty json objects coming back from the api
+ continue
+ }
+ t := map[string]interface{}{
+ "project_id": original["projectId"],
+ "dataset_id": original["datasetId"],
+ "table_id": original["tableId"],
+ }
+
+ if bigqueryTableRegexp.MatchString(d.Get(fmt.Sprintf("copy.0.source_tables.%d.table_id", i)).(string)) {
+ // The user specified the table_id as a URL, so store it in state that way
+ t["table_id"] = fmt.Sprintf("projects/%s/datasets/%s/tables/%s", t["project_id"], t["dataset_id"], t["table_id"])
+ }
+ transformed = append(transformed, t)
+ }
+
+ return transformed
+}
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref_extract_sourcetable.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref_extract_sourcetable.go.erb
new file mode 100644
index 000000000000..702bd0f39ac7
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref_extract_sourcetable.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<%= lines(compile_template(pwd + '/templates/terraform/custom_flatten/bigquery_table_ref.go.erb',
+ prefix: prefix,
+ property: property,
+ prop_path: 'extract.0.source_table.0.table_id')) -%>
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref_load_destinationtable.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref_load_destinationtable.go.erb
new file mode 100644
index 000000000000..5d258fd07710
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref_load_destinationtable.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<%= lines(compile_template(pwd + '/templates/terraform/custom_flatten/bigquery_table_ref.go.erb',
+ prefix: prefix,
+ property: property,
+ prop_path: 'load.0.destination_table.0.table_id')) -%>
diff --git a/templates/terraform/custom_flatten/bigquery_table_ref_query_destinationtable.go.erb b/templates/terraform/custom_flatten/bigquery_table_ref_query_destinationtable.go.erb
new file mode 100644
index 000000000000..c70252648382
--- /dev/null
+++ b/templates/terraform/custom_flatten/bigquery_table_ref_query_destinationtable.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<%= lines(compile_template(pwd + '/templates/terraform/custom_flatten/bigquery_table_ref.go.erb',
+ prefix: prefix,
+ property: property,
+ prop_path: 'query.0.destination_table.0.table_id')) -%>
diff --git a/templates/terraform/custom_flatten/data_catalog_tag.go.erb b/templates/terraform/custom_flatten/data_catalog_tag.go.erb
new file mode 100644
index 000000000000..d996ef47e3dc
--- /dev/null
+++ b/templates/terraform/custom_flatten/data_catalog_tag.go.erb
@@ -0,0 +1,21 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+
+ return v.(map[string]interface{})["displayName"]
+}
\ No newline at end of file
diff --git a/templates/terraform/custom_flatten/duration_string_to_days.go.erb b/templates/terraform/custom_flatten/duration_string_to_days.go.erb
new file mode 100644
index 000000000000..8ab8600a3d2a
--- /dev/null
+++ b/templates/terraform/custom_flatten/duration_string_to_days.go.erb
@@ -0,0 +1,27 @@
+<%- # the license inside this block applies to this file
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+ if v.(string) == "" {
+ return nil
+ }
+ dur, err := time.ParseDuration(v.(string))
+ if err != nil {
+ return nil
+ }
+ return int(dur/(time.Hour*24))
+}
diff --git a/templates/terraform/custom_flatten/firewall_log_config.go.erb b/templates/terraform/custom_flatten/firewall_log_config.go.erb
new file mode 100644
index 000000000000..ff7ff4d7903f
--- /dev/null
+++ b/templates/terraform/custom_flatten/firewall_log_config.go.erb
@@ -0,0 +1,32 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+ original := v.(map[string]interface{})
+ if len(original) == 0 {
+ return nil
+ }
+
+ v, ok := original["enable"]
+ if ok && !v.(bool) {
+ return nil
+ }
+
+ transformed := make(map[string]interface{})
+ transformed["metadata"] = original["metadata"]
+ return []interface{}{transformed}
+}
diff --git a/templates/terraform/custom_flatten/full_to_relative_path.erb b/templates/terraform/custom_flatten/full_to_relative_path.erb
new file mode 100644
index 000000000000..c2d751040da9
--- /dev/null
+++ b/templates/terraform/custom_flatten/full_to_relative_path.erb
@@ -0,0 +1,10 @@
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return v
+ }
+ relative, err := getRelativePath(v.(string))
+ if err != nil {
+ return v
+ }
+ return relative
+}
diff --git a/templates/terraform/custom_flatten/json_schema.erb b/templates/terraform/custom_flatten/json_schema.erb
new file mode 100644
index 000000000000..ee6080405942
--- /dev/null
+++ b/templates/terraform/custom_flatten/json_schema.erb
@@ -0,0 +1,25 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return nil
+ }
+ b, err := json.Marshal(v)
+ if err != nil {
+ // TODO: return error once https://github.com/GoogleCloudPlatform/magic-modules/issues/3257 is fixed.
+ log.Printf("[ERROR] failed to marshal schema to JSON: %v", err)
+ }
+ return string(b)
+}
diff --git a/templates/terraform/custom_flatten/preserved_state_disks.go.erb b/templates/terraform/custom_flatten/preserved_state_disks.go.erb
new file mode 100644
index 000000000000..d3008d7c1d0e
--- /dev/null
+++ b/templates/terraform/custom_flatten/preserved_state_disks.go.erb
@@ -0,0 +1,35 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2019 Google Inc.
+ # 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.
+-%>
+func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
+ if v == nil {
+ return v
+ }
+ disks := v.(map[string]interface{})
+ transformed := make([]interface{}, 0, len(disks))
+ for devName, deleteRuleRaw := range disks {
+ diskObj := deleteRuleRaw.(map[string]interface{})
+ source, err := getRelativePath(diskObj["source"].(string))
+ if err != nil {
+ source = diskObj["source"].(string)
+ }
+ transformed = append(transformed, map[string]interface{}{
+ "device_name": devName,
+ "delete_rule": diskObj["autoDelete"],
+ "source": source,
+ "mode": diskObj["mode"],
+ })
+ }
+ return transformed
+}
\ No newline at end of file
diff --git a/templates/terraform/custom_import/cloud_asset_feed.go.erb b/templates/terraform/custom_import/cloud_asset_feed.go.erb
new file mode 100644
index 000000000000..a089f93aee9a
--- /dev/null
+++ b/templates/terraform/custom_import/cloud_asset_feed.go.erb
@@ -0,0 +1,4 @@
+if err := d.Set("name", d.Id()); err != nil {
+ return nil, err
+}
+return []*schema.ResourceData{d}, nil
\ No newline at end of file
diff --git a/templates/terraform/custom_import/data_catalog_entry.go.erb b/templates/terraform/custom_import/data_catalog_entry.go.erb
new file mode 100644
index 000000000000..5f39756fdfdb
--- /dev/null
+++ b/templates/terraform/custom_import/data_catalog_entry.go.erb
@@ -0,0 +1,17 @@
+ config := meta.(*Config)
+
+ // current import_formats can't import fields with forward slashes in their value
+ if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+ }
+
+ name := d.Get("name").(string)
+ egRegex := regexp.MustCompile("(projects/.+/locations/.+/entryGroups/.+)/entries/(.+)")
+
+ parts := egRegex.FindStringSubmatch(name)
+ if len(parts) != 3 {
+ return nil, fmt.Errorf("entry name does not fit the format %s", egRegex)
+ }
+ d.Set("entry_group", parts[1])
+ d.Set("entry_id", parts[2])
+ return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/data_catalog_entry_group.go.erb b/templates/terraform/custom_import/data_catalog_entry_group.go.erb
new file mode 100644
index 000000000000..d9b1ffaefc85
--- /dev/null
+++ b/templates/terraform/custom_import/data_catalog_entry_group.go.erb
@@ -0,0 +1,18 @@
+ config := meta.(*Config)
+
+ // current import_formats can't import fields with forward slashes in their value
+ if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+ }
+
+ name := d.Get("name").(string)
+ egRegex := regexp.MustCompile("projects/(.+)/locations/(.+)/entryGroups/(.+)")
+
+ parts := egRegex.FindStringSubmatch(name)
+ if len(parts) != 4 {
+ return nil, fmt.Errorf("entry group name does not fit the format %s", egRegex)
+ }
+ d.Set("project", parts[1])
+ d.Set("region", parts[2])
+ d.Set("entry_group_id", parts[3])
+ return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/data_catalog_tag.go.erb b/templates/terraform/custom_import/data_catalog_tag.go.erb
new file mode 100644
index 000000000000..0f676f1ed82e
--- /dev/null
+++ b/templates/terraform/custom_import/data_catalog_tag.go.erb
@@ -0,0 +1,17 @@
+ config := meta.(*Config)
+
+ // current import_formats can't import fields with forward slashes in their value
+ if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+ }
+
+ name := d.Get("name").(string)
+ egRegex := regexp.MustCompile("(.+)/tags")
+
+ parts := egRegex.FindStringSubmatch(name)
+ if len(parts) != 2 {
+ return nil, fmt.Errorf("entry name does not fit the format %s", egRegex)
+ }
+
+ d.Set("parent", parts[1])
+ return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/data_catalog_tag_template.go.erb b/templates/terraform/custom_import/data_catalog_tag_template.go.erb
new file mode 100644
index 000000000000..203eb935c301
--- /dev/null
+++ b/templates/terraform/custom_import/data_catalog_tag_template.go.erb
@@ -0,0 +1,18 @@
+ config := meta.(*Config)
+
+ // current import_formats can't import fields with forward slashes in their value
+ if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+ }
+
+ name := d.Get("name").(string)
+ egRegex := regexp.MustCompile("projects/(.+)/locations/(.+)/tagTemplates/(.+)")
+
+ parts := egRegex.FindStringSubmatch(name)
+ if len(parts) != 4 {
+ return nil, fmt.Errorf("tag template name does not fit the format %s", egRegex)
+ }
+ d.Set("project", parts[1])
+ d.Set("region", parts[2])
+ d.Set("tag_template_id", parts[3])
+ return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/kms_key_ring_import_job.go.erb b/templates/terraform/custom_import/kms_key_ring_import_job.go.erb
new file mode 100644
index 000000000000..c4e04cd91b2e
--- /dev/null
+++ b/templates/terraform/custom_import/kms_key_ring_import_job.go.erb
@@ -0,0 +1,20 @@
+
+ config := meta.(*Config)
+
+ // current import_formats can't import fields with forward slashes in their value
+ if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+ }
+
+ stringParts := strings.Split(d.Get("name").(string), "/")
+ if len(stringParts) != 8 {
+ return nil, fmt.Errorf(
+ "Saw %s when the name is expected to have shape %s",
+ d.Get("name"),
+ "projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/importJobs/{{importJobId}}",
+ )
+ }
+
+ d.Set("key_ring", stringParts[3])
+ d.Set("import_job_id", stringParts[5])
+ return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/service_directory_endpoint.go.erb b/templates/terraform/custom_import/service_directory_endpoint.go.erb
new file mode 100644
index 000000000000..e31eebb61713
--- /dev/null
+++ b/templates/terraform/custom_import/service_directory_endpoint.go.erb
@@ -0,0 +1,39 @@
+config := meta.(*Config)
+
+// current import_formats cannot import fields with forward slashes in their value
+if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+}
+
+nameParts := strings.Split(d.Get("name").(string), "/")
+if len(nameParts) == 10 {
+ // `projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}/endpoints/{{endpoint_id}}`
+ d.Set("service", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s", nameParts[1], nameParts[3], nameParts[5], nameParts[7]))
+ d.Set("endpoint_id", nameParts[9])
+} else if len(nameParts) == 5 {
+ // `{{project}}/{{location}}/{{namespace_id}}/{{service_id}}/{{endpoint_id}}`
+ d.Set("service", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s", nameParts[0], nameParts[1], nameParts[2], nameParts[3]))
+ d.Set("endpoint_id", nameParts[4])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s/endpoints/%s", nameParts[0], nameParts[1], nameParts[2], nameParts[3], nameParts[4])
+ d.Set("name", id)
+ d.SetId(id)
+} else if len(nameParts) == 4 {
+ // `{{location}}/{{namespace_id}}/{{service_id}}/{{endpoint_id}}`
+ project, err := getProject(d, config)
+ if err != nil {
+ return nil, err
+ }
+ d.Set("service", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s", project, nameParts[0], nameParts[1], nameParts[2]))
+ d.Set("endpoint_id", nameParts[3])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s/endpoints/%s", project, nameParts[0], nameParts[1], nameParts[2], nameParts[3])
+ d.Set("name", id)
+ d.SetId(id)
+} else {
+ return nil, fmt.Errorf(
+ "Saw %s when the name is expected to have shape %s, %s or %s",
+ d.Get("name"),
+ "projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}/endpoints/{{endpoint_id}}",
+ "{{project}}/{{location}}/{{namespace_id}}/{{service_id}}/{{endpoint_id}}",
+ "{{location}}/{{namespace_id}}/{{service_id}}/{{endpoint_id}}")
+}
+return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/service_directory_namespace.go.erb b/templates/terraform/custom_import/service_directory_namespace.go.erb
new file mode 100644
index 000000000000..153aceda8764
--- /dev/null
+++ b/templates/terraform/custom_import/service_directory_namespace.go.erb
@@ -0,0 +1,42 @@
+config := meta.(*Config)
+
+// current import_formats cannot import fields with forward slashes in their value
+if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+}
+
+nameParts := strings.Split(d.Get("name").(string), "/")
+if len(nameParts) == 6 {
+ // `projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}`
+ d.Set("project", nameParts[1])
+ d.Set("location", nameParts[3])
+ d.Set("namespace_id", nameParts[5])
+} else if len(nameParts) == 3 {
+ // `{{project}}/{{location}}/{{namespace_id}}`
+ d.Set("project", nameParts[0])
+ d.Set("location", nameParts[1])
+ d.Set("namespace_id", nameParts[2])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s", nameParts[0], nameParts[1], nameParts[2])
+ d.Set("name", id)
+ d.SetId(id)
+} else if len(nameParts) == 2 {
+ // `{{location}}/{{namespace_id}}`
+ project, err := getProject(d, config)
+ if err != nil {
+ return nil, err
+ }
+ d.Set("project", project)
+ d.Set("location", nameParts[0])
+ d.Set("namespace_id", nameParts[1])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s", project, nameParts[0], nameParts[1])
+ d.Set("name", id)
+ d.SetId(id)
+} else {
+ return nil, fmt.Errorf(
+ "Saw %s when the name is expected to have shape %s, %s or %s",
+ d.Get("name"),
+ "projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}",
+ "{{project}}/{{location}}/{{namespace_id}}",
+ "{{location}}/{{namespace_id}}")
+}
+return []*schema.ResourceData{d}, nil
diff --git a/templates/terraform/custom_import/service_directory_service.go.erb b/templates/terraform/custom_import/service_directory_service.go.erb
new file mode 100644
index 000000000000..8b7da023ea4e
--- /dev/null
+++ b/templates/terraform/custom_import/service_directory_service.go.erb
@@ -0,0 +1,40 @@
+config := meta.(*Config)
+
+// current import_formats cannot import fields with forward slashes in their value
+if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil {
+ return nil, err
+}
+
+nameParts := strings.Split(d.Get("name").(string), "/")
+if len(nameParts) == 8 {
+ // `projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}`
+ d.Set("namespace", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s", nameParts[1], nameParts[3], nameParts[5]))
+ d.Set("service_id", nameParts[7])
+} else if len(nameParts) == 4 {
+ // `{{project}}/{{location}}/{{namespace_id}}/{{service_id}}`
+ d.Set("namespace", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s", nameParts[0], nameParts[1], nameParts[2]))
+ d.Set("service_id", nameParts[3])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s", nameParts[0], nameParts[1], nameParts[2], nameParts[3])
+ d.Set("name", id)
+ d.SetId(id)
+} else if len(nameParts) == 3 {
+ // `{{location}}/{{namespace_id}}/{{service_id}}`
+ project, err := getProject(d, config)
+ if err != nil {
+ return nil, err
+ }
+ d.Set("namespace", fmt.Sprintf("projects/%s/locations/%s/namespaces/%s", project, nameParts[0], nameParts[1]))
+ d.Set("service_id", nameParts[2])
+ id := fmt.Sprintf("projects/%s/locations/%s/namespaces/%s/services/%s", project, nameParts[0], nameParts[1], nameParts[2])
+ d.Set("name", id)
+ d.SetId(id)
+} else {
+ return nil, fmt.Errorf(
+ "Saw %s when the name is expected to have shape %s, %s or %s",
+ d.Get("name"),
+ "projects/{{project}}/locations/{{location}}/namespaces/{{namespace_id}}/services/{{service_id}}",
+ "{{project}}/{{location}}/{{namespace_id}}/{{service_id}}",
+ "{{location}}/{{namespace_id}}/{{service_id}}")
+}
+return []*schema.ResourceData{d}, nil
+
diff --git a/templates/terraform/decoders/backend_service.go.erb b/templates/terraform/decoders/backend_service.go.erb
index 50df79d6a47b..3e0796f151a5 100644
--- a/templates/terraform/decoders/backend_service.go.erb
+++ b/templates/terraform/decoders/backend_service.go.erb
@@ -24,4 +24,17 @@ if ok && m["enabled"] == false {
delete(res, "iap")
}
+// Requests with consistentHash will error for specific values of
+// localityLbPolicy. However, the API will not remove it if the backend
+// service is updated to from supporting to non-supporting localityLbPolicy
+// (e.g. RING_HASH to RANDOM), which causes an error on subsequent update.
+// In order to prevent errors, we ignore any consistentHash returned
+// from the API when the localityLbPolicy doesn't support it.
+if v, ok := res["localityLbPolicy"]; ok {
+ lbPolicy := v.(string)
+ if lbPolicy != "MAGLEV" && lbPolicy != "RING_HASH" {
+ delete(res, "consistentHash")
+ }
+}
+
return res, nil
diff --git a/templates/terraform/decoders/cloudiot_device_registry.go.erb b/templates/terraform/decoders/cloudiot_device_registry.go.erb
new file mode 100644
index 000000000000..1ce63da41715
--- /dev/null
+++ b/templates/terraform/decoders/cloudiot_device_registry.go.erb
@@ -0,0 +1,31 @@
+config := meta.(*Config)
+
+log.Printf("[DEBUG] Decoding state notification config: %q", d.Id())
+log.Printf("[DEBUG] State notification config before decoding: %v", d.Get("state_notification_config"))
+if err := d.Set("state_notification_config", flattenCloudIotDeviceRegistryStateNotificationConfig(res["stateNotificationConfig"], d, config)); err != nil {
+ return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err)
+}
+log.Printf("[DEBUG] State notification config after decoding: %v", d.Get("state_notification_config"))
+
+log.Printf("[DEBUG] Decoding HTTP config: %q", d.Id())
+log.Printf("[DEBUG] HTTP config before decoding: %v", d.Get("http_config"))
+if err := d.Set("http_config", flattenCloudIotDeviceRegistryHTTPConfig(res["httpConfig"], d, config)); err != nil {
+ return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err)
+}
+log.Printf("[DEBUG] HTTP config after decoding: %v", d.Get("http_config"))
+
+log.Printf("[DEBUG] Decoding MQTT config: %q", d.Id())
+log.Printf("[DEBUG] MQTT config before decoding: %v", d.Get("mqtt_config"))
+if err := d.Set("mqtt_config", flattenCloudIotDeviceRegistryMqttConfig(res["mqttConfig"], d, config)); err != nil {
+ return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err)
+}
+log.Printf("[DEBUG] MQTT config after decoding: %v", d.Get("mqtt_config"))
+
+log.Printf("[DEBUG] Decoding credentials: %q", d.Id())
+log.Printf("[DEBUG] credentials before decoding: %v", d.Get("credentials"))
+if err := d.Set("credentials", flattenCloudIotDeviceRegistryCredentials(res["credentials"], d, config)); err != nil {
+ return nil, fmt.Errorf("Error reading DeviceRegistry: %s", err)
+}
+log.Printf("[DEBUG] credentials after decoding: %v", d.Get("credentials"))
+
+return res, nil
diff --git a/templates/terraform/decoders/containeranalysis_occurrence.go.erb b/templates/terraform/decoders/containeranalysis_occurrence.go.erb
new file mode 100644
index 000000000000..0b7dbc5c91bc
--- /dev/null
+++ b/templates/terraform/decoders/containeranalysis_occurrence.go.erb
@@ -0,0 +1,43 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<% unless version == 'ga' -%>
+// Resource object was flattened in GA API
+if nestedResource, ok := res["resource"]; ok {
+ if resObj, ok := nestedResource.(map[string]interface{}); ok {
+ res["resourceUri"] = resObj["uri"]
+ delete(res, "resource")
+ }
+}
+
+// Beta attestation.attestation.genericSignedAttestation
+// => GA attestation
+if attV, ok := res["attestation"]; ok && attV != nil {
+ att := attV.(map[string]interface{})
+ if nestedAttV, ok := att["attestation"]; ok && nestedAttV != nil {
+ nestedAtt := nestedAttV.(map[string]interface{})
+ if genericV, ok := nestedAtt["genericSignedAttestation"]; ok {
+ genericAtt := genericV.(map[string]interface{})
+ res["attestation"] = map[string]interface{}{
+ "serializedPayload": genericAtt["serializedPayload"],
+ "signatures": genericAtt["signatures"],
+ }
+ }
+ }
+}
+
+<% else -%>
+// encoder logic only in non-GA version
+<% end -%>
+return res, nil
diff --git a/templates/terraform/decoders/os_config_patch_deployment.go.erb b/templates/terraform/decoders/os_config_patch_deployment.go.erb
new file mode 100644
index 000000000000..fce9e9366fc3
--- /dev/null
+++ b/templates/terraform/decoders/os_config_patch_deployment.go.erb
@@ -0,0 +1,9 @@
+if res["patchConfig"] != nil {
+ patchConfig := res["patchConfig"].(map[string]interface{})
+ if patchConfig["goo"] != nil {
+ patchConfig["goo"].(map[string]interface{})["enabled"] = true
+ res["patchConfig"] = patchConfig
+ }
+}
+
+return res, nil
diff --git a/templates/terraform/decoders/region_backend_service.go.erb b/templates/terraform/decoders/region_backend_service.go.erb
new file mode 100644
index 000000000000..1d1eacba8e53
--- /dev/null
+++ b/templates/terraform/decoders/region_backend_service.go.erb
@@ -0,0 +1,28 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+// Requests with consistentHash will error for specific values of
+// localityLbPolicy. However, the API will not remove it if the backend
+// service is updated to from supporting to non-supporting localityLbPolicy
+// (e.g. RING_HASH to RANDOM), which causes an error on subsequent update.
+// In order to prevent errors, we ignore any consistentHash returned
+// from the API when the localityLbPolicy doesn't support it.
+if v, ok := res["localityLbPolicy"]; ok {
+ lbPolicy := v.(string)
+ if lbPolicy != "MAGLEV" && lbPolicy != "RING_HASH" {
+ delete(res, "consistentHash")
+ }
+}
+
+return res, nil
diff --git a/templates/terraform/encoders/backend_service.go.erb b/templates/terraform/encoders/backend_service.go.erb
index 93ae452dfb7f..db47dca273af 100644
--- a/templates/terraform/encoders/backend_service.go.erb
+++ b/templates/terraform/encoders/backend_service.go.erb
@@ -32,5 +32,22 @@ if iapVal == nil {
obj["iap"] = iap
}
+backendsRaw, ok := obj["backends"]
+if !ok {
+ return obj, nil
+}
+backends := backendsRaw.([]interface{})
+for _, backendRaw := range backends {
+ backend := backendRaw.(map[string]interface{})
+ backendGroup, ok := backend["group"]
+ if !ok {
+ continue
+ }
+ if strings.Contains(backendGroup.(string), "global/networkEndpointGroups") {
+ // Remove `max_utilization` from any backend that belongs to a global NEG. This field
+ // has a default value and causes API validation errors
+ backend["maxUtilization"] = nil
+ }
+}
return obj, nil
diff --git a/templates/terraform/encoders/bigquery_job.go.erb b/templates/terraform/encoders/bigquery_job.go.erb
new file mode 100644
index 000000000000..f9c94f684fcb
--- /dev/null
+++ b/templates/terraform/encoders/bigquery_job.go.erb
@@ -0,0 +1,20 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+project, err := getProject(d, meta.(*Config))
+if err != nil {
+ return nil, err
+}
+obj["jobReference"].(map[string]interface{})["project"] = project
+return obj, nil
\ No newline at end of file
diff --git a/templates/terraform/encoders/cloud_asset_feed.go.erb b/templates/terraform/encoders/cloud_asset_feed.go.erb
new file mode 100644
index 000000000000..5d2c986d9ace
--- /dev/null
+++ b/templates/terraform/encoders/cloud_asset_feed.go.erb
@@ -0,0 +1,8 @@
+// Remove the "folders/" prefix from the folder ID
+if folder, ok := d.GetOkExists("folder"); ok {
+ d.Set("folder_id", strings.TrimPrefix(folder.(string), "folders/"))
+}
+// The feed object must be under the "feed" attribute on the request.
+newObj := make(map[string]interface{})
+newObj["feed"] = obj
+return newObj, nil
\ No newline at end of file
diff --git a/templates/terraform/encoders/cloudiot_device_registry.go.erb b/templates/terraform/encoders/cloudiot_device_registry.go.erb
new file mode 100644
index 000000000000..695c0bca5679
--- /dev/null
+++ b/templates/terraform/encoders/cloudiot_device_registry.go.erb
@@ -0,0 +1,43 @@
+config := meta.(*Config)
+
+log.Printf("[DEBUG] Resource data before encoding extra schema entries %q: %#v", d.Id(), obj)
+
+log.Printf("[DEBUG] Encoding state notification config: %q", d.Id())
+stateNotificationConfigProp, err := expandCloudIotDeviceRegistryStateNotificationConfig(d.Get("state_notification_config"), d, config)
+if err != nil {
+ return nil, err
+} else if v, ok := d.GetOkExists("state_notification_config"); !isEmptyValue(reflect.ValueOf(stateNotificationConfigProp)) && (ok || !reflect.DeepEqual(v, stateNotificationConfigProp)) {
+ log.Printf("[DEBUG] Encoding %q. Setting stateNotificationConfig: %#v", d.Id(), stateNotificationConfigProp)
+ obj["stateNotificationConfig"] = stateNotificationConfigProp
+}
+
+log.Printf("[DEBUG] Encoding HTTP config: %q", d.Id())
+httpConfigProp, err := expandCloudIotDeviceRegistryHTTPConfig(d.Get("http_config"), d, config)
+if err != nil {
+ return nil, err
+} else if v, ok := d.GetOkExists("http_config"); !isEmptyValue(reflect.ValueOf(httpConfigProp)) && (ok || !reflect.DeepEqual(v, httpConfigProp)) {
+ log.Printf("[DEBUG] Encoding %q. Setting httpConfig: %#v", d.Id(), httpConfigProp)
+ obj["httpConfig"] = httpConfigProp
+}
+
+log.Printf("[DEBUG] Encoding MQTT config: %q", d.Id())
+mqttConfigProp, err := expandCloudIotDeviceRegistryMqttConfig(d.Get("mqtt_config"), d, config)
+if err != nil {
+ return nil, err
+} else if v, ok := d.GetOkExists("mqtt_config"); !isEmptyValue(reflect.ValueOf(mqttConfigProp)) && (ok || !reflect.DeepEqual(v, mqttConfigProp)) {
+ log.Printf("[DEBUG] Encoding %q. Setting mqttConfig: %#v", d.Id(), mqttConfigProp)
+ obj["mqttConfig"] = mqttConfigProp
+}
+
+log.Printf("[DEBUG] Encoding credentials: %q", d.Id())
+credentialsProp, err := expandCloudIotDeviceRegistryCredentials(d.Get("credentials"), d, config)
+if err != nil {
+ return nil, err
+} else if v, ok := d.GetOkExists("credentials"); !isEmptyValue(reflect.ValueOf(credentialsProp)) && (ok || !reflect.DeepEqual(v, credentialsProp)) {
+ log.Printf("[DEBUG] Encoding %q. Setting credentials: %#v", d.Id(), credentialsProp)
+ obj["credentials"] = credentialsProp
+}
+
+log.Printf("[DEBUG] Resource data after encoding extra schema entries %q: %#v", d.Id(), obj)
+
+return obj, nil
diff --git a/templates/terraform/encoders/compute_per_instance_config.go.erb b/templates/terraform/encoders/compute_per_instance_config.go.erb
new file mode 100644
index 000000000000..6daa41778f8a
--- /dev/null
+++ b/templates/terraform/encoders/compute_per_instance_config.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2017 Google Inc.
+ # 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.
+-%>
+wrappedReq := map[string]interface{}{
+ "instances": []interface{}{obj},
+}
+return wrappedReq, nil
diff --git a/templates/terraform/encoders/containeranalysis_occurrence.go.erb b/templates/terraform/encoders/containeranalysis_occurrence.go.erb
new file mode 100644
index 000000000000..5697d9c8fa66
--- /dev/null
+++ b/templates/terraform/encoders/containeranalysis_occurrence.go.erb
@@ -0,0 +1,43 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+<% unless version == 'ga' -%>
+// Resource object was flattened in GA API
+if resourceuri, ok := obj["resourceUri"]; ok {
+ obj["resource"] = map[string]interface{}{
+ "uri": resourceuri,
+ }
+ delete(obj, "resourceUri")
+}
+
+
+// Beta `attestation.genericSignedAttestation` was flattened to just
+// `attestation` (no contentType) in GA
+if v, ok := obj["attestation"]; ok && v != nil {
+ gaAtt := v.(map[string]interface{})
+ obj["attestation"] = map[string]interface{}{
+ "attestation": map[string]interface{}{
+ "genericSignedAttestation": map[string]interface{}{
+ "contentType": "SIMPLE_SIGNING_JSON",
+ "serializedPayload": gaAtt["serializedPayload"],
+ "signatures": gaAtt["signatures"],
+ },
+ },
+ }
+}
+<% else -%>
+// encoder logic only in non-GA versions
+<% end -%>
+
+return obj, nil
diff --git a/templates/terraform/encoders/monitoring_slo.go.erb b/templates/terraform/encoders/monitoring_slo.go.erb
new file mode 100644
index 000000000000..6a8a950629a4
--- /dev/null
+++ b/templates/terraform/encoders/monitoring_slo.go.erb
@@ -0,0 +1,18 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+// Name/Service Level Objective ID is a query parameter and cannot
+// be given in data
+delete(obj, "sloId")
+return obj, nil
\ No newline at end of file
diff --git a/templates/terraform/encoders/os_config_patch_deployment.go.erb b/templates/terraform/encoders/os_config_patch_deployment.go.erb
new file mode 100644
index 000000000000..a146d237e8c6
--- /dev/null
+++ b/templates/terraform/encoders/os_config_patch_deployment.go.erb
@@ -0,0 +1,24 @@
+schedule := obj["recurringSchedule"].(map[string]interface{})
+if schedule["monthly"] != nil {
+ obj["recurringSchedule"].(map[string]interface{})["frequency"] = "MONTHLY"
+} else if schedule["weekly"] != nil {
+ obj["recurringSchedule"].(map[string]interface{})["frequency"] = "WEEKLY"
+}
+
+if obj["patchConfig"] != nil {
+ patchConfig := obj["patchConfig"].(map[string]interface{})
+ if patchConfig["goo"] != nil {
+ goo := patchConfig["goo"].(map[string]interface{})
+
+ if goo["enabled"] == true {
+ delete(goo, "enabled")
+ patchConfig["goo"] = goo
+ } else {
+ delete(patchConfig, "goo")
+ }
+
+ obj["patchConfig"] = patchConfig
+ }
+}
+
+return obj, nil
diff --git a/templates/terraform/env_var_context.go.erb b/templates/terraform/env_var_context.go.erb
index d0809f7520be..3d9ac7b88a0d 100644
--- a/templates/terraform/env_var_context.go.erb
+++ b/templates/terraform/env_var_context.go.erb
@@ -17,5 +17,9 @@
"<%= var_name -%>": getTestProjectFromEnv(),
<% elsif var_type == :FIRESTORE_PROJECT_NAME -%>
"<%= var_name -%>": getTestFirestoreProjectFromEnv(t),
+ <% elsif var_type == :CUST_ID -%>
+ "<%= var_name -%>": getTestCustIdFromEnv(t),
+ <% elsif var_type == :IDENTITY_USER -%>
+ "<%= var_name -%>": getTestIdentityUserFromEnv(t),
<% end -%>
<% end -%>
diff --git a/templates/terraform/examples/access_context_manager_access_level_basic.tf.erb b/templates/terraform/examples/access_context_manager_access_level_basic.tf.erb
index 26f57256e105..ec6e32c0cf45 100644
--- a/templates/terraform/examples/access_context_manager_access_level_basic.tf.erb
+++ b/templates/terraform/examples/access_context_manager_access_level_basic.tf.erb
@@ -1,11 +1,11 @@
resource "google_access_context_manager_access_level" "<%= ctx[:primary_resource_id] %>" {
- parent = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}"
- name = "accessPolicies/${google_access_context_manager_access_policy.test-access.name}/accessLevels/<%= ctx[:vars]['access_level_name'] %>"
+ parent = "accessPolicies/${google_access_context_manager_access_policy.access-policy.name}"
+ name = "accessPolicies/${google_access_context_manager_access_policy.access-policy.name}/accessLevels/<%= ctx[:vars]['access_level_name'] %>"
title = "<%= ctx[:vars]['access_level_name'] %>"
basic {
conditions {
device_policy {
- require_screen_lock = false
+ require_screen_lock = true
os_constraints {
os_type = "DESKTOP_CHROME_OS"
}
diff --git a/templates/terraform/examples/active_directory_domain_basic.tf.erb b/templates/terraform/examples/active_directory_domain_basic.tf.erb
new file mode 100644
index 000000000000..caf8f8871c7c
--- /dev/null
+++ b/templates/terraform/examples/active_directory_domain_basic.tf.erb
@@ -0,0 +1,5 @@
+resource "google_active_directory_domain" "ad-domain" {
+ domain_name = "mydomain.org.com"
+ locations = ["us-central1"]
+ reserved_ip_range = "192.168.255.0/24"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/address_with_shared_loadbalancer_vip.tf.erb b/templates/terraform/examples/address_with_shared_loadbalancer_vip.tf.erb
new file mode 100644
index 000000000000..a06579f539af
--- /dev/null
+++ b/templates/terraform/examples/address_with_shared_loadbalancer_vip.tf.erb
@@ -0,0 +1,6 @@
+resource "google_compute_address" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['address_name'] %>"
+ address_type = "INTERNAL"
+ purpose = "SHARED_LOADBALANCER_VIP"
+}
diff --git a/templates/terraform/examples/app_engine_flexible_app_version.tf.erb b/templates/terraform/examples/app_engine_flexible_app_version.tf.erb
index 4b220e9cd5db..a65b47ed63b8 100644
--- a/templates/terraform/examples/app_engine_flexible_app_version.tf.erb
+++ b/templates/terraform/examples/app_engine_flexible_app_version.tf.erb
@@ -1,12 +1,32 @@
+resource "google_project" "my_project" {
+ name = "<%= ctx[:vars]['project'] %>"
+ project_id = "<%= ctx[:vars]['project'] %>"
+ org_id = "<%= ctx[:test_env_vars]['org_id'] %>"
+ billing_account = "<%= ctx[:test_env_vars]['billing_account'] %>"
+}
+
+resource "google_app_engine_application" "app" {
+ project = google_project.my_project.project_id
+ location_id = "us-central"
+}
+
resource "google_project_service" "service" {
+ project = google_project.my_project.project_id
service = "appengineflex.googleapis.com"
disable_dependent_services = false
}
+resource "google_project_iam_member" "gae_api" {
+ project = google_project_service.service.project
+ role = "roles/compute.networkUser"
+ member = "serviceAccount:service-${google_project.my_project.number}@gae-api-prod.google.com.iam.gserviceaccount.com"
+}
+
resource "google_app_engine_flexible_app_version" "<%= ctx[:primary_resource_id] %>" {
version_id = "v1"
- service = "<%= ctx[:vars]['service_name'] %>"
+ project = google_project_iam_member.gae_api.project
+ service = "default"
runtime = "nodejs"
entrypoint {
@@ -31,6 +51,18 @@ resource "google_app_engine_flexible_app_version" "<%= ctx[:primary_resource_id]
port = "8080"
}
+ handlers {
+ url_regex = ".*\\/my-path\\/*"
+ security_level = "SECURE_ALWAYS"
+ login = "LOGIN_REQUIRED"
+ auth_fail_action = "AUTH_FAIL_ACTION_REDIRECT"
+
+ static_files {
+ path = "my-other-path"
+ upload_path_regex = ".*\\/my-path\\/*"
+ }
+ }
+
automatic_scaling {
cool_down_period = "120s"
cpu_utilization {
@@ -38,10 +70,11 @@ resource "google_app_engine_flexible_app_version" "<%= ctx[:primary_resource_id]
}
}
- delete_service_on_destroy = true
+ noop_on_destroy = true
}
resource "google_storage_bucket" "bucket" {
+ project = google_project.my_project.project_id
name = "<%= ctx[:vars]['bucket_name'] %>"
}
diff --git a/templates/terraform/examples/app_engine_standard_app_version.tf.erb b/templates/terraform/examples/app_engine_standard_app_version.tf.erb
index cdf15ef6acbb..9af3a5cceaf3 100644
--- a/templates/terraform/examples/app_engine_standard_app_version.tf.erb
+++ b/templates/terraform/examples/app_engine_standard_app_version.tf.erb
@@ -17,6 +17,20 @@ resource "google_app_engine_standard_app_version" "<%= ctx[:primary_resource_id]
port = "8080"
}
+ automatic_scaling {
+ max_concurrent_requests = 10
+ min_idle_instances = 1
+ max_idle_instances = 3
+ min_pending_latency = "1s"
+ max_pending_latency = "5s"
+ standard_scheduler_settings {
+ target_cpu_utilization = 0.5
+ target_throughput_utilization = 0.75
+ min_instances = 2
+ max_instances = 10
+ }
+ }
+
delete_service_on_destroy = true
}
@@ -39,6 +53,10 @@ resource "google_app_engine_standard_app_version" "myapp_v2" {
port = "8080"
}
+ basic_scaling {
+ max_instances = 5
+ }
+
noop_on_destroy = true
}
diff --git a/templates/terraform/examples/artifact_registry_repository_basic.tf.erb b/templates/terraform/examples/artifact_registry_repository_basic.tf.erb
new file mode 100644
index 000000000000..28a74bdbf584
--- /dev/null
+++ b/templates/terraform/examples/artifact_registry_repository_basic.tf.erb
@@ -0,0 +1,8 @@
+resource "google_artifact_registry_repository" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+
+ location = "us-central1"
+ repository_id = "<%= ctx[:vars]['repository_id'] %>"
+ description = "<%= ctx[:vars]['description'] %>"
+ format = "DOCKER"
+}
diff --git a/templates/terraform/examples/artifact_registry_repository_cmek.tf.erb b/templates/terraform/examples/artifact_registry_repository_cmek.tf.erb
new file mode 100644
index 000000000000..6217d3b2d052
--- /dev/null
+++ b/templates/terraform/examples/artifact_registry_repository_cmek.tf.erb
@@ -0,0 +1,9 @@
+resource "google_artifact_registry_repository" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+
+ location = "us-central1"
+ repository_id = "<%= ctx[:vars]['repository_id'] %>"
+ description = "example docker repository with cmek"
+ format = "DOCKER"
+ kms_key_name = "<%= ctx[:vars]['kms_key_name'] %>"
+}
diff --git a/templates/terraform/examples/artifact_registry_repository_iam.tf.erb b/templates/terraform/examples/artifact_registry_repository_iam.tf.erb
new file mode 100644
index 000000000000..3ac1ebdfa31c
--- /dev/null
+++ b/templates/terraform/examples/artifact_registry_repository_iam.tf.erb
@@ -0,0 +1,24 @@
+resource "google_artifact_registry_repository" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+
+ location = "us-central1"
+ repository_id = "<%= ctx[:vars]['repository_id'] %>"
+ description = "<%= ctx[:vars]['description'] %>"
+ format = "DOCKER"
+}
+
+resource "google_service_account" "test-account" {
+ provider = google-beta
+
+ account_id = "<%= ctx[:vars]['account_id'] %>"
+ display_name = "Test Service Account"
+}
+
+resource "google_artifact_registry_repository_iam_member" "test-iam" {
+ provider = google-beta
+
+ location = google_artifact_registry_repository.<%= ctx[:primary_resource_id] %>.location
+ repository = google_artifact_registry_repository.<%= ctx[:primary_resource_id] %>.name
+ role = "roles/artifactregistry.reader"
+ member = "serviceAccount:${google_service_account.test-account.email}"
+}
diff --git a/templates/terraform/examples/autoscaler_basic.tf.erb b/templates/terraform/examples/autoscaler_basic.tf.erb
index e0a644b14b0d..f8333408ace6 100644
--- a/templates/terraform/examples/autoscaler_basic.tf.erb
+++ b/templates/terraform/examples/autoscaler_basic.tf.erb
@@ -22,7 +22,7 @@ resource "google_compute_instance_template" "foobar" {
tags = ["foo", "bar"]
disk {
- source_image = data.google_compute_image.debian_9.self_link
+ source_image = data.google_compute_image.debian_9.id
}
network_interface {
diff --git a/templates/terraform/examples/autoscaler_single_instance.tf.erb b/templates/terraform/examples/autoscaler_single_instance.tf.erb
index c7aac8d1d70a..fc603e073f88 100644
--- a/templates/terraform/examples/autoscaler_single_instance.tf.erb
+++ b/templates/terraform/examples/autoscaler_single_instance.tf.erb
@@ -28,7 +28,7 @@ resource "google_compute_instance_template" "default" {
tags = ["foo", "bar"]
disk {
- source_image = data.google_compute_image.debian_9.self_link
+ source_image = data.google_compute_image.debian_9.id
}
network_interface {
diff --git a/templates/terraform/examples/backend_service_basic.tf.erb b/templates/terraform/examples/backend_service_basic.tf.erb
index c3779e7cb9d2..f46281cdb9ce 100644
--- a/templates/terraform/examples/backend_service_basic.tf.erb
+++ b/templates/terraform/examples/backend_service_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_backend_service" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['backend_service_name'] %>"
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/backend_service_network_endpoint.tf.erb b/templates/terraform/examples/backend_service_network_endpoint.tf.erb
new file mode 100644
index 000000000000..53cb96620ee7
--- /dev/null
+++ b/templates/terraform/examples/backend_service_network_endpoint.tf.erb
@@ -0,0 +1,24 @@
+resource "google_compute_global_network_endpoint_group" "external_proxy" {
+ name = "<%= ctx[:vars]['neg_name'] %>"
+ network_endpoint_type = "INTERNET_FQDN_PORT"
+ default_port = "443"
+}
+
+resource "google_compute_global_network_endpoint" "proxy" {
+ global_network_endpoint_group = google_compute_global_network_endpoint_group.external_proxy.id
+ fqdn = "test.example.com"
+ port = google_compute_global_network_endpoint_group.external_proxy.default_port
+}
+
+resource "google_compute_backend_service" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['backend_service_name'] %>"
+ enable_cdn = true
+ timeout_sec = 10
+ connection_draining_timeout_sec = 10
+
+ custom_request_headers = ["host: ${google_compute_global_network_endpoint.proxy.fqdn}"]
+
+ backend {
+ group = google_compute_global_network_endpoint_group.external_proxy.id
+ }
+}
diff --git a/templates/terraform/examples/backend_service_signed_url_key.tf.erb b/templates/terraform/examples/backend_service_signed_url_key.tf.erb
index b9570befa984..7ce1d3b5a635 100644
--- a/templates/terraform/examples/backend_service_signed_url_key.tf.erb
+++ b/templates/terraform/examples/backend_service_signed_url_key.tf.erb
@@ -16,14 +16,14 @@ resource "google_compute_backend_service" "example_backend" {
group = google_compute_instance_group_manager.webservers.instance_group
}
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_instance_group_manager" "webservers" {
name = "my-webservers"
version {
- instance_template = google_compute_instance_template.webserver.self_link
+ instance_template = google_compute_instance_template.webserver.id
name = "primary"
}
diff --git a/templates/terraform/examples/backend_service_traffic_director_ring_hash.tf.erb b/templates/terraform/examples/backend_service_traffic_director_ring_hash.tf.erb
index 080fb2aee9de..46b584e3c4f8 100644
--- a/templates/terraform/examples/backend_service_traffic_director_ring_hash.tf.erb
+++ b/templates/terraform/examples/backend_service_traffic_director_ring_hash.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_backend_service" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
name = "<%= ctx[:vars]['backend_service_name'] %>"
- health_checks = [google_compute_health_check.health_check.self_link]
+ health_checks = [google_compute_health_check.health_check.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
locality_lb_policy = "RING_HASH"
session_affinity = "HTTP_COOKIE"
diff --git a/templates/terraform/examples/backend_service_traffic_director_round_robin.tf.erb b/templates/terraform/examples/backend_service_traffic_director_round_robin.tf.erb
index 068013aee910..e45e8f354ba8 100644
--- a/templates/terraform/examples/backend_service_traffic_director_round_robin.tf.erb
+++ b/templates/terraform/examples/backend_service_traffic_director_round_robin.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_backend_service" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
name = "<%= ctx[:vars]['backend_service_name'] %>"
- health_checks = [google_compute_health_check.health_check.self_link]
+ health_checks = [google_compute_health_check.health_check.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
locality_lb_policy = "ROUND_ROBIN"
}
diff --git a/templates/terraform/examples/base_configs/example_file.tf.erb b/templates/terraform/examples/base_configs/example_file.tf.erb
index 5d2155f0173b..bad51ff17c74 100644
--- a/templates/terraform/examples/base_configs/example_file.tf.erb
+++ b/templates/terraform/examples/base_configs/example_file.tf.erb
@@ -1,2 +1,2 @@
<% autogen_exception -%>
-<%= example.config_example -%>
+<%= example.config_example(pwd) -%>
diff --git a/templates/terraform/examples/base_configs/iam_test_file.go.erb b/templates/terraform/examples/base_configs/iam_test_file.go.erb
index c7c939f8c9e9..dca7bd54cbcf 100644
--- a/templates/terraform/examples/base_configs/iam_test_file.go.erb
+++ b/templates/terraform/examples/base_configs/iam_test_file.go.erb
@@ -1,4 +1,4 @@
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
@@ -52,9 +52,9 @@ import_url = import_format.gsub(/({{)(\w+)(}})/, '%s').gsub(object.__product.bas
func TestAcc<%= resource_name -%>IamBindingGenerated(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -92,9 +92,9 @@ func TestAcc<%= resource_name -%>IamBindingGenerated(t *testing.T) {
func TestAcc<%= resource_name -%>IamMemberGenerated(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -121,12 +121,16 @@ func TestAcc<%= resource_name -%>IamMemberGenerated(t *testing.T) {
func TestAcc<%= resource_name -%>IamPolicyGenerated(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
<% unless object.iam_policy.admin_iam_role.nil? -%>
- context["service_account"] = getTestServiceAccountFromEnv(t)
+ // This may skip test, so do it first
+ sa := getTestServiceAccountFromEnv(t)
+<% end -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
+<% unless object.iam_policy.admin_iam_role.nil? -%>
+ context["service_account"] = sa
<% end -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -164,9 +168,9 @@ func TestAcc<%= resource_name -%>IamPolicyGenerated(t *testing.T) {
func TestAcc<%= resource_name -%>IamBindingGenerated_withCondition(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -192,9 +196,9 @@ func TestAcc<%= resource_name -%>IamBindingGenerated_withCondition(t *testing.T)
func TestAcc<%= resource_name -%>IamBindingGenerated_withAndWithoutCondition(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -228,9 +232,9 @@ func TestAcc<%= resource_name -%>IamBindingGenerated_withAndWithoutCondition(t *
func TestAcc<%= resource_name -%>IamMemberGenerated_withCondition(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -256,9 +260,9 @@ func TestAcc<%= resource_name -%>IamMemberGenerated_withCondition(t *testing.T)
func TestAcc<%= resource_name -%>IamMemberGenerated_withAndWithoutCondition(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -292,12 +296,16 @@ func TestAcc<%= resource_name -%>IamMemberGenerated_withAndWithoutCondition(t *t
func TestAcc<%= resource_name -%>IamPolicyGenerated_withCondition(t *testing.T) {
t.Parallel()
-<%= lines(compile('templates/terraform/iam/iam_context.go.erb')) -%>
<% unless object.iam_policy.admin_iam_role.nil? -%>
- context["service_account"] = getTestServiceAccountFromEnv(t)
+ // This may skip test, so do it first
+ sa := getTestServiceAccountFromEnv(t)
+<% end -%>
+<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
+<% unless object.iam_policy.admin_iam_role.nil? -%>
+ context["service_account"] = sa
<% end -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
Providers: testAccProvidersOiCS,
@@ -323,13 +331,13 @@ func TestAcc<%= resource_name -%>IamPolicyGenerated_withCondition(t *testing.T)
func testAcc<%= resource_name -%>IamMember_basicGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
member = "user:admin@hashicorptest.com"
}
@@ -338,7 +346,7 @@ resource "<%= resource_ns_iam -%>_member" "foo" {
func testAcc<%= resource_name -%>IamPolicy_basicGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
@@ -360,7 +368,7 @@ resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
@@ -368,7 +376,7 @@ resource "<%= resource_ns_iam -%>_policy" "foo" {
func testAcc<%= resource_name -%>IamPolicy_emptyBinding(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
@@ -380,7 +388,7 @@ resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
@@ -388,13 +396,13 @@ resource "<%= resource_ns_iam -%>_policy" "foo" {
func testAcc<%= resource_name -%>IamBinding_basicGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
members = ["user:admin@hashicorptest.com"]
}
@@ -403,13 +411,13 @@ resource "<%= resource_ns_iam -%>_binding" "foo" {
func testAcc<%= resource_name -%>IamBinding_updateGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"]
}
@@ -419,13 +427,13 @@ resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
func testAcc<%= resource_name -%>IamBinding_withConditionGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
members = ["user:admin@hashicorptest.com"]
condition {
@@ -439,13 +447,13 @@ resource "<%= resource_ns_iam -%>_binding" "foo" {
func testAcc<%= resource_name -%>IamBinding_withAndWithoutConditionGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
members = ["user:admin@hashicorptest.com"]
}
@@ -454,7 +462,7 @@ resource "<%= resource_ns_iam -%>_binding" "foo2" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
members = ["user:admin@hashicorptest.com"]
condition {
@@ -468,13 +476,13 @@ resource "<%= resource_ns_iam -%>_binding" "foo2" {
func testAcc<%= resource_name -%>IamMember_withConditionGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
member = "user:admin@hashicorptest.com"
condition {
@@ -488,13 +496,13 @@ resource "<%= resource_ns_iam -%>_member" "foo" {
func testAcc<%= resource_name -%>IamMember_withAndWithoutConditionGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
member = "user:admin@hashicorptest.com"
}
@@ -503,7 +511,7 @@ resource "<%= resource_ns_iam -%>_member" "foo2" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
role = "%{role}"
member = "user:admin@hashicorptest.com"
condition {
@@ -517,7 +525,7 @@ resource "<%= resource_ns_iam -%>_member" "foo2" {
func testAcc<%= resource_name -%>IamPolicy_withConditionGenerated(context map[string]interface{}) string {
return Nprintf(`
-<%= example.config_test_body -%>
+<%= example.config_test_body(pwd) -%>
data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
@@ -544,7 +552,7 @@ resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
provider = google-beta
<% end -%>
-<%= lines(compile(object.iam_policy.example_config_body)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
diff --git a/templates/terraform/examples/base_configs/test_file.go.erb b/templates/terraform/examples/base_configs/test_file.go.erb
index 2c023942abb0..26323863ee6e 100644
--- a/templates/terraform/examples/base_configs/test_file.go.erb
+++ b/templates/terraform/examples/base_configs/test_file.go.erb
@@ -1,4 +1,4 @@
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
@@ -6,7 +6,6 @@ import (
"fmt"
"testing"
- "github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)
<%
@@ -40,20 +39,23 @@ object.examples
-%>
func TestAcc<%= test_slug -%>(t *testing.T) {
+<% if example.skip_vcr -%>
+ skipIfVcr(t)
+<% end -%>
t.Parallel()
context := map[string]interface{} {
-<%= lines(indent(compile('templates/terraform/env_var_context.go.erb'), 4)) -%>
+<%= lines(indent(compile(pwd + '/templates/terraform/env_var_context.go.erb'), 4)) -%>
<% unless example.test_vars_overrides.nil? -%>
<% example.test_vars_overrides.each do |var_name, override| -%>
"<%= var_name %>": <%= override %>,
<% end -%>
<% end -%>
- "random_suffix": acctest.RandString(10),
+ "random_suffix": randString(t, 10),
}
<% versioned_provider = !example_version.nil? && example_version != 'ga' -%>
- resource.Test(t, resource.TestCase{
+ vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
<% unless versioned_provider -%>
Providers: testAccProviders,
@@ -61,7 +63,7 @@ func TestAcc<%= test_slug -%>(t *testing.T) {
Providers: testAccProvidersOiCS,
<% end -%>
<% unless object.skip_delete -%>
- CheckDestroy: testAccCheck<%= "#{resource_name}" -%>Destroy,
+ CheckDestroy: testAccCheck<%= "#{resource_name}" -%>DestroyProducer(t),
<% end -%>
Steps: []resource.TestStep{
{
@@ -83,37 +85,39 @@ func TestAcc<%= test_slug -%>(t *testing.T) {
}
func testAcc<%= test_slug -%>(context map[string]interface{}) string {
-<%= example.config_test -%>
+<%= example.config_test(pwd) -%>
}
<%- end %>
<% unless object.skip_delete -%>
-func testAccCheck<%= resource_name -%>Destroy(s *terraform.State) error {
- for name, rs := range s.RootModule().Resources {
- if rs.Type != "<%= terraform_name -%>" {
- continue
- }
- if strings.HasPrefix(name, "data.") {
- continue
- }
-
- <% if object.custom_code.test_check_destroy -%>
-<%= lines(compile(object.custom_code.test_check_destroy)) -%>
- <% else -%>
- config := testAccProvider.Meta().(*Config)
+func testAccCheck<%= resource_name -%>DestroyProducer(t *testing.T) func(s *terraform.State) error {
+ return func(s *terraform.State) error {
+ for name, rs := range s.RootModule().Resources {
+ if rs.Type != "<%= terraform_name -%>" {
+ continue
+ }
+ if strings.HasPrefix(name, "data.") {
+ continue
+ }
+
+ <% if object.custom_code.test_check_destroy -%>
+ <%= lines(compile(pwd + '/' + object.custom_code.test_check_destroy)) -%>
+ <% else -%>
+ config := googleProviderConfig(t)
- url, err := replaceVarsForTest(config, rs, "<%= "{{#{object.__product.name}BasePath}}#{object.self_link_uri}" -%>")
- if err != nil {
- return err
- }
+ url, err := replaceVarsForTest(config, rs, "<%= "{{#{object.__product.name}BasePath}}#{object.self_link_uri}" -%>")
+ if err != nil {
+ return err
+ }
- _, err = sendRequest(config, "<%= object.read_verb.to_s.upcase -%>", "", url, nil<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
- if err == nil {
- return fmt.Errorf("<%= resource_name -%> still exists at %s", url)
+ _, err = sendRequest(config, "<%= object.read_verb.to_s.upcase -%>", "", url, nil<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
+ if err == nil {
+ return fmt.Errorf("<%= resource_name -%> still exists at %s", url)
+ }
+ <% end -%>
}
- <% end -%>
- }
- return nil
+ return nil
+ }
}
-<%- end %>
\ No newline at end of file
+<% end -%>
diff --git a/templates/terraform/examples/bigquery_connection_basic.tf.erb b/templates/terraform/examples/bigquery_connection_basic.tf.erb
new file mode 100644
index 000000000000..5e1f8beb4630
--- /dev/null
+++ b/templates/terraform/examples/bigquery_connection_basic.tf.erb
@@ -0,0 +1,42 @@
+resource "google_sql_database_instance" "instance" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['database_instance_name'] %>"
+ database_version = "POSTGRES_11"
+ region = "us-central1"
+ settings {
+ tier = "db-f1-micro"
+ }
+}
+
+resource "google_sql_database" "db" {
+ provider = google-beta
+ instance = google_sql_database_instance.instance.name
+ name = "db"
+}
+
+resource "random_password" "pwd" {
+ length = 16
+ special = false
+}
+
+resource "google_sql_user" "user" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['username'] %>"
+ instance = google_sql_database_instance.instance.name
+ password = random_password.pwd.result
+}
+
+resource "google_bigquery_connection" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ friendly_name = "👋"
+ description = "a riveting description"
+ cloud_sql {
+ instance_id = google_sql_database_instance.instance.connection_name
+ database = google_sql_database.db.name
+ type = "POSTGRES"
+ credential {
+ username = google_sql_user.user.name
+ password = google_sql_user.user.password
+ }
+ }
+}
diff --git a/templates/terraform/examples/bigquery_connection_full.tf.erb b/templates/terraform/examples/bigquery_connection_full.tf.erb
new file mode 100644
index 000000000000..07291bc69538
--- /dev/null
+++ b/templates/terraform/examples/bigquery_connection_full.tf.erb
@@ -0,0 +1,44 @@
+resource "google_sql_database_instance" "instance" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['database_instance_name'] %>"
+ database_version = "POSTGRES_11"
+ region = "us-central1"
+ settings {
+ tier = "db-f1-micro"
+ }
+}
+
+resource "google_sql_database" "db" {
+ provider = google-beta
+ instance = google_sql_database_instance.instance.name
+ name = "db"
+}
+
+resource "random_password" "pwd" {
+ length = 16
+ special = false
+}
+
+resource "google_sql_user" "user" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['username'] %>"
+ instance = google_sql_database_instance.instance.name
+ password = random_password.pwd.result
+}
+
+resource "google_bigquery_connection" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ connection_id = "<%= ctx[:vars]['connection_id'] %>"
+ location = "US"
+ friendly_name = "👋"
+ description = "a riveting description"
+ cloud_sql {
+ instance_id = google_sql_database_instance.instance.connection_name
+ database = google_sql_database.db.name
+ type = "POSTGRES"
+ credential {
+ username = google_sql_user.user.name
+ password = google_sql_user.user.password
+ }
+ }
+}
diff --git a/templates/terraform/examples/bigquery_dataset_cmek.tf.erb b/templates/terraform/examples/bigquery_dataset_cmek.tf.erb
index 5bec43c07e05..589c400ba84b 100644
--- a/templates/terraform/examples/bigquery_dataset_cmek.tf.erb
+++ b/templates/terraform/examples/bigquery_dataset_cmek.tf.erb
@@ -6,13 +6,13 @@ resource "google_bigquery_dataset" "<%= ctx[:primary_resource_id] %>" {
default_table_expiration_ms = 3600000
default_encryption_configuration {
- kms_key_name = google_kms_crypto_key.crypto_key.self_link
+ kms_key_name = google_kms_crypto_key.crypto_key.id
}
}
resource "google_kms_crypto_key" "crypto_key" {
name = "<%= ctx[:vars]['key_name'] %>"
- key_ring = google_kms_key_ring.key_ring.self_link
+ key_ring = google_kms_key_ring.key_ring.id
}
resource "google_kms_key_ring" "key_ring" {
diff --git a/templates/terraform/examples/bigquery_job_copy.tf.erb b/templates/terraform/examples/bigquery_job_copy.tf.erb
new file mode 100644
index 000000000000..a827a1bf6c36
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_copy.tf.erb
@@ -0,0 +1,122 @@
+resource "google_bigquery_table" "source" {
+ count = length(google_bigquery_dataset.source)
+
+ dataset_id = google_bigquery_dataset.source[count.index].dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_${count.index}_table"
+
+ schema = <" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ copy {
+ source_tables {
+ project_id = google_bigquery_table.source.0.project
+ dataset_id = google_bigquery_table.source.0.dataset_id
+ table_id = google_bigquery_table.source.0.table_id
+ }
+
+ source_tables {
+ project_id = google_bigquery_table.source.1.project
+ dataset_id = google_bigquery_table.source.1.dataset_id
+ table_id = google_bigquery_table.source.1.table_id
+ }
+
+ destination_table {
+ project_id = google_bigquery_table.dest.project
+ dataset_id = google_bigquery_table.dest.dataset_id
+ table_id = google_bigquery_table.dest.table_id
+ }
+
+ destination_encryption_configuration {
+ kms_key_name = google_kms_crypto_key.crypto_key.id
+ }
+ }
+
+ depends_on = ["google_project_iam_member.encrypt_role"]
+}
diff --git a/templates/terraform/examples/bigquery_job_copy_table_reference.tf.erb b/templates/terraform/examples/bigquery_job_copy_table_reference.tf.erb
new file mode 100644
index 000000000000..3083a5b87505
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_copy_table_reference.tf.erb
@@ -0,0 +1,116 @@
+resource "google_bigquery_table" "source" {
+ count = length(google_bigquery_dataset.source)
+
+ dataset_id = google_bigquery_dataset.source[count.index].dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_${count.index}_table"
+
+ schema = <" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ copy {
+ source_tables {
+ table_id = google_bigquery_table.source.0.id
+ }
+
+ source_tables {
+ table_id = google_bigquery_table.source.1.id
+ }
+
+ destination_table {
+ table_id = google_bigquery_table.dest.id
+ }
+
+ destination_encryption_configuration {
+ kms_key_name = google_kms_crypto_key.crypto_key.id
+ }
+ }
+
+ depends_on = ["google_project_iam_member.encrypt_role"]
+}
diff --git a/templates/terraform/examples/bigquery_job_extract.tf.erb b/templates/terraform/examples/bigquery_job_extract.tf.erb
new file mode 100644
index 000000000000..58f008dd384d
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_extract.tf.erb
@@ -0,0 +1,54 @@
+resource "google_bigquery_table" "source-one" {
+ dataset_id = google_bigquery_dataset.source-one.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+
+ schema = <" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ extract {
+ destination_uris = ["${google_storage_bucket.dest.url}/extract"]
+
+ source_table {
+ project_id = google_bigquery_table.source-one.project
+ dataset_id = google_bigquery_table.source-one.dataset_id
+ table_id = google_bigquery_table.source-one.table_id
+ }
+
+ destination_format = "NEWLINE_DELIMITED_JSON"
+ compression = "GZIP"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_job_extract_table_reference.tf.erb b/templates/terraform/examples/bigquery_job_extract_table_reference.tf.erb
new file mode 100644
index 000000000000..0a2ce51ea1b0
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_extract_table_reference.tf.erb
@@ -0,0 +1,52 @@
+resource "google_bigquery_table" "source-one" {
+ dataset_id = google_bigquery_dataset.source-one.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+
+ schema = <" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ extract {
+ destination_uris = ["${google_storage_bucket.dest.url}/extract"]
+
+ source_table {
+ table_id = google_bigquery_table.source-one.id
+ }
+
+ destination_format = "NEWLINE_DELIMITED_JSON"
+ compression = "GZIP"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_job_load.tf.erb b/templates/terraform/examples/bigquery_job_load.tf.erb
new file mode 100644
index 000000000000..3643a86492f8
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_load.tf.erb
@@ -0,0 +1,37 @@
+resource "google_bigquery_table" "foo" {
+ dataset_id = google_bigquery_dataset.bar.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+}
+
+resource "google_bigquery_dataset" "bar" {
+ dataset_id = "<%= ctx[:vars]['job_id'] %>_dataset"
+ friendly_name = "test"
+ description = "This is a test description"
+ location = "US"
+}
+
+resource "google_bigquery_job" "<%= ctx[:primary_resource_id] %>" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ labels = {
+ "my_job" ="load"
+ }
+
+ load {
+ source_uris = [
+ "gs://cloud-samples-data/bigquery/us-states/us-states-by-date.csv",
+ ]
+
+ destination_table {
+ project_id = google_bigquery_table.foo.project
+ dataset_id = google_bigquery_table.foo.dataset_id
+ table_id = google_bigquery_table.foo.table_id
+ }
+
+ skip_leading_rows = 1
+ schema_update_options = ["ALLOW_FIELD_RELAXATION", "ALLOW_FIELD_ADDITION"]
+
+ write_disposition = "WRITE_APPEND"
+ autodetect = true
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_job_load_table_reference.tf.erb b/templates/terraform/examples/bigquery_job_load_table_reference.tf.erb
new file mode 100644
index 000000000000..c9a07cb92962
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_load_table_reference.tf.erb
@@ -0,0 +1,35 @@
+resource "google_bigquery_table" "foo" {
+ dataset_id = google_bigquery_dataset.bar.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+}
+
+resource "google_bigquery_dataset" "bar" {
+ dataset_id = "<%= ctx[:vars]['job_id'] %>_dataset"
+ friendly_name = "test"
+ description = "This is a test description"
+ location = "US"
+}
+
+resource "google_bigquery_job" "<%= ctx[:primary_resource_id] %>" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ labels = {
+ "my_job" ="load"
+ }
+
+ load {
+ source_uris = [
+ "gs://cloud-samples-data/bigquery/us-states/us-states-by-date.csv",
+ ]
+
+ destination_table {
+ table_id = google_bigquery_table.foo.id
+ }
+
+ skip_leading_rows = 1
+ schema_update_options = ["ALLOW_FIELD_RELAXATION", "ALLOW_FIELD_ADDITION"]
+
+ write_disposition = "WRITE_APPEND"
+ autodetect = true
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_job_query.tf.erb b/templates/terraform/examples/bigquery_job_query.tf.erb
new file mode 100644
index 000000000000..c848701ef448
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_query.tf.erb
@@ -0,0 +1,36 @@
+resource "google_bigquery_table" "foo" {
+ dataset_id = google_bigquery_dataset.bar.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+}
+
+resource "google_bigquery_dataset" "bar" {
+ dataset_id = "<%= ctx[:vars]['job_id'] %>_dataset"
+ friendly_name = "test"
+ description = "This is a test description"
+ location = "US"
+}
+
+resource "google_bigquery_job" "<%= ctx[:primary_resource_id] %>" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ labels = {
+ "example-label" ="example-value"
+ }
+
+ query {
+ query = "SELECT state FROM [lookerdata:cdc.project_tycho_reports]"
+
+ destination_table {
+ project_id = google_bigquery_table.foo.project
+ dataset_id = google_bigquery_table.foo.dataset_id
+ table_id = google_bigquery_table.foo.table_id
+ }
+
+ allow_large_results = true
+ flatten_results = true
+
+ script_options {
+ key_result_statement = "LAST"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_job_query_table_reference.tf.erb b/templates/terraform/examples/bigquery_job_query_table_reference.tf.erb
new file mode 100644
index 000000000000..52e34e0b79dc
--- /dev/null
+++ b/templates/terraform/examples/bigquery_job_query_table_reference.tf.erb
@@ -0,0 +1,38 @@
+resource "google_bigquery_table" "foo" {
+ dataset_id = google_bigquery_dataset.bar.dataset_id
+ table_id = "<%= ctx[:vars]['job_id'] %>_table"
+}
+
+resource "google_bigquery_dataset" "bar" {
+ dataset_id = "<%= ctx[:vars]['job_id'] %>_dataset"
+ friendly_name = "test"
+ description = "This is a test description"
+ location = "US"
+}
+
+resource "google_bigquery_job" "<%= ctx[:primary_resource_id] %>" {
+ job_id = "<%= ctx[:vars]['job_id'] %>"
+
+ labels = {
+ "example-label" ="example-value"
+ }
+
+ query {
+ query = "SELECT state FROM [lookerdata:cdc.project_tycho_reports]"
+
+ destination_table {
+ table_id = google_bigquery_table.foo.id
+ }
+
+ default_dataset {
+ dataset_id = google_bigquery_dataset.bar.id
+ }
+
+ allow_large_results = true
+ flatten_results = true
+
+ script_options {
+ key_result_statement = "LAST"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/bigquery_reservation_basic.tf.erb b/templates/terraform/examples/bigquery_reservation_basic.tf.erb
index 2bb683049da8..f1c5754927ad 100644
--- a/templates/terraform/examples/bigquery_reservation_basic.tf.erb
+++ b/templates/terraform/examples/bigquery_reservation_basic.tf.erb
@@ -5,5 +5,5 @@ resource "google_bigquery_reservation" "<%= ctx[:primary_resource_id] %>" {
// Set to 0 for testing purposes
// In reality this would be larger than zero
slot_capacity = 0
- ignore_idle_slots = true
+ ignore_idle_slots = false
}
\ No newline at end of file
diff --git a/templates/terraform/examples/scheduled_query.tf.erb b/templates/terraform/examples/bigquerydatatransfer_config_scheduled_query.tf.erb
similarity index 95%
rename from templates/terraform/examples/scheduled_query.tf.erb
rename to templates/terraform/examples/bigquerydatatransfer_config_scheduled_query.tf.erb
index 2c5ae0b1c57d..bd7ed87b04a3 100644
--- a/templates/terraform/examples/scheduled_query.tf.erb
+++ b/templates/terraform/examples/bigquerydatatransfer_config_scheduled_query.tf.erb
@@ -15,7 +15,7 @@ resource "google_bigquery_data_transfer_config" "<%= ctx[:primary_resource_id] %
schedule = "first sunday of quarter 00:00"
destination_dataset_id = google_bigquery_dataset.my_dataset.dataset_id
params = {
- destination_table_name_template = "my-table"
+ destination_table_name_template = "my_table"
write_disposition = "WRITE_APPEND"
query = "SELECT name FROM tabl WHERE x = 'y'"
}
diff --git a/templates/terraform/examples/bigtable_app_profile_multicluster.tf.erb b/templates/terraform/examples/bigtable_app_profile_multicluster.tf.erb
index 52748eeb377b..4314b7728b5e 100644
--- a/templates/terraform/examples/bigtable_app_profile_multicluster.tf.erb
+++ b/templates/terraform/examples/bigtable_app_profile_multicluster.tf.erb
@@ -6,6 +6,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}
+
+ deletion_protection = "<%= ctx[:vars]['deletion_protection'] %>"
}
resource "google_bigtable_app_profile" "ap" {
diff --git a/templates/terraform/examples/bigtable_app_profile_singlecluster.tf.erb b/templates/terraform/examples/bigtable_app_profile_singlecluster.tf.erb
index 3aee678a14fe..3e76ca678e37 100644
--- a/templates/terraform/examples/bigtable_app_profile_singlecluster.tf.erb
+++ b/templates/terraform/examples/bigtable_app_profile_singlecluster.tf.erb
@@ -6,6 +6,8 @@ resource "google_bigtable_instance" "instance" {
num_nodes = 3
storage_type = "HDD"
}
+
+ deletion_protection = "<%= ctx[:vars]['deletion_protection'] %>"
}
resource "google_bigtable_app_profile" "ap" {
diff --git a/templates/terraform/examples/cloud_asset_folder_feed.tf.erb b/templates/terraform/examples/cloud_asset_folder_feed.tf.erb
new file mode 100644
index 000000000000..34fe8e58850a
--- /dev/null
+++ b/templates/terraform/examples/cloud_asset_folder_feed.tf.erb
@@ -0,0 +1,51 @@
+# Create a feed that sends notifications about network resource updates under a
+# particular folder.
+resource "google_cloud_asset_folder_feed" "<%= ctx[:primary_resource_id] %>" {
+ billing_project = "<%= ctx[:test_env_vars]["project"] %>"
+ folder = google_folder.my_folder.folder_id
+ feed_id = "<%= ctx[:vars]["feed_id"] %>"
+ content_type = "RESOURCE"
+
+ asset_types = [
+ "compute.googleapis.com/Subnetwork",
+ "compute.googleapis.com/Network",
+ ]
+
+ feed_output_config {
+ pubsub_destination {
+ topic = google_pubsub_topic.feed_output.id
+ }
+ }
+
+ # Wait for the permission to be ready on the destination topic.
+ depends_on = [
+ google_pubsub_topic_iam_member.cloud_asset_writer,
+ ]
+}
+
+# The topic where the resource change notifications will be sent.
+resource "google_pubsub_topic" "feed_output" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ name = "<%= ctx[:vars]["feed_id"] %>"
+}
+
+# The folder that will be monitored for resource updates.
+resource "google_folder" "my_folder" {
+ display_name = "<%= ctx[:vars]["folder_name"] %>"
+ parent = "organizations/<%= ctx[:test_env_vars]["org_id"] %>"
+}
+
+# Find the project number of the project whose identity will be used for sending
+# the asset change notifications.
+data "google_project" "project" {
+ project_id = "<%= ctx[:test_env_vars]["project"] %>"
+}
+
+# Allow the publishing role to the Cloud Asset service account of the project that
+# was used for sending the notifications.
+resource "google_pubsub_topic_iam_member" "cloud_asset_writer" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ topic = google_pubsub_topic.feed_output.id
+ role = "roles/pubsub.publisher"
+ member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-cloudasset.iam.gserviceaccount.com"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/cloud_asset_organization_feed.tf.erb b/templates/terraform/examples/cloud_asset_organization_feed.tf.erb
new file mode 100644
index 000000000000..7546b178d35e
--- /dev/null
+++ b/templates/terraform/examples/cloud_asset_organization_feed.tf.erb
@@ -0,0 +1,45 @@
+# Create a feed that sends notifications about network resource updates under a
+# particular organization.
+resource "google_cloud_asset_organization_feed" "<%= ctx[:primary_resource_id] %>" {
+ billing_project = "<%= ctx[:test_env_vars]["project"] %>"
+ org_id = "<%= ctx[:test_env_vars]["org_id"] %>"
+ feed_id = "<%= ctx[:vars]["feed_id"] %>"
+ content_type = "RESOURCE"
+
+ asset_types = [
+ "compute.googleapis.com/Subnetwork",
+ "compute.googleapis.com/Network",
+ ]
+
+ feed_output_config {
+ pubsub_destination {
+ topic = google_pubsub_topic.feed_output.id
+ }
+ }
+
+ # Wait for the permission to be ready on the destination topic.
+ depends_on = [
+ google_pubsub_topic_iam_member.cloud_asset_writer,
+ ]
+}
+
+# The topic where the resource change notifications will be sent.
+resource "google_pubsub_topic" "feed_output" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ name = "<%= ctx[:vars]["feed_id"] %>"
+}
+
+# Find the project number of the project whose identity will be used for sending
+# the asset change notifications.
+data "google_project" "project" {
+ project_id = "<%= ctx[:test_env_vars]["project"] %>"
+}
+
+# Allow the publishing role to the Cloud Asset service account of the project that
+# was used for sending the notifications.
+resource "google_pubsub_topic_iam_member" "cloud_asset_writer" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ topic = google_pubsub_topic.feed_output.id
+ role = "roles/pubsub.publisher"
+ member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-cloudasset.iam.gserviceaccount.com"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/cloud_asset_project_feed.tf.erb b/templates/terraform/examples/cloud_asset_project_feed.tf.erb
new file mode 100644
index 000000000000..786f209e9481
--- /dev/null
+++ b/templates/terraform/examples/cloud_asset_project_feed.tf.erb
@@ -0,0 +1,43 @@
+# Create a feed that sends notifications about network resource updates.
+resource "google_cloud_asset_project_feed" "<%= ctx[:primary_resource_id] %>" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ feed_id = "<%= ctx[:vars]["feed_id"] %>"
+ content_type = "RESOURCE"
+
+ asset_types = [
+ "compute.googleapis.com/Subnetwork",
+ "compute.googleapis.com/Network",
+ ]
+
+ feed_output_config {
+ pubsub_destination {
+ topic = google_pubsub_topic.feed_output.id
+ }
+ }
+
+ # Wait for the permission to be ready on the destination topic.
+ depends_on = [
+ google_pubsub_topic_iam_member.cloud_asset_writer,
+ ]
+}
+
+# The topic where the resource change notifications will be sent.
+resource "google_pubsub_topic" "feed_output" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ name = "<%= ctx[:vars]["feed_id"] %>"
+}
+
+# Find the project number of the project whose identity will be used for sending
+# the asset change notifications.
+data "google_project" "project" {
+ project_id = "<%= ctx[:test_env_vars]["project"] %>"
+}
+
+# Allow the publishing role to the Cloud Asset service account of the project that
+# was used for sending the notifications.
+resource "google_pubsub_topic_iam_member" "cloud_asset_writer" {
+ project = "<%= ctx[:test_env_vars]["project"] %>"
+ topic = google_pubsub_topic.feed_output.id
+ role = "roles/pubsub.publisher"
+ member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-cloudasset.iam.gserviceaccount.com"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/cloud_identity_group_membership.tf.erb b/templates/terraform/examples/cloud_identity_group_membership.tf.erb
new file mode 100644
index 000000000000..d1edd447f956
--- /dev/null
+++ b/templates/terraform/examples/cloud_identity_group_membership.tf.erb
@@ -0,0 +1,42 @@
+resource "google_cloud_identity_group" "group" {
+ provider = google-beta
+ display_name = "<%= ctx[:vars]['id_group'] %>"
+
+ parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"
+
+ group_key {
+ id = "<%= ctx[:vars]['id_group'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ labels = {
+ "cloudidentity.googleapis.com/groups.discussion_forum" = ""
+ }
+}
+
+resource "google_cloud_identity_group" "child-group" {
+ provider = google-beta
+ display_name = "<%= ctx[:vars]['id_group'] %>-child"
+
+ parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"
+
+ group_key {
+ id = "<%= ctx[:vars]['id_group'] %>-child@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ labels = {
+ "cloudidentity.googleapis.com/groups.discussion_forum" = ""
+ }
+}
+
+resource "google_cloud_identity_group_membership" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ group = google_cloud_identity_group.group.id
+
+ member_key {
+ id = google_cloud_identity_group.child-group.group_key[0].id
+ }
+
+ roles {
+ name = "MEMBER"
+ }
+}
diff --git a/templates/terraform/examples/cloud_identity_group_membership_user.tf.erb b/templates/terraform/examples/cloud_identity_group_membership_user.tf.erb
new file mode 100644
index 000000000000..d3a708ec7ea3
--- /dev/null
+++ b/templates/terraform/examples/cloud_identity_group_membership_user.tf.erb
@@ -0,0 +1,31 @@
+resource "google_cloud_identity_group" "group" {
+ provider = google-beta
+ display_name = "<%= ctx[:vars]['id_group'] %>"
+
+ parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"
+
+ group_key {
+ id = "<%= ctx[:vars]['id_group'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ labels = {
+ "cloudidentity.googleapis.com/groups.discussion_forum" = ""
+ }
+}
+
+resource "google_cloud_identity_group_membership" "cloud_identity_group_membership_basic" {
+ provider = google-beta
+ group = google_cloud_identity_group.group.id
+
+ member_key {
+ id = "<%= ctx[:test_env_vars]['identity_user'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ roles {
+ name = "MEMBER"
+ }
+
+ roles {
+ name = "MANAGER"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/cloud_identity_groups_basic.tf.erb b/templates/terraform/examples/cloud_identity_groups_basic.tf.erb
new file mode 100644
index 000000000000..6b5ea7405134
--- /dev/null
+++ b/templates/terraform/examples/cloud_identity_groups_basic.tf.erb
@@ -0,0 +1,14 @@
+resource "google_cloud_identity_group" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ display_name = "<%= ctx[:vars]['id_group'] %>"
+
+ parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"
+
+ group_key {
+ id = "<%= ctx[:vars]['id_group'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ labels = {
+ "cloudidentity.googleapis.com/groups.discussion_forum" = ""
+ }
+}
diff --git a/templates/terraform/examples/cloud_identity_groups_full.tf.erb b/templates/terraform/examples/cloud_identity_groups_full.tf.erb
new file mode 100644
index 000000000000..2e01f47b5f97
--- /dev/null
+++ b/templates/terraform/examples/cloud_identity_groups_full.tf.erb
@@ -0,0 +1,26 @@
+resource "google_cloud_identity_group" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ display_name = "<%= ctx[:vars]['id_group'] %>"
+ description = "my new cloud identity group"
+
+ parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"
+
+ group_key {
+ id = "<%= ctx[:vars]['id_group'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ additional_group_keys {
+ id = "<%= ctx[:vars]['id_group'] %>-two@<%= ctx[:test_env_vars]['org_domain'] %>"
+ }
+
+ labels = {
+ "cloudidentity.googleapis.com/groups.discussion_forum" = ""
+ }
+
+ dynamic_group_metadata {
+ queries {
+ resource_type = "USER"
+ query = "organizations.department.exists(org, org.department=='engineering'"
+ }
+ }
+}
diff --git a/templates/terraform/examples/cloud_run_service_sql.tf.erb b/templates/terraform/examples/cloud_run_service_sql.tf.erb
index 42ab5d8b4f93..16d54ae53878 100644
--- a/templates/terraform/examples/cloud_run_service_sql.tf.erb
+++ b/templates/terraform/examples/cloud_run_service_sql.tf.erb
@@ -13,7 +13,7 @@ resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" {
annotations = {
"autoscaling.knative.dev/maxScale" = "1000"
"run.googleapis.com/cloudsql-instances" = "<%= ctx[:test_env_vars]['project'] %>:us-central1:${google_sql_database_instance.instance.name}"
- "run.googleapis.com/client-name" = "cloud-console"
+ "run.googleapis.com/client-name" = "terraform"
}
}
}
diff --git a/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb b/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb
new file mode 100644
index 000000000000..b3dcffce5a0a
--- /dev/null
+++ b/templates/terraform/examples/cloud_run_service_traffic_split.tf.erb
@@ -0,0 +1,26 @@
+resource "google_cloud_run_service" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloud_run_service_name'] %>"
+ location = "us-central1"
+
+ template {
+ spec {
+ containers {
+ image = "gcr.io/cloudrun/hello"
+ }
+ }
+ metadata {
+ name = "<%= ctx[:vars]['cloud_run_service_name'] %>-green"
+ }
+ }
+
+ traffic {
+ percent = 25
+ revision_name = "<%= ctx[:vars]['cloud_run_service_name'] %>-green"
+ }
+
+ traffic {
+ percent = 75
+ # This revision needs to already exist
+ revision_name = "<%= ctx[:vars]['cloud_run_service_name'] %>-blue"
+ }
+}
diff --git a/templates/terraform/examples/cloudiot_device_basic.tf.erb b/templates/terraform/examples/cloudiot_device_basic.tf.erb
new file mode 100644
index 000000000000..dbfd02b17e4d
--- /dev/null
+++ b/templates/terraform/examples/cloudiot_device_basic.tf.erb
@@ -0,0 +1,8 @@
+resource "google_cloudiot_registry" "registry" {
+ name = "<%= ctx[:vars]['cloudiot_device_registry_name'] %>"
+}
+
+resource "google_cloudiot_device" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloudiot_device_name'] %>"
+ registry = google_cloudiot_registry.registry.id
+}
diff --git a/templates/terraform/examples/cloudiot_device_full.tf.erb b/templates/terraform/examples/cloudiot_device_full.tf.erb
new file mode 100644
index 000000000000..0c3457d4029c
--- /dev/null
+++ b/templates/terraform/examples/cloudiot_device_full.tf.erb
@@ -0,0 +1,27 @@
+resource "google_cloudiot_registry" "registry" {
+ name = "<%= ctx[:vars]['cloudiot_device_registry_name'] %>"
+}
+
+resource "google_cloudiot_device" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloudiot_device_name'] %>"
+ registry = google_cloudiot_registry.registry.id
+
+ credentials {
+ public_key {
+ format = "RSA_PEM"
+ key = file("test-fixtures/rsa_public.pem")
+ }
+ }
+
+ blocked = false
+
+ log_level = "INFO"
+
+ metadata = {
+ test_key_1 = "test_value_1"
+ }
+
+ gateway_config {
+ gateway_type = "NON_GATEWAY"
+ }
+}
diff --git a/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb b/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb
new file mode 100644
index 000000000000..67bf5e108304
--- /dev/null
+++ b/templates/terraform/examples/cloudiot_device_registry_basic.tf.erb
@@ -0,0 +1,3 @@
+resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloudiot_registry_name'] %>"
+}
diff --git a/templates/terraform/examples/cloudiot_device_registry_full.tf.erb b/templates/terraform/examples/cloudiot_device_registry_full.tf.erb
new file mode 100644
index 000000000000..f5c11d9abdcc
--- /dev/null
+++ b/templates/terraform/examples/cloudiot_device_registry_full.tf.erb
@@ -0,0 +1,46 @@
+resource "google_pubsub_topic" "default-devicestatus" {
+ name = "<%= ctx[:vars]['cloudiot_device_status_topic_name'] %>"
+}
+
+resource "google_pubsub_topic" "default-telemetry" {
+ name = "<%= ctx[:vars]['cloudiot_device_telemetry_topic_name'] %>"
+}
+
+resource "google_pubsub_topic" "additional-telemetry" {
+ name = "<%= ctx[:vars]['cloudiot_additional_device_telemetry_topic_name'] %>"
+}
+
+resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloudiot_registry_name'] %>"
+
+ event_notification_configs {
+ pubsub_topic_name = google_pubsub_topic.additional-telemetry.id
+ subfolder_matches = "<%= ctx[:vars]['cloudiot_subfolder_matches_additional_device_telemetry_topic'] %>"
+ }
+
+ event_notification_configs {
+ pubsub_topic_name = google_pubsub_topic.default-telemetry.id
+ subfolder_matches = ""
+ }
+
+ state_notification_config = {
+ pubsub_topic_name = google_pubsub_topic.default-devicestatus.id
+ }
+
+ mqtt_config = {
+ mqtt_enabled_state = "MQTT_ENABLED"
+ }
+
+ http_config = {
+ http_enabled_state = "HTTP_ENABLED"
+ }
+
+ log_level = "INFO"
+
+ credentials {
+ public_key_certificate = {
+ format = "X509_CERTIFICATE_PEM"
+ certificate = file("test-fixtures/rsa_cert.pem")
+ }
+ }
+}
diff --git a/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb b/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb
new file mode 100644
index 000000000000..45139229a27c
--- /dev/null
+++ b/templates/terraform/examples/cloudiot_device_registry_single_event_notification_configs.tf.erb
@@ -0,0 +1,13 @@
+resource "google_pubsub_topic" "default-telemetry" {
+ name = "<%= ctx[:vars]['cloudiot_device_telemetry_topic_name'] %>"
+}
+
+resource "google_cloudiot_registry" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['cloudiot_registry_name'] %>"
+
+ event_notification_configs {
+ pubsub_topic_name = google_pubsub_topic.default-telemetry.id
+ subfolder_matches = ""
+ }
+
+}
diff --git a/templates/terraform/examples/compute_packet_mirroring_full.tf.erb b/templates/terraform/examples/compute_packet_mirroring_full.tf.erb
index fddffadab0ec..07ea295f8908 100644
--- a/templates/terraform/examples/compute_packet_mirroring_full.tf.erb
+++ b/templates/terraform/examples/compute_packet_mirroring_full.tf.erb
@@ -10,7 +10,7 @@ resource "google_compute_instance" "mirror" {
}
network_interface {
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
access_config {
}
}
@@ -21,15 +21,15 @@ resource "google_compute_packet_mirroring" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
description = "bar"
network {
- url = google_compute_network.default.self_link
+ url = google_compute_network.default.id
}
collector_ilb {
- url = google_compute_forwarding_rule.default.self_link
+ url = google_compute_forwarding_rule.default.id
}
mirrored_resources {
tags = ["foo"]
instances {
- url = google_compute_instance.mirror.self_link
+ url = google_compute_instance.mirror.id
}
}
filter {
@@ -45,7 +45,7 @@ resource "google_compute_network" "default" {
resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['subnetwork_name'] %>"
provider = google-beta
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
ip_cidr_range = "10.2.0.0/16"
}
@@ -53,7 +53,7 @@ resource "google_compute_subnetwork" "default" {
resource "google_compute_region_backend_service" "default" {
name = "<%= ctx[:vars]['service_name'] %>"
provider = google-beta
- health_checks = ["${google_compute_health_check.default.self_link}"]
+ health_checks = [google_compute_health_check.default.id]
}
resource "google_compute_health_check" "default" {
@@ -74,9 +74,9 @@ resource "google_compute_forwarding_rule" "default" {
is_mirroring_collector = true
ip_protocol = "TCP"
load_balancing_scheme = "INTERNAL"
- backend_service = google_compute_region_backend_service.default.self_link
+ backend_service = google_compute_region_backend_service.default.id
all_ports = true
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
network_tier = "PREMIUM"
}
diff --git a/templates/terraform/examples/container_analysis_note_attestation_full.tf.erb b/templates/terraform/examples/container_analysis_note_attestation_full.tf.erb
new file mode 100644
index 000000000000..994ec46b55d0
--- /dev/null
+++ b/templates/terraform/examples/container_analysis_note_attestation_full.tf.erb
@@ -0,0 +1,22 @@
+resource "google_container_analysis_note" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]["note_name"] %>"
+
+ short_description = "test note"
+ long_description = "a longer description of test note"
+ expiration_time = "2120-10-02T15:01:23.045123456Z"
+
+ related_url {
+ url = "some.url"
+ label = "foo"
+ }
+
+ related_url {
+ url = "google.com"
+ }
+
+ attestation_authority {
+ hint {
+ human_readable_name = "Attestor Note"
+ }
+ }
+}
diff --git a/templates/terraform/examples/container_analysis_occurence_attestation.tf.erb b/templates/terraform/examples/container_analysis_occurence_attestation.tf.erb
new file mode 100644
index 000000000000..8d0fceec2b8d
--- /dev/null
+++ b/templates/terraform/examples/container_analysis_occurence_attestation.tf.erb
@@ -0,0 +1,35 @@
+resource "google_binary_authorization_attestor" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]["attestor_name"] %>"
+ attestation_authority_note {
+ note_reference = google_container_analysis_note.note.name
+ public_keys {
+ ascii_armored_pgp_public_key = <"
+ attestation_authority {
+ hint {
+ human_readable_name = "Attestor Note"
+ }
+ }
+}
diff --git a/templates/terraform/examples/container_analysis_occurrence_kms.tf.erb b/templates/terraform/examples/container_analysis_occurrence_kms.tf.erb
new file mode 100644
index 000000000000..505393076c54
--- /dev/null
+++ b/templates/terraform/examples/container_analysis_occurrence_kms.tf.erb
@@ -0,0 +1,51 @@
+resource "google_binary_authorization_attestor" "attestor" {
+ name = "<%= ctx[:vars]["attestor"] %>"
+ attestation_authority_note {
+ note_reference = google_container_analysis_note.note.name
+ public_keys {
+ id = data.google_kms_crypto_key_version.version.id
+ pkix_public_key {
+ public_key_pem = data.google_kms_crypto_key_version.version.public_key[0].pem
+ signature_algorithm = data.google_kms_crypto_key_version.version.public_key[0].algorithm
+ }
+ }
+ }
+}
+
+resource "google_container_analysis_note" "note" {
+ name = "<%= ctx[:vars]["note_name"] %>"
+ attestation_authority {
+ hint {
+ human_readable_name = "Attestor Note"
+ }
+ }
+}
+
+data "google_kms_key_ring" "keyring" {
+ name = "my-key-ring"
+ location = "global"
+}
+
+data "google_kms_crypto_key" "crypto-key" {
+ name = "my-key"
+ key_ring = data.google_kms_key_ring.keyring.self_link
+}
+
+data "google_kms_crypto_key_version" "version" {
+ crypto_key = data.google_kms_crypto_key.crypto-key.self_link
+}
+
+resource "google_container_analysis_occurrence" "<%= ctx[:primary_resource_id] %>" {
+ resource_uri = "gcr.io/my-project/my-image"
+ note_name = google_container_analysis_note.note.id
+
+ // See "Creating Attestations" Guide for expected
+ // payload and signature formats.
+ attestation {
+ serialized_payload = filebase64("path/to/my/payload.json")
+ signatures {
+ public_key_id = data.google_kms_crypto_key_version.version.id
+ serialized_payload = filebase64("path/to/my/payload.json.sig")
+ }
+ }
+}
diff --git a/templates/terraform/examples/data_catalog_entry_basic.tf.erb b/templates/terraform/examples/data_catalog_entry_basic.tf.erb
new file mode 100644
index 000000000000..b59545415f74
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_basic.tf.erb
@@ -0,0 +1,11 @@
+resource "google_data_catalog_entry" "<%= ctx[:primary_resource_id] %>" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['entry_id'] %>"
+
+ user_specified_type = "my_custom_type"
+ user_specified_system = "SomethingExternal"
+}
+
+resource "google_data_catalog_entry_group" "entry_group" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/data_catalog_entry_fileset.tf.erb b/templates/terraform/examples/data_catalog_entry_fileset.tf.erb
new file mode 100644
index 000000000000..ad7ea3e213b2
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_fileset.tf.erb
@@ -0,0 +1,14 @@
+resource "google_data_catalog_entry" "<%= ctx[:primary_resource_id] %>" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['entry_id'] %>"
+
+ type = "FILESET"
+
+ gcs_fileset_spec {
+ file_patterns = ["gs://fake_bucket/dir/*"]
+ }
+}
+
+resource "google_data_catalog_entry_group" "entry_group" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/data_catalog_entry_full.tf.erb b/templates/terraform/examples/data_catalog_entry_full.tf.erb
new file mode 100644
index 000000000000..56d995b91bff
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_full.tf.erb
@@ -0,0 +1,54 @@
+resource "google_data_catalog_entry" "<%= ctx[:primary_resource_id] %>" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['entry_id'] %>"
+
+ user_specified_type = "my_user_specified_type"
+ user_specified_system = "Something_custom"
+ linked_resource = "my/linked/resource"
+
+ display_name = "my custom type entry"
+ description = "a custom type entry for a user specified system"
+
+ schema = <" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+}
diff --git a/templates/terraform/examples/data_catalog_entry_group_full.tf.erb b/templates/terraform/examples/data_catalog_entry_group_full.tf.erb
new file mode 100644
index 000000000000..0aea77513532
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_group_full.tf.erb
@@ -0,0 +1,6 @@
+resource "google_data_catalog_entry_group" "<%= ctx[:primary_resource_id] %>" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+
+ display_name = "terraform entry group"
+ description = "entry group created by Terraform"
+}
diff --git a/templates/terraform/examples/data_catalog_entry_group_tag.tf.erb b/templates/terraform/examples/data_catalog_entry_group_tag.tf.erb
new file mode 100644
index 000000000000..3eddbfe6e767
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_group_tag.tf.erb
@@ -0,0 +1,72 @@
+resource "google_data_catalog_entry" "first_entry" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['first_entry'] %>"
+
+ user_specified_type = "my_custom_type"
+ user_specified_system = "SomethingExternal"
+}
+
+resource "google_data_catalog_entry" "second_entry" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['second_entry'] %>"
+
+ user_specified_type = "another_custom_type"
+ user_specified_system = "SomethingElseExternal"
+}
+
+resource "google_data_catalog_entry_group" "entry_group" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+}
+
+resource "google_data_catalog_tag_template" "tag_template" {
+ tag_template_id = "<%= ctx[:vars]['tag_template_id'] %>"
+ region = "us-central1"
+ display_name = "Demo Tag Template"
+
+ fields {
+ field_id = "source"
+ display_name = "Source of data asset"
+ type {
+ primitive_type = "STRING"
+ }
+ is_required = true
+ }
+
+ fields {
+ field_id = "num_rows"
+ display_name = "Number of rows in the data asset"
+ type {
+ primitive_type = "DOUBLE"
+ }
+ }
+
+ fields {
+ field_id = "pii_type"
+ display_name = "PII type"
+ type {
+ enum_type {
+ allowed_values {
+ display_name = "EMAIL"
+ }
+ allowed_values {
+ display_name = "SOCIAL SECURITY NUMBER"
+ }
+ allowed_values {
+ display_name = "NONE"
+ }
+ }
+ }
+ }
+
+ force_delete = "<%= ctx[:vars]['force_delete'] %>"
+}
+
+resource "google_data_catalog_tag" "<%= ctx[:primary_resource_id] %>" {
+ parent = google_data_catalog_entry_group.entry_group.id
+ template = google_data_catalog_tag_template.tag_template.id
+
+ fields {
+ field_name = "source"
+ string_value = "my-string"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/data_catalog_entry_tag_basic.tf.erb b/templates/terraform/examples/data_catalog_entry_tag_basic.tf.erb
new file mode 100644
index 000000000000..162f86409ec1
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_tag_basic.tf.erb
@@ -0,0 +1,64 @@
+resource "google_data_catalog_entry" "entry" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['entry_id'] %>"
+
+ user_specified_type = "my_custom_type"
+ user_specified_system = "SomethingExternal"
+}
+
+resource "google_data_catalog_entry_group" "entry_group" {
+ entry_group_id = "<%= ctx[:vars]['entry_group_id'] %>"
+}
+
+resource "google_data_catalog_tag_template" "tag_template" {
+ tag_template_id = "<%= ctx[:vars]['tag_template_id'] %>"
+ region = "us-central1"
+ display_name = "Demo Tag Template"
+
+ fields {
+ field_id = "source"
+ display_name = "Source of data asset"
+ type {
+ primitive_type = "STRING"
+ }
+ is_required = true
+ }
+
+ fields {
+ field_id = "num_rows"
+ display_name = "Number of rows in the data asset"
+ type {
+ primitive_type = "DOUBLE"
+ }
+ }
+
+ fields {
+ field_id = "pii_type"
+ display_name = "PII type"
+ type {
+ enum_type {
+ allowed_values {
+ display_name = "EMAIL"
+ }
+ allowed_values {
+ display_name = "SOCIAL SECURITY NUMBER"
+ }
+ allowed_values {
+ display_name = "NONE"
+ }
+ }
+ }
+ }
+
+ force_delete = "<%= ctx[:vars]['force_delete'] %>"
+}
+
+resource "google_data_catalog_tag" "<%= ctx[:primary_resource_id] %>" {
+ parent = google_data_catalog_entry.entry.id
+ template = google_data_catalog_tag_template.tag_template.id
+
+ fields {
+ field_name = "source"
+ string_value = "my-string"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/data_catalog_entry_tag_full.tf.erb b/templates/terraform/examples/data_catalog_entry_tag_full.tf.erb
new file mode 100644
index 000000000000..0eae34529a17
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_entry_tag_full.tf.erb
@@ -0,0 +1,132 @@
+resource "google_data_catalog_entry" "entry" {
+ entry_group = google_data_catalog_entry_group.entry_group.id
+ entry_id = "<%= ctx[:vars]['entry_id'] %>"
+
+ user_specified_type = "my_custom_type"
+ user_specified_system = "SomethingExternal"
+
+ schema = <" {
+ parent = google_data_catalog_entry.entry.id
+ template = google_data_catalog_tag_template.tag_template.id
+
+ fields {
+ field_name = "source"
+ string_value = "my-string"
+ }
+
+ fields {
+ field_name = "num_rows"
+ double_value = 5
+ }
+
+ fields {
+ field_name = "pii_type"
+ enum_value = "EMAIL"
+ }
+
+ column = "address"
+}
+
+resource "google_data_catalog_tag" "second-tag" {
+ parent = google_data_catalog_entry.entry.id
+ template = google_data_catalog_tag_template.tag_template.id
+
+ fields {
+ field_name = "source"
+ string_value = "my-string"
+ }
+
+ fields {
+ field_name = "pii_type"
+ enum_value = "NONE"
+ }
+
+ column = "first_name"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/data_catalog_tag_template_basic.tf.erb b/templates/terraform/examples/data_catalog_tag_template_basic.tf.erb
new file mode 100644
index 000000000000..02d0d67c20ab
--- /dev/null
+++ b/templates/terraform/examples/data_catalog_tag_template_basic.tf.erb
@@ -0,0 +1,42 @@
+resource "google_data_catalog_tag_template" "<%= ctx[:primary_resource_id] %>" {
+ tag_template_id = "<%= ctx[:vars]['tag_template_id'] %>"
+ region = "us-central1"
+ display_name = "Demo Tag Template"
+
+ fields {
+ field_id = "source"
+ display_name = "Source of data asset"
+ type {
+ primitive_type = "STRING"
+ }
+ is_required = true
+ }
+
+ fields {
+ field_id = "num_rows"
+ display_name = "Number of rows in the data asset"
+ type {
+ primitive_type = "DOUBLE"
+ }
+ }
+
+ fields {
+ field_id = "pii_type"
+ display_name = "PII type"
+ type {
+ enum_type {
+ allowed_values {
+ display_name = "EMAIL"
+ }
+ allowed_values {
+ display_name = "SOCIAL SECURITY NUMBER"
+ }
+ allowed_values {
+ display_name = "NONE"
+ }
+ }
+ }
+ }
+
+ force_delete = "<%= ctx[:vars]['force_delete'] %>"
+}
diff --git a/templates/terraform/examples/data_fusion_instance_full.tf.erb b/templates/terraform/examples/data_fusion_instance_full.tf.erb
index f1d47153f95c..91e9f6bff87e 100644
--- a/templates/terraform/examples/data_fusion_instance_full.tf.erb
+++ b/templates/terraform/examples/data_fusion_instance_full.tf.erb
@@ -14,4 +14,5 @@ resource "google_data_fusion_instance" "<%= ctx[:primary_resource_id] %>" {
network = "default"
ip_allocation = "10.89.48.0/22"
}
+ version = "6.1.1"
}
\ No newline at end of file
diff --git a/templates/terraform/examples/dialogflow_entity_type_basic.tf.erb b/templates/terraform/examples/dialogflow_entity_type_basic.tf.erb
new file mode 100644
index 000000000000..bafe6d533f82
--- /dev/null
+++ b/templates/terraform/examples/dialogflow_entity_type_basic.tf.erb
@@ -0,0 +1,19 @@
+resource "google_dialogflow_agent" "basic_agent" {
+ display_name = "example_agent"
+ default_language_code = "en"
+ time_zone = "America/New_York"
+}
+
+resource "google_dialogflow_entity_type" "<%= ctx[:primary_resource_id] %>" {
+ depends_on = [google_dialogflow_agent.basic_agent]
+ display_name = "<%= ctx[:vars]["entity_type_name"] %>"
+ kind = "KIND_MAP"
+ entities {
+ value = "value1"
+ synonyms = ["synonym1","synonym2"]
+ }
+ entities {
+ value = "value2"
+ synonyms = ["synonym3","synonym4"]
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/dns_managed_zone_private.tf.erb b/templates/terraform/examples/dns_managed_zone_private.tf.erb
index b3afb2178df1..2b6ca85e12ab 100644
--- a/templates/terraform/examples/dns_managed_zone_private.tf.erb
+++ b/templates/terraform/examples/dns_managed_zone_private.tf.erb
@@ -10,10 +10,10 @@ resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
private_visibility_config {
networks {
- network_url = google_compute_network.network-1.self_link
+ network_url = google_compute_network.network-1.id
}
networks {
- network_url = google_compute_network.network-2.self_link
+ network_url = google_compute_network.network-2.id
}
}
}
diff --git a/templates/terraform/examples/dns_managed_zone_private_forwarding.tf.erb b/templates/terraform/examples/dns_managed_zone_private_forwarding.tf.erb
index 6b38db0716d3..e5f49dd70e80 100644
--- a/templates/terraform/examples/dns_managed_zone_private_forwarding.tf.erb
+++ b/templates/terraform/examples/dns_managed_zone_private_forwarding.tf.erb
@@ -1,5 +1,4 @@
resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
name = "<%= ctx[:vars]['zone_name'] %>"
dns_name = "private.example.com."
description = "Example private DNS zone"
@@ -11,10 +10,10 @@ resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
private_visibility_config {
networks {
- network_url = google_compute_network.network-1.self_link
+ network_url = google_compute_network.network-1.id
}
networks {
- network_url = google_compute_network.network-2.self_link
+ network_url = google_compute_network.network-2.id
}
}
diff --git a/templates/terraform/examples/dns_managed_zone_private_peering.tf.erb b/templates/terraform/examples/dns_managed_zone_private_peering.tf.erb
index 129b1aa8e25d..e574801bafae 100644
--- a/templates/terraform/examples/dns_managed_zone_private_peering.tf.erb
+++ b/templates/terraform/examples/dns_managed_zone_private_peering.tf.erb
@@ -1,6 +1,4 @@
resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
-
name = "<%= ctx[:vars]['zone_name'] %>"
dns_name = "peering.example.com."
description = "Example private DNS peering zone"
@@ -9,32 +7,24 @@ resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
private_visibility_config {
networks {
- network_url = google_compute_network.network-source.self_link
+ network_url = google_compute_network.network-source.id
}
}
peering_config {
target_network {
- network_url = google_compute_network.network-target.self_link
+ network_url = google_compute_network.network-target.id
}
}
}
resource "google_compute_network" "network-source" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_source_name'] %>"
auto_create_subnetworks = false
}
resource "google_compute_network" "network-target" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_target_name'] %>"
auto_create_subnetworks = false
}
-provider "google-beta" {
- region = "us-central1"
- zone = "us-central1-a"
-}
diff --git a/templates/terraform/examples/dns_managed_zone_service_directory.tf.erb b/templates/terraform/examples/dns_managed_zone_service_directory.tf.erb
new file mode 100644
index 000000000000..6960aa263971
--- /dev/null
+++ b/templates/terraform/examples/dns_managed_zone_service_directory.tf.erb
@@ -0,0 +1,29 @@
+resource "google_dns_managed_zone" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+
+ name = "<%= ctx[:vars]['zone_name'] %>"
+ dns_name = "services.example.com."
+ description = "Example private DNS Service Directory zone"
+
+ visibility = "private"
+
+ service_directory_config {
+ namespace {
+ namespace_url = google_service_directory_namespace.example.id
+ }
+ }
+}
+
+resource "google_service_directory_namespace" "example" {
+ provider = google-beta
+
+ namespace_id = "example"
+ location = "us-central1"
+}
+
+resource "google_compute_network" "network" {
+ provider = google-beta
+
+ name = "<%= ctx[:vars]['network_name'] %>"
+ auto_create_subnetworks = false
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/dns_policy_basic.tf.erb b/templates/terraform/examples/dns_policy_basic.tf.erb
index 89b0f3f3b599..117499f69a31 100644
--- a/templates/terraform/examples/dns_policy_basic.tf.erb
+++ b/templates/terraform/examples/dns_policy_basic.tf.erb
@@ -1,6 +1,4 @@
resource "google_dns_policy" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
-
name = "<%= ctx[:vars]['policy_name'] %>"
enable_inbound_forwarding = true
@@ -16,28 +14,19 @@ resource "google_dns_policy" "<%= ctx[:primary_resource_id] %>" {
}
networks {
- network_url = google_compute_network.network-1.self_link
+ network_url = google_compute_network.network-1.id
}
networks {
- network_url = google_compute_network.network-2.self_link
+ network_url = google_compute_network.network-2.id
}
}
resource "google_compute_network" "network-1" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_1_name'] %>"
auto_create_subnetworks = false
}
resource "google_compute_network" "network-2" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_2_name'] %>"
auto_create_subnetworks = false
}
-
-provider "google-beta" {
- region = "us-central1"
- zone = "us-central1-a"
-}
diff --git a/templates/terraform/examples/external_vpn_gateway.tf.erb b/templates/terraform/examples/external_vpn_gateway.tf.erb
index 2b45778d9edd..8851c143be8a 100644
--- a/templates/terraform/examples/external_vpn_gateway.tf.erb
+++ b/templates/terraform/examples/external_vpn_gateway.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway" {
provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['ha_vpn_gateway_name'] %>"
- network = google_compute_network.network.self_link
+ network = google_compute_network.network.id
}
resource "google_compute_external_vpn_gateway" "external_gateway" {
@@ -28,7 +28,7 @@ resource "google_compute_subnetwork" "network_subnet1" {
name = "ha-vpn-subnet-1"
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
- network = google_compute_network.network.self_link
+ network = google_compute_network.network.id
}
resource "google_compute_subnetwork" "network_subnet2" {
@@ -36,7 +36,7 @@ resource "google_compute_subnetwork" "network_subnet2" {
name = "ha-vpn-subnet-2"
ip_cidr_range = "10.0.2.0/24"
region = "us-west1"
- network = google_compute_network.network.self_link
+ network = google_compute_network.network.id
}
resource "google_compute_router" "router1" {
@@ -52,11 +52,11 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
provider = google-beta
name = "ha-vpn-tunnel1"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway.self_link
- peer_external_gateway = google_compute_external_vpn_gateway.external_gateway.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway.id
+ peer_external_gateway = google_compute_external_vpn_gateway.external_gateway.id
peer_external_gateway_interface = 0
shared_secret = "a secret message"
- router = google_compute_router.router1.self_link
+ router = google_compute_router.router1.id
vpn_gateway_interface = 0
}
@@ -64,11 +64,11 @@ resource "google_compute_vpn_tunnel" "tunnel2" {
provider = google-beta
name = "ha-vpn-tunnel2"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway.self_link
- peer_external_gateway = google_compute_external_vpn_gateway.external_gateway.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway.id
+ peer_external_gateway = google_compute_external_vpn_gateway.external_gateway.id
peer_external_gateway_interface = 0
shared_secret = "a secret message"
- router = " ${google_compute_router.router1.self_link}"
+ router = " ${google_compute_router.router1.id}"
vpn_gateway_interface = 1
}
diff --git a/templates/terraform/examples/filestore_instance_full.tf.erb b/templates/terraform/examples/filestore_instance_full.tf.erb
new file mode 100644
index 000000000000..988dc0431ca6
--- /dev/null
+++ b/templates/terraform/examples/filestore_instance_full.tf.erb
@@ -0,0 +1,30 @@
+resource "google_filestore_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ zone = "us-central1-b"
+ tier = "BASIC_SSD"
+
+ file_shares {
+ capacity_gb = 2660
+ name = "share1"
+
+ nfs_export_options {
+ ip_ranges = ["10.0.0.0/24"]
+ access_mode = "READ_WRITE"
+ squash_mode = "NO_ROOT_SQUASH"
+ }
+
+ nfs_export_options {
+ ip_ranges = ["10.10.0.0/24"]
+ access_mode = "READ_ONLY"
+ squash_mode = "ROOT_SQUASH"
+ anon_uid = 123
+ anon_gid = 456
+ }
+ }
+
+ networks {
+ network = "default"
+ modes = ["MODE_IPV4"]
+ }
+}
diff --git a/templates/terraform/examples/firebase_web_app_basic.tf.erb b/templates/terraform/examples/firebase_web_app_basic.tf.erb
new file mode 100644
index 000000000000..5a7b4f99120e
--- /dev/null
+++ b/templates/terraform/examples/firebase_web_app_basic.tf.erb
@@ -0,0 +1,46 @@
+resource "google_project" "default" {
+ provider = google-beta
+
+ project_id = "tf-test%{random_suffix}"
+ name = "tf-test%{random_suffix}"
+ org_id = "<%= ctx[:test_env_vars]['org_id'] %>"
+}
+
+resource "google_firebase_project" "default" {
+ provider = google-beta
+ project = google_project.default.project_id
+}
+
+resource "google_firebase_web_app" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ project = google_project.default.project_id
+ display_name = "<%= ctx[:vars]['display_name'] %>"
+
+ depends_on = [google_firebase_project.default]
+}
+
+data "google_firebase_web_app_config" "basic" {
+ provider = google-beta
+ web_app_id = google_firebase_web_app.basic.app_id
+}
+
+resource "google_storage_bucket" "default" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['bucket_name'] %>"
+}
+
+resource "google_storage_bucket_object" "default" {
+ provider = google-beta
+ bucket = google_storage_bucket.default.name
+ name = "firebase-config.json"
+
+ content = jsonencode({
+ appId = google_firebase_web_app.basic.app_id
+ apiKey = data.google_firebase_web_app_config.basic.api_key
+ authDomain = data.google_firebase_web_app_config.basic.auth_domain
+ databaseURL = lookup(data.google_firebase_web_app_config.basic, "database_url", "")
+ storageBucket = lookup(data.google_firebase_web_app_config.basic, "storage_bucket", "")
+ messagingSenderId = lookup(data.google_firebase_web_app_config.basic, "messaging_sender_id", "")
+ measurementId = lookup(data.google_firebase_web_app_config.basic, "measurement_id", "")
+ })
+}
diff --git a/templates/terraform/examples/forwarding_rule_basic.tf.erb b/templates/terraform/examples/forwarding_rule_basic.tf.erb
index 47fa4a17245c..1774fdda51bb 100644
--- a/templates/terraform/examples/forwarding_rule_basic.tf.erb
+++ b/templates/terraform/examples/forwarding_rule_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_forwarding_rule" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['forwarding_rule_name'] %>"
- target = google_compute_target_pool.default.self_link
+ target = google_compute_target_pool.default.id
port_range = "80"
}
diff --git a/templates/terraform/examples/forwarding_rule_global_internallb.tf.erb b/templates/terraform/examples/forwarding_rule_global_internallb.tf.erb
index f8f96a8c84c1..baba424e88d8 100644
--- a/templates/terraform/examples/forwarding_rule_global_internallb.tf.erb
+++ b/templates/terraform/examples/forwarding_rule_global_internallb.tf.erb
@@ -3,16 +3,16 @@ resource "google_compute_forwarding_rule" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['forwarding_rule_name'] %>"
region = "us-central1"
load_balancing_scheme = "INTERNAL"
- backend_service = "${google_compute_region_backend_service.backend.self_link}"
+ backend_service = google_compute_region_backend_service.backend.id
all_ports = true
allow_global_access = true
- network = "${google_compute_network.default.name}"
- subnetwork = "${google_compute_subnetwork.default.name}"
+ network = google_compute_network.default.name
+ subnetwork = google_compute_subnetwork.default.name
}
resource "google_compute_region_backend_service" "backend" {
name = "<%= ctx[:vars]['backend_name'] %>"
region = "us-central1"
- health_checks = ["${google_compute_health_check.hc.self_link}"]
+ health_checks = [google_compute_health_check.hc.id]
}
resource "google_compute_health_check" "hc" {
name = "check-<%= ctx[:vars]['backend_name'] %>"
@@ -30,5 +30,5 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['network_name'] %>"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
- network = "${google_compute_network.default.self_link}"
-}
\ No newline at end of file
+ network = google_compute_network.default.id
+}
diff --git a/templates/terraform/examples/forwarding_rule_http_lb.tf.erb b/templates/terraform/examples/forwarding_rule_http_lb.tf.erb
index c7381e2dc9f2..b04eb8da4f97 100644
--- a/templates/terraform/examples/forwarding_rule_http_lb.tf.erb
+++ b/templates/terraform/examples/forwarding_rule_http_lb.tf.erb
@@ -8,9 +8,9 @@ resource "google_compute_forwarding_rule" "<%= ctx[:primary_resource_id] %>" {
ip_protocol = "TCP"
load_balancing_scheme = "INTERNAL_MANAGED"
port_range = "80"
- target = google_compute_region_target_http_proxy.default.self_link
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ target = google_compute_region_target_http_proxy.default.id
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
network_tier = "PREMIUM"
}
@@ -19,7 +19,7 @@ resource "google_compute_region_target_http_proxy" "default" {
region = "us-central1"
name = "<%= ctx[:vars]['region_target_http_proxy_name'] %>"
- url_map = google_compute_region_url_map.default.self_link
+ url_map = google_compute_region_url_map.default.id
}
resource "google_compute_region_url_map" "default" {
@@ -27,7 +27,7 @@ resource "google_compute_region_url_map" "default" {
region = "us-central1"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
}
resource "google_compute_region_backend_service" "default" {
@@ -46,7 +46,7 @@ resource "google_compute_region_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
data "google_compute_image" "debian_image" {
@@ -58,9 +58,9 @@ data "google_compute_image" "debian_image" {
resource "google_compute_region_instance_group_manager" "rigm" {
provider = google-beta
region = "us-central1"
- name = "rigm-internal"
+ name = "<%= ctx[:vars]['rigm_name'] %>"
version {
- instance_template = google_compute_instance_template.instance_template.self_link
+ instance_template = google_compute_instance_template.instance_template.id
name = "primary"
}
base_instance_name = "internal-glb"
@@ -73,8 +73,8 @@ resource "google_compute_instance_template" "instance_template" {
machine_type = "n1-standard-1"
network_interface {
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
}
disk {
@@ -100,7 +100,7 @@ resource "google_compute_region_health_check" "default" {
resource "google_compute_firewall" "fw1" {
provider = google-beta
name = "<%= ctx[:vars]['fw_name'] %>-1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
source_ranges = ["10.1.2.0/24"]
allow {
protocol = "tcp"
@@ -118,7 +118,7 @@ resource "google_compute_firewall" "fw2" {
depends_on = [google_compute_firewall.fw1]
provider = google-beta
name = "<%= ctx[:vars]['fw_name'] %>-2"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
source_ranges = ["0.0.0.0/0"]
allow {
protocol = "tcp"
@@ -132,7 +132,7 @@ resource "google_compute_firewall" "fw3" {
depends_on = [google_compute_firewall.fw2]
provider = google-beta
name = "<%= ctx[:vars]['fw_name'] %>-3"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]
allow {
protocol = "tcp"
@@ -145,7 +145,7 @@ resource "google_compute_firewall" "fw4" {
depends_on = [google_compute_firewall.fw3]
provider = google-beta
name = "<%= ctx[:vars]['fw_name'] %>-4"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
source_ranges = ["10.129.0.0/26"]
target_tags = ["load-balanced-backend"]
allow {
@@ -175,7 +175,7 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['network_name'] %>-default"
ip_cidr_range = "10.1.2.0/24"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
resource "google_compute_subnetwork" "proxy" {
@@ -183,7 +183,7 @@ resource "google_compute_subnetwork" "proxy" {
name = "<%= ctx[:vars]['network_name'] %>-proxy"
ip_cidr_range = "10.129.0.0/26"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
purpose = "INTERNAL_HTTPS_LOAD_BALANCER"
role = "ACTIVE"
}
diff --git a/templates/terraform/examples/forwarding_rule_internallb.tf.erb b/templates/terraform/examples/forwarding_rule_internallb.tf.erb
index d78072f6392e..886884b60af6 100644
--- a/templates/terraform/examples/forwarding_rule_internallb.tf.erb
+++ b/templates/terraform/examples/forwarding_rule_internallb.tf.erb
@@ -4,7 +4,7 @@ resource "google_compute_forwarding_rule" "<%= ctx[:primary_resource_id] %>" {
region = "us-central1"
load_balancing_scheme = "INTERNAL"
- backend_service = google_compute_region_backend_service.backend.self_link
+ backend_service = google_compute_region_backend_service.backend.id
all_ports = true
network = google_compute_network.default.name
subnetwork = google_compute_subnetwork.default.name
@@ -13,7 +13,7 @@ resource "google_compute_forwarding_rule" "<%= ctx[:primary_resource_id] %>" {
resource "google_compute_region_backend_service" "backend" {
name = "<%= ctx[:vars]['backend_name'] %>"
region = "us-central1"
- health_checks = [google_compute_health_check.hc.self_link]
+ health_checks = [google_compute_health_check.hc.id]
}
resource "google_compute_health_check" "hc" {
@@ -35,5 +35,5 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['network_name'] %>"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
diff --git a/templates/terraform/examples/global_forwarding_rule_http.tf.erb b/templates/terraform/examples/global_forwarding_rule_http.tf.erb
index 71225b15e162..8d9793018471 100644
--- a/templates/terraform/examples/global_forwarding_rule_http.tf.erb
+++ b/templates/terraform/examples/global_forwarding_rule_http.tf.erb
@@ -1,19 +1,19 @@
resource "google_compute_global_forwarding_rule" "default" {
name = "<%= ctx[:vars]['forwarding_rule_name'] %>"
- target = google_compute_target_http_proxy.default.self_link
+ target = google_compute_target_http_proxy.default.id
port_range = "80"
}
resource "google_compute_target_http_proxy" "default" {
name = "<%= ctx[:vars]['http_proxy_name'] %>"
description = "a description"
- url_map = google_compute_url_map.default.self_link
+ url_map = google_compute_url_map.default.id
}
resource "google_compute_url_map" "default" {
name = "url-map-<%= ctx[:vars]['http_proxy_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -22,11 +22,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -37,7 +37,7 @@ resource "google_compute_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/global_forwarding_rule_internal.tf.erb b/templates/terraform/examples/global_forwarding_rule_internal.tf.erb
index aa01994cb81e..6b1baac7090f 100644
--- a/templates/terraform/examples/global_forwarding_rule_internal.tf.erb
+++ b/templates/terraform/examples/global_forwarding_rule_internal.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_global_forwarding_rule" "default" {
provider = google-beta
name = "<%= ctx[:vars]['forwarding_rule_name'] %>"
- target = google_compute_target_http_proxy.default.self_link
+ target = google_compute_target_http_proxy.default.id
port_range = "80"
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
ip_address = "0.0.0.0"
@@ -18,14 +18,14 @@ resource "google_compute_target_http_proxy" "default" {
provider = google-beta
name = "<%= ctx[:vars]['http_proxy_name'] %>"
description = "a description"
- url_map = google_compute_url_map.default.self_link
+ url_map = google_compute_url_map.default.id
}
resource "google_compute_url_map" "default" {
provider = google-beta
name = "url-map-<%= ctx[:vars]['http_proxy_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -34,11 +34,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -58,7 +58,7 @@ resource "google_compute_backend_service" "default" {
max_rate_per_instance = 50
}
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
}
data "google_compute_image" "debian_image" {
@@ -71,7 +71,7 @@ resource "google_compute_instance_group_manager" "igm" {
provider = google-beta
name = "igm-internal"
version {
- instance_template = google_compute_instance_template.instance_template.self_link
+ instance_template = google_compute_instance_template.instance_template.id
name = "primary"
}
base_instance_name = "internal-glb"
diff --git a/templates/terraform/examples/global_network_endpoint.tf.erb b/templates/terraform/examples/global_network_endpoint.tf.erb
index 5dbf2770adc7..32592e299c85 100644
--- a/templates/terraform/examples/global_network_endpoint.tf.erb
+++ b/templates/terraform/examples/global_network_endpoint.tf.erb
@@ -1,18 +1,13 @@
resource "google_compute_global_network_endpoint" "<%= ctx[:primary_resource_id] %>" {
- global_network_endpoint_group = google_compute_network_endpoint_group.neg.name
+ global_network_endpoint_group = google_compute_global_network_endpoint_group.neg.name
fqdn = "www.example.com"
- port = google_compute_network_endpoint_group.neg.default_port
- ip_address = google_compute_instance.endpoint-instance.network_interface[0].network_ip
+ port = 90
+ ip_address = "8.8.8.8"
}
-resource "google_compute_global_network_endpoint_group" "group" {
- name = "<%= ctx[:vars]['neg_name'] %>"
- network = google_compute_network.default.self_link
- default_port = "90"
-}
-
-resource "google_compute_network" "default" {
- name = "<%= ctx[:vars]['network_name'] %>"
- auto_create_subnetworks = false
+resource "google_compute_global_network_endpoint_group" "neg" {
+ name = "<%= ctx[:vars]['neg_name'] %>"
+ default_port = "90"
+ network_endpoint_type = "INTERNET_IP_PORT"
}
diff --git a/templates/terraform/examples/ha_vpn_gateway_basic.tf.erb b/templates/terraform/examples/ha_vpn_gateway_basic.tf.erb
index 98c135c1621d..0352a7e92621 100644
--- a/templates/terraform/examples/ha_vpn_gateway_basic.tf.erb
+++ b/templates/terraform/examples/ha_vpn_gateway_basic.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway1" {
provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['ha_vpn_gateway1_name'] %>"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_network" "network1" {
diff --git a/templates/terraform/examples/ha_vpn_gateway_gcp_to_gcp.tf.erb b/templates/terraform/examples/ha_vpn_gateway_gcp_to_gcp.tf.erb
index abc47c260485..dd7139e1b4a7 100644
--- a/templates/terraform/examples/ha_vpn_gateway_gcp_to_gcp.tf.erb
+++ b/templates/terraform/examples/ha_vpn_gateway_gcp_to_gcp.tf.erb
@@ -2,14 +2,14 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway1" {
provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['ha_vpn_gateway1_name'] %>"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_ha_vpn_gateway" "ha_gateway2" {
provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['ha_vpn_gateway2_name'] %>"
- network = google_compute_network.network2.self_link
+ network = google_compute_network.network2.id
}
resource "google_compute_network" "network1" {
@@ -31,7 +31,7 @@ resource "google_compute_subnetwork" "network1_subnet1" {
name = "ha-vpn-subnet-1"
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_subnetwork" "network1_subnet2" {
@@ -39,7 +39,7 @@ resource "google_compute_subnetwork" "network1_subnet2" {
name = "ha-vpn-subnet-2"
ip_cidr_range = "10.0.2.0/24"
region = "us-west1"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_subnetwork" "network2_subnet1" {
@@ -47,7 +47,7 @@ resource "google_compute_subnetwork" "network2_subnet1" {
name = "ha-vpn-subnet-3"
ip_cidr_range = "192.168.1.0/24"
region = "us-central1"
- network = google_compute_network.network2.self_link
+ network = google_compute_network.network2.id
}
resource "google_compute_subnetwork" "network2_subnet2" {
@@ -55,7 +55,7 @@ resource "google_compute_subnetwork" "network2_subnet2" {
name = "ha-vpn-subnet-4"
ip_cidr_range = "192.168.2.0/24"
region = "us-east1"
- network = google_compute_network.network2.self_link
+ network = google_compute_network.network2.id
}
resource "google_compute_router" "router1" {
@@ -80,10 +80,10 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
provider = google-beta
name = "ha-vpn-tunnel1"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway1.self_link
- peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway2.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway1.id
+ peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway2.id
shared_secret = "a secret message"
- router = google_compute_router.router1.self_link
+ router = google_compute_router.router1.id
vpn_gateway_interface = 0
}
@@ -91,10 +91,10 @@ resource "google_compute_vpn_tunnel" "tunnel2" {
provider = google-beta
name = "ha-vpn-tunnel2"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway1.self_link
- peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway2.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway1.id
+ peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway2.id
shared_secret = "a secret message"
- router = google_compute_router.router1.self_link
+ router = google_compute_router.router1.id
vpn_gateway_interface = 1
}
@@ -102,10 +102,10 @@ resource "google_compute_vpn_tunnel" "tunnel3" {
provider = google-beta
name = "ha-vpn-tunnel3"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway2.self_link
- peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway1.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway2.id
+ peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway1.id
shared_secret = "a secret message"
- router = google_compute_router.router2.self_link
+ router = google_compute_router.router2.id
vpn_gateway_interface = 0
}
@@ -113,10 +113,10 @@ resource "google_compute_vpn_tunnel" "tunnel4" {
provider = google-beta
name = "ha-vpn-tunnel4"
region = "us-central1"
- vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway2.self_link
- peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway1.self_link
+ vpn_gateway = google_compute_ha_vpn_gateway.ha_gateway2.id
+ peer_gcp_gateway = google_compute_ha_vpn_gateway.ha_gateway1.id
shared_secret = "a secret message"
- router = google_compute_router.router2.self_link
+ router = google_compute_router.router2.id
vpn_gateway_interface = 1
}
diff --git a/templates/terraform/examples/healthcare_dataset_basic.tf.erb b/templates/terraform/examples/healthcare_dataset_basic.tf.erb
index a8c8c6b98615..8f9719a6108d 100644
--- a/templates/terraform/examples/healthcare_dataset_basic.tf.erb
+++ b/templates/terraform/examples/healthcare_dataset_basic.tf.erb
@@ -2,5 +2,4 @@ resource "google_healthcare_dataset" "default" {
name = "<%= ctx[:vars]['dataset_name'] %>"
location = "us-central1"
time_zone = "UTC"
- provider = google-beta
}
diff --git a/templates/terraform/examples/healthcare_dicom_store_basic.tf.erb b/templates/terraform/examples/healthcare_dicom_store_basic.tf.erb
index 8828bb2294bb..00db67aba347 100644
--- a/templates/terraform/examples/healthcare_dicom_store_basic.tf.erb
+++ b/templates/terraform/examples/healthcare_dicom_store_basic.tf.erb
@@ -9,16 +9,13 @@ resource "google_healthcare_dicom_store" "default" {
labels = {
label1 = "labelvalue1"
}
- provider = google-beta
}
resource "google_pubsub_topic" "topic" {
name = "<%= ctx[:vars]['pubsub_topic']%>"
- provider = google-beta
}
resource "google_healthcare_dataset" "dataset" {
name = "<%= ctx[:vars]['dataset_name'] %>"
location = "us-central1"
- provider = google-beta
}
diff --git a/templates/terraform/examples/healthcare_fhir_store_basic.tf.erb b/templates/terraform/examples/healthcare_fhir_store_basic.tf.erb
index 1f167f660a6d..1ff31c2fce66 100644
--- a/templates/terraform/examples/healthcare_fhir_store_basic.tf.erb
+++ b/templates/terraform/examples/healthcare_fhir_store_basic.tf.erb
@@ -15,16 +15,13 @@ resource "google_healthcare_fhir_store" "default" {
labels = {
label1 = "labelvalue1"
}
- provider = google-beta
}
resource "google_pubsub_topic" "topic" {
name = "<%= ctx[:vars]['pubsub_topic']%>"
- provider = google-beta
}
resource "google_healthcare_dataset" "dataset" {
name = "<%= ctx[:vars]['dataset_name'] %>"
location = "us-central1"
- provider = google-beta
}
diff --git a/templates/terraform/examples/healthcare_fhir_store_streaming_config.tf.erb b/templates/terraform/examples/healthcare_fhir_store_streaming_config.tf.erb
new file mode 100644
index 000000000000..7418e6334566
--- /dev/null
+++ b/templates/terraform/examples/healthcare_fhir_store_streaming_config.tf.erb
@@ -0,0 +1,41 @@
+resource "google_healthcare_fhir_store" "default" {
+ name = "<%= ctx[:vars]['fhir_store_name'] %>"
+ dataset = google_healthcare_dataset.dataset.id
+ version = "R4"
+
+ enable_update_create = false
+ disable_referential_integrity = false
+ disable_resource_versioning = false
+ enable_history_import = false
+
+ labels = {
+ label1 = "labelvalue1"
+ }
+
+ stream_configs {
+ resource_types = ["Observation"]
+ bigquery_destination {
+ dataset_uri = "bq://${google_bigquery_dataset.bq_dataset.project}.${google_bigquery_dataset.bq_dataset.dataset_id}"
+ schema_config {
+ recursive_structure_depth = 3
+ }
+ }
+ }
+}
+
+resource "google_pubsub_topic" "topic" {
+ name = "<%= ctx[:vars]['pubsub_topic']%>"
+}
+
+resource "google_healthcare_dataset" "dataset" {
+ name = "<%= ctx[:vars]['dataset_name'] %>"
+ location = "us-central1"
+}
+
+resource "google_bigquery_dataset" "bq_dataset" {
+ dataset_id = "<%= ctx[:vars]['bq_dataset_name'] %>"
+ friendly_name = "test"
+ description = "This is a test description"
+ location = "US"
+ delete_contents_on_destroy = true
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/healthcare_hl7_v2_store_basic.tf.erb b/templates/terraform/examples/healthcare_hl7_v2_store_basic.tf.erb
index c49aba55018e..908532fe2aa0 100644
--- a/templates/terraform/examples/healthcare_hl7_v2_store_basic.tf.erb
+++ b/templates/terraform/examples/healthcare_hl7_v2_store_basic.tf.erb
@@ -2,28 +2,20 @@ resource "google_healthcare_hl7_v2_store" "default" {
name = "<%= ctx[:vars]['hl7_v2_store_name'] %>"
dataset = google_healthcare_dataset.dataset.id
- parser_config {
- allow_null_header = false
- segment_terminator = "Jw=="
- }
-
- notification_config {
+ notification_configs {
pubsub_topic = google_pubsub_topic.topic.id
}
labels = {
label1 = "labelvalue1"
}
- provider = google-beta
}
resource "google_pubsub_topic" "topic" {
name = "<%= ctx[:vars]['pubsub_topic']%>"
- provider = google-beta
}
resource "google_healthcare_dataset" "dataset" {
name = "<%= ctx[:vars]['dataset_name'] %>"
location = "us-central1"
- provider = google-beta
}
diff --git a/templates/terraform/examples/healthcare_hl7_v2_store_parser_config.tf.erb b/templates/terraform/examples/healthcare_hl7_v2_store_parser_config.tf.erb
new file mode 100644
index 000000000000..04f73fb405ae
--- /dev/null
+++ b/templates/terraform/examples/healthcare_hl7_v2_store_parser_config.tf.erb
@@ -0,0 +1,96 @@
+resource "google_healthcare_hl7_v2_store" "default" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['hl7_v2_store_name'] %>"
+ dataset = google_healthcare_dataset.dataset.id
+
+ parser_config {
+ allow_null_header = false
+ segment_terminator = "Jw=="
+ schema = <" {
name = "<%= ctx[:vars]['interconnect_attachment_name'] %>"
interconnect = "my-interconnect-id"
- router = google_compute_router.foobar.self_link
+ router = google_compute_router.foobar.id
}
resource "google_compute_router" "foobar" {
diff --git a/templates/terraform/examples/kms_crypto_key_asymmetric_sign.tf.erb b/templates/terraform/examples/kms_crypto_key_asymmetric_sign.tf.erb
index 2d3152d67351..9020af7f6854 100644
--- a/templates/terraform/examples/kms_crypto_key_asymmetric_sign.tf.erb
+++ b/templates/terraform/examples/kms_crypto_key_asymmetric_sign.tf.erb
@@ -5,7 +5,7 @@ resource "google_kms_key_ring" "keyring" {
resource "google_kms_crypto_key" "<%= ctx[:primary_resource_id] %>" {
name = "crypto-key-example"
- key_ring = google_kms_key_ring.keyring.self_link
+ key_ring = google_kms_key_ring.keyring.id
purpose = "ASYMMETRIC_SIGN"
version_template {
diff --git a/templates/terraform/examples/kms_crypto_key_basic.tf.erb b/templates/terraform/examples/kms_crypto_key_basic.tf.erb
index 9e95e976cce0..6730375aee43 100644
--- a/templates/terraform/examples/kms_crypto_key_basic.tf.erb
+++ b/templates/terraform/examples/kms_crypto_key_basic.tf.erb
@@ -5,7 +5,7 @@ resource "google_kms_key_ring" "keyring" {
resource "google_kms_crypto_key" "<%= ctx[:primary_resource_id] %>" {
name = "crypto-key-example"
- key_ring = google_kms_key_ring.keyring.self_link
+ key_ring = google_kms_key_ring.keyring.id
rotation_period = "100000s"
lifecycle {
diff --git a/templates/terraform/examples/kms_key_ring_import_job.tf.erb b/templates/terraform/examples/kms_key_ring_import_job.tf.erb
new file mode 100644
index 000000000000..3c316881495f
--- /dev/null
+++ b/templates/terraform/examples/kms_key_ring_import_job.tf.erb
@@ -0,0 +1,12 @@
+resource "google_kms_key_ring" "keyring" {
+ name = "<%= ctx[:vars]['keyring'] %>"
+ location = "global"
+}
+
+resource "google_kms_key_ring_import_job" "<%= ctx[:primary_resource_id] %>" {
+ key_ring = google_kms_key_ring.keyring.id
+ import_job_id = "my-import-job"
+
+ import_method = "RSA_OAEP_3072_SHA1_AES_256"
+ protection_level = "SOFTWARE"
+}
diff --git a/templates/terraform/examples/machine_image_basic.tf.erb b/templates/terraform/examples/machine_image_basic.tf.erb
new file mode 100644
index 000000000000..3cbc359540be
--- /dev/null
+++ b/templates/terraform/examples/machine_image_basic.tf.erb
@@ -0,0 +1,21 @@
+resource "google_compute_instance" "vm" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['vm_name'] %>"
+ machine_type = "n1-standard-1"
+
+ boot_disk {
+ initialize_params {
+ image = "debian-cloud/debian-9"
+ }
+ }
+
+ network_interface {
+ network = "default"
+ }
+}
+
+resource "google_compute_machine_image" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['image_name'] %>"
+ source_instance = google_compute_instance.vm.self_link
+}
diff --git a/templates/terraform/examples/managed_ssl_certificate_basic.tf.erb b/templates/terraform/examples/managed_ssl_certificate_basic.tf.erb
index fce3f3fe2403..af30857c9213 100644
--- a/templates/terraform/examples/managed_ssl_certificate_basic.tf.erb
+++ b/templates/terraform/examples/managed_ssl_certificate_basic.tf.erb
@@ -12,8 +12,8 @@ resource "google_compute_target_https_proxy" "default" {
provider = google-beta
name = "<%= ctx[:vars]['proxy_name'] %>"
- url_map = google_compute_url_map.default.self_link
- ssl_certificates = [google_compute_managed_ssl_certificate.default.self_link]
+ url_map = google_compute_url_map.default.id
+ ssl_certificates = [google_compute_managed_ssl_certificate.default.id]
}
resource "google_compute_url_map" "default" {
@@ -22,7 +22,7 @@ resource "google_compute_url_map" "default" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["sslcert.tf-test.club"]
@@ -31,11 +31,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -48,7 +48,7 @@ resource "google_compute_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
@@ -71,7 +71,7 @@ resource "google_compute_global_forwarding_rule" "default" {
provider = google-beta
name = "<%= ctx[:vars]['forwarding_rule_name'] %>"
- target = google_compute_target_https_proxy.default.self_link
+ target = google_compute_target_https_proxy.default.id
port_range = 443
}
diff --git a/templates/terraform/examples/managed_ssl_certificate_recreation.tf.erb b/templates/terraform/examples/managed_ssl_certificate_recreation.tf.erb
new file mode 100644
index 000000000000..b8156337374b
--- /dev/null
+++ b/templates/terraform/examples/managed_ssl_certificate_recreation.tf.erb
@@ -0,0 +1,71 @@
+// This example allows the list of managed domains to be modified and will
+// recreate the ssl certificate and update the target https proxy correctly
+
+resource "google_compute_target_https_proxy" "default" {
+ provider = google-beta
+ name = "test-proxy"
+ url_map = google_compute_url_map.default.id
+ ssl_certificates = [google_compute_managed_ssl_certificate.cert.id]
+}
+
+locals {
+ managed_domains = list("test.example.com")
+}
+
+resource "random_id" "certificate" {
+ byte_length = 4
+ prefix = "issue6147-cert-"
+
+ keepers = {
+ domains = join(",", local.managed_domains)
+ }
+}
+
+resource "google_compute_managed_ssl_certificate" "cert" {
+ provider = google-beta
+ name = random_id.certificate.hex
+
+ lifecycle {
+ create_before_destroy = true
+ }
+
+ managed {
+ domains = local.managed_domains
+ }
+}
+
+resource "google_compute_url_map" "default" {
+ provider = google-beta
+ name = "url-map"
+ description = "a description"
+ default_service = google_compute_backend_service.default.id
+ host_rule {
+ hosts = ["mysite.com"]
+ path_matcher = "allpaths"
+ }
+ path_matcher {
+ name = "allpaths"
+ default_service = google_compute_backend_service.default.id
+ path_rule {
+ paths = ["/*"]
+ service = google_compute_backend_service.default.id
+ }
+ }
+}
+
+resource "google_compute_backend_service" "default" {
+ provider = google-beta
+ name = "backend-service"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_http_health_check" "default" {
+ provider = google-beta
+ name = "http-health-check"
+ request_path = "/"
+ check_interval_sec = 1
+ timeout_sec = 1
+}
diff --git a/templates/terraform/examples/memcache_instance_basic.tf.erb b/templates/terraform/examples/memcache_instance_basic.tf.erb
new file mode 100644
index 000000000000..94611af6af40
--- /dev/null
+++ b/templates/terraform/examples/memcache_instance_basic.tf.erb
@@ -0,0 +1,33 @@
+resource "google_compute_network" "network" {
+ provider = google-beta
+ name = "tf-test%{random_suffix}"
+}
+
+resource "google_compute_global_address" "service_range" {
+ provider = google-beta
+ name = "tf-test%{random_suffix}"
+ purpose = "VPC_PEERING"
+ address_type = "INTERNAL"
+ prefix_length = 16
+ network = google_compute_network.network.id
+}
+
+resource "google_service_networking_connection" "private_service_connection" {
+ provider = google-beta
+ network = google_compute_network.network.id
+ service = "servicenetworking.googleapis.com"
+ reserved_peering_ranges = [google_compute_global_address.service_range.name]
+}
+
+resource "google_memcache_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ region = "us-central1"
+ authorized_network = google_service_networking_connection.private_service_connection.network
+
+ node_config {
+ cpu_count = 1
+ memory_size_mb = 1024
+ }
+ node_count = 1
+}
diff --git a/templates/terraform/examples/monitoring_metric_descriptor_alert.tf.erb b/templates/terraform/examples/monitoring_metric_descriptor_alert.tf.erb
new file mode 100644
index 000000000000..8bb1d5355007
--- /dev/null
+++ b/templates/terraform/examples/monitoring_metric_descriptor_alert.tf.erb
@@ -0,0 +1,21 @@
+resource "google_monitoring_metric_descriptor" "<%= ctx[:primary_resource_id] %>" {
+ description = "Daily sales records from all branch stores."
+ display_name = "<%= ctx[:vars]["display_name"] %>"
+ type = "custom.googleapis.com/stores/<%= ctx[:vars]["type"] %>"
+ metric_kind = "GAUGE"
+ value_type = "DOUBLE"
+ unit = "{USD}"
+}
+
+resource "google_monitoring_alert_policy" "alert_policy" {
+ display_name = "<%= ctx[:vars]["display_name"] %>"
+ combiner = "OR"
+ conditions {
+ display_name = "test condition"
+ condition_threshold {
+ filter = "metric.type=\"${google_monitoring_metric_descriptor.<%= ctx[:primary_resource_id] %>.type}\" AND resource.type=\"gce_instance\""
+ duration = "60s"
+ comparison = "COMPARISON_GT"
+ }
+ }
+}
diff --git a/templates/terraform/examples/monitoring_metric_descriptor_basic.tf.erb b/templates/terraform/examples/monitoring_metric_descriptor_basic.tf.erb
new file mode 100644
index 000000000000..206c1df9535b
--- /dev/null
+++ b/templates/terraform/examples/monitoring_metric_descriptor_basic.tf.erb
@@ -0,0 +1,18 @@
+resource "google_monitoring_metric_descriptor" "<%= ctx[:primary_resource_id] %>" {
+ description = "Daily sales records from all branch stores."
+ display_name = "<%= ctx[:vars]["display_name"] %>"
+ type = "custom.googleapis.com/stores/<%= ctx[:vars]["type"] %>"
+ metric_kind = "GAUGE"
+ value_type = "DOUBLE"
+ unit = "{USD}"
+ labels {
+ key = "store_id"
+ value_type = "STRING"
+ description = "The ID of the store."
+ }
+ launch_stage = "BETA"
+ metadata {
+ sample_period = "60s"
+ ingest_delay = "30s"
+ }
+}
diff --git a/templates/terraform/examples/monitoring_slo_appengine.tf.erb b/templates/terraform/examples/monitoring_slo_appengine.tf.erb
new file mode 100644
index 000000000000..6025a44379e0
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_appengine.tf.erb
@@ -0,0 +1,19 @@
+data "google_monitoring_app_engine_service" "default" {
+ module_id = "default"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] -%>" {
+ service = data.google_monitoring_app_engine_service.default.service_id
+
+ slo_id = "<%= ctx[:vars]['slo_id'] -%>"
+ display_name = "Terraform Test SLO for App Engine"
+
+ goal = 0.9
+ calendar_period = "DAY"
+
+ basic_sli {
+ latency {
+ threshold = "1s"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/monitoring_slo_request_based.tf.erb b/templates/terraform/examples/monitoring_slo_request_based.tf.erb
new file mode 100644
index 000000000000..7ef0d61856e1
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_request_based.tf.erb
@@ -0,0 +1,27 @@
+resource "google_monitoring_custom_service" "customsrv" {
+ service_id = "<%= ctx[:vars]['service_id'] %>"
+ display_name = "My Custom Service"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] %>" {
+ service = google_monitoring_custom_service.customsrv.service_id
+ slo_id = "<%= ctx[:vars]['slo_id'] %>"
+ display_name = "Terraform Test SLO with request based SLI (good total ratio)"
+
+ goal = 0.9
+ rolling_period_days = 30
+
+ request_based_sli {
+ distribution_cut {
+ distribution_filter = join(" AND ", [
+ "metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
+ "resource.type=\"consumed_api\"",
+ "resource.label.\"project_id\"=\"<%= ctx[:test_env_vars]['project'] -%>\"",
+ ])
+
+ range {
+ max = 10
+ }
+ }
+ }
+}
diff --git a/templates/terraform/examples/monitoring_slo_windows_based_good_bad_metric_filter.tf.erb b/templates/terraform/examples/monitoring_slo_windows_based_good_bad_metric_filter.tf.erb
new file mode 100644
index 000000000000..f43f1adf18ab
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_windows_based_good_bad_metric_filter.tf.erb
@@ -0,0 +1,20 @@
+resource "google_monitoring_custom_service" "customsrv" {
+ service_id = "<%= ctx[:vars]['service_id'] %>"
+ display_name = "My Custom Service"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] %>" {
+ service = google_monitoring_custom_service.customsrv.service_id
+ display_name = "Terraform Test SLO with window based SLI"
+
+ goal = 0.95
+ calendar_period = "FORTNIGHT"
+
+ windows_based_sli {
+ window_period = "400s"
+ good_bad_metric_filter = join(" AND ", [
+ "metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
+ "resource.type=\"uptime_url\"",
+ ])
+ }
+}
diff --git a/templates/terraform/examples/monitoring_slo_windows_based_metric_mean.tf.erb b/templates/terraform/examples/monitoring_slo_windows_based_metric_mean.tf.erb
new file mode 100644
index 000000000000..f7a38919b97d
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_windows_based_metric_mean.tf.erb
@@ -0,0 +1,26 @@
+resource "google_monitoring_custom_service" "customsrv" {
+ service_id = "<%= ctx[:vars]['service_id'] %>"
+ display_name = "My Custom Service"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] %>" {
+ service = google_monitoring_custom_service.customsrv.service_id
+ display_name = "Terraform Test SLO with window based SLI"
+
+ goal = 0.9
+ rolling_period_days = 20
+
+ windows_based_sli {
+ window_period = "600s"
+ metric_mean_in_range {
+ time_series = join(" AND ", [
+ "metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
+ "resource.type=\"gce_instance\"",
+ ])
+
+ range {
+ max = 5
+ }
+ }
+ }
+}
diff --git a/templates/terraform/examples/monitoring_slo_windows_based_metric_sum.tf.erb b/templates/terraform/examples/monitoring_slo_windows_based_metric_sum.tf.erb
new file mode 100644
index 000000000000..aee54b150f02
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_windows_based_metric_sum.tf.erb
@@ -0,0 +1,26 @@
+resource "google_monitoring_custom_service" "customsrv" {
+ service_id = "<%= ctx[:vars]['service_id'] %>"
+ display_name = "My Custom Service"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] %>" {
+ service = google_monitoring_custom_service.customsrv.service_id
+ display_name = "Terraform Test SLO with window based SLI"
+
+ goal = 0.9
+ rolling_period_days = 20
+
+ windows_based_sli {
+ window_period = "400s"
+ metric_sum_in_range {
+ time_series = join(" AND ", [
+ "metric.type=\"monitoring.googleapis.com/uptime_check/request_latency\"",
+ "resource.type=\"uptime_url\"",
+ ])
+
+ range {
+ max = 5000
+ }
+ }
+ }
+}
diff --git a/templates/terraform/examples/monitoring_slo_windows_based_ratio_threshold.tf.erb b/templates/terraform/examples/monitoring_slo_windows_based_ratio_threshold.tf.erb
new file mode 100644
index 000000000000..0bacbe7e9c18
--- /dev/null
+++ b/templates/terraform/examples/monitoring_slo_windows_based_ratio_threshold.tf.erb
@@ -0,0 +1,33 @@
+resource "google_monitoring_custom_service" "customsrv" {
+ service_id = "<%= ctx[:vars]['service_id'] %>"
+ display_name = "My Custom Service"
+}
+
+resource "google_monitoring_slo" "<%= ctx[:primary_resource_id] %>" {
+ service = google_monitoring_custom_service.customsrv.service_id
+ display_name = "Terraform Test SLO with window based SLI"
+
+ goal = 0.9
+ rolling_period_days = 20
+
+ windows_based_sli {
+ window_period = "100s"
+
+ good_total_ratio_threshold {
+ threshold = 0.1
+ performance {
+ distribution_cut {
+ distribution_filter = join(" AND ", [
+ "metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
+ "resource.type=\"consumed_api\"",
+ ])
+
+ range {
+ min = 1
+ max = 9
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/templates/terraform/examples/network_endpoint.tf.erb b/templates/terraform/examples/network_endpoint.tf.erb
index 52ad5025ebb5..9d52e2a6e9b0 100644
--- a/templates/terraform/examples/network_endpoint.tf.erb
+++ b/templates/terraform/examples/network_endpoint.tf.erb
@@ -22,7 +22,7 @@ resource "google_compute_instance" "endpoint-instance" {
}
network_interface {
- subnetwork = google_compute_subnetwork.default.self_link
+ subnetwork = google_compute_subnetwork.default.id
access_config {
}
}
@@ -30,8 +30,8 @@ resource "google_compute_instance" "endpoint-instance" {
resource "google_compute_network_endpoint_group" "group" {
name = "<%= ctx[:vars]['neg_name'] %>"
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
default_port = "90"
zone = "us-central1-a"
}
@@ -45,5 +45,5 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['subnetwork_name'] %>"
ip_cidr_range = "10.0.0.1/16"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
diff --git a/templates/terraform/examples/network_endpoint_group.tf.erb b/templates/terraform/examples/network_endpoint_group.tf.erb
index 693d60782028..2001acc3c070 100644
--- a/templates/terraform/examples/network_endpoint_group.tf.erb
+++ b/templates/terraform/examples/network_endpoint_group.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_network_endpoint_group" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['neg_name'] %>"
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
default_port = "90"
zone = "us-central1-a"
}
@@ -15,5 +15,5 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['subnetwork_name'] %>"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
diff --git a/templates/terraform/examples/network_management_connectivity_test_addresses.tf.erb b/templates/terraform/examples/network_management_connectivity_test_addresses.tf.erb
new file mode 100644
index 000000000000..f67260dd4f94
--- /dev/null
+++ b/templates/terraform/examples/network_management_connectivity_test_addresses.tf.erb
@@ -0,0 +1,44 @@
+resource "google_network_management_connectivity_test" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['primary_resource_name'] %>"
+ source {
+ ip_address = google_compute_address.source-addr.address
+ project_id = google_compute_address.source-addr.project
+ network = google_compute_network.vpc.id
+ network_type = "GCP_NETWORK"
+ }
+
+ destination {
+ ip_address = google_compute_address.dest-addr.address
+ project_id = google_compute_address.dest-addr.project
+ network = google_compute_network.vpc.id
+ }
+
+ protocol = "UDP"
+}
+
+resource "google_compute_network" "vpc" {
+ name = "<%= ctx[:vars]['network'] %>"
+}
+
+resource "google_compute_subnetwork" "subnet" {
+ name = "<%= ctx[:vars]['network'] %>-subnet"
+ ip_cidr_range = "10.0.0.0/16"
+ region = "us-central1"
+ network = google_compute_network.vpc.id
+}
+
+resource "google_compute_address" "source-addr" {
+ name = "<%= ctx[:vars]['source_addr'] %>"
+ subnetwork = google_compute_subnetwork.subnet.id
+ address_type = "INTERNAL"
+ address = "10.0.42.42"
+ region = "us-central1"
+}
+
+resource "google_compute_address" "dest-addr" {
+ name = "<%= ctx[:vars]['dest_addr'] %>"
+ subnetwork = google_compute_subnetwork.subnet.id
+ address_type = "INTERNAL"
+ address = "10.0.43.43"
+ region = "us-central1"
+}
diff --git a/templates/terraform/examples/network_management_connectivity_test_instances.tf.erb b/templates/terraform/examples/network_management_connectivity_test_instances.tf.erb
new file mode 100644
index 000000000000..30572705d2c7
--- /dev/null
+++ b/templates/terraform/examples/network_management_connectivity_test_instances.tf.erb
@@ -0,0 +1,55 @@
+resource "google_network_management_connectivity_test" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['primary_resource_name'] %>"
+ source {
+ instance = google_compute_instance.source.id
+ }
+
+ destination {
+ instance = google_compute_instance.destination.id
+ }
+
+ protocol = "TCP"
+}
+
+resource "google_compute_instance" "source" {
+ name = "<%= ctx[:vars]['source_instance'] %>"
+ machine_type = "n1-standard-1"
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.debian_9.id
+ }
+ }
+
+ network_interface {
+ network = google_compute_network.vpc.id
+ access_config {
+ }
+ }
+}
+
+resource "google_compute_instance" "destination" {
+ name = "<%= ctx[:vars]['dest_instance'] %>"
+ machine_type = "n1-standard-1"
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.debian_9.id
+ }
+ }
+
+ network_interface {
+ network = google_compute_network.vpc.id
+ access_config {
+ }
+ }
+}
+
+resource "google_compute_network" "vpc" {
+ name = "<%= ctx[:vars]['network_name'] %>"
+}
+
+data "google_compute_image" "debian_9" {
+ family = "debian-9"
+ project = "debian-cloud"
+}
diff --git a/templates/terraform/examples/network_peering_routes_config_basic.tf.erb b/templates/terraform/examples/network_peering_routes_config_basic.tf.erb
index eb33b6c5fbe0..92fecd467a8c 100644
--- a/templates/terraform/examples/network_peering_routes_config_basic.tf.erb
+++ b/templates/terraform/examples/network_peering_routes_config_basic.tf.erb
@@ -8,8 +8,8 @@ resource "google_compute_network_peering_routes_config" "<%= ctx[:primary_resour
resource "google_compute_network_peering" "peering_primary" {
name = "<%= ctx[:vars]['peering_primary_name'] %>"
- network = google_compute_network.network_primary.self_link
- peer_network = google_compute_network.network_secondary.self_link
+ network = google_compute_network.network_primary.id
+ peer_network = google_compute_network.network_secondary.id
import_custom_routes = true
export_custom_routes = true
@@ -17,8 +17,8 @@ resource "google_compute_network_peering" "peering_primary" {
resource "google_compute_network_peering" "peering_secondary" {
name = "<%= ctx[:vars]['peering_secondary_name'] %>"
- network = google_compute_network.network_secondary.self_link
- peer_network = google_compute_network.network_primary.self_link
+ network = google_compute_network.network_secondary.id
+ peer_network = google_compute_network.network_primary.id
}
resource "google_compute_network" "network_primary" {
diff --git a/templates/terraform/examples/node_group_autoscaling_policy.tf.erb b/templates/terraform/examples/node_group_autoscaling_policy.tf.erb
index da1be0e9a3a8..abc9694b7e16 100644
--- a/templates/terraform/examples/node_group_autoscaling_policy.tf.erb
+++ b/templates/terraform/examples/node_group_autoscaling_policy.tf.erb
@@ -1,13 +1,8 @@
-data "google_compute_node_types" "central1a" {
- provider = google-beta
- zone = "us-central1-a"
-}
-
resource "google_compute_node_template" "soletenant-tmpl" {
provider = google-beta
name = "<%= ctx[:vars]['template_name'] %>"
region = "us-central1"
- node_type = data.google_compute_node_types.central1a.names[0]
+ node_type = "n1-node-96-624"
}
resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" {
@@ -17,7 +12,7 @@ resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" {
description = "example google_compute_node_group for Terraform Google Provider"
size = 1
- node_template = google_compute_node_template.soletenant-tmpl.self_link
+ node_template = google_compute_node_template.soletenant-tmpl.id
autoscaling_policy {
mode = "ON"
min_nodes = 1
diff --git a/templates/terraform/examples/node_group_basic.tf.erb b/templates/terraform/examples/node_group_basic.tf.erb
index 821d7e16cb40..9de28cdaf0aa 100644
--- a/templates/terraform/examples/node_group_basic.tf.erb
+++ b/templates/terraform/examples/node_group_basic.tf.erb
@@ -1,11 +1,7 @@
-data "google_compute_node_types" "central1a" {
- zone = "us-central1-a"
-}
-
resource "google_compute_node_template" "soletenant-tmpl" {
name = "<%= ctx[:vars]['template_name'] %>"
region = "us-central1"
- node_type = data.google_compute_node_types.central1a.names[0]
+ node_type = "n1-node-96-624"
}
resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" {
@@ -14,5 +10,5 @@ resource "google_compute_node_group" "<%= ctx[:primary_resource_id] %>" {
description = "example google_compute_node_group for Terraform Google Provider"
size = 1
- node_template = google_compute_node_template.soletenant-tmpl.self_link
+ node_template = google_compute_node_template.soletenant-tmpl.id
}
diff --git a/templates/terraform/examples/node_template_basic.tf.erb b/templates/terraform/examples/node_template_basic.tf.erb
index 7dc0ce41c03d..4b932196b9b4 100644
--- a/templates/terraform/examples/node_template_basic.tf.erb
+++ b/templates/terraform/examples/node_template_basic.tf.erb
@@ -1,9 +1,5 @@
-data "google_compute_node_types" "central1a" {
- zone = "us-central1-a"
-}
-
resource "google_compute_node_template" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['template_name'] %>"
region = "us-central1"
- node_type = data.google_compute_node_types.central1a.names[0]
+ node_type = "n1-node-96-624"
}
diff --git a/templates/terraform/examples/node_template_server_binding.tf.erb b/templates/terraform/examples/node_template_server_binding.tf.erb
index f300437aa4dc..391355935e43 100644
--- a/templates/terraform/examples/node_template_server_binding.tf.erb
+++ b/templates/terraform/examples/node_template_server_binding.tf.erb
@@ -13,7 +13,7 @@ resource "google_compute_node_template" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['template_name'] %>"
region = "us-central1"
- node_type = data.google_compute_node_types.central1a.names[0]
+ node_type = "n1-node-96-624"
node_affinity_labels = {
foo = "baz"
diff --git a/templates/terraform/examples/notebook_environment_basic.tf.erb b/templates/terraform/examples/notebook_environment_basic.tf.erb
new file mode 100644
index 000000000000..b89f2e6a8ac7
--- /dev/null
+++ b/templates/terraform/examples/notebook_environment_basic.tf.erb
@@ -0,0 +1,8 @@
+resource "google_notebooks_environment" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["environment_name"] %>"
+ location = "us-west1-a"
+ container_image {
+ repository = "gcr.io/deeplearning-platform-release/base-cpu"
+ }
+}
diff --git a/templates/terraform/examples/notebook_instance_basic.tf.erb b/templates/terraform/examples/notebook_instance_basic.tf.erb
new file mode 100644
index 000000000000..5a418bfef193
--- /dev/null
+++ b/templates/terraform/examples/notebook_instance_basic.tf.erb
@@ -0,0 +1,10 @@
+resource "google_notebooks_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ location = "us-west1-a"
+ machine_type = "n1-standard-1"
+ vm_image {
+ project = "deeplearning-platform-release"
+ image_family = "tf-latest-cpu"
+ }
+}
diff --git a/templates/terraform/examples/notebook_instance_basic_container.tf.erb b/templates/terraform/examples/notebook_instance_basic_container.tf.erb
new file mode 100644
index 000000000000..cff8598c9907
--- /dev/null
+++ b/templates/terraform/examples/notebook_instance_basic_container.tf.erb
@@ -0,0 +1,14 @@
+resource "google_notebooks_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ location = "us-west1-a"
+ machine_type = "n1-standard-1"
+ metadata = {
+ proxy-mode = "service_account"
+ terraform = "true"
+ }
+ container_image {
+ repository = "gcr.io/deeplearning-platform-release/base-cpu"
+ tag = "latest"
+ }
+}
diff --git a/templates/terraform/examples/notebook_instance_basic_gpu.tf.erb b/templates/terraform/examples/notebook_instance_basic_gpu.tf.erb
new file mode 100644
index 000000000000..491280d1f3db
--- /dev/null
+++ b/templates/terraform/examples/notebook_instance_basic_gpu.tf.erb
@@ -0,0 +1,16 @@
+resource "google_notebooks_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ location = "us-west1-a"
+ machine_type = "n1-standard-1"
+
+ install_gpu_driver = true
+ accelerator_config {
+ type = "NVIDIA_TESLA_T4"
+ core_count = 1
+ }
+ vm_image {
+ project = "deeplearning-platform-release"
+ image_family = "tf-latest-gpu"
+ }
+}
diff --git a/templates/terraform/examples/notebook_instance_full.tf.erb b/templates/terraform/examples/notebook_instance_full.tf.erb
new file mode 100644
index 000000000000..df2404b8b2a1
--- /dev/null
+++ b/templates/terraform/examples/notebook_instance_full.tf.erb
@@ -0,0 +1,43 @@
+resource "google_notebooks_instance" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ name = "<%= ctx[:vars]["instance_name"] %>"
+ location = "us-central1-a"
+ machine_type = "n1-standard-1"
+
+ vm_image {
+ project = "deeplearning-platform-release"
+ image_family = "tf-latest-cpu"
+ }
+
+ instance_owners = "admin@hashicorptest.com"
+ service_account = "<%= ctx[:test_env_vars]["service_account"] %>"
+
+ install_gpu_driver = true
+ boot_disk_type = "PD_SSD"
+ boot_disk_size_gb = 110
+
+ no_public_ip = true
+ no_proxy_access = true
+
+ network = data.google_compute_network.my_network.id
+ subnet = data.google_compute_subnetwork.my_subnetwork.id
+
+ labels = {
+ k = "val"
+ }
+
+ metadata = {
+ terraform = "true"
+ }
+}
+
+data "google_compute_network" "my_network" {
+ provider = google-beta
+ name = "default"
+}
+
+data "google_compute_subnetwork" "my_subnetwork" {
+ provider = google-beta
+ name = "default"
+ region = "us-central1"
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_guest_policies_basic.tf.erb b/templates/terraform/examples/os_config_guest_policies_basic.tf.erb
new file mode 100644
index 000000000000..29eadc0991ee
--- /dev/null
+++ b/templates/terraform/examples/os_config_guest_policies_basic.tf.erb
@@ -0,0 +1,42 @@
+data "google_compute_image" "my_image" {
+ provider = google-beta
+ family = "debian-9"
+ project = "debian-cloud"
+}
+
+resource "google_compute_instance" "foobar" {
+ provider = google-beta
+ name = "<%= ctx[:vars]['instance_name'] %>"
+ machine_type = "n1-standard-1"
+ zone = "us-central1-a"
+ can_ip_forward = false
+ tags = ["foo", "bar"]
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.my_image.self_link
+ }
+ }
+
+ network_interface {
+ network = "default"
+ }
+
+ metadata = {
+ foo = "bar"
+ }
+}
+
+resource "google_os_config_guest_policies" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ guest_policy_id = "<%= ctx[:vars]['guest_policy_id'] %>"
+
+ assignment {
+ instances = [google_compute_instance.foobar.id]
+ }
+
+ packages {
+ name = "my-package"
+ desired_state = "UPDATED"
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_guest_policies_packages.tf.erb b/templates/terraform/examples/os_config_guest_policies_packages.tf.erb
new file mode 100644
index 000000000000..a8fe5e23332b
--- /dev/null
+++ b/templates/terraform/examples/os_config_guest_policies_packages.tf.erb
@@ -0,0 +1,54 @@
+resource "google_os_config_guest_policies" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ guest_policy_id = "<%= ctx[:vars]['guest_policy_id'] %>"
+
+ assignment {
+ group_labels {
+ labels = {
+ color = "red",
+ env = "test"
+ }
+ }
+
+ group_labels {
+ labels = {
+ color = "blue",
+ env = "test"
+ }
+ }
+ }
+
+ packages {
+ name = "my-package"
+ desired_state = "INSTALLED"
+ }
+
+ packages {
+ name = "bad-package-1"
+ desired_state = "REMOVED"
+ }
+
+ packages {
+ name = "bad-package-2"
+ desired_state = "REMOVED"
+ manager = "APT"
+ }
+
+ package_repositories {
+ apt {
+ uri = "https://packages.cloud.google.com/apt"
+ archive_type = "DEB"
+ distribution = "cloud-sdk-stretch"
+ components = ["main"]
+ }
+ }
+
+ package_repositories {
+ yum {
+ id = "google-cloud-sdk"
+ display_name = "Google Cloud SDK"
+ base_url = "https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64"
+ gpg_keys = ["https://packages.cloud.google.com/yum/doc/yum-key.gpg", "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg"]
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_guest_policies_recipes.tf.erb b/templates/terraform/examples/os_config_guest_policies_recipes.tf.erb
new file mode 100644
index 000000000000..718ca22a1154
--- /dev/null
+++ b/templates/terraform/examples/os_config_guest_policies_recipes.tf.erb
@@ -0,0 +1,29 @@
+resource "google_os_config_guest_policies" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ guest_policy_id = "<%= ctx[:vars]['guest_policy_id'] %>"
+
+ assignment {
+ zones = ["us-east1-b", "us-east1-d"]
+ }
+
+ recipes {
+ name = "<%= ctx[:vars]['guest_policy_id'] %>-recipe"
+ desired_state = "INSTALLED"
+
+ artifacts {
+ id = "<%= ctx[:vars]['guest_policy_id'] %>-artifact-id"
+
+ gcs {
+ bucket = "my-bucket"
+ object = "executable.msi"
+ generation = 1546030865175603
+ }
+ }
+
+ install_steps {
+ msi_installation {
+ artifact_id = "<%= ctx[:vars]['guest_policy_id'] %>-artifact-id"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_patch_deployment_basic.tf.erb b/templates/terraform/examples/os_config_patch_deployment_basic.tf.erb
new file mode 100644
index 000000000000..0a173a68e43d
--- /dev/null
+++ b/templates/terraform/examples/os_config_patch_deployment_basic.tf.erb
@@ -0,0 +1,21 @@
+resource "google_os_config_patch_deployment" "<%= ctx[:primary_resource_id] %>" {
+ patch_deployment_id = "<%= ctx[:vars]['instance_name'] %>"
+
+ instance_filter {
+ all = true
+ }
+
+ recurring_schedule {
+ time_zone {
+ id = "America/New_York"
+ }
+
+ time_of_day {
+ hours = 1
+ }
+
+ weekly {
+ day_of_week = "MONDAY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_patch_deployment_full.tf.erb b/templates/terraform/examples/os_config_patch_deployment_full.tf.erb
new file mode 100644
index 000000000000..76178e499c28
--- /dev/null
+++ b/templates/terraform/examples/os_config_patch_deployment_full.tf.erb
@@ -0,0 +1,97 @@
+resource "google_os_config_patch_deployment" "<%= ctx[:primary_resource_id] %>" {
+ patch_deployment_id = "<%= ctx[:vars]['instance_name'] %>"
+
+ instance_filter {
+ group_labels {
+ labels = {
+ env = "dev",
+ app = "web"
+ }
+ }
+
+ instance_name_prefixes = ["test-"]
+
+ zones = ["us-central1-a", "us-central-1c"]
+ }
+
+ patch_config {
+ reboot_config = "ALWAYS"
+
+ apt {
+ type = "DIST"
+ excludes = ["python"]
+ }
+
+ yum {
+ security = true
+ minimal = true
+ excludes = ["bash"]
+ }
+
+ goo {
+ enabled = true
+ }
+
+ zypper {
+ categories = ["security"]
+ }
+
+ windows_update {
+ exclusive_patches = ["KB4339284"]
+ }
+
+ pre_step {
+ linux_exec_step_config {
+ allowed_success_codes = [0,3]
+ local_path = "/tmp/pre_patch_script.sh"
+ }
+
+ windows_exec_step_config {
+ interpreter = "SHELL"
+ allowed_success_codes = [0,2]
+ local_path = "C:\\Users\\user\\pre-patch-script.cmd"
+ }
+ }
+
+ post_step {
+ linux_exec_step_config {
+ gcs_object {
+ bucket = "my-patch-scripts"
+ generation_number = "1523477886880"
+ object = "linux/post_patch_script"
+ }
+ }
+
+ windows_exec_step_config {
+ interpreter = "POWERSHELL"
+ gcs_object {
+ bucket = "my-patch-scripts"
+ generation_number = "135920493447"
+ object = "windows/post_patch_script.ps1"
+ }
+ }
+ }
+ }
+
+ duration = "10s"
+
+ recurring_schedule {
+ time_zone {
+ id = "America/New_York"
+ }
+
+ time_of_day {
+ hours = 0
+ minutes = 30
+ seconds = 30
+ nanos = 20
+ }
+
+ monthly {
+ week_day_of_month {
+ week_ordinal = -1
+ day_of_week = "TUESDAY"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/os_config_patch_deployment_instance.tf.erb b/templates/terraform/examples/os_config_patch_deployment_instance.tf.erb
new file mode 100644
index 000000000000..c8ac959c81e2
--- /dev/null
+++ b/templates/terraform/examples/os_config_patch_deployment_instance.tf.erb
@@ -0,0 +1,59 @@
+data "google_compute_image" "my_image" {
+ family = "debian-9"
+ project = "debian-cloud"
+}
+
+resource "google_compute_instance" "foobar" {
+ name = "<%= ctx[:vars]['instance_name'] %>"
+ machine_type = "n1-standard-1"
+ zone = "us-central1-a"
+ can_ip_forward = false
+ tags = ["foo", "bar"]
+
+ boot_disk {
+ initialize_params {
+ image = data.google_compute_image.my_image.self_link
+ }
+ }
+
+ network_interface {
+ network = "default"
+ }
+
+ metadata = {
+ foo = "bar"
+ }
+}
+
+resource "google_os_config_patch_deployment" "<%= ctx[:primary_resource_id] %>" {
+ patch_deployment_id = "<%= ctx[:vars]['instance_name'] %>"
+
+ instance_filter {
+ instances = [google_compute_instance.foobar.id]
+ }
+
+ patch_config {
+ yum {
+ security = true
+ minimal = true
+ excludes = ["bash"]
+ }
+ }
+
+ recurring_schedule {
+ time_zone {
+ id = "America/New_York"
+ }
+
+ time_of_day {
+ hours = 0
+ minutes = 30
+ seconds = 30
+ nanos = 20
+ }
+
+ monthly {
+ month_day = 1
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/pubsub_topic_cmek.tf.erb b/templates/terraform/examples/pubsub_topic_cmek.tf.erb
index 974de2457c3a..258dfacd5455 100644
--- a/templates/terraform/examples/pubsub_topic_cmek.tf.erb
+++ b/templates/terraform/examples/pubsub_topic_cmek.tf.erb
@@ -1,11 +1,11 @@
resource "google_pubsub_topic" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['topic_name'] %>"
- kms_key_name = google_kms_crypto_key.crypto_key.self_link
+ kms_key_name = google_kms_crypto_key.crypto_key.id
}
resource "google_kms_crypto_key" "crypto_key" {
name = "<%= ctx[:vars]['key_name'] %>"
- key_ring = google_kms_key_ring.key_ring.self_link
+ key_ring = google_kms_key_ring.key_ring.id
}
resource "google_kms_key_ring" "key_ring" {
diff --git a/templates/terraform/examples/redis_instance_full.tf.erb b/templates/terraform/examples/redis_instance_full.tf.erb
index 9ac81a29cc85..a76043b58a4d 100644
--- a/templates/terraform/examples/redis_instance_full.tf.erb
+++ b/templates/terraform/examples/redis_instance_full.tf.erb
@@ -6,7 +6,7 @@ resource "google_redis_instance" "<%= ctx[:primary_resource_id] %>" {
location_id = "us-central1-a"
alternative_location_id = "us-central1-f"
- authorized_network = data.google_compute_network.redis-network.self_link
+ authorized_network = data.google_compute_network.redis-network.id
redis_version = "REDIS_3_2"
display_name = "Terraform Test Instance"
diff --git a/templates/terraform/examples/redis_instance_private_service.tf.erb b/templates/terraform/examples/redis_instance_private_service.tf.erb
index c70cb77d84a9..65db1ff4aa80 100644
--- a/templates/terraform/examples/redis_instance_private_service.tf.erb
+++ b/templates/terraform/examples/redis_instance_private_service.tf.erb
@@ -7,11 +7,11 @@ resource "google_compute_global_address" "service_range" {
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
- network = google_compute_network.network.self_link
+ network = google_compute_network.network.id
}
resource "google_service_networking_connection" "private_service_connection" {
- network = google_compute_network.network.self_link
+ network = google_compute_network.network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.service_range.name]
}
@@ -24,7 +24,7 @@ resource "google_redis_instance" "<%= ctx[:primary_resource_id] %>" {
location_id = "us-central1-a"
alternative_location_id = "us-central1-f"
- authorized_network = google_compute_network.network.self_link
+ authorized_network = google_compute_network.network.id
connect_mode = "PRIVATE_SERVICE_ACCESS"
redis_version = "REDIS_3_2"
diff --git a/templates/terraform/examples/region_autoscaler_basic.tf.erb b/templates/terraform/examples/region_autoscaler_basic.tf.erb
index 355d02440f8b..c3c4ef4a2528 100644
--- a/templates/terraform/examples/region_autoscaler_basic.tf.erb
+++ b/templates/terraform/examples/region_autoscaler_basic.tf.erb
@@ -22,7 +22,7 @@ resource "google_compute_instance_template" "foobar" {
tags = ["foo", "bar"]
disk {
- source_image = data.google_compute_image.debian_9.self_link
+ source_image = data.google_compute_image.debian_9.id
}
network_interface {
diff --git a/templates/terraform/examples/region_backend_service_balancing_mode.tf.erb b/templates/terraform/examples/region_backend_service_balancing_mode.tf.erb
index fb29e0ddf88c..fb521a835700 100644
--- a/templates/terraform/examples/region_backend_service_balancing_mode.tf.erb
+++ b/templates/terraform/examples/region_backend_service_balancing_mode.tf.erb
@@ -1,6 +1,4 @@
resource "google_compute_region_backend_service" "default" {
- provider = google-beta
-
load_balancing_scheme = "INTERNAL_MANAGED"
backend {
@@ -14,23 +12,19 @@ resource "google_compute_region_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
data "google_compute_image" "debian_image" {
- provider = google-beta
-
family = "debian-9"
project = "debian-cloud"
}
resource "google_compute_region_instance_group_manager" "rigm" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['rigm_name'] %>"
version {
- instance_template = google_compute_instance_template.instance_template.self_link
+ instance_template = google_compute_instance_template.instance_template.id
name = "primary"
}
base_instance_name = "internal-glb"
@@ -38,14 +32,12 @@ resource "google_compute_region_instance_group_manager" "rigm" {
}
resource "google_compute_instance_template" "instance_template" {
- provider = google-beta
-
name = "template-<%= ctx[:vars]['region_backend_service_name'] %>"
machine_type = "n1-standard-1"
network_interface {
- network = google_compute_network.default.self_link
- subnetwork = google_compute_subnetwork.default.self_link
+ network = google_compute_network.default.id
+ subnetwork = google_compute_subnetwork.default.id
}
disk {
@@ -58,8 +50,6 @@ resource "google_compute_instance_template" "instance_template" {
}
resource "google_compute_region_health_check" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
@@ -68,18 +58,14 @@ resource "google_compute_region_health_check" "default" {
}
resource "google_compute_network" "default" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_name'] %>"
auto_create_subnetworks = false
routing_mode = "REGIONAL"
}
resource "google_compute_subnetwork" "default" {
- provider = google-beta
-
name = "<%= ctx[:vars]['network_name'] %>-default"
ip_cidr_range = "10.1.2.0/24"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
diff --git a/templates/terraform/examples/region_backend_service_basic.tf.erb b/templates/terraform/examples/region_backend_service_basic.tf.erb
index b7a04720e926..acbc9a75e482 100644
--- a/templates/terraform/examples/region_backend_service_basic.tf.erb
+++ b/templates/terraform/examples/region_backend_service_basic.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_region_backend_service" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
region = "us-central1"
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
connection_draining_timeout_sec = 10
session_affinity = "CLIENT_IP"
}
diff --git a/templates/terraform/examples/region_backend_service_ilb_ring_hash.tf.erb b/templates/terraform/examples/region_backend_service_ilb_ring_hash.tf.erb
index 4c754df00b24..cce5eb0ae5c3 100644
--- a/templates/terraform/examples/region_backend_service_ilb_ring_hash.tf.erb
+++ b/templates/terraform/examples/region_backend_service_ilb_ring_hash.tf.erb
@@ -1,9 +1,7 @@
resource "google_compute_region_backend_service" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
-
region = "us-central1"
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
- health_checks = ["${google_compute_health_check.health_check.self_link}"]
+ health_checks = [google_compute_health_check.health_check.id]
load_balancing_scheme = "INTERNAL_MANAGED"
locality_lb_policy = "RING_HASH"
session_affinity = "HTTP_COOKIE"
@@ -26,8 +24,6 @@ resource "google_compute_region_backend_service" "<%= ctx[:primary_resource_id]
}
resource "google_compute_health_check" "health_check" {
- provider = "google-beta"
-
name = "<%= ctx[:vars]['health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/region_backend_service_ilb_round_robin.tf.erb b/templates/terraform/examples/region_backend_service_ilb_round_robin.tf.erb
index 488de257e029..2d93c3b2c2f3 100644
--- a/templates/terraform/examples/region_backend_service_ilb_round_robin.tf.erb
+++ b/templates/terraform/examples/region_backend_service_ilb_round_robin.tf.erb
@@ -1,17 +1,13 @@
resource "google_compute_region_backend_service" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
-
region = "us-central1"
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
- health_checks = ["${google_compute_health_check.health_check.self_link}"]
+ health_checks = [google_compute_health_check.health_check.id]
protocol = "HTTP"
load_balancing_scheme = "INTERNAL_MANAGED"
locality_lb_policy = "ROUND_ROBIN"
}
resource "google_compute_health_check" "health_check" {
- provider = "google-beta"
-
name = "<%= ctx[:vars]['health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/region_disk_basic.tf.erb b/templates/terraform/examples/region_disk_basic.tf.erb
index 52726d6d9277..4945baa0a3b0 100644
--- a/templates/terraform/examples/region_disk_basic.tf.erb
+++ b/templates/terraform/examples/region_disk_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_region_disk" "regiondisk" {
name = "<%= ctx[:vars]['region_disk_name'] %>"
- snapshot = google_compute_snapshot.snapdisk.self_link
+ snapshot = google_compute_snapshot.snapdisk.id
type = "pd-ssd"
region = "us-central1"
physical_block_size_bytes = 4096
diff --git a/templates/terraform/examples/region_disk_resource_policy_attachment_basic.tf.erb b/templates/terraform/examples/region_disk_resource_policy_attachment_basic.tf.erb
index aae4fa46e7dc..d7fea5727985 100644
--- a/templates/terraform/examples/region_disk_resource_policy_attachment_basic.tf.erb
+++ b/templates/terraform/examples/region_disk_resource_policy_attachment_basic.tf.erb
@@ -21,7 +21,7 @@ resource "google_compute_snapshot" "snapdisk" {
resource "google_compute_region_disk" "ssd" {
name = "<%= ctx[:vars]['disk_name'] %>"
replica_zones = ["us-central1-a", "us-central1-f"]
- snapshot = google_compute_snapshot.snapdisk.self_link
+ snapshot = google_compute_snapshot.snapdisk.id
size = 50
type = "pd-ssd"
region = "us-central1"
diff --git a/templates/terraform/examples/region_ssl_certificate_target_https_proxies.tf.erb b/templates/terraform/examples/region_ssl_certificate_target_https_proxies.tf.erb
index 50a6bf311b36..9be83a3f210c 100644
--- a/templates/terraform/examples/region_ssl_certificate_target_https_proxies.tf.erb
+++ b/templates/terraform/examples/region_ssl_certificate_target_https_proxies.tf.erb
@@ -9,7 +9,6 @@
// name with name_prefix, or use random_id resource. Example:
resource "google_compute_region_ssl_certificate" "default" {
- provider = google-beta
region = "us-central1"
name_prefix = "my-certificate-"
private_key = file("path/to/private.key")
@@ -21,20 +20,18 @@ resource "google_compute_region_ssl_certificate" "default" {
}
resource "google_compute_region_target_https_proxy" "default" {
- provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['region_target_https_proxy_name'] %>"
- url_map = google_compute_region_url_map.default.self_link
- ssl_certificates = [google_compute_region_ssl_certificate.default.self_link]
+ url_map = google_compute_region_url_map.default.id
+ ssl_certificates = [google_compute_region_ssl_certificate.default.id]
}
resource "google_compute_region_url_map" "default" {
- provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -43,27 +40,25 @@ resource "google_compute_region_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_region_backend_service.default.self_link
+ service = google_compute_region_backend_service.default.id
}
}
}
resource "google_compute_region_backend_service" "default" {
- provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
resource "google_compute_region_health_check" "default" {
- provider = google-beta
region = "us-central1"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
diff --git a/templates/terraform/examples/region_target_http_proxy_basic.tf.erb b/templates/terraform/examples/region_target_http_proxy_basic.tf.erb
index dff5528e3958..ca44fc4f296f 100644
--- a/templates/terraform/examples/region_target_http_proxy_basic.tf.erb
+++ b/templates/terraform/examples/region_target_http_proxy_basic.tf.erb
@@ -1,17 +1,13 @@
resource "google_compute_region_target_http_proxy" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_target_http_proxy_name'] %>"
- url_map = google_compute_region_url_map.default.self_link
+ url_map = google_compute_region_url_map.default.id
}
resource "google_compute_region_url_map" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -20,29 +16,25 @@ resource "google_compute_region_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_region_backend_service.default.self_link
+ service = google_compute_region_backend_service.default.id
}
}
}
resource "google_compute_region_backend_service" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
resource "google_compute_region_health_check" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
diff --git a/templates/terraform/examples/region_target_http_proxy_https_redirect.tf.erb b/templates/terraform/examples/region_target_http_proxy_https_redirect.tf.erb
new file mode 100644
index 000000000000..b4cca54587e9
--- /dev/null
+++ b/templates/terraform/examples/region_target_http_proxy_https_redirect.tf.erb
@@ -0,0 +1,14 @@
+resource "google_compute_region_target_http_proxy" "default" {
+ region = "us-central1"
+ name = "<%= ctx[:vars]['region_target_http_proxy_name'] %>"
+ url_map = google_compute_region_url_map.default.id
+}
+
+resource "google_compute_region_url_map" "default" {
+ region = "us-central1"
+ name = "<%= ctx[:vars]['region_url_map_name'] %>"
+ default_url_redirect {
+ https_redirect = true
+ strip_query = false
+ }
+}
diff --git a/templates/terraform/examples/region_target_https_proxy_basic.tf.erb b/templates/terraform/examples/region_target_https_proxy_basic.tf.erb
index bde6dde8671c..3924678ac3c5 100644
--- a/templates/terraform/examples/region_target_https_proxy_basic.tf.erb
+++ b/templates/terraform/examples/region_target_https_proxy_basic.tf.erb
@@ -1,15 +1,11 @@
resource "google_compute_region_target_https_proxy" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_target_https_proxy_name'] %>"
- url_map = google_compute_region_url_map.default.self_link
- ssl_certificates = [google_compute_region_ssl_certificate.default.self_link]
+ url_map = google_compute_region_url_map.default.id
+ ssl_certificates = [google_compute_region_ssl_certificate.default.id]
}
resource "google_compute_region_ssl_certificate" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_ssl_certificate_name'] %>"
private_key = file("path/to/private.key")
@@ -17,13 +13,11 @@ resource "google_compute_region_ssl_certificate" "default" {
}
resource "google_compute_region_url_map" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -32,29 +26,25 @@ resource "google_compute_region_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.default.self_link
+ default_service = google_compute_region_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_region_backend_service.default.self_link
+ service = google_compute_region_backend_service.default.id
}
}
}
resource "google_compute_region_backend_service" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
resource "google_compute_region_health_check" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
diff --git a/templates/terraform/examples/region_url_map_basic.tf.erb b/templates/terraform/examples/region_url_map_basic.tf.erb
index f819aaaa8dd3..01b4b5a18958 100644
--- a/templates/terraform/examples/region_url_map_basic.tf.erb
+++ b/templates/terraform/examples/region_url_map_basic.tf.erb
@@ -1,12 +1,10 @@
resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -15,53 +13,47 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
path_rule {
paths = ["/home"]
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
}
path_rule {
paths = ["/login"]
- service = google_compute_region_backend_service.login.self_link
+ service = google_compute_region_backend_service.login.id
}
}
test {
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
host = "hi.com"
path = "/home"
}
}
resource "google_compute_region_backend_service" "login" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['login_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
resource "google_compute_region_backend_service" "home" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['home_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
}
resource "google_compute_region_health_check" "default" {
- provider = google-beta
-
region = "us-central1"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
diff --git a/templates/terraform/examples/region_url_map_l7_ilb_path.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_path.tf.erb
index 13eb610fd80a..43523de9f88e 100644
--- a/templates/terraform/examples/region_url_map_l7_ilb_path.tf.erb
+++ b/templates/terraform/examples/region_url_map_l7_ilb_path.tf.erb
@@ -1,8 +1,7 @@
resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -11,7 +10,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
path_rule {
paths = ["/home"]
@@ -39,7 +38,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
}
}
request_mirror_policy {
- backend_service = google_compute_region_backend_service.home.self_link
+ backend_service = google_compute_region_backend_service.home.id
}
retry_policy {
num_retries = 4
@@ -57,7 +56,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_prefix_rewrite = "A replacement path"
}
weighted_backend_services {
- backend_service = google_compute_region_backend_service.home.self_link
+ backend_service = google_compute_region_backend_service.home.id
weight = 400
header_action {
request_headers_to_remove = ["RemoveMe"]
@@ -79,24 +78,22 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
host = "hi.com"
path = "/home"
}
}
resource "google_compute_region_backend_service" "home" {
- provider = "google-beta"
name = "<%= ctx[:vars]['home_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
load_balancing_scheme = "INTERNAL_MANAGED"
}
resource "google_compute_region_health_check" "default" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/region_url_map_l7_ilb_path_partial.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_path_partial.tf.erb
index b5b264144248..48eebdab4d3e 100644
--- a/templates/terraform/examples/region_url_map_l7_ilb_path_partial.tf.erb
+++ b/templates/terraform/examples/region_url_map_l7_ilb_path_partial.tf.erb
@@ -1,8 +1,7 @@
resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -11,7 +10,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
path_rule {
paths = ["/home"]
@@ -32,7 +31,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_prefix_rewrite = "A replacement path"
}
weighted_backend_services {
- backend_service = google_compute_region_backend_service.home.self_link
+ backend_service = google_compute_region_backend_service.home.id
weight = 400
header_action {
response_headers_to_add {
@@ -47,24 +46,22 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
host = "hi.com"
path = "/home"
}
}
resource "google_compute_region_backend_service" "home" {
- provider = "google-beta"
name = "<%= ctx[:vars]['home_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
load_balancing_scheme = "INTERNAL_MANAGED"
}
resource "google_compute_region_health_check" "default" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb
index e6f691367ebb..017cea1c1095 100644
--- a/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb
+++ b/templates/terraform/examples/region_url_map_l7_ilb_route.tf.erb
@@ -1,8 +1,7 @@
resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -11,7 +10,7 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
route_rules {
priority = 1
@@ -60,24 +59,22 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
host = "hi.com"
path = "/home"
}
}
resource "google_compute_region_backend_service" "home" {
- provider = "google-beta"
name = "<%= ctx[:vars]['home_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
load_balancing_scheme = "INTERNAL_MANAGED"
}
resource "google_compute_region_health_check" "default" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb b/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb
index 7060f3ed6937..a15b770a5a8d 100644
--- a/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb
+++ b/templates/terraform/examples/region_url_map_l7_ilb_route_partial.tf.erb
@@ -1,8 +1,7 @@
resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_url_map_name'] %>"
description = "a description"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -11,11 +10,11 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_region_backend_service.home.self_link
+ default_service = google_compute_region_backend_service.home.id
route_rules {
priority = 1
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
header_action {
request_headers_to_remove = ["RemoveMe2"]
}
@@ -35,24 +34,22 @@ resource "google_compute_region_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_region_backend_service.home.self_link
+ service = google_compute_region_backend_service.home.id
host = "hi.com"
path = "/home"
}
}
resource "google_compute_region_backend_service" "home" {
- provider = "google-beta"
name = "<%= ctx[:vars]['home_region_backend_service_name'] %>"
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_region_health_check.default.self_link]
+ health_checks = [google_compute_region_health_check.default.id]
load_balancing_scheme = "INTERNAL_MANAGED"
}
resource "google_compute_region_health_check" "default" {
- provider = "google-beta"
name = "<%= ctx[:vars]['region_health_check_name'] %>"
http_health_check {
port = 80
diff --git a/templates/terraform/examples/resource_policy_placement_policy.tf.erb b/templates/terraform/examples/resource_policy_placement_policy.tf.erb
new file mode 100644
index 000000000000..d7b986612db4
--- /dev/null
+++ b/templates/terraform/examples/resource_policy_placement_policy.tf.erb
@@ -0,0 +1,8 @@
+resource "google_compute_resource_policy" "baz" {
+ name = "<%= ctx[:vars]['name'] %>"
+ region = "us-central1"
+ group_placement_policy {
+ vm_count = 2
+ collocation = "COLLOCATED"
+ }
+}
diff --git a/templates/terraform/examples/route_ilb.tf.erb b/templates/terraform/examples/route_ilb.tf.erb
index 8d9ba6902f22..8a6376c32031 100644
--- a/templates/terraform/examples/route_ilb.tf.erb
+++ b/templates/terraform/examples/route_ilb.tf.erb
@@ -7,7 +7,7 @@ resource "google_compute_subnetwork" "default" {
name = "<%= ctx[:vars]['subnet_name'] %>"
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
- network = google_compute_network.default.self_link
+ network = google_compute_network.default.id
}
resource "google_compute_health_check" "hc" {
@@ -23,7 +23,7 @@ resource "google_compute_health_check" "hc" {
resource "google_compute_region_backend_service" "backend" {
name = "<%= ctx[:vars]['backend_name'] %>"
region = "us-central1"
- health_checks = [google_compute_health_check.hc.self_link]
+ health_checks = [google_compute_health_check.hc.id]
}
resource "google_compute_forwarding_rule" "default" {
@@ -31,7 +31,7 @@ resource "google_compute_forwarding_rule" "default" {
region = "us-central1"
load_balancing_scheme = "INTERNAL"
- backend_service = google_compute_region_backend_service.backend.self_link
+ backend_service = google_compute_region_backend_service.backend.id
all_ports = true
network = google_compute_network.default.name
subnetwork = google_compute_subnetwork.default.name
@@ -41,6 +41,6 @@ resource "google_compute_route" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['route_name'] %>"
dest_range = "0.0.0.0/0"
network = google_compute_network.default.name
- next_hop_ilb = google_compute_forwarding_rule.default.self_link
+ next_hop_ilb = google_compute_forwarding_rule.default.id
priority = 2000
}
diff --git a/templates/terraform/examples/router_nat_basic.tf.erb b/templates/terraform/examples/router_nat_basic.tf.erb
index 8dfb43925135..7bb8629a90c1 100644
--- a/templates/terraform/examples/router_nat_basic.tf.erb
+++ b/templates/terraform/examples/router_nat_basic.tf.erb
@@ -4,7 +4,7 @@ resource "google_compute_network" "net" {
resource "google_compute_subnetwork" "subnet" {
name = "<%= ctx[:vars]['subnet_name'] %>"
- network = google_compute_network.net.self_link
+ network = google_compute_network.net.id
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}
@@ -12,7 +12,7 @@ resource "google_compute_subnetwork" "subnet" {
resource "google_compute_router" "router" {
name = "<%= ctx[:vars]['router_name'] %>"
region = google_compute_subnetwork.subnet.region
- network = google_compute_network.net.self_link
+ network = google_compute_network.net.id
bgp {
asn = 64514
diff --git a/templates/terraform/examples/router_nat_manual_ips.tf.erb b/templates/terraform/examples/router_nat_manual_ips.tf.erb
index 231ee13a102c..fa549eeec86b 100644
--- a/templates/terraform/examples/router_nat_manual_ips.tf.erb
+++ b/templates/terraform/examples/router_nat_manual_ips.tf.erb
@@ -4,7 +4,7 @@ resource "google_compute_network" "net" {
resource "google_compute_subnetwork" "subnet" {
name = "<%= ctx[:vars]['subnet_name'] %>"
- network = google_compute_network.net.self_link
+ network = google_compute_network.net.id
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}
@@ -12,7 +12,7 @@ resource "google_compute_subnetwork" "subnet" {
resource "google_compute_router" "router" {
name = "<%= ctx[:vars]['router_name'] %>"
region = google_compute_subnetwork.subnet.region
- network = google_compute_network.net.self_link
+ network = google_compute_network.net.id
}
resource "google_compute_address" "address" {
@@ -31,7 +31,7 @@ resource "google_compute_router_nat" "<%= ctx[:primary_resource_id] %>" {
source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
- name = google_compute_subnetwork.default.self_link
+ name = google_compute_subnetwork.subnet.id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}
}
diff --git a/templates/terraform/examples/scheduler_job_app_engine.tf.erb b/templates/terraform/examples/scheduler_job_app_engine.tf.erb
index d3e1586acd25..259b563b0ba0 100644
--- a/templates/terraform/examples/scheduler_job_app_engine.tf.erb
+++ b/templates/terraform/examples/scheduler_job_app_engine.tf.erb
@@ -5,6 +5,13 @@ resource "google_cloud_scheduler_job" "job" {
time_zone = "Europe/London"
attempt_deadline = "320s"
+ retry_config {
+ min_backoff_duration = "1s"
+ max_retry_duration = "10s"
+ max_doublings = 2
+ retry_count = 3
+ }
+
app_engine_http_target {
http_method = "POST"
diff --git a/templates/terraform/examples/scheduler_job_http.tf.erb b/templates/terraform/examples/scheduler_job_http.tf.erb
index 5cf2cbebe681..e994f49bcb53 100644
--- a/templates/terraform/examples/scheduler_job_http.tf.erb
+++ b/templates/terraform/examples/scheduler_job_http.tf.erb
@@ -5,6 +5,10 @@ resource "google_cloud_scheduler_job" "job" {
time_zone = "America/New_York"
attempt_deadline = "320s"
+ retry_config {
+ retry_count = 1
+ }
+
http_target {
http_method = "POST"
uri = "https://example.com/ping"
diff --git a/templates/terraform/examples/secret_config_basic.tf.erb b/templates/terraform/examples/secret_config_basic.tf.erb
index 1fcb383d7dea..9e4daaa00033 100644
--- a/templates/terraform/examples/secret_config_basic.tf.erb
+++ b/templates/terraform/examples/secret_config_basic.tf.erb
@@ -1,6 +1,4 @@
resource "google_secret_manager_secret" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
-
secret_id = "<%= ctx[:vars]['secret_id'] %>"
labels = {
diff --git a/templates/terraform/examples/secret_version_basic.tf.erb b/templates/terraform/examples/secret_version_basic.tf.erb
index 13a1a74c42dc..3df2522be8f0 100644
--- a/templates/terraform/examples/secret_version_basic.tf.erb
+++ b/templates/terraform/examples/secret_version_basic.tf.erb
@@ -1,6 +1,4 @@
resource "google_secret_manager_secret" "secret-basic" {
- provider = google-beta
-
secret_id = "<%= ctx[:vars]['secret_id'] %>"
labels = {
@@ -14,8 +12,6 @@ resource "google_secret_manager_secret" "secret-basic" {
resource "google_secret_manager_secret_version" "<%= ctx[:primary_resource_id] %>" {
- provider = google-beta
-
secret = google_secret_manager_secret.secret-basic.id
secret_data = "<%= ctx[:vars]['data'] %>"
diff --git a/templates/terraform/examples/service_directory_endpoint_basic.tf.erb b/templates/terraform/examples/service_directory_endpoint_basic.tf.erb
new file mode 100644
index 000000000000..2f55c715beff
--- /dev/null
+++ b/templates/terraform/examples/service_directory_endpoint_basic.tf.erb
@@ -0,0 +1,25 @@
+resource "google_service_directory_namespace" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ namespace_id = "<%= ctx[:vars]["namespace_id"] %>"
+ location = "us-central1"
+}
+
+resource "google_service_directory_service" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ service_id = "<%= ctx[:vars]["service_id"] %>"
+ namespace = google_service_directory_namespace.<%= ctx[:primary_resource_id] %>.id
+}
+
+resource "google_service_directory_endpoint" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ endpoint_id = "<%= ctx[:vars]["endpoint_id"] %>"
+ service = google_service_directory_service.<%= ctx[:primary_resource_id] %>.id
+
+ metadata = {
+ stage = "prod"
+ region = "us-central1"
+ }
+
+ address = "1.2.3.4"
+ port = 5353
+}
diff --git a/templates/terraform/examples/service_directory_namespace_basic.tf.erb b/templates/terraform/examples/service_directory_namespace_basic.tf.erb
new file mode 100644
index 000000000000..28b6e4a5b5b9
--- /dev/null
+++ b/templates/terraform/examples/service_directory_namespace_basic.tf.erb
@@ -0,0 +1,10 @@
+resource "google_service_directory_namespace" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ namespace_id = "<%= ctx[:vars]["namespace_id"] %>"
+ location = "us-central1"
+
+ labels = {
+ key = "value"
+ foo = "bar"
+ }
+}
diff --git a/templates/terraform/examples/service_directory_service_basic.tf.erb b/templates/terraform/examples/service_directory_service_basic.tf.erb
new file mode 100644
index 000000000000..c62ff6711961
--- /dev/null
+++ b/templates/terraform/examples/service_directory_service_basic.tf.erb
@@ -0,0 +1,16 @@
+resource "google_service_directory_namespace" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ namespace_id = "<%= ctx[:vars]["namespace_id"] %>"
+ location = "us-central1"
+}
+
+resource "google_service_directory_service" "<%= ctx[:primary_resource_id] %>" {
+ provider = google-beta
+ service_id = "<%= ctx[:vars]["service_id"] %>"
+ namespace = google_service_directory_namespace.<%= ctx[:primary_resource_id] %>.id
+
+ metadata = {
+ stage = "prod"
+ region = "us-central1"
+ }
+}
diff --git a/templates/terraform/examples/ssl_certificate_target_https_proxies.tf.erb b/templates/terraform/examples/ssl_certificate_target_https_proxies.tf.erb
index 85f0644444dd..62b3082dabd0 100644
--- a/templates/terraform/examples/ssl_certificate_target_https_proxies.tf.erb
+++ b/templates/terraform/examples/ssl_certificate_target_https_proxies.tf.erb
@@ -20,15 +20,15 @@ resource "google_compute_ssl_certificate" "default" {
resource "google_compute_target_https_proxy" "default" {
name = "<%= ctx[:vars]['target_https_proxy_name'] %>"
- url_map = google_compute_url_map.default.self_link
- ssl_certificates = [google_compute_ssl_certificate.default.self_link]
+ url_map = google_compute_url_map.default.id
+ ssl_certificates = [google_compute_ssl_certificate.default.id]
}
resource "google_compute_url_map" "default" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -37,11 +37,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -52,7 +52,7 @@ resource "google_compute_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/stateful_igm.tf.erb b/templates/terraform/examples/stateful_igm.tf.erb
new file mode 100644
index 000000000000..4df648bb26a8
--- /dev/null
+++ b/templates/terraform/examples/stateful_igm.tf.erb
@@ -0,0 +1,64 @@
+data "google_compute_image" "my_image" {
+ family = "debian-9"
+ project = "debian-cloud"
+}
+
+resource "google_compute_instance_template" "igm-basic" {
+ name = "<%= ctx[:vars]['template_name'] %>"
+ machine_type = "n1-standard-1"
+ can_ip_forward = false
+ tags = ["foo", "bar"]
+
+ disk {
+ source_image = data.google_compute_image.my_image.self_link
+ auto_delete = true
+ boot = true
+ }
+
+ network_interface {
+ network = "default"
+ }
+
+ service_account {
+ scopes = ["userinfo-email", "compute-ro", "storage-ro"]
+ }
+}
+
+resource "google_compute_instance_group_manager" "igm-no-tp" {
+ description = "Terraform test instance group manager"
+ name = "<%= ctx[:vars]['igm_name'] %>"
+
+ version {
+ name = "prod"
+ instance_template = google_compute_instance_template.igm-basic.self_link
+ }
+
+ base_instance_name = "igm-no-tp"
+ zone = "us-central1-c"
+ target_size = 2
+}
+
+resource "google_compute_disk" "default" {
+ name = "test-disk-%{random_suffix}"
+ type = "pd-ssd"
+ zone = google_compute_instance_group_manager.igm.zone
+ image = "debian-8-jessie-v20170523"
+ physical_block_size_bytes = 4096
+}
+
+resource "google_compute_per_instance_config" "with_disk" {
+ zone = google_compute_instance_group_manager.igm.zone
+ instance_group_manager = google_compute_instance_group_manager.igm.name
+ name = "instance-1"
+ preserved_state {
+ metadata = {
+ foo = "bar"
+ }
+
+ disk {
+ device_name = "my-stateful-disk"
+ source = google_compute_disk.default.id
+ mode = "READ_ONLY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/stateful_rigm.tf.erb b/templates/terraform/examples/stateful_rigm.tf.erb
new file mode 100644
index 000000000000..c6ca87ac404b
--- /dev/null
+++ b/templates/terraform/examples/stateful_rigm.tf.erb
@@ -0,0 +1,64 @@
+data "google_compute_image" "my_image" {
+ family = "debian-9"
+ project = "debian-cloud"
+}
+
+resource "google_compute_instance_template" "igm-basic" {
+ name = "<%= ctx[:vars]['template_name'] %>"
+ machine_type = "n1-standard-1"
+ can_ip_forward = false
+ tags = ["foo", "bar"]
+
+ disk {
+ source_image = data.google_compute_image.my_image.self_link
+ auto_delete = true
+ boot = true
+ }
+
+ network_interface {
+ network = "default"
+ }
+
+ service_account {
+ scopes = ["userinfo-email", "compute-ro", "storage-ro"]
+ }
+}
+
+resource "google_compute_region_instance_group_manager" "rigm" {
+ description = "Terraform test instance group manager"
+ name = "<%= ctx[:vars]['igm_name'] %>"
+
+ version {
+ name = "prod"
+ instance_template = google_compute_instance_template.igm-basic.self_link
+ }
+
+ base_instance_name = "rigm"
+ region = "us-central1"
+ target_size = 2
+}
+
+resource "google_compute_disk" "default" {
+ name = "test-disk-%{random_suffix}"
+ type = "pd-ssd"
+ zone = "us-central1-a"
+ image = "debian-8-jessie-v20170523"
+ physical_block_size_bytes = 4096
+}
+
+resource "google_compute_region_per_instance_config" "with_disk" {
+ region = google_compute_instance_group_manager.igm.region
+ region_instance_group_manager = google_compute_region_instance_group_manager.rigm.name
+ name = "instance-1"
+ preserved_state {
+ metadata = {
+ foo = "bar"
+ }
+
+ disk {
+ device_name = "my-stateful-disk"
+ source = google_compute_disk.default.id
+ mode = "READ_ONLY"
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/terraform/examples/subnetwork_basic.tf.erb b/templates/terraform/examples/subnetwork_basic.tf.erb
index 4cd85ab1e126..f5e224b07d2e 100644
--- a/templates/terraform/examples/subnetwork_basic.tf.erb
+++ b/templates/terraform/examples/subnetwork_basic.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges"
name = "<%= ctx[:vars]['subnetwork_name'] %>"
ip_cidr_range = "10.2.0.0/16"
region = "us-central1"
- network = google_compute_network.custom-test.self_link
+ network = google_compute_network.custom-test.id
secondary_ip_range {
range_name = "tf-test-secondary-range-update1"
ip_cidr_range = "192.168.10.0/24"
diff --git a/templates/terraform/examples/subnetwork_internal_l7lb.tf.erb b/templates/terraform/examples/subnetwork_internal_l7lb.tf.erb
index 12bf8b878ecb..a59d00fcd673 100644
--- a/templates/terraform/examples/subnetwork_internal_l7lb.tf.erb
+++ b/templates/terraform/examples/subnetwork_internal_l7lb.tf.erb
@@ -6,7 +6,7 @@ resource "google_compute_subnetwork" "network-for-l7lb" {
region = "us-central1"
purpose = "INTERNAL_HTTPS_LOAD_BALANCER"
role = "ACTIVE"
- network = google_compute_network.custom-test.self_link
+ network = google_compute_network.custom-test.id
}
resource "google_compute_network" "custom-test" {
diff --git a/templates/terraform/examples/subnetwork_logging_config.tf.erb b/templates/terraform/examples/subnetwork_logging_config.tf.erb
index 048a98af49a5..159c6df99094 100644
--- a/templates/terraform/examples/subnetwork_logging_config.tf.erb
+++ b/templates/terraform/examples/subnetwork_logging_config.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_subnetwork" "subnet-with-logging" {
name = "<%= ctx[:vars]['subnetwork_name'] %>"
ip_cidr_range = "10.2.0.0/16"
region = "us-central1"
- network = google_compute_network.custom-test.self_link
+ network = google_compute_network.custom-test.id
log_config {
aggregation_interval = "INTERVAL_10_MIN"
diff --git a/templates/terraform/examples/target_http_proxy_basic.tf.erb b/templates/terraform/examples/target_http_proxy_basic.tf.erb
index a3e099b98fca..86877bfe8c86 100644
--- a/templates/terraform/examples/target_http_proxy_basic.tf.erb
+++ b/templates/terraform/examples/target_http_proxy_basic.tf.erb
@@ -1,11 +1,11 @@
resource "google_compute_target_http_proxy" "default" {
name = "<%= ctx[:vars]['target_http_proxy_name'] %>"
- url_map = google_compute_url_map.default.self_link
+ url_map = google_compute_url_map.default.id
}
resource "google_compute_url_map" "default" {
name = "<%= ctx[:vars]['url_map_name'] %>"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -14,11 +14,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -29,7 +29,7 @@ resource "google_compute_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/target_http_proxy_https_redirect.tf.erb b/templates/terraform/examples/target_http_proxy_https_redirect.tf.erb
new file mode 100644
index 000000000000..a3afb4721400
--- /dev/null
+++ b/templates/terraform/examples/target_http_proxy_https_redirect.tf.erb
@@ -0,0 +1,12 @@
+resource "google_compute_target_http_proxy" "default" {
+ name = "<%= ctx[:vars]['target_http_proxy_name'] %>"
+ url_map = google_compute_url_map.default.id
+}
+
+resource "google_compute_url_map" "default" {
+ name = "<%= ctx[:vars]['url_map_name'] %>"
+ default_url_redirect {
+ https_redirect = true
+ strip_query = false
+ }
+}
diff --git a/templates/terraform/examples/target_https_proxy_basic.tf.erb b/templates/terraform/examples/target_https_proxy_basic.tf.erb
index d8de469b10c1..bf515488eeab 100644
--- a/templates/terraform/examples/target_https_proxy_basic.tf.erb
+++ b/templates/terraform/examples/target_https_proxy_basic.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_target_https_proxy" "default" {
name = "<%= ctx[:vars]['target_https_proxy_name'] %>"
- url_map = google_compute_url_map.default.self_link
- ssl_certificates = [google_compute_ssl_certificate.default.self_link]
+ url_map = google_compute_url_map.default.id
+ ssl_certificates = [google_compute_ssl_certificate.default.id]
}
resource "google_compute_ssl_certificate" "default" {
@@ -14,7 +14,7 @@ resource "google_compute_url_map" "default" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["mysite.com"]
@@ -23,11 +23,11 @@ resource "google_compute_url_map" "default" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.default.self_link
+ default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/*"]
- service = google_compute_backend_service.default.self_link
+ service = google_compute_backend_service.default.id
}
}
}
@@ -38,7 +38,7 @@ resource "google_compute_backend_service" "default" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/target_instance_basic.tf.erb b/templates/terraform/examples/target_instance_basic.tf.erb
index c1ea4e2daacb..2a83b88b2c9e 100644
--- a/templates/terraform/examples/target_instance_basic.tf.erb
+++ b/templates/terraform/examples/target_instance_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_target_instance" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['target_name'] %>"
- instance = google_compute_instance.target-vm.self_link
+ instance = google_compute_instance.target-vm.id
}
data "google_compute_image" "vmimage" {
diff --git a/templates/terraform/examples/target_ssl_proxy_basic.tf.erb b/templates/terraform/examples/target_ssl_proxy_basic.tf.erb
index cd1207a9cc69..8bbfcf259643 100644
--- a/templates/terraform/examples/target_ssl_proxy_basic.tf.erb
+++ b/templates/terraform/examples/target_ssl_proxy_basic.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_target_ssl_proxy" "default" {
name = "<%= ctx[:vars]['target_ssl_proxy_name'] %>"
- backend_service = google_compute_backend_service.default.self_link
- ssl_certificates = [google_compute_ssl_certificate.default.self_link]
+ backend_service = google_compute_backend_service.default.id
+ ssl_certificates = [google_compute_ssl_certificate.default.id]
}
resource "google_compute_ssl_certificate" "default" {
@@ -13,7 +13,7 @@ resource "google_compute_ssl_certificate" "default" {
resource "google_compute_backend_service" "default" {
name = "<%= ctx[:vars]['backend_service_name'] %>"
protocol = "SSL"
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
}
resource "google_compute_health_check" "default" {
diff --git a/templates/terraform/examples/target_tcp_proxy_basic.tf.erb b/templates/terraform/examples/target_tcp_proxy_basic.tf.erb
index fd9c04fc5346..69ad592fdeb0 100644
--- a/templates/terraform/examples/target_tcp_proxy_basic.tf.erb
+++ b/templates/terraform/examples/target_tcp_proxy_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_target_tcp_proxy" "default" {
name = "<%= ctx[:vars]['target_tcp_proxy_name'] %>"
- backend_service = google_compute_backend_service.default.self_link
+ backend_service = google_compute_backend_service.default.id
}
resource "google_compute_backend_service" "default" {
@@ -8,7 +8,7 @@ resource "google_compute_backend_service" "default" {
protocol = "TCP"
timeout_sec = 10
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
}
resource "google_compute_health_check" "default" {
diff --git a/templates/terraform/examples/target_vpn_gateway_basic.tf.erb b/templates/terraform/examples/target_vpn_gateway_basic.tf.erb
index 824ce65f7772..0b57481df59d 100644
--- a/templates/terraform/examples/target_vpn_gateway_basic.tf.erb
+++ b/templates/terraform/examples/target_vpn_gateway_basic.tf.erb
@@ -1,6 +1,6 @@
resource "google_compute_vpn_gateway" "target_gateway" {
name = "<%= ctx[:vars]['target_vpn_gateway_name'] %>"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_network" "network1" {
@@ -15,7 +15,7 @@ resource "google_compute_forwarding_rule" "fr_esp" {
name = "<%= ctx[:vars]['esp_forwarding_rule_name'] %>"
ip_protocol = "ESP"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp500" {
@@ -23,7 +23,7 @@ resource "google_compute_forwarding_rule" "fr_udp500" {
ip_protocol = "UDP"
port_range = "500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp4500" {
@@ -31,7 +31,7 @@ resource "google_compute_forwarding_rule" "fr_udp4500" {
ip_protocol = "UDP"
port_range = "4500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_vpn_tunnel" "tunnel1" {
@@ -39,7 +39,7 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
peer_ip = "15.0.0.120"
shared_secret = "a secret message"
- target_vpn_gateway = google_compute_vpn_gateway.target_gateway.self_link
+ target_vpn_gateway = google_compute_vpn_gateway.target_gateway.id
depends_on = [
google_compute_forwarding_rule.fr_esp,
@@ -54,5 +54,5 @@ resource "google_compute_route" "route1" {
dest_range = "15.0.0.0/24"
priority = 1000
- next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.self_link
+ next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.id
}
diff --git a/templates/terraform/examples/uptime_check_config_http.tf.erb b/templates/terraform/examples/uptime_check_config_http.tf.erb
index 4c10c16a974b..738eb5eab249 100644
--- a/templates/terraform/examples/uptime_check_config_http.tf.erb
+++ b/templates/terraform/examples/uptime_check_config_http.tf.erb
@@ -5,6 +5,9 @@ resource "google_monitoring_uptime_check_config" "<%= ctx[:primary_resource_id]
http_check {
path = "/some-path"
port = "8010"
+ request_method = "POST"
+ content_type = "URL_ENCODED"
+ body = "Zm9vJTI1M0RiYXI="
}
monitored_resource {
diff --git a/templates/terraform/examples/url_map_basic.tf.erb b/templates/terraform/examples/url_map_basic.tf.erb
index 5d870c445cf2..586ad7593ad2 100644
--- a/templates/terraform/examples/url_map_basic.tf.erb
+++ b/templates/terraform/examples/url_map_basic.tf.erb
@@ -2,7 +2,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -16,31 +16,31 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "mysite"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
path_rule {
paths = ["/home"]
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
}
path_rule {
paths = ["/login"]
- service = google_compute_backend_service.login.self_link
+ service = google_compute_backend_service.login.id
}
path_rule {
paths = ["/static"]
- service = google_compute_backend_bucket.static.self_link
+ service = google_compute_backend_bucket.static.id
}
}
path_matcher {
name = "otherpaths"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
}
test {
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
host = "hi.com"
path = "/home"
}
@@ -52,7 +52,7 @@ resource "google_compute_backend_service" "login" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_backend_service" "home" {
@@ -61,7 +61,7 @@ resource "google_compute_backend_service" "home" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_http_health_check.default.self_link]
+ health_checks = [google_compute_http_health_check.default.id]
}
resource "google_compute_http_health_check" "default" {
diff --git a/templates/terraform/examples/url_map_header_based_routing.tf.erb b/templates/terraform/examples/url_map_header_based_routing.tf.erb
new file mode 100644
index 000000000000..dbc35a54325f
--- /dev/null
+++ b/templates/terraform/examples/url_map_header_based_routing.tf.erb
@@ -0,0 +1,75 @@
+resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['url_map_name'] %>"
+ description = "header-based routing example"
+ default_service = google_compute_backend_service.default.id
+
+ host_rule {
+ hosts = ["*"]
+ path_matcher = "allpaths"
+ }
+
+ path_matcher {
+ name = "allpaths"
+ default_service = google_compute_backend_service.default.id
+
+ route_rules {
+ priority = 1
+ service = google_compute_backend_service.service-a.id
+ match_rules {
+ prefix_match = "/"
+ ignore_case = true
+ header_matches {
+ header_name = "abtest"
+ exact_match = "a"
+ }
+ }
+ }
+ route_rules {
+ priority = 2
+ service = google_compute_backend_service.service-b.id
+ match_rules {
+ ignore_case = true
+ prefix_match = "/"
+ header_matches {
+ header_name = "abtest"
+ exact_match = "b"
+ }
+ }
+ }
+ }
+}
+
+resource "google_compute_backend_service" "default" {
+ name = "<%= ctx[:vars]['default_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_backend_service" "service-a" {
+ name = "<%= ctx[:vars]['service_a_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_backend_service" "service-b" {
+ name = "<%= ctx[:vars]['service_b_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_http_health_check" "default" {
+ name = "<%= ctx[:vars]['health_check_name'] %>"
+ request_path = "/"
+ check_interval_sec = 1
+ timeout_sec = 1
+}
+
diff --git a/templates/terraform/examples/url_map_parameter_based_routing.tf.erb b/templates/terraform/examples/url_map_parameter_based_routing.tf.erb
new file mode 100644
index 000000000000..bef10d1a4e97
--- /dev/null
+++ b/templates/terraform/examples/url_map_parameter_based_routing.tf.erb
@@ -0,0 +1,75 @@
+resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
+ name = "<%= ctx[:vars]['url_map_name'] %>"
+ description = "parameter-based routing example"
+ default_service = google_compute_backend_service.default.id
+
+ host_rule {
+ hosts = ["*"]
+ path_matcher = "allpaths"
+ }
+
+ path_matcher {
+ name = "allpaths"
+ default_service = google_compute_backend_service.default.id
+
+ route_rules {
+ priority = 1
+ service = google_compute_backend_service.service-a.id
+ match_rules {
+ prefix_match = "/"
+ ignore_case = true
+ query_parameter_matches {
+ name = "abtest"
+ exact_match = "a"
+ }
+ }
+ }
+ route_rules {
+ priority = 2
+ service = google_compute_backend_service.service-b.id
+ match_rules {
+ ignore_case = true
+ prefix_match = "/"
+ query_parameter_matches {
+ name = "abtest"
+ exact_match = "b"
+ }
+ }
+ }
+ }
+}
+
+resource "google_compute_backend_service" "default" {
+ name = "<%= ctx[:vars]['default_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_backend_service" "service-a" {
+ name = "<%= ctx[:vars]['service_a_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_backend_service" "service-b" {
+ name = "<%= ctx[:vars]['service_b_backend_service_name'] %>"
+ port_name = "http"
+ protocol = "HTTP"
+ timeout_sec = 10
+
+ health_checks = [google_compute_http_health_check.default.id]
+}
+
+resource "google_compute_http_health_check" "default" {
+ name = "<%= ctx[:vars]['health_check_name'] %>"
+ request_path = "/"
+ check_interval_sec = 1
+ timeout_sec = 1
+}
+
diff --git a/templates/terraform/examples/url_map_traffic_director_path.tf.erb b/templates/terraform/examples/url_map_traffic_director_path.tf.erb
index d20634c96738..d61fbc0d7989 100644
--- a/templates/terraform/examples/url_map_traffic_director_path.tf.erb
+++ b/templates/terraform/examples/url_map_traffic_director_path.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -10,7 +10,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
path_rule {
paths = ["/home"]
@@ -39,7 +39,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
}
}
request_mirror_policy {
- backend_service = google_compute_backend_service.home.self_link
+ backend_service = google_compute_backend_service.home.id
}
retry_policy {
num_retries = 4
@@ -57,7 +57,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_prefix_rewrite = "A replacement path"
}
weighted_backend_services {
- backend_service = google_compute_backend_service.home.self_link
+ backend_service = google_compute_backend_service.home.id
weight = 400
header_action {
request_headers_to_remove = ["RemoveMe"]
@@ -79,7 +79,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
host = "hi.com"
path = "/home"
}
@@ -91,7 +91,7 @@ resource "google_compute_backend_service" "home" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
}
diff --git a/templates/terraform/examples/url_map_traffic_director_path_partial.tf.erb b/templates/terraform/examples/url_map_traffic_director_path_partial.tf.erb
index 97b40b773645..aea9bc2f8333 100644
--- a/templates/terraform/examples/url_map_traffic_director_path_partial.tf.erb
+++ b/templates/terraform/examples/url_map_traffic_director_path_partial.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -10,7 +10,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
path_rule {
paths = ["/home"]
@@ -26,7 +26,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
disabled = false
}
weighted_backend_services {
- backend_service = google_compute_backend_service.home.self_link
+ backend_service = google_compute_backend_service.home.id
weight = 400
header_action {
request_headers_to_remove = ["RemoveMe"]
@@ -48,7 +48,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
host = "hi.com"
path = "/home"
}
@@ -60,7 +60,7 @@ resource "google_compute_backend_service" "home" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
}
diff --git a/templates/terraform/examples/url_map_traffic_director_route.tf.erb b/templates/terraform/examples/url_map_traffic_director_route.tf.erb
index 2f4cb7f4f0cc..e959621a45e1 100644
--- a/templates/terraform/examples/url_map_traffic_director_route.tf.erb
+++ b/templates/terraform/examples/url_map_traffic_director_route.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -10,7 +10,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
route_rules {
priority = 1
@@ -59,7 +59,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
host = "hi.com"
path = "/home"
}
@@ -71,7 +71,7 @@ resource "google_compute_backend_service" "home" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
}
diff --git a/templates/terraform/examples/url_map_traffic_director_route_partial.tf.erb b/templates/terraform/examples/url_map_traffic_director_route_partial.tf.erb
index cfa07f561772..c0c8777ee9f6 100644
--- a/templates/terraform/examples/url_map_traffic_director_route_partial.tf.erb
+++ b/templates/terraform/examples/url_map_traffic_director_route_partial.tf.erb
@@ -1,7 +1,7 @@
resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['url_map_name'] %>"
description = "a description"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
host_rule {
hosts = ["mysite.com"]
@@ -10,7 +10,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
path_matcher {
name = "allpaths"
- default_service = google_compute_backend_service.home.self_link
+ default_service = google_compute_backend_service.home.id
route_rules {
priority = 1
@@ -30,7 +30,7 @@ resource "google_compute_url_map" "<%= ctx[:primary_resource_id] %>" {
}
test {
- service = google_compute_backend_service.home.self_link
+ service = google_compute_backend_service.home.id
host = "hi.com"
path = "/home"
}
@@ -42,7 +42,7 @@ resource "google_compute_backend_service" "home" {
protocol = "HTTP"
timeout_sec = 10
- health_checks = [google_compute_health_check.default.self_link]
+ health_checks = [google_compute_health_check.default.id]
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
}
diff --git a/templates/terraform/examples/vpn_tunnel_basic.tf.erb b/templates/terraform/examples/vpn_tunnel_basic.tf.erb
index 4991d0d0234b..6ee49cb02c60 100644
--- a/templates/terraform/examples/vpn_tunnel_basic.tf.erb
+++ b/templates/terraform/examples/vpn_tunnel_basic.tf.erb
@@ -3,7 +3,7 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
peer_ip = "15.0.0.120"
shared_secret = "a secret message"
- target_vpn_gateway = google_compute_vpn_gateway.target_gateway.self_link
+ target_vpn_gateway = google_compute_vpn_gateway.target_gateway.id
depends_on = [
google_compute_forwarding_rule.fr_esp,
@@ -14,7 +14,7 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
resource "google_compute_vpn_gateway" "target_gateway" {
name = "<%= ctx[:vars]['target_vpn_gateway_name'] %>"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_network" "network1" {
@@ -29,7 +29,7 @@ resource "google_compute_forwarding_rule" "fr_esp" {
name = "<%= ctx[:vars]['esp_forwarding_rule_name'] %>"
ip_protocol = "ESP"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp500" {
@@ -37,7 +37,7 @@ resource "google_compute_forwarding_rule" "fr_udp500" {
ip_protocol = "UDP"
port_range = "500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp4500" {
@@ -45,7 +45,7 @@ resource "google_compute_forwarding_rule" "fr_udp4500" {
ip_protocol = "UDP"
port_range = "4500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_route" "route1" {
@@ -54,5 +54,5 @@ resource "google_compute_route" "route1" {
dest_range = "15.0.0.0/24"
priority = 1000
- next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.self_link
+ next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.id
}
diff --git a/templates/terraform/examples/vpn_tunnel_beta.tf.erb b/templates/terraform/examples/vpn_tunnel_beta.tf.erb
index a363eb6b5da0..0b2415d4e1df 100644
--- a/templates/terraform/examples/vpn_tunnel_beta.tf.erb
+++ b/templates/terraform/examples/vpn_tunnel_beta.tf.erb
@@ -4,7 +4,7 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
peer_ip = "15.0.0.120"
shared_secret = "a secret message"
- target_vpn_gateway = google_compute_vpn_gateway.target_gateway.self_link
+ target_vpn_gateway = google_compute_vpn_gateway.target_gateway.id
depends_on = [
google_compute_forwarding_rule.fr_esp,
@@ -20,7 +20,7 @@ resource "google_compute_vpn_tunnel" "tunnel1" {
resource "google_compute_vpn_gateway" "target_gateway" {
provider = google-beta
name = "<%= ctx[:vars]['target_vpn_gateway_name'] %>"
- network = google_compute_network.network1.self_link
+ network = google_compute_network.network1.id
}
resource "google_compute_network" "network1" {
@@ -38,7 +38,7 @@ resource "google_compute_forwarding_rule" "fr_esp" {
name = "<%= ctx[:vars]['esp_forwarding_rule_name'] %>"
ip_protocol = "ESP"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp500" {
@@ -47,7 +47,7 @@ resource "google_compute_forwarding_rule" "fr_udp500" {
ip_protocol = "UDP"
port_range = "500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_forwarding_rule" "fr_udp4500" {
@@ -56,7 +56,7 @@ resource "google_compute_forwarding_rule" "fr_udp4500" {
ip_protocol = "UDP"
port_range = "4500"
ip_address = google_compute_address.vpn_static_ip.address
- target = google_compute_vpn_gateway.target_gateway.self_link
+ target = google_compute_vpn_gateway.target_gateway.id
}
resource "google_compute_route" "route1" {
@@ -66,7 +66,7 @@ resource "google_compute_route" "route1" {
dest_range = "15.0.0.0/24"
priority = 1000
- next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.self_link
+ next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel1.id
}
provider "google-beta" {
diff --git a/templates/terraform/expand_property_method.erb b/templates/terraform/expand_property_method.erb
index f1169861172d..0c7301f9ebad 100644
--- a/templates/terraform/expand_property_method.erb
+++ b/templates/terraform/expand_property_method.erb
@@ -13,10 +13,11 @@
# limitations under the License.
-%>
<% if property.custom_expand -%>
-<%= lines(compile_template(property.custom_expand,
+<%= lines(compile_template(pwd + '/' + property.custom_expand,
prefix: prefix,
property: property,
- object: object)) -%>
+ object: object,
+ pwd: pwd)) -%>
<% else -%>
<%# Generate expanders for Maps %>
@@ -35,8 +36,14 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T
transformed<%= titlelize_property(prop) -%>, err := expand<%= prefix -%><%= titlelize_property(property) -%><%= titlelize_property(prop) -%>(original["<%= Google::StringUtils.underscore(prop.name) -%>"], d, config)
if err != nil {
return nil, err
+ <% if prop.send_empty_value -%>
+ } else {
+ transformed["<%= prop.api_name -%>"] = transformed<%= titlelize_property(prop) -%>
+ <% else -%>
+ } else if val := reflect.ValueOf(transformed<%= titlelize_property(prop) -%>); val.IsValid() && !isEmptyValue(val) {
+ transformed["<%= prop.api_name -%>"] = transformed<%= titlelize_property(prop) -%>
+ <% end -%>
}
- transformed["<%= prop.api_name -%>"] = transformed<%= titlelize_property(prop) -%>
<% end -%>
@@ -150,7 +157,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T
if raw == nil {
return nil, fmt.Errorf("Invalid value for <%= property.name.underscore -%>: nil")
}
- f, err := <%= build_expand_resource_ref('raw.(string)', property.item_type) %>
+ f, err := <%= build_expand_resource_ref('raw.(string)', property.item_type, pwd) %>
if err != nil {
return nil, fmt.Errorf("Invalid value for <%= property.name.underscore -%>: %s", err)
}
@@ -160,7 +167,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T
}
<% else -%>
<% if property.is_a?(Api::Type::ResourceRef) -%>
- f, err := <%= build_expand_resource_ref('v.(string)', property) %>
+ f, err := <%= build_expand_resource_ref('v.(string)', property, pwd) %>
if err != nil {
return nil, fmt.Errorf("Invalid value for <%= property.name.underscore -%>: %s", err)
}
@@ -180,7 +187,7 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T
<% property.nested_properties.each do |prop| -%>
<%# Map is a map from {key -> object} in the API, but Terraform can't represent that
so we treat the key as a property of the object in Terraform schema. %>
-<%= lines(build_expand_method(prefix + titlelize_property(property), prop, object), 1) -%>
+<%= lines(build_expand_method(prefix + titlelize_property(property), prop, object, pwd), 1) -%>
<% end -%>
<% end -%>
diff --git a/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb b/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb
new file mode 100644
index 000000000000..4f9c955aa201
--- /dev/null
+++ b/templates/terraform/extra_schema_entry/cloudiot_device_registry.go.erb
@@ -0,0 +1,80 @@
+"state_notification_config": {
+ Type: schema.TypeMap,
+ Description: `A PubSub topic to publish device state updates.`,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "pubsub_topic_name": {
+ Type: schema.TypeString,
+ Description: `PubSub topic name to publish device state updates.`,
+ Required: true,
+ DiffSuppressFunc: compareSelfLinkOrResourceName,
+ },
+ },
+ },
+},
+"mqtt_config": {
+ Type: schema.TypeMap,
+ Description: `Activate or deactivate MQTT.`,
+ Computed: true,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "mqtt_enabled_state": {
+ Type: schema.TypeString,
+ Description: `The field allows MQTT_ENABLED or MQTT_DISABLED`,
+ Required: true,
+ ValidateFunc: validation.StringInSlice(
+ []string{"MQTT_DISABLED", "MQTT_ENABLED"}, false),
+ },
+ },
+ },
+},
+"http_config": {
+ Type: schema.TypeMap,
+ Description: `Activate or deactivate HTTP.`,
+ Computed: true,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "http_enabled_state": {
+ Type: schema.TypeString,
+ Description: `The field allows HTTP_ENABLED or HTTP_DISABLED`,
+ Required: true,
+ ValidateFunc: validation.StringInSlice(
+ []string{"HTTP_DISABLED", "HTTP_ENABLED"}, false),
+ },
+ },
+ },
+},
+"credentials": {
+ Type: schema.TypeList,
+ Description: `List of public key certificates to authenticate devices.`,
+ Optional: true,
+ MaxItems: 10,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "public_key_certificate": {
+ Type: schema.TypeMap,
+ Description: `A public key certificate format and data.`,
+ Required: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "format": {
+ Type: schema.TypeString,
+ Description: `The field allows only X509_CERTIFICATE_PEM.`,
+ Required: true,
+ ValidateFunc: validation.StringInSlice(
+ []string{"X509_CERTIFICATE_PEM"}, false),
+ },
+ "certificate": {
+ Type: schema.TypeString,
+ Description: `The certificate data.`,
+ Required: true,
+ },
+ },
+ },
+ },
+ },
+ },
+},
diff --git a/templates/terraform/extra_schema_entry/firewall.erb b/templates/terraform/extra_schema_entry/firewall.erb
new file mode 100644
index 000000000000..2997c9083647
--- /dev/null
+++ b/templates/terraform/extra_schema_entry/firewall.erb
@@ -0,0 +1,21 @@
+<%# The license inside this block applies to this file.
+ # Copyright 2020 Google Inc.
+ # 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.
+-%>
+"enable_logging": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Computed: true,
+ Deprecated: "Deprecated in favor of log_config",
+ Description: "This field denotes whether to enable logging for a particular firewall rule. If logging is enabled, logs will be exported to Stackdriver.",
+},
\ No newline at end of file
diff --git a/templates/terraform/flatten_property_method.erb b/templates/terraform/flatten_property_method.erb
index f3258bd2ddda..70e6d46b7ab0 100644
--- a/templates/terraform/flatten_property_method.erb
+++ b/templates/terraform/flatten_property_method.erb
@@ -13,9 +13,10 @@
# limitations under the License.
-%>
<% if property.custom_flatten -%>
-<%= lines(compile_template(property.custom_flatten,
+<%= lines(compile_template(pwd + '/' + property.custom_flatten,
prefix: prefix,
- property: property)) -%>
+ property: property,
+ pwd: pwd)) -%>
<% else -%>
<% if tf_types.include?(property.class) -%>
func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d *schema.ResourceData, config *Config) interface{} {
@@ -132,7 +133,7 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d
}
<% if property.nested_properties? -%>
<% property.nested_properties.each do |prop| -%>
- <%= lines(build_flatten_method(prefix + titlelize_property(property), prop, object), 1) -%>
+ <%= lines(build_flatten_method(prefix + titlelize_property(property), prop, object, pwd), 1) -%>
<% end -%>
<% end -%>
<% else -%>
diff --git a/templates/terraform/iam/iam_context.go.erb b/templates/terraform/iam/iam_context.go.erb
index 70e551ede8e7..55bafd393547 100644
--- a/templates/terraform/iam/iam_context.go.erb
+++ b/templates/terraform/iam/iam_context.go.erb
@@ -1,13 +1,13 @@
context := map[string]interface{}{
- "random_suffix": acctest.RandString(10),
+ "random_suffix": randString(t, 10),
"role": "<%= object.iam_policy.allowed_iam_role -%>",
<% unless object.iam_policy.admin_iam_role.nil? -%>
"admin_role": "<%= object.iam_policy.admin_iam_role-%>",
<% end -%>
<% unless object.iam_policy.test_project_name.nil? -%>
- "project_id" : fmt.Sprintf("<%= object.iam_policy.test_project_name -%>%s", acctest.RandString(10)),
+ "project_id" : fmt.Sprintf("<%= object.iam_policy.test_project_name -%>%s", randString(t, 10)),
<% end -%>
-<%= lines(compile('templates/terraform/env_var_context.go.erb')) -%>
+<%= lines(compile(pwd + '/templates/terraform/env_var_context.go.erb')) -%>
<% unless example.test_vars_overrides.nil? -%>
<% example.test_vars_overrides.each do |var_name, override| -%>
"<%= var_name %>": <%= override %>,
diff --git a/templates/terraform/iam_policy.go.erb b/templates/terraform/iam_policy.go.erb
index 546534926f9e..3ea2a255365b 100644
--- a/templates/terraform/iam_policy.go.erb
+++ b/templates/terraform/iam_policy.go.erb
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
import (
@@ -57,7 +57,7 @@ var <%= resource_name -%>IamSchema = map[string]*schema.Schema{
}
<% unless object.iam_policy.custom_diff_suppress.nil? -%>
-<%= lines(compile(object.iam_policy.custom_diff_suppress)) -%>
+<%= lines(compile(pwd + '/' + object.iam_policy.custom_diff_suppress)) -%>
<% end -%>
type <%= resource_name -%>IamUpdater struct {
diff --git a/templates/terraform/nested_property_documentation.erb b/templates/terraform/nested_property_documentation.erb
index f52def3caa49..50c53b8efeba 100644
--- a/templates/terraform/nested_property_documentation.erb
+++ b/templates/terraform/nested_property_documentation.erb
@@ -1,7 +1,7 @@
<% if property.flatten_object -%>
<% property.nested_properties.each do |prop| -%>
-<%= lines(build_nested_property_documentation(prop)) -%>
+<%= lines(build_nested_property_documentation(prop, pwd)) -%>
<% end -%>
<%
elsif property.nested_properties?
@@ -11,10 +11,10 @@ The `<%= property.name.underscore -%>` block <%= if property.output then "contai
* `<%= property.key_name.underscore -%>` - (Required) The identifier for this object. Format specified above.
<% end -%>
<% property.nested_properties.each do |prop| -%>
-<%= lines(build_property_documentation(prop)) -%>
+<%= lines(build_property_documentation(prop, pwd)) -%>
<% end -%>
<% property.nested_properties.each do |prop| -%>
-<%= lines(build_nested_property_documentation(prop)) -%>
+<%= lines(build_nested_property_documentation(prop, pwd)) -%>
<% end -%>
<% end -%>
diff --git a/templates/terraform/nested_query.go.erb b/templates/terraform/nested_query.go.erb
index 79e0e04d9351..2a989c64a70b 100644
--- a/templates/terraform/nested_query.go.erb
+++ b/templates/terraform/nested_query.go.erb
@@ -13,9 +13,7 @@ func flattenNested<%= resource_name -%>(d *schema.ResourceData, meta interface{}
<% end -%>
v, ok = res["<%=object.nested_query.keys[-1]-%>"]
if !ok || v == nil {
- // It's possible that there is only one of these resources and
- // that res represents that resource.
- v = res
+ return nil,nil
}
switch v.(type) {
diff --git a/templates/terraform/objectlib/base.go.erb b/templates/terraform/objectlib/base.go.erb
index 917fecc91388..15f9804fd6ba 100644
--- a/templates/terraform/objectlib/base.go.erb
+++ b/templates/terraform/objectlib/base.go.erb
@@ -1,16 +1,18 @@
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
<%
resource_name = product_ns + object.name
properties = object.all_user_properties
- api_version = @base_url.split("/")[-1]
# See discussion on asset name here: https://github.com/GoogleCloudPlatform/magic-modules/pull/1520
asset_name_template = '//' + product_ns.downcase + '.googleapis.com/' + (!object.self_link.nil? && !object.self_link.empty? ? object.self_link : object.base_url + '/{{name}}')
+ version_regex = /\/(v\d[^\/]*)\//
+ api_version = version_regex.match?(asset_name_template) ? version_regex.match(asset_name_template)[1] : @base_url.split("/")[-1]
+ asset_name_template.gsub!(version_regex, '/')
%>
-<%= lines(compile(object.custom_code.constants)) if object.custom_code.constants -%>
+<%= lines(compile(pwd + '/' + object.custom_code.constants)) if object.custom_code.constants -%>
func Get<%= resource_name -%>CaiObject(d TerraformResourceData, config *Config) (Asset, error) {
name, err := assetName(d, config, "<%= asset_name_template -%>")
@@ -61,11 +63,11 @@ func Get<%= resource_name -%>ApiObject(d TerraformResourceData, config *Config)
<% if object.custom_code.encoder -%>
func resource<%= resource_name -%>Encoder(d TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
-<%= lines(compile(object.custom_code.encoder)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.encoder)) -%>
}
<% end -%>
<% object.settable_properties.each do |prop| -%>
-<%= lines(build_expand_method(resource_name, prop, object), 1) -%>
+<%= lines(build_expand_method(resource_name, prop, object, pwd), 1) -%>
<% end -%>
diff --git a/templates/terraform/operation.go.erb b/templates/terraform/operation.go.erb
index 60a8e69de3a7..c5c92d51fdb7 100644
--- a/templates/terraform/operation.go.erb
+++ b/templates/terraform/operation.go.erb
@@ -2,7 +2,7 @@
product_name = object.__product.name
has_project = object.base_url.include?("{{project}}")
-%>
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
import (
@@ -49,24 +49,24 @@ func create<%= product_name %>Waiter(config *Config, op map[string]interface{},
Might as well just nolint it so we can pass the linter checks.
-%>
// nolint: deadcode,unused
-func <%= product_name.camelize(:lower) -%>OperationWaitTimeWithResponse(config *Config, op map[string]interface{}, response *map[string]interface{},<% if has_project -%> project,<% end -%> activity string, timeoutMinutes int) error {
+func <%= product_name.camelize(:lower) -%>OperationWaitTimeWithResponse(config *Config, op map[string]interface{}, response *map[string]interface{},<% if has_project -%> project,<% end -%> activity string, timeout time.Duration) error {
w, err := create<%= product_name %>Waiter(config, op, <% if has_project -%> project, <%end-%> activity)
if err != nil || w == nil {
// If w is nil, the op was synchronous.
return err
}
- if err := OperationWait(w, activity, timeoutMinutes, config.PollInterval); err != nil {
+ if err := OperationWait(w, activity, timeout, config.PollInterval); err != nil {
return err
}
return json.Unmarshal([]byte(w.CommonOperationWaiter.Op.Response), response)
}
<% end -%>
-func <%= product_name.camelize(:lower) -%>OperationWaitTime(config *Config, op map[string]interface{}, <% if has_project -%> project,<% end -%> activity string, timeoutMinutes int) error {
+func <%= product_name.camelize(:lower) -%>OperationWaitTime(config *Config, op map[string]interface{}, <% if has_project -%> project,<% end -%> activity string, timeout time.Duration) error {
w, err := create<%= product_name %>Waiter(config, op, <% if has_project -%> project, <%end-%> activity)
if err != nil || w == nil {
// If w is nil, the op was synchronous.
return err
}
- return OperationWait(w, activity, timeoutMinutes, config.PollInterval)
+ return OperationWait(w, activity, timeout, config.PollInterval)
}
diff --git a/templates/terraform/post_create/cloud_asset_feed.go.erb b/templates/terraform/post_create/cloud_asset_feed.go.erb
new file mode 100644
index 000000000000..ea3cf4fe41b0
--- /dev/null
+++ b/templates/terraform/post_create/cloud_asset_feed.go.erb
@@ -0,0 +1,2 @@
+// Restore the original value of user_project_override.
+config.UserProjectOverride = origUserProjectOverride
\ No newline at end of file
diff --git a/templates/terraform/post_create/compute_backend_service_security_policy.go.erb b/templates/terraform/post_create/compute_backend_service_security_policy.go.erb
index 451631628976..a34cf43d8639 100644
--- a/templates/terraform/post_create/compute_backend_service_security_policy.go.erb
+++ b/templates/terraform/post_create/compute_backend_service_security_policy.go.erb
@@ -11,7 +11,8 @@ if o, n := d.GetChange("security_policy"); o.(string) != n.(string) {
if err != nil {
return errwrap.Wrapf("Error setting Backend Service security policy: {{err}}", err)
}
- waitErr := computeOperationWait(config, op, project, "Setting Backend Service Security Policy")
+ // This uses the create timeout for simplicity, though technically this code appears in both create and update
+ waitErr := computeOperationWaitTime(config, op, project, "Setting Backend Service Security Policy", d.Timeout(schema.TimeoutCreate))
if waitErr != nil {
return waitErr
}
diff --git a/templates/terraform/post_create/compute_network_delete_default_route.erb b/templates/terraform/post_create/compute_network_delete_default_route.erb
index 31f31ef5612a..70f1b1d3f0a2 100644
--- a/templates/terraform/post_create/compute_network_delete_default_route.erb
+++ b/templates/terraform/post_create/compute_network_delete_default_route.erb
@@ -16,7 +16,7 @@ if d.Get("delete_default_routes_on_create").(bool) {
if err != nil {
return fmt.Errorf("Error deleting route: %s", err)
}
- err = computeOperationWait(config, op, project, "Deleting Route")
+ err = computeOperationWaitTime(config, op, project, "Deleting Route", d.Timeout(schema.TimeoutCreate))
if err != nil {
return err
}
diff --git a/templates/terraform/post_create/labels.erb b/templates/terraform/post_create/labels.erb
index db554f32914d..030fd48fd2c4 100644
--- a/templates/terraform/post_create/labels.erb
+++ b/templates/terraform/post_create/labels.erb
@@ -27,7 +27,7 @@ if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(v)) && (ok ||
err = computeOperationWaitTime(
config, res, project, "Updating <%= resource_name -%> Labels",
- int(d.Timeout(schema.TimeoutUpdate).Minutes()))
+ d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
diff --git a/templates/terraform/post_create/set_computed_name.erb b/templates/terraform/post_create/set_computed_name.erb
index 54638e146a87..4a3342ee8d8d 100644
--- a/templates/terraform/post_create/set_computed_name.erb
+++ b/templates/terraform/post_create/set_computed_name.erb
@@ -1,7 +1,15 @@
// `name` is autogenerated from the api so needs to be set post-create
name, ok := res["name"]
if !ok {
- return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
+ respBody, ok := res["response"]
+ if !ok {
+ return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
+ }
+
+ name, ok = respBody.(map[string]interface{})["name"]
+ if !ok {
+ return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
+ }
}
d.Set("name", name.(string))
d.SetId(name.(string))
diff --git a/templates/terraform/post_update/compute_per_instance_config.go.erb b/templates/terraform/post_update/compute_per_instance_config.go.erb
new file mode 100644
index 000000000000..2d641b55ea40
--- /dev/null
+++ b/templates/terraform/post_update/compute_per_instance_config.go.erb
@@ -0,0 +1,40 @@
+// Instance name in applyUpdatesToInstances request must include zone
+instanceName, err := replaceVars(d, config, "zones/{{zone}}/instances/{{name}}")
+if err != nil {
+ return err
+}
+
+obj = make(map[string]interface{})
+obj["instances"] = []string{instanceName}
+
+minAction := d.Get("minimal_action")
+if minAction == "" {
+ minAction = "NONE"
+}
+obj["minimalAction"] = minAction
+
+mostDisruptiveAction := d.Get("most_disruptive_action_allowed")
+if mostDisruptiveAction != "" {
+ mostDisruptiveAction = "REPLACE"
+}
+obj["mostDisruptiveActionAllowed"] = mostDisruptiveAction
+
+url, err = replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/applyUpdatesToInstances")
+if err != nil {
+ return err
+}
+
+log.Printf("[DEBUG] Applying updates to PerInstanceConfig %q: %#v", d.Id(), obj)
+res, err = sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutUpdate))
+
+if err != nil {
+ return fmt.Errorf("Error updating PerInstanceConfig %q: %s", d.Id(), err)
+}
+
+err = computeOperationWaitTime(
+ config, res, project, "Applying update to PerInstanceConfig",
+ d.Timeout(schema.TimeoutUpdate))
+
+if err != nil {
+ return err
+}
\ No newline at end of file
diff --git a/templates/terraform/post_update/compute_region_per_instance_config.go.erb b/templates/terraform/post_update/compute_region_per_instance_config.go.erb
new file mode 100644
index 000000000000..75870d1a5568
--- /dev/null
+++ b/templates/terraform/post_update/compute_region_per_instance_config.go.erb
@@ -0,0 +1,40 @@
+// Instance name in applyUpdatesToInstances request must include zone
+instanceName, err := findInstanceName(d, config)
+if err != nil {
+ return err
+}
+
+obj = make(map[string]interface{})
+obj["instances"] = []string{instanceName}
+
+minAction := d.Get("minimal_action")
+if minAction == "" {
+ minAction = "NONE"
+}
+obj["minimalAction"] = minAction
+
+mostDisruptiveAction := d.Get("most_disruptive_action_allowed")
+if mostDisruptiveAction != "" {
+ mostDisruptiveAction = "REPLACE"
+}
+obj["mostDisruptiveActionAllowed"] = mostDisruptiveAction
+
+url, err = replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/instanceGroupManagers/{{region_instance_group_manager}}/applyUpdatesToInstances")
+if err != nil {
+ return err
+}
+
+log.Printf("[DEBUG] Applying updates to PerInstanceConfig %q: %#v", d.Id(), obj)
+res, err = sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutUpdate))
+
+if err != nil {
+ return fmt.Errorf("Error updating PerInstanceConfig %q: %s", d.Id(), err)
+}
+
+err = computeOperationWaitTime(
+ config, res, project, "Applying update to PerInstanceConfig",
+ d.Timeout(schema.TimeoutUpdate))
+
+if err != nil {
+ return err
+}
\ No newline at end of file
diff --git a/templates/terraform/pre_create/cloud_asset_feed.go.erb b/templates/terraform/pre_create/cloud_asset_feed.go.erb
new file mode 100644
index 000000000000..a8354702cc68
--- /dev/null
+++ b/templates/terraform/pre_create/cloud_asset_feed.go.erb
@@ -0,0 +1,16 @@
+// This should never happen, but the linter complains otherwise with ineffectual assignment to `project`
+if project == "dummy lint" {
+ log.Printf("[DEBUG] Found project in url: %s", project)
+}
+// Send the project ID in the X-Goog-User-Project header.
+origUserProjectOverride := config.UserProjectOverride
+config.UserProjectOverride = true
+// If we have a billing project, use that one in the header.
+bp, bpok := d.GetOk("billing_project")
+if bpok && bp != "" {
+ project = bp.(string)
+} else {
+ // otherwise, use the resource's project
+ rp, _ := d.GetOk("project")
+ project = rp.(string)
+}
diff --git a/templates/terraform/pre_delete/compute_per_instance_config.go.erb b/templates/terraform/pre_delete/compute_per_instance_config.go.erb
new file mode 100644
index 000000000000..0fcf58a17620
--- /dev/null
+++ b/templates/terraform/pre_delete/compute_per_instance_config.go.erb
@@ -0,0 +1,3 @@
+obj = map[string]interface{}{
+ "names": [1]string{d.Get("name").(string)},
+}
\ No newline at end of file
diff --git a/templates/terraform/pre_delete/detach_disk.erb b/templates/terraform/pre_delete/detach_disk.erb
index aecc82e09a1e..2f5a4e923801 100644
--- a/templates/terraform/pre_delete/detach_disk.erb
+++ b/templates/terraform/pre_delete/detach_disk.erb
@@ -41,8 +41,8 @@ if v, ok := readRes["users"].([]interface{}); ok {
return fmt.Errorf("Error detaching disk %s from instance %s/%s/%s: %s", call.deviceName, call.project,
call.zone, call.instance, err.Error())
}
- err = computeOperationWait(config, op, call.project,
- fmt.Sprintf("Detaching disk from %s/%s/%s", call.project, call.zone, call.instance))
+ err = computeOperationWaitTime(config, op, call.project,
+ fmt.Sprintf("Detaching disk from %s/%s/%s", call.project, call.zone, call.instance), d.Timeout(schema.TimeoutDelete))
if err != nil {
if opErr, ok := err.(ComputeOperationError); ok && len(opErr.Errors) == 1 && opErr.Errors[0].Code == "RESOURCE_NOT_FOUND" {
log.Printf("[WARN] instance %q was deleted while awaiting detach", call.instance)
diff --git a/templates/terraform/pre_update/cloudiot_device_registry.go.erb b/templates/terraform/pre_update/cloudiot_device_registry.go.erb
new file mode 100644
index 000000000000..8170993ab0c5
--- /dev/null
+++ b/templates/terraform/pre_update/cloudiot_device_registry.go.erb
@@ -0,0 +1,35 @@
+log.Printf("[DEBUG] updateMask before adding extra schema entries %q: %v", d.Id(), updateMask)
+
+log.Printf("[DEBUG] Pre-update on state notification config: %q", d.Id())
+if d.HasChange("state_notification_config") {
+ log.Printf("[DEBUG] %q stateNotificationConfig.pubsubTopicName has a change. Adding it to the update mask", d.Id())
+ updateMask = append(updateMask, "stateNotificationConfig.pubsubTopicName")
+}
+
+log.Printf("[DEBUG] Pre-update on MQTT config: %q", d.Id())
+if d.HasChange("mqtt_config") {
+ log.Printf("[DEBUG] %q mqttConfig.mqttEnabledState has a change. Adding it to the update mask", d.Id())
+ updateMask = append(updateMask, "mqttConfig.mqttEnabledState")
+}
+
+log.Printf("[DEBUG] Pre-update on HTTP config: %q", d.Id())
+if d.HasChange("http_config") {
+ log.Printf("[DEBUG] %q httpConfig.httpEnabledState has a change. Adding it to the update mask", d.Id())
+ updateMask = append(updateMask, "httpConfig.httpEnabledState")
+}
+
+log.Printf("[DEBUG] Pre-update on credentials: %q", d.Id())
+if d.HasChange("credentials") {
+ log.Printf("[DEBUG] %q credentials has a change. Adding it to the update mask", d.Id())
+ updateMask = append(updateMask, "credentials")
+}
+
+log.Printf("[DEBUG] updateMask after adding extra schema entries %q: %v", d.Id(), updateMask)
+
+// Refreshing updateMask after adding extra schema entries
+url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
+if err != nil {
+ return err
+}
+
+log.Printf("[DEBUG] Update URL %q: %v", d.Id(), url)
diff --git a/templates/terraform/property_documentation.erb b/templates/terraform/property_documentation.erb
index 3f4bf27169d3..ca30bc5216ab 100644
--- a/templates/terraform/property_documentation.erb
+++ b/templates/terraform/property_documentation.erb
@@ -14,6 +14,21 @@
<% end -%>
<% end -%>
<%= indent(property.description.strip.gsub("\n\n", "\n"), 2) -%>
+<% if property.is_a?(Api::Type::Enum) && !property.output && !property.skip_docs_values -%>
+
+
+<% unless property.default_value.nil? || property.default_value == "" -%>
+ Default value: `<%= property.default_value %>`
+
+<% end -%>
+ Possible values are:
+<% property.values.select { |v| v != "" }.each do |v| -%>
+ * `<%= v %>`
+<% end -%>
+<% end -%>
+<% if property.sensitive -%>
+ **Note**: This property is sensitive and will not be displayed in the plan.
+<% end -%>
<% if property.is_a?(Api::Type::NestedObject) || property.is_a?(Api::Type::Map) || (property.is_a?(Api::Type::Array) && property.item_type.is_a?(Api::Type::NestedObject)) -%>
Structure is documented below.
<% end -%>
diff --git a/templates/terraform/resource.erb b/templates/terraform/resource.erb
index e6396d09897d..e2c52e66b3f8 100644
--- a/templates/terraform/resource.erb
+++ b/templates/terraform/resource.erb
@@ -12,11 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
-<%= lines(autogen_notice :go) -%>
+<%= lines(autogen_notice(:go, pwd)) -%>
package google
-<%= lines(compile(object.custom_code.constants)) if object.custom_code.constants -%>
+<%= lines(compile(pwd + '/' + object.custom_code.constants)) if object.custom_code.constants -%>
<%
resource_name = product_ns + object.name
@@ -28,7 +28,7 @@ package google
client_name_camel = client_name.camelize(:lower)
client_name_pascal = client_name.camelize(:upper)
client_name_lower = client_name.downcase
- has_project = object.base_url.include?('{{project}}')
+ has_project = object.base_url.include?('{{project}}') || (object.create_url && object.create_url.include?('{{project}}'))
has_region = object.base_url.include?('{{region}}') && object.parameters.any?{ |p| p.name == 'region' && p.ignore_read }
# In order of preference, use TF override,
# general defined timeouts, or default Timeouts
@@ -82,22 +82,22 @@ func resource<%= resource_name -%>() *schema.Resource {
<% end -%>
<% end -%>
-<%= lines(compile(object.custom_code.resource_definition)) if object.custom_code.resource_definition -%>
+<%= lines(compile(pwd + '/' + object.custom_code.resource_definition)) if object.custom_code.resource_definition -%>
Schema: map[string]*schema.Schema{
<% order_properties(properties).each do |prop| -%>
-<%= lines(build_schema_property(prop, object)) -%>
+<%= lines(build_schema_property(prop, object, pwd)) -%>
<% end -%>
<%- unless object.virtual_fields.empty? -%>
<%- object.virtual_fields.each do |field| -%>
"<%= field.name -%>": {
- Type: schema.TypeBool,
+ Type: <%= tf_type(field) -%>,
Optional: true,
- Default: false,
+ Default: <%= go_literal(field.default_value) -%>,
},
<% end -%>
<% end -%>
-<%= lines(compile(object.custom_code.extra_schema_entry)) if object.custom_code.extra_schema_entry -%>
+<%= lines(compile(pwd + '/' + object.custom_code.extra_schema_entry)) if object.custom_code.extra_schema_entry -%>
<% if has_project -%>
"project": {
Type: schema.TypeString,
@@ -117,13 +117,13 @@ func resource<%= resource_name -%>() *schema.Resource {
}
<% properties.each do |prop| -%>
-<%= lines(build_subresource_schema(prop, object), 1) -%>
+<%= lines(build_subresource_schema(prop, object, pwd), 1) -%>
<% end -%>
<% object.settable_properties.select {|p| p.unordered_list}.each do |prop| -%>
func resource<%= resource_name -%><%= prop.name.camelize(:upper) -%>SetStyleDiff(diff *schema.ResourceDiff, meta interface{}) error {
<%=
- compile_template('templates/terraform/unordered_list_customize_diff.erb',
+ compile_template(pwd + '/templates/terraform/unordered_list_customize_diff.erb',
prop: prop,
resource_name: resource_name)
-%>
@@ -132,7 +132,7 @@ func resource<%= resource_name -%><%= prop.name.camelize(:upper) -%>SetStyleDiff
func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{}) error {
<% if object.custom_code.custom_create -%>
- <%= lines(compile(object.custom_code.custom_create)) -%>
+ <%= lines(compile(pwd + '/' + object.custom_code.custom_create)) -%>
<% else -%>
config := meta.(*Config)
@@ -201,6 +201,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
project = parts[1]
}
<% end -%>
+<%= lines(compile(pwd + '/' + object.custom_code.pre_create)) if object.custom_code.pre_create -%>
res, err := sendRequestWithTimeout(config, "<%= object.create_verb.to_s.upcase -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, obj, d.Timeout(schema.TimeoutCreate)<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
if err != nil {
<% if object.custom_code.post_create_failure && object.async.nil? # Only add if not handled by async error handling -%>
@@ -228,7 +229,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
<% if object.async&.allow?('create') -%>
<% if object.async.is_a? Provider::Terraform::PollAsync -%>
- err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func -%>, "Creating <%= object.name -%>", d.Timeout(schema.TimeoutCreate))
+ err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func_existence -%>, "Creating <%= object.name -%>", d.Timeout(schema.TimeoutCreate), <%= object.async.target_occurrences -%>)
if err != nil {
<% if object.async.suppress_error -%>
log.Printf("[ERROR] Unable to confirm eventually consistent <%= object.name -%> %q finished updating: %q", d.Id(), err)
@@ -248,7 +249,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
var opRes map[string]interface{}
err = <%= client_name_camel -%>OperationWaitTimeWithResponse(
config, res, &opRes, <% if has_project -%> project, <% end -%> "Creating <%= object.name -%>",
- int(d.Timeout(schema.TimeoutCreate).Minutes()))
+ d.Timeout(schema.TimeoutCreate))
if err != nil {
<% if object.custom_code.post_create_failure -%>
resource<%= resource_name -%>PostCreateFailure(d, meta)
@@ -298,7 +299,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
<% else -%>
err = <%= client_name_camel -%>OperationWaitTime(
config, res, <% if has_project -%> project, <% end -%> "Creating <%= object.name -%>",
- int(d.Timeout(schema.TimeoutCreate).Minutes()))
+ d.Timeout(schema.TimeoutCreate))
if err != nil {
<% if object.custom_code.post_create_failure -%>
@@ -315,7 +316,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
log.Printf("[DEBUG] Finished creating <%= object.name -%> %q: %#v", d.Id(), res)
-<%= lines(compile(object.custom_code.post_create)) if object.custom_code.post_create -%>
+<%= lines(compile(pwd + '/' + object.custom_code.post_create)) if object.custom_code.post_create -%>
return resource<%= resource_name -%>Read(d, meta)
<% end # if custom_create -%>
@@ -325,7 +326,7 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
func resource<%= resource_name -%>PollRead(d *schema.ResourceData, meta interface{}) PollReadFunc {
return func() (map[string]interface{}, error) {
<% if object.async.custom_poll_read -%>
-<%= lines(compile(object.async.custom_poll_read)) -%>
+<%= lines(compile(pwd + '/' + object.async.custom_poll_read)) -%>
<% else -%>
config := meta.(*Config)
@@ -407,7 +408,11 @@ func resource<%= resource_name -%>Read(d *schema.ResourceData, meta interface{})
<% end -%>
res, err := sendRequest(config, "<%= object.read_verb.to_s.upcase -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, nil<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
if err != nil {
+<% if object.read_error_transform -%>
+ return handleNotFoundError(<%= object.read_error_transform %>(err), d, fmt.Sprintf("<%= resource_name -%> %q", d.Id()))
+<% else -%>
return handleNotFoundError(err, d, fmt.Sprintf("<%= resource_name -%> %q", d.Id()))
+<% end -%>
}
<% if object.nested_query -%>
@@ -443,7 +448,7 @@ func resource<%= resource_name -%>Read(d *schema.ResourceData, meta interface{})
// Explicitly set virtual fields to default values if unset
<%- object.virtual_fields.each do |field| -%>
if _, ok := d.GetOk("<%= field.name -%>"); !ok {
- d.Set("<%= field.name -%>", false)
+ d.Set("<%= field.name -%>", <%= go_literal(field.default_value) -%>)
}
<% end -%>
<% end -%>
@@ -594,7 +599,7 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
project = parts[1]
}
<% end -%>
-<% if object.async.is_a? Api::OpAsync-%>
+<% if object.async&.allow?('update') && object.async.is_a?(Api::OpAsync) -%>
res, err := sendRequestWithTimeout(config, "<%= key[:update_verb] -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, obj, d.Timeout(schema.TimeoutUpdate)<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
<% else -%>
_, err = sendRequestWithTimeout(config, "<%= key[:update_verb] -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, obj, d.Timeout(schema.TimeoutUpdate)<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
@@ -607,12 +612,12 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
<% if object.async.is_a? Api::OpAsync-%>
err = <%= client_name_camel -%>OperationWaitTime(
config, res, <% if has_project -%> project, <% end -%> "Updating <%= object.name -%>",
- int(d.Timeout(schema.TimeoutUpdate).Minutes()))
+ d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
}
<% elsif object.async.is_a? Provider::Terraform::PollAsync -%>
- err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func -%>, "Updating <%= object.name -%>", d.Timeout(schema.TimeoutUpdate))
+ err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func_existence -%>, "Updating <%= object.name -%>", d.Timeout(schema.TimeoutUpdate), <%= object.async.target_occurrences -%>)
if err != nil {
<% if object.async.suppress_error-%>
log.Printf("[ERROR] Unable to confirm eventually consistent <%= object.name -%> %q finished updating: %q", d.Id(), err)
@@ -677,8 +682,8 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
}
log.Printf("[DEBUG] Updating <%= object.name -%> %q: %#v", d.Id(), obj)
-<%= lines(compile('templates/terraform/update_mask.erb')) if object.update_mask -%>
-<%= lines(compile(object.custom_code.pre_update)) if object.custom_code.pre_update -%>
+<%= lines(compile(pwd + '/templates/terraform/update_mask.erb')) if object.update_mask -%>
+<%= lines(compile(pwd + '/' + object.custom_code.pre_update)) if object.custom_code.pre_update -%>
<% if object.nested_query&.modify_by_patch -%>
<%# Keep this after mutex - patch request data relies on current resource state %>
obj, err = resource<%= resource_name -%>PatchUpdateEncoder(d, meta, obj)
@@ -692,7 +697,7 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
project = parts[1]
}
<% end -%>
-<% if object.async.is_a? Api::OpAsync-%>
+<% if object.async&.allow?('update') && object.async.is_a?(Api::OpAsync) -%>
res, err := sendRequestWithTimeout(config, "<%= object.update_verb -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, obj, d.Timeout(schema.TimeoutUpdate)<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
<% else -%>
_, err = sendRequestWithTimeout(config, "<%= object.update_verb -%>", <% if has_project || object.supports_indirect_user_project_override %>project<% else %>""<% end %>, url, obj, d.Timeout(schema.TimeoutUpdate)<%= object.error_retry_predicates ? ", " + object.error_retry_predicates.join(',') : "" -%>)
@@ -706,13 +711,13 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
<% if object.async.is_a? Api::OpAsync -%>
err = <%= client_name_camel -%>OperationWaitTime(
config, res, <% if has_project -%> project, <% end -%> "Updating <%= object.name -%>",
- int(d.Timeout(schema.TimeoutUpdate).Minutes()))
+ d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
}
<% elsif object.async.is_a? Provider::Terraform::PollAsync -%>
- err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func -%>, "Updating <%= object.name -%>", d.Timeout(schema.TimeoutUpdate))
+ err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func_existence -%>, "Updating <%= object.name -%>", d.Timeout(schema.TimeoutUpdate), <%= object.async.target_occurrences -%>)
if err != nil {
<% if object.async.suppress_error-%>
log.Printf("[ERROR] Unable to confirm eventually consistent <%= object.name -%> %q finished updating: %q", d.Id(), err)
@@ -724,7 +729,7 @@ if <%= props.map { |prop| "d.HasChange(\"#{prop.name.underscore}\")" }.join ' ||
<% end -%>
<% end # if object.input -%>
-<%= lines(compile(object.custom_code.post_update)) if object.custom_code.post_update -%>
+<%= lines(compile(pwd + '/' + object.custom_code.post_update)) if object.custom_code.post_update -%>
return resource<%= resource_name -%>Read(d, meta)
}
<% end # if updatable? -%>
@@ -738,7 +743,7 @@ func resource<%= resource_name -%>Delete(d *schema.ResourceData, meta interface{
return nil
<% elsif object.custom_code.custom_delete -%>
-<%= lines(compile(object.custom_code.custom_delete)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.custom_delete)) -%>
<% else -%>
config := meta.(*Config)
@@ -765,7 +770,7 @@ func resource<%= resource_name -%>Delete(d *schema.ResourceData, meta interface{
<%# If the deletion of the object requires sending a request body, the custom code will set 'obj' -%>
var obj map[string]interface{}
-<%= lines(compile(object.custom_code.pre_delete)) if object.custom_code.pre_delete -%>
+<%= lines(compile(pwd + '/' + object.custom_code.pre_delete)) if object.custom_code.pre_delete -%>
<% if object.nested_query&.modify_by_patch -%>
<%# Keep this after mutex - patch request data relies on current resource state %>
obj, err = resource<%= resource_name -%>PatchDeleteEncoder(d, meta, obj)
@@ -793,14 +798,24 @@ func resource<%= resource_name -%>Delete(d *schema.ResourceData, meta interface{
}
<% if object.async&.allow?('delete') -%>
+<% if object.async.is_a? Provider::Terraform::PollAsync -%>
+ err = PollingWaitTime(resource<%= resource_name -%>PollRead(d, meta), <%= object.async.check_response_func_absence -%>, "Deleting <%= object.name -%>", d.Timeout(schema.TimeoutCreate), <%= object.async.target_occurrences -%>)
+ if err != nil {
+<% if object.async.suppress_error -%>
+ log.Printf("[ERROR] Unable to confirm eventually consistent <%= object.name -%> %q finished updating: %q", d.Id(), err)
+<% else -%>
+ return fmt.Errorf("Error waiting to delete <%= object.name -%>: %s", err)
+<% end -%>
+ }
+<% else -%>
err = <%= client_name_camel -%>OperationWaitTime(
config, res, <% if has_project -%> project, <% end -%> "Deleting <%= object.name -%>",
- int(d.Timeout(schema.TimeoutDelete).Minutes()))
+ d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
}
-
+<% end -%>
<% end -%>
log.Printf("[DEBUG] Finished deleting <%= object.name -%> %q: %#v", d.Id(), res)
@@ -811,7 +826,7 @@ func resource<%= resource_name -%>Delete(d *schema.ResourceData, meta interface{
<% unless object.exclude_import -%>
func resource<%= resource_name -%>Import(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
<% if object.custom_code.custom_import -%>
-<%= lines(compile(object.custom_code.custom_import)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.custom_import)) -%>
<% else -%>
config := meta.(*Config)
if err := parseImportId([]string{
@@ -832,10 +847,10 @@ func resource<%= resource_name -%>Import(d *schema.ResourceData, meta interface{
<%- unless object.virtual_fields.empty? -%>
// Explicitly set virtual fields to default values on import
<%- object.virtual_fields.each do |field| -%>
- d.Set("<%= field.name %>", false)
+ d.Set("<%= field.name %>", <%= go_literal(field.default_value) -%>)
<% end -%>
<% end -%>
-<%= lines(compile(object.custom_code.post_import)) if object.custom_code.post_import -%>
+<%= lines(compile(pwd + '/' + object.custom_code.post_import)) if object.custom_code.post_import -%>
return []*schema.ResourceData{d}, nil
<% end -%>
@@ -844,27 +859,27 @@ func resource<%= resource_name -%>Import(d *schema.ResourceData, meta interface{
<%- nested_prefix = object.nested_query ? "Nested" : "" -%>
<% object.gettable_properties.reject(&:ignore_read).each do |prop| -%>
-<%= lines(build_flatten_method(nested_prefix+resource_name, prop, object), 1) -%>
+<%= lines(build_flatten_method(nested_prefix+resource_name, prop, object, pwd), 1) -%>
<% end -%>
<% object.settable_properties.each do |prop| -%>
-<%= lines(build_expand_method(nested_prefix+resource_name, prop, object), 1) -%>
+<%= lines(build_expand_method(nested_prefix+resource_name, prop, object, pwd), 1) -%>
<% end -%>
<% if object.custom_code.encoder -%>
func resource<%= resource_name -%>Encoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
-<%= lines(compile(object.custom_code.encoder)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.encoder)) -%>
}
<% end -%>
<% if object.custom_code.update_encoder-%>
func resource<%= resource_name -%>UpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
-<%= lines(compile(object.custom_code.update_encoder)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.update_encoder)) -%>
}
<% end -%>
<% if object.nested_query -%>
-<%= compile_template('templates/terraform/nested_query.go.erb',
+<%= compile_template(pwd + '/templates/terraform/nested_query.go.erb',
object: object,
settable_properties: object.settable_properties,
resource_name: resource_name) -%>
@@ -872,17 +887,17 @@ func resource<%= resource_name -%>UpdateEncoder(d *schema.ResourceData, meta int
<% if object.custom_code.decoder -%>
func resource<%= resource_name -%>Decoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
-<%= lines(compile(object.custom_code.decoder)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.decoder)) -%>
}
<% end -%>
<% if object.custom_code.post_create_failure -%>
func resource<%= resource_name -%>PostCreateFailure(d *schema.ResourceData, meta interface{}) {
-<%= lines(compile(object.custom_code.post_create_failure)) -%>
+<%= lines(compile(pwd + '/' + object.custom_code.post_create_failure)) -%>
}
<% end -%>
<% if object.schema_version -%>
-<%= lines(compile("templates/terraform/state_migrations/#{product_ns.underscore}_#{object.name.underscore}.go.erb")) -%>
+<%= lines(compile(pwd + "/templates/terraform/state_migrations/#{product_ns.underscore}_#{object.name.underscore}.go.erb")) -%>
<% end -%>
diff --git a/templates/terraform/resource.html.markdown.erb b/templates/terraform/resource.html.markdown.erb
index 4136380dfcb8..9c2017316773 100644
--- a/templates/terraform/resource.html.markdown.erb
+++ b/templates/terraform/resource.html.markdown.erb
@@ -40,6 +40,7 @@
tf_subcategory = (object.__product.display_name)
terraform_name = object.legacy_name || "google_#{tf_product}_#{object.name.underscore}"
properties = object.all_user_properties
+ sensitive_props = object.all_nested_properties(object.root_properties).select(&:sensitive)
# In order of preference, use TF override,
# general defined timeouts, or default Timeouts
timeouts = object.timeouts
@@ -47,7 +48,7 @@
timeouts ||= Api::Timeouts.new
-%>
---
-<%= lines(autogen_notice :yaml) -%>
+<%= lines(autogen_notice(:yaml, pwd)) -%>
subcategory: "<%= tf_subcategory -%>"
layout: "google"
page_title: "Google: <%= terraform_name -%>"
@@ -82,11 +83,19 @@ To get more information about <%= object.name -%>, see:
~> **Warning:** <%= object.docs.warning -%>
<%- end -%>
+<%- if !sensitive_props.empty? -%>
+<%-
+ sense_props = sensitive_props.map! {|prop| "`"+prop.lineage+"`"}.to_sentence
+-%>
+
+~> **Warning:** All arguments including <%= sense_props -%> will be stored in the raw
+state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html).
+<%- end -%>
<%#- We over-generate examples/oics buttons here; they'll all be _valid_ just not necessarily intended for this provider version.
Unless/Until we split our docs, this is a non-issue. -%>
<% unless object.examples.empty? -%>
- <%- object.examples.each do |example| -%>
+ <%- object.examples.reject(&:skip_docs).each do |example| -%>
<%- unless example.skip_test -%>