summary refs log tree commit diff
path: root/pkgs/applications/networking/cluster/terraform-providers/update-provider
blob: 482da6a60275b3a21c78a653aabfe8e088184e5b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env nix-shell
#! nix-shell -I nixpkgs=../../../../.. -i bash -p coreutils curl git jq moreutils nix nix-prefetch
# shellcheck shell=bash
# vim: ft=sh
#
# Update a terraform provider to the latest version advertised at the
# provider source address.
#
set -euo pipefail
shopt -s inherit_errexit

show_usage() {
  cat <<DOC
Usage: ./update-provider [--force] [--no-build] [<owner>/]<provider>

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 '<owner>/<provider>'
to add the provider to the list:

    ./update-provider hetznercloud/hcloud

Options:

  * --force: Force the update even if the version matches.
  * --no-build: Don't build provider
  * --vendor-sha256 <sha256>: Override the SHA256 or "null".
DOC
}

force=
provider=
build=1
vendorSha256=

while [[ $# -gt 0 ]]; do
  case "$1" in
  -h | --help)
    show_usage
    exit
    ;;
  --force)
    force=1
    shift
    ;;
  --no-build)
    build=0
    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

# Usage: read_attr <key>
read_attr() {
  jq -r ".\"${provider}\".\"$1\"" providers.json
}

# Usage: update_attr <key> <value>
update_attr() {
  if [[ $2 == "null" ]]; then
    jq -S ".\"${provider}\".\"$1\" = null" providers.json | sponge providers.json
  else
    jq -S ".\"${provider}\".\"$1\" = \"$2\"" providers.json | sponge providers.json
  fi
}

repo_root=$(git rev-parse --show-toplevel)

generate_hash() {
  nix-prefetch -I nixpkgs="${repo_root}" \
    "{ sha256 }: (import ${repo_root} {}).terraform-providers.${provider}.$1.overrideAttrs (_: { $2 = sha256; })"
}

echo_provider() {
  echo "== terraform-providers.${provider}: $* =="
}

if [[ ${provider} =~ ^[^/]+/[^/]+$ ]]; then
  echo_provider "init"
  source_address=registry.terraform.io/${provider}
  provider=$(basename "${provider}")
  update_attr "provider-source-address" "${source_address}"
  update_attr version "0"
  # create empty stings so nix-prefetch works
  update_attr sha256 ""
  update_attr vendorSha256 ""
else
  source_address="$(read_attr provider-source-address)"
fi

old_vendor_sha256=$(read_attr vendorSha256)
old_version=$(read_attr version)

# 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 "already at version ${version}"
  exit
fi
if [[ ${version} =~ [[:alpha:]] && ${force} != 1 ]]; then
  echo_provider "not updating to unstable version ${version}"
  exit
fi
echo_provider "updating from ${old_version} to ${version}"
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}"
echo_provider "calculating sha256"
sha256=$(generate_hash src outputHash)
update_attr sha256 "${sha256}"

if [[ -z ${vendorSha256} ]]; then
  if [[ ${old_vendor_sha256} == null ]]; then
    vendorSha256=null
  else
    echo_provider "calculating vendorSha256"
    vendorSha256=$(generate_hash go-modules vendorSha256)
  fi
fi

update_attr vendorSha256 "${vendorSha256}"

# Check that the provider builds
if [[ ${build} == 1 ]]; then
  echo_provider "building"
  nix-build --no-out-link "${repo_root}" -A "terraform-providers.${provider}"
fi