From 34120e579528dfb72dddace0485d38efaf9202bd Mon Sep 17 00:00:00 2001 From: Bharath KKB Date: Fri, 27 May 2022 17:27:37 -0500 Subject: [PATCH] feat: add TF cloudbuilder blueprint (#154) * feat: add TF cloudbuilder blueprint * add example * add tests * fix img * fmt * rel arch path * more fmt * ci * bump devtools * retry during e2e test --- Makefile | 2 +- build/int.cloudbuild.yaml | 22 +- build/lint.cloudbuild.yaml | 2 +- .../tf_cloudbuild_builder_simple/Dockerfile | 39 + .../tf_cloudbuild_builder_simple/README.md | 23 + examples/tf_cloudbuild_builder_simple/apis.tf | 33 + examples/tf_cloudbuild_builder_simple/main.tf | 40 + .../tf_cloudbuild_builder_simple/outputs.tf | 44 ++ .../scripts/push-to-repo.sh | 42 ++ .../tf_cloudbuild_builder_simple/variables.tf | 19 + modules/tf_cloudbuild_builder/README.md | 99 +++ modules/tf_cloudbuild_builder/assets/arch.png | Bin 0 -> 90910 bytes modules/tf_cloudbuild_builder/cb.tf | 114 +++ modules/tf_cloudbuild_builder/gar.tf | 51 ++ modules/tf_cloudbuild_builder/outputs.tf | 45 ++ .../templates/workflow.yaml.tftpl | 44 ++ modules/tf_cloudbuild_builder/variables.tf | 105 +++ modules/tf_cloudbuild_builder/versions.tf | 34 + modules/tf_cloudbuild_builder/workflow.tf | 80 ++ test/integration/discover_test.go | 25 + test/integration/go.mod | 8 + test/integration/go.sum | 712 ++++++++++++++++++ .../tf_cloudbuild_builder_simple_test.go | 109 +++ test/setup/main.tf | 4 +- 24 files changed, 1692 insertions(+), 4 deletions(-) create mode 100644 examples/tf_cloudbuild_builder_simple/Dockerfile create mode 100644 examples/tf_cloudbuild_builder_simple/README.md create mode 100644 examples/tf_cloudbuild_builder_simple/apis.tf create mode 100644 examples/tf_cloudbuild_builder_simple/main.tf create mode 100644 examples/tf_cloudbuild_builder_simple/outputs.tf create mode 100755 examples/tf_cloudbuild_builder_simple/scripts/push-to-repo.sh create mode 100644 examples/tf_cloudbuild_builder_simple/variables.tf create mode 100644 modules/tf_cloudbuild_builder/README.md create mode 100644 modules/tf_cloudbuild_builder/assets/arch.png create mode 100644 modules/tf_cloudbuild_builder/cb.tf create mode 100644 modules/tf_cloudbuild_builder/gar.tf create mode 100644 modules/tf_cloudbuild_builder/outputs.tf create mode 100644 modules/tf_cloudbuild_builder/templates/workflow.yaml.tftpl create mode 100644 modules/tf_cloudbuild_builder/variables.tf create mode 100644 modules/tf_cloudbuild_builder/versions.tf create mode 100644 modules/tf_cloudbuild_builder/workflow.tf create mode 100644 test/integration/discover_test.go create mode 100644 test/integration/go.mod create mode 100644 test/integration/go.sum create mode 100644 test/integration/tf_cloudbuild_builder_simple/tf_cloudbuild_builder_simple_test.go diff --git a/Makefile b/Makefile index 01b84857..79b309f7 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # Make will use bash instead of sh SHELL := /usr/bin/env bash -DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.0 +DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.4 DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools REGISTRY_URL := gcr.io/cloud-foundation-cicd diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 663876ea..e2d927d7 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -73,9 +73,29 @@ steps: - id: destroy-simple-folder name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy simple-folder-default'] +- id: init-tfbuilder + waitFor: + - prepare + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestTFCloudBuildBuilder --stage init --verbose'] +- id: apply-tfbuilder + waitFor: + - init-tfbuilder + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestTFCloudBuildBuilder --stage apply --verbose'] +- id: verify-tfbuilder + waitFor: + - apply-tfbuilder + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestTFCloudBuildBuilder --stage verify --verbose'] +- id: teardown-tfbuilder + waitFor: + - verify-tfbuilder + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestTFCloudBuildBuilder --stage teardown --verbose'] tags: - 'ci' - 'integration' substitutions: _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' - _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.0' + _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.4' diff --git a/build/lint.cloudbuild.yaml b/build/lint.cloudbuild.yaml index 34d006db..7437fd5a 100644 --- a/build/lint.cloudbuild.yaml +++ b/build/lint.cloudbuild.yaml @@ -21,4 +21,4 @@ tags: - 'lint' substitutions: _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' - _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.0' + _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.4' diff --git a/examples/tf_cloudbuild_builder_simple/Dockerfile b/examples/tf_cloudbuild_builder_simple/Dockerfile new file mode 100644 index 00000000..2784db45 --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/Dockerfile @@ -0,0 +1,39 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + +FROM gcr.io/cloud-builders/gcloud-slim + +# Use ARG so that values can be overriden by user/cloudbuild +ARG TERRAFORM_VERSION=1.1.0 + +ENV ENV_TERRAFORM_VERSION=$TERRAFORM_VERSION + +RUN apt-get update && \ + /builder/google-cloud-sdk/bin/gcloud -q components install alpha beta && \ + apt-get -y install curl jq unzip git ca-certificates gnupg && \ + curl https://releases.hashicorp.com/terraform/${ENV_TERRAFORM_VERSION}/terraform_${ENV_TERRAFORM_VERSION}_linux_amd64.zip --output terraform_${ENV_TERRAFORM_VERSION}_linux_amd64.zip && \ + curl https://releases.hashicorp.com/terraform/${ENV_TERRAFORM_VERSION}/terraform_${ENV_TERRAFORM_VERSION}_SHA256SUMS.sig --output terraform_SHA256SUMS.sig && \ + curl https://releases.hashicorp.com/terraform/${ENV_TERRAFORM_VERSION}/terraform_${ENV_TERRAFORM_VERSION}_SHA256SUMS --output terraform_SHA256SUMS && \ + curl https://keybase.io/hashicorp/pgp_keys.asc --output pgp_keys.asc && \ + gpg --import pgp_keys.asc && \ + gpg --verify terraform_SHA256SUMS.sig terraform_SHA256SUMS && \ + grep terraform_${ENV_TERRAFORM_VERSION}_linux_amd64.zip terraform_SHA256SUMS | shasum --algorithm 256 --check && \ + unzip terraform_${ENV_TERRAFORM_VERSION}_linux_amd64.zip -d /builder/terraform && \ + rm -f terraform_${ENV_TERRAFORM_VERSION}_linux_amd64.zip terraform_SHA256SUMS && \ + apt-get --purge -y autoremove && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ENV PATH=/builder/terraform/:$PATH +ENTRYPOINT ["terraform"] diff --git a/examples/tf_cloudbuild_builder_simple/README.md b/examples/tf_cloudbuild_builder_simple/README.md new file mode 100644 index 00000000..e0bc5b0f --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/README.md @@ -0,0 +1,23 @@ +## Overview + +This example demonstrates the simplest usage of the [tf_cloudbuild_builder](../../modules/tf_cloudbuild_builder/) module. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | n/a | `string` | `"test-builder-workflow-4"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| artifact\_repo | GAR Repo created to store TF Cloud Builder images | +| cloudbuild\_trigger\_id | Trigger used for building new TF Builder | +| csr\_repo\_url | CSR repo for storing cloudbuilder Dockerfile | +| project\_id | n/a | +| scheduler\_id | Scheduler ID for periodically triggering TF Builder build Workflow | +| workflow\_id | Workflow ID for triggering new TF Builder build | + + diff --git a/examples/tf_cloudbuild_builder_simple/apis.tf b/examples/tf_cloudbuild_builder_simple/apis.tf new file mode 100644 index 00000000..8b23202b --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/apis.tf @@ -0,0 +1,33 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "enabled_google_apis" { + source = "terraform-google-modules/project-factory/google//modules/project_services" + version = "~> 11.3" + + project_id = var.project_id + disable_services_on_destroy = false + + activate_apis = [ + "iam.googleapis.com", + "compute.googleapis.com", + "sourcerepo.googleapis.com", + "workflows.googleapis.com", + "artifactregistry.googleapis.com", + "cloudbuild.googleapis.com", + "cloudscheduler.googleapis.com" + ] +} diff --git a/examples/tf_cloudbuild_builder_simple/main.tf b/examples/tf_cloudbuild_builder_simple/main.tf new file mode 100644 index 00000000..8fae844c --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/main.tf @@ -0,0 +1,40 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "cloudbuilder" { + source = "../../modules/tf_cloudbuild_builder" + + project_id = module.enabled_google_apis.project_id + dockerfile_repo_uri = google_sourcerepo_repository.builder_dockerfile_repo.url + # allow logs bucket to be destroyed + cb_logs_bucket_force_destroy = true +} + +# CSR for storing Dockerfile +resource "google_sourcerepo_repository" "builder_dockerfile_repo" { + project = module.enabled_google_apis.project_id + name = "tf-cloudbuilder" +} + +# Bootstrap CSR with Dockerfile +module "bootstrap_csr_repo" { + source = "terraform-google-modules/gcloud/google" + version = "~> 3.1.0" + upgrade = false + + create_cmd_entrypoint = "${path.module}/scripts/push-to-repo.sh" + create_cmd_body = "${module.enabled_google_apis.project_id} ${split("/", google_sourcerepo_repository.builder_dockerfile_repo.id)[3]} ${path.module}/Dockerfile" +} diff --git a/examples/tf_cloudbuild_builder_simple/outputs.tf b/examples/tf_cloudbuild_builder_simple/outputs.tf new file mode 100644 index 00000000..ca66138d --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/outputs.tf @@ -0,0 +1,44 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "artifact_repo" { + description = "GAR Repo created to store TF Cloud Builder images" + value = module.cloudbuilder.artifact_repo +} + +output "workflow_id" { + description = "Workflow ID for triggering new TF Builder build" + value = module.cloudbuilder.workflow_id +} + +output "scheduler_id" { + description = "Scheduler ID for periodically triggering TF Builder build Workflow" + value = module.cloudbuilder.scheduler_id +} + +output "cloudbuild_trigger_id" { + description = "Trigger used for building new TF Builder" + value = module.cloudbuilder.cloudbuild_trigger_id +} + +output "csr_repo_url" { + description = "CSR repo for storing cloudbuilder Dockerfile" + value = google_sourcerepo_repository.builder_dockerfile_repo.url +} + +output "project_id" { + value = var.project_id +} diff --git a/examples/tf_cloudbuild_builder_simple/scripts/push-to-repo.sh b/examples/tf_cloudbuild_builder_simple/scripts/push-to-repo.sh new file mode 100755 index 00000000..a08f56b2 --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/scripts/push-to-repo.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +set -ex + +if [ "$#" -lt 3 ]; then + >&2 echo "Not all expected arguments set." + exit 1 +fi + +CSR_PROJECT_ID=$1 +CSR_NAME=$2 +DOCKERFILE_PATH=$3 + +# create temp dir, cleanup at exit +tmp_dir=$(mktemp -d) +# # shellcheck disable=SC2064 +# trap "rm -rf $tmp_dir" EXIT +gcloud source repos clone "${CSR_NAME}" "${tmp_dir}" --project "${CSR_PROJECT_ID}" +cp "${DOCKERFILE_PATH}" "${tmp_dir}" +pushd "${tmp_dir}" +git config credential.helper gcloud.sh +git config init.defaultBranch main +git config user.email "terraform-robot@example.com" +git config user.name "TF Robot" +git checkout main || git checkout -b main +git add Dockerfile +git commit -m "init tf dockerfile" +git push origin main -f diff --git a/examples/tf_cloudbuild_builder_simple/variables.tf b/examples/tf_cloudbuild_builder_simple/variables.tf new file mode 100644 index 00000000..1d3d2a83 --- /dev/null +++ b/examples/tf_cloudbuild_builder_simple/variables.tf @@ -0,0 +1,19 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + default = "test-builder-workflow-4" +} diff --git a/modules/tf_cloudbuild_builder/README.md b/modules/tf_cloudbuild_builder/README.md new file mode 100644 index 00000000..00ced6f6 --- /dev/null +++ b/modules/tf_cloudbuild_builder/README.md @@ -0,0 +1,99 @@ +## Overview + +TF Cloud Builder blueprint automates the creation and management of Terraform [Cloud Build Builder/Runner](https://cloud.google.com/build/docs/cloud-builders) images. These images are used in the context of build steps for automating Terraform deployments using Cloud Build. + +## Usage + +Basic usage of this module is as follows: + +```hcl +module "tfbuilder" { + source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder" + version = "~> 5.0" + + project_id = module.enabled_google_apis.project_id + dockerfile_repo_uri = "https://github.com/org/repo" +} +``` + +Sample Dockerfile and functional examples are included in the [examples](../../examples/) directory. + +## Resources created + +This module creates: +- Cloud Workflow for querying upstream Terraform releases, existing TF Builder images and triggering a Cloud Build build if an image does not exist for the latest Terraform release +- Cloud Build trigger with an inline build configuration for building and pushing a Dockerfile to an Artifact repository +- Artifact Registry Repository for storing TF Builder images +- Cloud Scheduler job for periodically triggering the Workflow + +![](./assets/arch.png) + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| cb\_logs\_bucket\_force\_destroy | When deleting the bucket for storing CloudBuild logs, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects. | `bool` | `false` | no | +| cloudbuild\_sa | Custom SA email to be used by the CloudBuild trigger. Defaults to being created if empty. | `string` | `""` | no | +| dockerfile\_repo\_dir | The directory inside the repo where the Dockerfile is located. If empty defaults to repo root. | `string` | `""` | no | +| dockerfile\_repo\_ref | The branch or tag to use. Use refs/heads/branchname for branches or refs/tags/tagname for tags. | `string` | `"refs/heads/main"` | no | +| dockerfile\_repo\_type | Type of repo | `string` | `"CLOUD_SOURCE_REPOSITORIES"` | no | +| dockerfile\_repo\_uri | The URI of the repo where the Dockerfile for Terraform builder is stored | `string` | n/a | yes | +| gar\_repo\_location | Name of the location for the Google Artifact Repository. | `string` | `"us"` | no | +| gar\_repo\_name | Name of the Google Artifact Repository where the Terraform builder images are stored. | `string` | `"tf-runners"` | no | +| image\_name | Name of the image for the Terraform builder. | `string` | `"terraform"` | no | +| project\_id | GCP project for Cloud Build trigger,workflow and scheduler. | `string` | n/a | yes | +| trigger\_name | Name of the Cloud Build trigger building the Terraform builder. | `string` | `"tf-cloud-builder-build"` | no | +| workflow\_name | Name of the workflow managing builds. | `string` | `"terraform-runner-workflow"` | no | +| workflow\_region | The region of the workflow. | `string` | `"us-central1"` | no | +| workflow\_sa | Custom SA email to be used by the workflow. Defaults to being created if empty. | `string` | `""` | no | +| workflow\_schedule | The workflow frequency, in cron syntax | `string` | `"0 8 * * *"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| artifact\_repo | GAR Repo created to store TF Cloud Builder images | +| cloudbuild\_sa | SA used by Cloud Build trigger | +| cloudbuild\_trigger\_id | Trigger used for building new TF Builder | +| scheduler\_id | Scheduler ID for periodically triggering TF Builder build Workflow | +| workflow\_id | Workflow ID for triggering new TF Builder build | +| workflow\_sa | SA used by Workflow for triggering new TF Builder build | + + + +## Requirements + +### Software + +- [Terraform](https://www.terraform.io/downloads.html) >= 0.13.0 +- [terraform-provider-google] plugin >= 3.50.x + +### Permissions + +- `roles/artifactregistry.admin` +- `roles/cloudscheduler.admin` +- `roles/cloudbuild.builds.editor` +- `roles/workflows.admin` +- `roles/iam.serviceAccountAdmin` +- `roles/iam.securityAdmin` + +### APIs + +A project with the following APIs enabled must be used to host the +resources of this module: + +```hcl +"iam.googleapis.com", +"compute.googleapis.com", +"sourcerepo.googleapis.com", +"workflows.googleapis.com", +"artifactregistry.googleapis.com", +"cloudbuild.googleapis.com", +"cloudscheduler.googleapis.com" +``` + +## Contributing + +Refer to the [contribution guidelines](../../CONTRIBUTING.md) for +information on contributing to this module. diff --git a/modules/tf_cloudbuild_builder/assets/arch.png b/modules/tf_cloudbuild_builder/assets/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..b6ba3e05e375308a583a44071b78556a015aa89c GIT binary patch literal 90910 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/r/ + source_repo_url_split = local.is_source_repo ? split("/", var.dockerfile_repo_uri) : [] + source_repo_project = local.is_source_repo ? local.source_repo_url_split[4] : "" + source_repo_name = local.is_source_repo ? local.source_repo_url_split[6] : "" +} + +resource "google_cloudbuild_trigger" "build_trigger" { + project = var.project_id + name = var.trigger_name + description = "Builds a Terraform runner image. Managed by Terraform." + source_to_build { + uri = var.dockerfile_repo_uri + ref = var.dockerfile_repo_ref + repo_type = var.dockerfile_repo_type + } + + # todo(bharathkkb): switch to yaml after https://github.com/hashicorp/terraform-provider-google/issues/9818 + build { + step { + name = "gcr.io/cloud-builders/docker" + args = concat( + ["build"], + [for img_tag in local.img_tags_subst : "--tag=${img_tag}"], + ["--build-arg=TERRAFORM_VERSION=$${_TERRAFORM_FULL_VERSION}", "."] + ) + dir = var.dockerfile_repo_dir != "" ? var.dockerfile_repo_dir : null + } + step { + name = "${local.gar_uri}:v$${_TERRAFORM_FULL_VERSION}" + args = ["version"] + } + images = local.img_tags_subst + logs_bucket = module.bucket.bucket.url + } + + substitutions = local.tags_subst + service_account = local.cloudbuild_sa + + depends_on = [ + google_artifact_registry_repository_iam_member.push_images, + google_project_iam_member.logs_writer + ] +} + +resource "google_service_account" "cb_sa" { + count = var.cloudbuild_sa == "" ? 1 : 0 + project = var.project_id + account_id = "tf-cb-builder-sa" + display_name = "SA for Terraform builder build trigger. Managed by Terraform." +} + +# https://cloud.google.com/build/docs/securing-builds/configure-user-specified-service-accounts#permissions +resource "google_project_iam_member" "logs_writer" { + project = var.project_id + role = "roles/logging.logWriter" + member = "serviceAccount:${local.cloudbuild_sa_email}" +} + +# Custom bucket for storing build logs when user provided SA is used +# https://cloud.google.com/build/docs/securing-builds/store-manage-build-logs#store-custom-bucket +module "bucket" { + source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket" + version = "~> 3.2" + + name = "tf-cloudbuilder-build-logs-${var.project_id}" + project_id = var.project_id + location = var.gar_repo_location + force_destroy = var.cb_logs_bucket_force_destroy +} + +resource "google_storage_bucket_iam_member" "member" { + bucket = module.bucket.bucket.self_link + role = "roles/storage.admin" + member = "serviceAccount:${local.cloudbuild_sa_email}" +} + +# allow CB SA to view source code if google source repo +resource "google_sourcerepo_repository_iam_member" "member" { + count = local.is_source_repo ? 1 : 0 + project = local.source_repo_project + repository = local.source_repo_name + role = "roles/viewer" + member = "serviceAccount:${local.cloudbuild_sa_email}" +} diff --git a/modules/tf_cloudbuild_builder/gar.tf b/modules/tf_cloudbuild_builder/gar.tf new file mode 100644 index 00000000..c0265235 --- /dev/null +++ b/modules/tf_cloudbuild_builder/gar.tf @@ -0,0 +1,51 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + gar_name = split("/", google_artifact_registry_repository.tf-image-repo.name)[length(split("/", google_artifact_registry_repository.tf-image-repo.name)) - 1] +} + +resource "google_artifact_registry_repository" "tf-image-repo" { + provider = google-beta + project = var.project_id + + location = var.gar_repo_location + repository_id = var.gar_repo_name + description = "Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform." + format = "DOCKER" +} + +# Grant CB SA permissions to push to repo +resource "google_artifact_registry_repository_iam_member" "push_images" { + provider = google-beta + project = var.project_id + + location = google_artifact_registry_repository.tf-image-repo.location + repository = google_artifact_registry_repository.tf-image-repo.name + role = "roles/artifactregistry.writer" + member = "serviceAccount:${local.cloudbuild_sa_email}" +} + +# Grant Workflows SA access to list images in the artifact repo +resource "google_artifact_registry_repository_iam_member" "workflow_list" { + provider = google-beta + project = var.project_id + + location = google_artifact_registry_repository.tf-image-repo.location + repository = google_artifact_registry_repository.tf-image-repo.name + role = "roles/artifactregistry.reader" + member = "serviceAccount:${local.workflow_sa}" +} diff --git a/modules/tf_cloudbuild_builder/outputs.tf b/modules/tf_cloudbuild_builder/outputs.tf new file mode 100644 index 00000000..a4625ff6 --- /dev/null +++ b/modules/tf_cloudbuild_builder/outputs.tf @@ -0,0 +1,45 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "artifact_repo" { + description = "GAR Repo created to store TF Cloud Builder images" + value = google_artifact_registry_repository.tf-image-repo.name +} + +output "workflow_id" { + description = "Workflow ID for triggering new TF Builder build" + value = google_workflows_workflow.builder.id +} + +output "workflow_sa" { + description = "SA used by Workflow for triggering new TF Builder build" + value = local.workflow_sa +} + +output "scheduler_id" { + description = "Scheduler ID for periodically triggering TF Builder build Workflow" + value = google_cloud_scheduler_job.trigger_workflow.id +} + +output "cloudbuild_trigger_id" { + description = "Trigger used for building new TF Builder" + value = google_cloudbuild_trigger.build_trigger.id +} + +output "cloudbuild_sa" { + description = "SA used by Cloud Build trigger" + value = local.cloudbuild_sa +} diff --git a/modules/tf_cloudbuild_builder/templates/workflow.yaml.tftpl b/modules/tf_cloudbuild_builder/templates/workflow.yaml.tftpl new file mode 100644 index 00000000..fed06115 --- /dev/null +++ b/modules/tf_cloudbuild_builder/templates/workflow.yaml.tftpl @@ -0,0 +1,44 @@ +main: + steps: + - getLatestTFRelease: + call: http.get + args: + url: https://api.github.com/repos/hashicorp/terraform/releases/latest + result: latestTFRelease + - findLatestTFReleaseVersion: + assign: + - latestTFReleaseVersion: $${latestTFRelease.body.name} + - latestTFReleaseVersionNum: $${text.replace_all(latestTFReleaseVersion,"v","")} + - latestTFReleaseSplit: $${text.split(latestTFReleaseVersionNum,".")} + - latestTFReleaseMinor: $${latestTFReleaseSplit[0] + "." + latestTFReleaseSplit[1]} + - latestTFReleaseMajor: $${latestTFReleaseSplit[0]} + - checkIfRunnerExists: + try: + call: http.get + args: + url: $${"https://artifactregistry.googleapis.com/v1beta2/projects/${project_id}/locations/${gar_repo_location}/repositories/${gar_repo_name}/packages/terraform/tags/"+latestTFReleaseVersion} + auth: + type: OAuth2 + result: currentRunner + except: + as: e + steps: + - known_errors: + switch: + - condition: $${e.code == 404} + next: triggerRunnerBuild + - unhandled_exception: + raise: $${e} + - logAndExit: + return: $${"Found latest runner for "+latestTFReleaseVersion+" as "+currentRunner.body.version+", skipping build."} + - triggerRunnerBuild: + call: googleapis.cloudbuild.v1.projects.triggers.run + args: + projectId: ${project_id} + triggerId: ${trigger_id} + body: + substitutions: + _TERRAFORM_FULL_VERSION: $${latestTFReleaseVersionNum} + _TERRAFORM_MINOR_VERSION: $${latestTFReleaseMinor} + _TERRAFORM_MAJOR_VERSION: $${latestTFReleaseMajor} + diff --git a/modules/tf_cloudbuild_builder/variables.tf b/modules/tf_cloudbuild_builder/variables.tf new file mode 100644 index 00000000..0c72634f --- /dev/null +++ b/modules/tf_cloudbuild_builder/variables.tf @@ -0,0 +1,105 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "GCP project for Cloud Build trigger,workflow and scheduler." + type = string +} + +variable "workflow_name" { + description = "Name of the workflow managing builds." + type = string + default = "terraform-runner-workflow" +} + +variable "workflow_region" { + description = "The region of the workflow." + type = string + default = "us-central1" +} + +variable "workflow_schedule" { + description = "The workflow frequency, in cron syntax" + type = string + default = "0 8 * * *" +} + +variable "workflow_sa" { + description = "Custom SA email to be used by the workflow. Defaults to being created if empty." + type = string + default = "" +} + +variable "cloudbuild_sa" { + description = "Custom SA email to be used by the CloudBuild trigger. Defaults to being created if empty." + type = string + default = "" +} + +variable "cb_logs_bucket_force_destroy" { + description = "When deleting the bucket for storing CloudBuild logs, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects." + type = bool + default = false +} + +variable "gar_repo_name" { + description = "Name of the Google Artifact Repository where the Terraform builder images are stored." + type = string + default = "tf-runners" +} + +variable "gar_repo_location" { + description = "Name of the location for the Google Artifact Repository." + type = string + default = "us" +} + +variable "image_name" { + description = "Name of the image for the Terraform builder." + type = string + default = "terraform" +} + +variable "trigger_name" { + description = "Name of the Cloud Build trigger building the Terraform builder." + type = string + default = "tf-cloud-builder-build" +} + +variable "dockerfile_repo_uri" { + description = "The URI of the repo where the Dockerfile for Terraform builder is stored" + type = string +} + +variable "dockerfile_repo_ref" { + description = "The branch or tag to use. Use refs/heads/branchname for branches or refs/tags/tagname for tags." + type = string + default = "refs/heads/main" +} + +variable "dockerfile_repo_dir" { + description = "The directory inside the repo where the Dockerfile is located. If empty defaults to repo root." + default = "" +} + +variable "dockerfile_repo_type" { + description = "Type of repo" + default = "CLOUD_SOURCE_REPOSITORIES" + validation { + condition = contains(["UNKNOWN", "CLOUD_SOURCE_REPOSITORIES", "GITHUB", "BITBUCKET_SERVER"], var.dockerfile_repo_type) + error_message = "Must be one of UNKNOWN, CLOUD_SOURCE_REPOSITORIES, GITHUB or BITBUCKET_SERVER." + } +} diff --git a/modules/tf_cloudbuild_builder/versions.tf b/modules/tf_cloudbuild_builder/versions.tf new file mode 100644 index 00000000..681afe73 --- /dev/null +++ b/modules/tf_cloudbuild_builder/versions.tf @@ -0,0 +1,34 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">=0.13.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 3.50, < 5.0" + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 3.50, < 5.0" + } + } + + provider_meta "google" { + module_name = "blueprints/terraform/terraform-google-bootstrap:tf_cloudbuild_builder/v5.0.1" + } +} diff --git a/modules/tf_cloudbuild_builder/workflow.tf b/modules/tf_cloudbuild_builder/workflow.tf new file mode 100644 index 00000000..cbe40aab --- /dev/null +++ b/modules/tf_cloudbuild_builder/workflow.tf @@ -0,0 +1,80 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +locals { + rendered_workflow_config = templatefile("${path.module}/templates/workflow.yaml.tftpl", { + project_id = var.project_id + gar_repo_location = var.gar_repo_location + gar_repo_name = var.gar_repo_name + trigger_id = var.trigger_name + }) + workflow_sa = coalesce(var.workflow_sa, google_service_account.workflow_sa[0].email) +} + +resource "google_service_account" "workflow_sa" { + count = var.workflow_sa == "" ? 1 : 0 + project = var.project_id + account_id = "terraform-runner-workflow-sa" + display_name = "SA for TF Builder Workflow. Managed by Terraform." +} + +resource "google_workflows_workflow" "builder" { + project = var.project_id + name = var.workflow_name + region = var.workflow_region + description = "Workflow for triggering TF Runner builds. Managed by Terraform." + service_account = local.workflow_sa + source_contents = local.rendered_workflow_config +} + +# Allow Workflow SA to trigger workflow via scheduler +resource "google_project_iam_member" "invoke_workflow_scheduler" { + project = var.project_id + member = "serviceAccount:${local.workflow_sa}" + role = "roles/workflows.invoker" +} + +# Grant Workflow SA access to trigger builds +resource "google_project_iam_member" "trigger_builds" { + project = var.project_id + role = "roles/cloudbuild.builds.editor" + member = "serviceAccount:${local.workflow_sa}" +} + +resource "google_service_account_iam_member" "use_cb_sa" { + service_account_id = local.cloudbuild_sa + role = "roles/iam.serviceAccountUser" + member = "serviceAccount:${local.workflow_sa}" +} + +resource "google_cloud_scheduler_job" "trigger_workflow" { + name = "trigger-${var.workflow_name}" + project = var.project_id + region = var.workflow_region + description = "Trigger workflow for TF Runner builds. Managed by Terraform." + schedule = var.workflow_schedule + time_zone = "Etc/UTC" + + http_target { + uri = "https://workflowexecutions.googleapis.com/v1/${google_workflows_workflow.builder.id}/executions" + http_method = "POST" + oauth_token { + scope = "https://www.googleapis.com/auth/cloud-platform" + service_account_email = local.workflow_sa + } + } +} diff --git a/test/integration/discover_test.go b/test/integration/discover_test.go new file mode 100644 index 00000000..349a396f --- /dev/null +++ b/test/integration/discover_test.go @@ -0,0 +1,25 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "testing" + + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" +) + +func TestAll(t *testing.T) { + tft.AutoDiscoverAndTest(t) +} diff --git a/test/integration/go.mod b/test/integration/go.mod new file mode 100644 index 00000000..b42b27c1 --- /dev/null +++ b/test/integration/go.mod @@ -0,0 +1,8 @@ +module github.com/terraform-google-modules/terraform-google-bootstrap/test/integration + +go 1.16 + +require ( + github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.0.0-20220505032038-d0a72574cc0b + github.com/stretchr/testify v1.7.0 +) diff --git a/test/integration/go.sum b/test/integration/go.sum new file mode 100644 index 00000000..69426a48 --- /dev/null +++ b/test/integration/go.sum @@ -0,0 +1,712 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.5/go.mod h1:foo3aIXRQ90zFve3r0QiDsrjGDUwWhKl0ZOQy1CT14k= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= +github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.0.0-20220505032038-d0a72574cc0b h1:cE9a3SJ7pkljSpV5CWXhRKosgziVhWe77Kj0oI/hJEk= +github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.0.0-20220505032038-d0a72574cc0b/go.mod h1:ZA21UTC1O82Y8uUfWFDe9rll4pZD/1kpPCC1HSpL2T0= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= +github.com/GoogleContainerTools/kpt-functions-sdk/go v0.0.0-20220301220754-6964a09d6cd2/go.mod h1:lJYiqfBOl6AOiefK9kmkhinbffIysu+nnclOBwKEPlQ= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.38.28/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= +github.com/gruntwork-io/terratest v0.35.6 h1:Q7pUd3JI4i5mmR/KgYkZJJ4q9ZbV8ru9KydwjA/ohaA= +github.com/gruntwork-io/terratest v0.35.6/go.mod h1:GIVJGBV1WIv1vxIG31Ycy0CuHYfXuvvkilNQuC9Wi+o= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY= +github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY= +github.com/hashicorp/terraform-json v0.9.0 h1:WE7+Wt93W93feOiCligElSyS0tlDzwZUtJuDGIBr8zg= +github.com/hashicorp/terraform-json v0.9.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= +github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.14.2-0.20210217184823-a52172cd2f64 h1:+9bM6qWXndPx7+czi9+Jj6zHPioFpfdhwVGOYOgujMY= +github.com/mitchellh/go-testing-interface v1.14.2-0.20210217184823-a52172cd2f64/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/gjson v1.12.1 h1:ikuZsLdhr8Ws0IdROXUS1Gi4v9Z4pGqpX/CvJkxvfpo= +github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc= +github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= +github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191205215504-7b8c8591a921/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201110201400-7099162a900a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= +k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= +k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= +k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= +k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM= +k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= +k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= +k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= +modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA= +sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/test/integration/tf_cloudbuild_builder_simple/tf_cloudbuild_builder_simple_test.go b/test/integration/tf_cloudbuild_builder_simple/tf_cloudbuild_builder_simple_test.go new file mode 100644 index 00000000..eaaf4e05 --- /dev/null +++ b/test/integration/tf_cloudbuild_builder_simple/tf_cloudbuild_builder_simple_test.go @@ -0,0 +1,109 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// define test package name +package tf_cloudbuild_builder_simple + +import ( + "fmt" + "log" + "strings" + "testing" + "time" + + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils" + "github.com/stretchr/testify/assert" +) + +func TestTFCloudBuildBuilder(t *testing.T) { + bpt := tft.NewTFBlueprintTest(t) + + bpt.DefineVerify(func(assert *assert.Assertions) { + bpt.DefaultVerify(assert) + + projectID := bpt.GetStringOutput("project_id") + artifactRepo := bpt.GetStringOutput("artifact_repo") + artifactRepoDockerRegistry := fmt.Sprintf("us-docker.pkg.dev/%s/%s/terraform", projectID, artifactRepo) + schedulerID := bpt.GetStringOutput("scheduler_id") + workflowID := bpt.GetStringOutput("workflow_id") + triggerFQN := bpt.GetStringOutput("cloudbuild_trigger_id") + triggerId := strings.Split(triggerFQN, "/")[len(strings.Split(triggerFQN, "/"))-1] + csrURL := bpt.GetStringOutput("csr_repo_url") + + schedulerOP := gcloud.Runf(t, "scheduler jobs describe %s", schedulerID) + assert.Contains(schedulerOP.Get("name").String(), "trigger-terraform-runner-workflow", "has the correct name") + assert.Equal("0 8 * * *", schedulerOP.Get("schedule").String(), "has the correct schedule") + assert.Equal(fmt.Sprintf("https://workflowexecutions.googleapis.com/v1/%s/executions", workflowID), schedulerOP.Get("httpTarget.uri").String(), "has the correct target") + + workflowOP := gcloud.Runf(t, "workflows describe %s", workflowID) + assert.Contains(workflowOP.Get("name").String(), "terraform-runner-workflow", "has the correct name") + assert.Equal(fmt.Sprintf("projects/%s/serviceAccounts/terraform-runner-workflow-sa@%s.iam.gserviceaccount.com", projectID, projectID), workflowOP.Get("serviceAccount").String(), "uses expected SA") + + cloudBuildOP := gcloud.Runf(t, "beta builds triggers describe %s --project %s", triggerId, projectID) + log.Print(cloudBuildOP) + assert.Equal("tf-cloud-builder-build", cloudBuildOP.Get("name").String(), "has the correct name") + assert.Equal(fmt.Sprintf("projects/%s/serviceAccounts/tf-cb-builder-sa@%s.iam.gserviceaccount.com", projectID, projectID), cloudBuildOP.Get("serviceAccount").String(), "uses expected SA") + assert.Equal(csrURL, cloudBuildOP.Get("sourceToBuild.uri").String(), "is connected to expected repo") + expectedSubsts := []string{"_TERRAFORM_FULL_VERSION", "_TERRAFORM_MAJOR_VERSION", "_TERRAFORM_MINOR_VERSION"} + gotSubsts := cloudBuildOP.Get("substitutions").Map() + imgs := utils.GetResultStrSlice(cloudBuildOP.Get("build.images").Array()) + for _, subst := range expectedSubsts { + _, found := gotSubsts[subst] + assert.Truef(found, "has %s substituion", found) + assert.Contains(imgs, fmt.Sprintf("%s:v${%s}", artifactRepoDockerRegistry, subst), "tags correct image") + } + + // e2e test + oldWorkflowRuns := gcloud.Runf(t, "workflows executions list %s", workflowID).Array() + // sometimes scheduler takes a minute to kick off workflow due to eventually consistent IAM + // continue to retrigger a few times until a new workflow is kicked off + triggerWorkflowFn := func() (bool, error) { + gcloud.Runf(t, "scheduler jobs run %s", schedulerID) + // workflow may take a few secs to trigger + time.Sleep(10 * time.Second) + newWorkflowRuns := gcloud.Runf(t, "workflows executions list %s", workflowID).Array() + // new workflow is kicked off since list has an additional workflow run + if len(newWorkflowRuns)-len(oldWorkflowRuns) > 0 { + return false, nil + } + return true, nil + } + utils.Poll(t, triggerWorkflowFn, 10, 10*time.Second) + + // poll until workflow complete + // workflow will poll CB LRO to completion + pollWorkflowFn := func() (bool, error) { + latestWorkflowRun := gcloud.Runf(t, "workflows executions list %s --sort-by=startTime --limit=1", workflowID).Array() + latestWorkflowRunStatus := latestWorkflowRun[0].Get("state").String() + if latestWorkflowRunStatus == "SUCCEEDED" { + return false, nil + } + // if failed it maybe due to eventually consistent IAM, retry trigger + if latestWorkflowRunStatus == "FAILED" { + triggerWorkflowFn() + } + return true, nil + } + utils.Poll(t, pollWorkflowFn, 100, 20*time.Second) + + images := gcloud.Runf(t, "artifacts docker images list %s --include-tags", artifactRepoDockerRegistry).Array() + assert.Equal(1, len(images), "only one image is in registry") + imageTags := strings.Split(images[0].Get("tags").String(), ",") + assert.Equal(3, len(imageTags), "image has three tags") + }) + + bpt.Test() +} diff --git a/test/setup/main.tf b/test/setup/main.tf index f270bff6..5bd882e9 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -33,7 +33,9 @@ module "project" { "cloudbuild.googleapis.com", "sourcerepo.googleapis.com", "cloudkms.googleapis.com", - "artifactregistry.googleapis.com" + "artifactregistry.googleapis.com", + "workflows.googleapis.com", + "cloudscheduler.googleapis.com" ] }