diff --git a/.gitignore b/.gitignore index 40f243918..ae1d0585a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.swp __pycache__ *.pyc +crmint.egg-info/ # System Files .DS_Store diff --git a/cli/.gitignore b/cli/.gitignore index 1f2e7d0cd..c749eff24 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -1,2 +1,4 @@ *.egg-info stages/*.py +build/ +dist/ diff --git a/cli/commands/cloud.py b/cli/commands/cloud.py index acea721c7..f21354b04 100644 --- a/cli/commands/cloud.py +++ b/cli/commands/cloud.py @@ -131,6 +131,20 @@ def terraform_switch_workspace(stage: shared.StageContext, debug=debug) +def patch_etc_hosts(debug: bool = False) -> None: + """Workaround to avoid Terraform to use IPv6 addresses.""" + cmd = 'bash scripts/force_ipv4_addresses.sh' + shared.execute_command( + 'Patch /etc/hosts to force IPv4', cmd, cwd='./cli', debug=debug) + + +def unpatch_etc_hosts(debug: bool = False) -> None: + """Restores the `/etc/hosts` file.""" + cmd = 'sudo cp /etc/hosts.backup /etc/hosts' + shared.execute_command( + 'Restore /etc/hosts', cmd, cwd='./cli', debug=debug) + + def terraform_init(debug: bool = False) -> bool: """Runs the Terraform init command.""" cmd = 'terraform init -upgrade' @@ -352,6 +366,7 @@ def setup(stage_path: Union[None, str], debug: bool) -> None: sys.exit(1) # Switches workspace. + patch_etc_hosts(debug=debug) terraform_init(debug=debug) terraform_switch_workspace(stage, debug=debug) @@ -363,6 +378,7 @@ def setup(stage_path: Union[None, str], debug: bool) -> None: terraform_plan(stage, debug=debug) configuration_summary_from_plan(debug=debug) terraform_apply(debug=debug) + unpatch_etc_hosts(debug=debug) click.echo(click.style('Done.', fg='magenta', bold=True)) diff --git a/cli/commands/cloud_tests.py b/cli/commands/cloud_tests.py index a077ec4af..c24d4d565 100644 --- a/cli/commands/cloud_tests.py +++ b/cli/commands/cloud_tests.py @@ -201,6 +201,7 @@ def test_validates_stdout_without_vpc(self): textwrap.dedent("""\ >>>> Setup Project ID found: dummy_project_with_vpc + ---> Patch /etc/hosts to force IPv4 ✓ ---> Initialize Terraform ✓ ---> List Terraform workspaces ✓ ---> Create new Terraform workspace: dummy_project_with_vpc ✓ @@ -215,6 +216,7 @@ def test_validates_stdout_without_vpc(self): Cloud Run Service IAM Member \\(3\\) (.|\\n)* ---> Apply Terraform plan \\(~10min\\) ✓ + ---> Restore /etc/hosts ✓ Done. """) ) diff --git a/cli/scripts/force_ipv4_addresses.sh b/cli/scripts/force_ipv4_addresses.sh new file mode 100755 index 000000000..f5b38fc85 --- /dev/null +++ b/cli/scripts/force_ipv4_addresses.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# +# IPv6 is disabled in Google Cloud Shell, though the DNS resolution in Go +# does not always comply with this setting and from time to time resolves to +# an IPv6 address. +# +# The following workaround as been described proposes, waiting for the Go team +# to solve this properly (https://github.com/golang/go/issues/25321). +# +# See: https://github.com/hashicorp/terraform-provider-google/issues/6782 +# + +# Checks that we run inside a Google VM. +GMETADATA_ADDR=`dig +short metadata.google.internal` +if [[ "${GMETADATA_ADDR}" == "" ]]; then + echo "Not on a Google VM, no need to patch the /etc/hosts file." + exit 0 +fi + +# Backup existing /etc/hosts. +if [ ! -f /etc/hosts.backup ]; then + sudo cp /etc/hosts /etc/hosts.backup +fi + +read -r -d '' APIS << EOM +aiplatform.googleapis.com +analytics.googleapis.com +analyticsadmin.googleapis.com +analyticsreporting.googleapis.com +cloudbuild.googleapis.com +cloudresourcemanager.googleapis.com +cloudscheduler.googleapis.com +compute.googleapis.com +container.googleapis.com +googleapis.com +iam.googleapis.com +logging.googleapis.com +monitoring.googleapis.com +pubsub.googleapis.com +secretmanager.googleapis.com +servicenetworking.googleapis.com +sqladmin.googleapis.com +storage-api.googleapis.com +storage-component.googleapis.com +storage.googleapis.com +www.googleapis.com +EOM + +# Restores the backup content. +sudo sh -c "cat /etc/hosts.backup > /etc/hosts" + +# Adds IPv4 addresses for each Google Cloud API. +sudo sh -c "echo -e '\n# Forcing IPv4 to workaround a Go issue: https://github.com/golang/go/issues/25321' >> /etc/hosts" +for name in $APIS +do + ipv4=$(getent ahostsv4 "$name" | head -n 1 | awk '{ print $1 }') + sudo sh -c "echo '$ipv4 $name' >> /etc/hosts" + echo "Forced IPv4 for $name: $ipv4" +done