#!/usr/bin/env nix-shell #! nix-shell -I nixpkgs=../../../../.. -i bash -p coreutils curl jq moreutils nix # shellcheck shell=bash # vim: ft=sh # # Update a terraform provider to the latest version advertised at the # provider source address. # set -euo pipefail show_usage() { cat </] Update a single provider in the providers.json inventory file. For example to update 'terraform-providers.aws' run: ./update-provider aws If the provider is not in the list already, use the form '/' to add the provider to the list: ./update-provider hetznercloud/hcloud Options: * --force: Force the update even if the version matches. * --vendor: Switch from go package to go modules with vendor. * --vendor-sha256 : Override the SHA256 or "null". DOC } force= provider= vendor= vendorSha256= while [[ $# -gt 0 ]]; do case "$1" in -h | --help) show_usage exit ;; --force) force=1 shift ;; --vendor) force=1 vendor=1 shift ;; --vendor-sha256) force=1 vendorSha256=$2 shift 2 ;; *) if [[ -n "$provider" ]]; then echo "ERROR: provider name was passed two times: '$provider' and '$1'" echo "Use --help for more info" exit 1 fi provider=$1 shift esac done if [[ -z "$provider" ]]; then echo "ERROR: No providers specified!" echo show_usage exit 1 fi provider_name=$(basename "$provider") # Usage: read_attr read_attr() { jq -r ".\"$provider_name\".\"$1\"" providers.json } # Usage: update_attr update_attr() { if [[ "$2" == "null" ]]; then jq -S ".\"$provider_name\".\"$1\" = null" providers.json | sponge providers.json else jq -S ".\"$provider_name\".\"$1\" = \"$2\"" providers.json | sponge providers.json fi } prefetch_github() { # of a given owner, repo and rev, fetch the tarball and return the output of # `nix-prefetch-url` local owner=$1 local repo=$2 local rev=$3 nix-prefetch-url --unpack "https://github.com/$owner/$repo/archive/$rev.tar.gz" } old_source_address="$(read_attr provider-source-address)" old_vendor_sha256=$(read_attr vendorSha256) old_version=$(read_attr version) if [[ $provider =~ ^[^/]+/[^/]+$ ]]; then source_address=registry.terraform.io/$provider else source_address=$old_source_address fi if [[ "$source_address" == "null" ]]; then echo "Could not find the source address for provider: $provider" exit 1 fi update_attr "provider-source-address" "$source_address" # The provider source address (used inside Terraform `required_providers` block) is # used to compute the registry API endpoint # # registry.terraform.io/hashicorp/aws (provider source address) # registry.terraform.io/providers/hashicorp/aws (provider URL for the website) # registry.terraform.io/v1/providers/hashicorp/aws (provider URL for the JSON API) registry_response=$(curl -s https://"${source_address/\///v1/providers/}") version="$(jq -r '.version' <<< "$registry_response")" if [[ "$old_version" = "$version" && "$force" != 1 && -z "$vendorSha256" && "$old_vendor_sha256" != "$vendorSha256" ]]; then echo "$provider_name is already at version $version" exit fi update_attr version "$version" provider_source_url="$(jq -r '.source' <<< "$registry_response")" org="$(echo "$provider_source_url" | cut -d '/' -f 4)" update_attr owner "$org" repo="$(echo "$provider_source_url" | cut -d '/' -f 5)" update_attr repo "$repo" rev="$(jq -r '.tag' <<< "$registry_response")" update_attr rev "$rev" sha256=$(prefetch_github "$org" "$repo" "$rev") update_attr sha256 "$sha256" repo_root=$(git rev-parse --show-toplevel) if [[ -z "$vendorSha256" ]]; then if [[ "$old_vendor_sha256" == null ]]; then vendorSha256=null elif [[ -n "$old_vendor_sha256" || "$vendor" = 1 ]]; then echo "=== Calculating vendorSha256 ===" update_attr vendorSha256 "0000000000000000000000000000000000000000000000000000000000000000" # Hackish way to find out the desired sha256. First build, then extract the # error message from the logs. set +e nix-build --no-out-link "$repo_root" -A "terraform-providers.$provider_name.go-modules" 2>vendor_log.txt set -e logs=$(< vendor_log.txt) if ! [[ $logs =~ got:\ +([^\ ]+) ]]; then echo "ERROR: could not find new hash in output:" cat vendor_log.txt rm -f vendor_log.txt exit 1 fi rm -f vendor_log.txt # trim the results in case it they have a sha256: prefix or contain more than one line vendorSha256=$(echo "${BASH_REMATCH[1]#sha256:}" | head -n 1) # Deal with nix unstable if [[ $vendorSha256 = sha256-* ]]; then vendorSha256=$(nix to-base32 "$vendorSha256") fi fi fi if [[ -n "$vendorSha256" ]]; then update_attr vendorSha256 "$vendorSha256" fi # Check that the provider builds echo "=== Building terraform-providers.$provider_name ===" nix-build "$repo_root" -A "terraform-providers.$provider_name"