-
Notifications
You must be signed in to change notification settings - Fork 19
/
pivnet
executable file
·197 lines (155 loc) · 6.37 KB
/
pivnet
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/bash
PIVNETRC=~/.pivnetrc
if [ -f "$PIVNETRC" ]; then
chmod 400 $PIVNETRC
source $PIVNETRC 2>/dev/null
fi
set -e
usage_and_exit() {
cat <<EOF
Usage: pivnet <command> [options]
Examples:
pivnet token sample983s28494b87e4v36dl3794581-r
pivnet download https://network.pivotal.io/.../product_files/7509/download
EOF
exit 1
}
error_and_exit() {
echo -e "$1" && exit 1
}
set_token() {
[ -f "$PIVNETRC" ] && chmod 600 $PIVNETRC
echo "PIVNET_REFRESH_TOKEN=$1" > $HOME/.pivnetrc
chmod 400 $PIVNETRC
echo "Updated Pivotal Network Refresh Token"
}
validate_sha256() {
local FILENAME=$1
local CHECKSUM=$2
local OUTPUT=$(shasum -a 256 $FILENAME)
[[ "$OUTPUT" =~ "$CHECKSUM" ]]
}
validate_md5() {
local FILENAME=$1
local CHECKSUM=$2
# Ubuntu uses md5sum; OS X uses md5
local MD5SUM=$(command -v md5sum 2>/dev/null || command -v md5 2>/dev/null)
local OUTPUT=$($MD5SUM $FILENAME)
[[ "$OUTPUT" =~ "$CHECKSUM" ]]
}
# return the product file json
get_product_file() {
local DOWNLOAD_URL=$1
local ACCESS_TOKEN=$2
# https://network.pivotal.io/api/v2/products/:slug/releases/:id/product_files/:id/download
local PIVNET_HOST=${DOWNLOAD_URL%/api/v2*}
local PRODUCT_SLUG=${DOWNLOAD_URL#*/products/*} && PRODUCT_SLUG=${PRODUCT_SLUG%*/releases/*}
local RELEASE_ID=${DOWNLOAD_URL#*/releases/*} && RELEASE_ID=${RELEASE_ID%*/product_files/*}
local FILE_ID=${DOWNLOAD_URL#*/product_files/*} && FILE_ID=${FILE_ID%*/download*}
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" $PIVNET_HOST/api/v2/products/$PRODUCT_SLUG/releases/$RELEASE_ID/product_files/$FILE_ID
}
# get the filename from the product file json
get_filename() {
local PRODUCT_FILE=$1
local AWS_OBJECT_KEY_VALUE=$(echo "$PRODUCT_FILE" | grep -oE '"aws_object_key":\s{0,}"[^"]*' | grep -o '[^"]*$')
basename "$AWS_OBJECT_KEY_VALUE"
}
# get the sha256 from the product file json
get_sha256() {
local PRODUCT_FILE=$1
echo "$PRODUCT_FILE" | grep -oE '"sha256":\s{0,}"[^"]*' | grep -o '[^"]*$'
}
# get the sha256 from the product file json
get_md5() {
local PRODUCT_FILE=$1
echo "$PRODUCT_FILE" | grep -oE '"md5":\s{0,}"[^"]*' | grep -o '[^"]*$'
}
# get the access_token from the authentication/access_tokens json
get_access_token() {
local ACCESS_TOKENS=$1
echo "$ACCESS_TOKENS" | grep -oE '"access_token":\s{0,}"[^"]*' | grep -o '[^"]*$'
}
download_from_pivnet() {
local PIVNET_REFRESH_TOKEN=$PIVNET_REFRESH_TOKEN
if [ -z "$PIVNET_REFRESH_TOKEN" ]; then
read -r -p "Pivnet Refresh Token: " PIVNET_REFRESH_TOKEN
local SAVE_TOKEN=
read -r -p "Save token for future use? [Y/n]: " SAVE_TOKEN
SAVE_TOKEN=$(echo "${SAVE_TOKEN:-y}" | awk '{print tolower($0)}')
if [ "$SAVE_TOKEN" = "y" ]; then
set_token $PIVNET_REFRESH_TOKEN
fi
fi
local OUTPUT=$(curl -s -H "Accept: application/json" -H "Content-Type: application/json" -d "{\"refresh_token\":\"$PIVNET_REFRESH_TOKEN\"}" -X POST https://network.pivotal.io/api/v2/authentication/access_tokens)
local ACCESS_TOKEN=$(get_access_token "$OUTPUT")
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "{}" ]; then
error_and_exit "Unable to obtain access token using supplied refresh token.\nPlease update your refresh token:\n pivnet token sample983s28494b87e4v36dl3794581-r"
fi
local DOWNLOAD_URL=$1
if [ -z "$DOWNLOAD_URL" ]; then
read -r -p "Remote file URL: " DOWNLOAD_URL
fi
# Hit the download URL but don't follow the redirect just yet so we can validate
# the response codes and get the filename
OUTPUT=$(curl -s --data '' -D- -o /dev/null -H "Authorization: Bearer $ACCESS_TOKEN" $DOWNLOAD_URL)
if echo "$OUTPUT" | grep -q 'HTTP/1.1 401'; then
error_and_exit "User could not be authenticated.\nPlease check your refresh token."
elif echo "$OUTPUT" | grep -q 'HTTP/1.1 403'; then
error_and_exit "User does not have access to download files from this release."
elif echo "$OUTPUT" | grep -q 'HTTP/1.1 404'; then
error_and_exit "The product or release cannot be found. Invalid Download URL: $DOWNLOAD_URL"
elif echo "$OUTPUT" | grep -q 'HTTP/1.1 451'; then
echo "User has not accepted the current EULA for this release."
local ACCEPT_EULA=
read -r -p "Accept End User License Agreement? [Y/n]: " ACCEPT_EULA
ACCEPT_EULA=$(echo "${ACCEPT_EULA:-y}" | awk '{print tolower($0)}')
if [ "$ACCEPT_EULA" != "y" ]; then
error_and_exit "You must agree to the End User License Agreement terms and conditions in order to download software."
fi
local BASE_URL=${DOWNLOAD_URL%/product_files*}
local ACCEPT_EULA_RESPONSE_CODE=$(curl -s -w "%{http_code}" -o /dev/null --data '' -H "Authorization: Bearer $ACCESS_TOKEN" $BASE_URL/eula_acceptance)
if [ "$ACCEPT_EULA_RESPONSE_CODE" != "200" ]; then
error_and_exit "Failed to accept End User License Agreement. Please visit the product page on network.pivotal.io and accept the EULA."
fi
echo "Accepted End User License Agreement. Visit https://network.pivotal.io/users/dashboard/eulas to view all accepted EULAs"
# Hit the download url again now that we've accepted the EULA
OUTPUT=$(curl -s --data '' -D- -o /dev/null -H "Authorization: Bearer $ACCESS_TOKEN" $DOWNLOAD_URL)
fi
local PRODUCT_FILE=$(get_product_file "$DOWNLOAD_URL" "$ACCESS_TOKEN")
local FILENAME=$(get_filename "$PRODUCT_FILE")
local SHA256=$(get_sha256 "$PRODUCT_FILE")
local MD5=$(get_md5 "$PRODUCT_FILE")
if [ -z "$FILENAME" ]; then
error_and_exit "Unable to get the filename from the download url."
fi
printf 'Downloading \e[33m%s\e[0m from %s \n' "$FILENAME" "$DOWNLOAD_URL"
curl -o $FILENAME \
-L --data '' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
$DOWNLOAD_URL
if [ -n "$SHA256" ]; then
printf 'Validating sha256 checksum: \e[33m%s\e[0m\n' "$SHA256"
if ! validate_sha256 $FILENAME $SHA256; then
error_and_exit "Checksum is invalid! Please re-download the product."
else
echo "Checksum is valid."
fi
elif [ -n "$MD5" ]; then
printf 'Validating md5 checksum: \e[33m%s\e[0m\n' "$MD5"
if ! validate_md5 $FILENAME $MD5; then
error_and_exit "Checksum is invalid! Please re-download the product."
else
echo "Checksum is valid."
fi
else
error_and_exit "No SHA256 or MD5 checksum found in product file: $PRODUCT_FILE"
fi
}
CMD=$1 ARG=$2
if [ "token" = "$CMD" ]; then
set_token $ARG
elif [ "download" = "$CMD" ]; then
download_from_pivnet $ARG
else
usage_and_exit
fi