@google-cloud/nodejs-common 1.1.0 → 1.2.1-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/apps_scripts.sh +209 -0
- package/bin/bigquery.sh +53 -0
- package/bin/google_ads.sh +115 -0
- package/bin/install_functions.sh +133 -38
- package/package.json +11 -11
- package/src/apis/google_ads.js +306 -54
- package/src/components/automl.js +36 -56
- package/src/components/scheduler.js +36 -24
- package/src/components/vertex_ai.js +4 -3
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2022 Google Inc.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
# Const the folder name of Apps Script.
|
|
18
|
+
DEFAULT_APPS_SCRIPT_FOLDER="apps_script"
|
|
19
|
+
|
|
20
|
+
#######################################
|
|
21
|
+
# Clasp login.
|
|
22
|
+
# Globals:
|
|
23
|
+
# None
|
|
24
|
+
# Arguments:
|
|
25
|
+
# None
|
|
26
|
+
#######################################
|
|
27
|
+
clasp_login() {
|
|
28
|
+
while :; do
|
|
29
|
+
local claspLogin=$(clasp login --status)
|
|
30
|
+
if [[ "${claspLogin}" != "You are not logged in." ]]; then
|
|
31
|
+
printf '%s' "${claspLogin} Would you like to continue with it? [Y/n]"
|
|
32
|
+
local logout
|
|
33
|
+
read -r logout
|
|
34
|
+
logout=${logout:-"Y"}
|
|
35
|
+
if [[ ${logout} == "Y" || ${logout} == "y" ]]; then
|
|
36
|
+
break
|
|
37
|
+
else
|
|
38
|
+
clasp logout
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
clasp login --no-localhost
|
|
42
|
+
done
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
#######################################
|
|
46
|
+
# Initialize a AppsScript project. Usually it involves following steps:
|
|
47
|
+
# 1. Create a AppsScript project within a new Google Sheet.
|
|
48
|
+
# 2. Prompt to update the Google Cloud Project number of the AppsScript project
|
|
49
|
+
# to enable external APIs for this AppsScript project.
|
|
50
|
+
# 3. Prompt to grant the access of Cloud Functions' default service account to
|
|
51
|
+
# this Google Sheet, so the Cloud Functions can query this Sheet later.
|
|
52
|
+
# 4. Initialize the Sheet based on requests.
|
|
53
|
+
# Globals:
|
|
54
|
+
# None
|
|
55
|
+
# Arguments:
|
|
56
|
+
# The Google Sheet name.
|
|
57
|
+
# The folder for Apps Script code, default value ${DEFAULT_APPS_SCRIPT_FOLDER}
|
|
58
|
+
#######################################
|
|
59
|
+
clasp_initialize() {
|
|
60
|
+
((STEP += 1))
|
|
61
|
+
printf '%s\n' "Step ${STEP}: Starting to create Google Sheets..."
|
|
62
|
+
local sheetName="${1}"
|
|
63
|
+
local apps_script_src="${2-"${DEFAULT_APPS_SCRIPT_FOLDER}"}"
|
|
64
|
+
clasp_login
|
|
65
|
+
while :; do
|
|
66
|
+
local claspStatus=$(
|
|
67
|
+
clasp status -P "${apps_script_src}" >/dev/null 2>&1
|
|
68
|
+
echo $?
|
|
69
|
+
)
|
|
70
|
+
if [[ $claspStatus -gt 0 ]]; then
|
|
71
|
+
clasp create --type sheets --title "${sheetName}" --rootDir "${apps_script_src}"
|
|
72
|
+
local createResult=$?
|
|
73
|
+
if [[ $createResult -gt 0 ]]; then
|
|
74
|
+
printf '%s' "Press any key to continue after you enable the Google \
|
|
75
|
+
Apps Script API: https://script.google.com/home/usersettings..."
|
|
76
|
+
local any
|
|
77
|
+
read -n1 -s any
|
|
78
|
+
printf '\n\n'
|
|
79
|
+
continue
|
|
80
|
+
fi
|
|
81
|
+
break
|
|
82
|
+
else
|
|
83
|
+
printf '%s' "AppsScript project exists. Would you like to continue with \
|
|
84
|
+
it? [Y/n]"
|
|
85
|
+
local useCurrent
|
|
86
|
+
read -r useCurrent
|
|
87
|
+
useCurrent=${useCurrent:-"Y"}
|
|
88
|
+
if [[ ${useCurrent} = "Y" || ${useCurrent} = "y" ]]; then
|
|
89
|
+
break
|
|
90
|
+
else
|
|
91
|
+
printf '%s' "Would you like to delete current AppsScript and create a \
|
|
92
|
+
new one? [N/y]"
|
|
93
|
+
local deleteCurrent
|
|
94
|
+
read -r deleteCurrent
|
|
95
|
+
deleteCurrent=${deleteCurrent:-"N"}
|
|
96
|
+
if [[ ${deleteCurrent} = "Y" || ${deleteCurrent} = "y" ]]; then
|
|
97
|
+
rm "${apps_script_src}/.clasp.json"
|
|
98
|
+
continue
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
done
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#######################################
|
|
106
|
+
# Copy GCP project configuration file to AppsScript codes as a constant named
|
|
107
|
+
# `GCP_CONFIG`.
|
|
108
|
+
# Globals:
|
|
109
|
+
# None
|
|
110
|
+
# Arguments:
|
|
111
|
+
# The folder for Apps Script code, default value ${DEFAULT_APPS_SCRIPT_FOLDER}
|
|
112
|
+
#######################################
|
|
113
|
+
generate_config_js_for_apps_script() {
|
|
114
|
+
local apps_script_src="${1-"${DEFAULT_APPS_SCRIPT_FOLDER}"}"
|
|
115
|
+
local generated_file="${apps_script_src}/.generated_config.js"
|
|
116
|
+
if [[ -f "${CONFIG_FILE}" ]]; then
|
|
117
|
+
echo '// Copyright 2022 Google Inc.
|
|
118
|
+
//
|
|
119
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
120
|
+
// you may not use this file except in compliance with the License.
|
|
121
|
+
// You may obtain a copy of the License at
|
|
122
|
+
//
|
|
123
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
124
|
+
//
|
|
125
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
126
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
127
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
128
|
+
// See the License for the specific language governing permissions and
|
|
129
|
+
// limitations under the License.
|
|
130
|
+
|
|
131
|
+
/** @fileoverview Auto-generated configuration file for Apps Script. */
|
|
132
|
+
'>"${generated_file}"
|
|
133
|
+
echo -n "const GCP_CONFIG = " >>"${generated_file}"
|
|
134
|
+
cat "${CONFIG_FILE}" >>"${generated_file}"
|
|
135
|
+
else
|
|
136
|
+
printf '%s\n' "Couldn't find ${CONFIG_FILE}."
|
|
137
|
+
fi
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#######################################
|
|
141
|
+
# Clasp pushes AppsScript codes.
|
|
142
|
+
# Globals:
|
|
143
|
+
# None
|
|
144
|
+
# Arguments:
|
|
145
|
+
# The folder for Apps Script code, default value ${DEFAULT_APPS_SCRIPT_FOLDER}
|
|
146
|
+
#######################################
|
|
147
|
+
clasp_push_codes() {
|
|
148
|
+
((STEP += 1))
|
|
149
|
+
printf '%s\n' "Step ${STEP}: Starting to push codes to the Google Sheets..."
|
|
150
|
+
local apps_script_src="${1-"${DEFAULT_APPS_SCRIPT_FOLDER}"}"
|
|
151
|
+
clasp status -P "${apps_script_src}" >>/dev/null
|
|
152
|
+
local project_status=$?
|
|
153
|
+
if [[ ${project_status} -gt 0 ]]; then
|
|
154
|
+
return ${project_status}
|
|
155
|
+
else
|
|
156
|
+
generate_config_js_for_apps_script "${apps_script_src}"
|
|
157
|
+
clasp push --force -P "${apps_script_src}"
|
|
158
|
+
fi
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#######################################
|
|
162
|
+
# Ask user to update the GCP number of this AppsScript.
|
|
163
|
+
# Globals:
|
|
164
|
+
# GCP_PROJECT
|
|
165
|
+
# Arguments:
|
|
166
|
+
# The folder for Apps Script code, default value ${DEFAULT_APPS_SCRIPT_FOLDER}
|
|
167
|
+
#######################################
|
|
168
|
+
clasp_update_project_number() {
|
|
169
|
+
((STEP += 1))
|
|
170
|
+
local projectNumber=$(get_project_number)
|
|
171
|
+
local apps_script_src="${1-"${DEFAULT_APPS_SCRIPT_FOLDER}"}"
|
|
172
|
+
printf '%s\n' "Step ${STEP}: Update Google Cloud Platform (GCP) Project for \
|
|
173
|
+
Apps Script."
|
|
174
|
+
printf '%s' " "
|
|
175
|
+
clasp open -P "${apps_script_src}"
|
|
176
|
+
printf '%s\n' " On the open tab of Apps Script, use 'Project \
|
|
177
|
+
Settings' to set the Google Cloud Platform (GCP) Project as: ${projectNumber}"
|
|
178
|
+
printf '%s' "Press any key to continue after you update the GCP number..."
|
|
179
|
+
local any
|
|
180
|
+
read -n1 -s any
|
|
181
|
+
printf '\n'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
#######################################
|
|
185
|
+
# Ask user to grant the access to CF's default service account.
|
|
186
|
+
# Note: the target GCP needs to have OAuth consent screen.
|
|
187
|
+
# Globals:
|
|
188
|
+
# SHEET_URL
|
|
189
|
+
# Arguments:
|
|
190
|
+
# The folder for Apps Script code, default value ${DEFAULT_APPS_SCRIPT_FOLDER}
|
|
191
|
+
#######################################
|
|
192
|
+
grant_access_to_service_account() {
|
|
193
|
+
((STEP += 1))
|
|
194
|
+
local apps_script_src="${1-"${DEFAULT_APPS_SCRIPT_FOLDER}"}"
|
|
195
|
+
local defaultServiceAccount=$(get_cloud_functions_service_account \
|
|
196
|
+
"${PROJECT_NAMESPACE}_main")
|
|
197
|
+
local parentId=$(get_value_from_json_file "${apps_script_src}"/.clasp.json \
|
|
198
|
+
parentId|cut -d\" -f2)
|
|
199
|
+
printf '%s\n' "Step ${STEP}: Share the Google Sheet with ${SOLUTION_NAME}."
|
|
200
|
+
|
|
201
|
+
printf '%s\n' " Open Google Sheet: \
|
|
202
|
+
https://drive.google.com/open?id=${parentId}"
|
|
203
|
+
printf '%s\n' " Click 'Share' and grant the Viewer access to: \
|
|
204
|
+
${defaultServiceAccount}"
|
|
205
|
+
printf '%s' "Press any key to continue after you grant the access..."
|
|
206
|
+
local any
|
|
207
|
+
read -n1 -s any
|
|
208
|
+
printf '\n'
|
|
209
|
+
}
|
package/bin/bigquery.sh
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2022 Google Inc.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
#######################################
|
|
18
|
+
# Checks whether the BigQuery object (table or view) exists.
|
|
19
|
+
# Globals:
|
|
20
|
+
# GCP_PROJECT
|
|
21
|
+
# DATASET
|
|
22
|
+
# BIGQUERY_LOG_TABLE
|
|
23
|
+
# Arguments:
|
|
24
|
+
# None
|
|
25
|
+
#######################################
|
|
26
|
+
check_existence_in_bigquery() {
|
|
27
|
+
bq show "${1}" >/dev/null 2>&1
|
|
28
|
+
printf '%d' $?
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#######################################
|
|
32
|
+
# Creates or updates the BigQuery view.
|
|
33
|
+
# Globals:
|
|
34
|
+
# GCP_PROJECT
|
|
35
|
+
# DATASET
|
|
36
|
+
# Arguments:
|
|
37
|
+
# The name of view.
|
|
38
|
+
# The query of view.
|
|
39
|
+
#######################################
|
|
40
|
+
create_or_update_view() {
|
|
41
|
+
local viewName viewQuery
|
|
42
|
+
viewName="${1}"
|
|
43
|
+
viewQuery=${2}
|
|
44
|
+
local action="mk"
|
|
45
|
+
if [[ $(check_existence_in_bigquery "${DATASET}.${viewName}") -eq 0 ]]; then
|
|
46
|
+
action="update"
|
|
47
|
+
fi
|
|
48
|
+
bq "${action}" \
|
|
49
|
+
--use_legacy_sql=false \
|
|
50
|
+
--view "${viewQuery}" \
|
|
51
|
+
--project_id ${GCP_PROJECT} \
|
|
52
|
+
"${DATASET}.${viewName}"
|
|
53
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2022 Google Inc.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
# Google Ads API version
|
|
18
|
+
GOOGLE_ADS_API_VERSION=10
|
|
19
|
+
|
|
20
|
+
#######################################
|
|
21
|
+
# Verify whether the current OAuth token, CID and developer token can work.
|
|
22
|
+
# Globals:
|
|
23
|
+
# None
|
|
24
|
+
# Arguments:
|
|
25
|
+
# MCC CID
|
|
26
|
+
# Developer token
|
|
27
|
+
#######################################
|
|
28
|
+
validate_googleads_account() {
|
|
29
|
+
local cid developerToken accessToken request response
|
|
30
|
+
cid=${1}
|
|
31
|
+
developerToken=${2}
|
|
32
|
+
accessToken=$(get_oauth_access_token)
|
|
33
|
+
request=(
|
|
34
|
+
-H "Accept: application/json"
|
|
35
|
+
-H "Content-Type: application/json"
|
|
36
|
+
-H "developer-token: ${developerToken}"
|
|
37
|
+
-H "Authorization: Bearer ${accessToken}"
|
|
38
|
+
-X POST "https://googleads.googleapis.com/v${GOOGLE_ADS_API_VERSION}/customers/${cid}/googleAds:search"
|
|
39
|
+
-d '{"query": "SELECT customer.id FROM customer"}'
|
|
40
|
+
)
|
|
41
|
+
response=$(curl "${request[@]}" 2>/dev/null)
|
|
42
|
+
local errorCode errorMessage
|
|
43
|
+
errorCode=$(get_value_from_json_string "${response}" "error.code")
|
|
44
|
+
if [[ -n "${errorCode}" ]]; then
|
|
45
|
+
errorMessage=$(get_value_from_json_string "${response}" "error.message")
|
|
46
|
+
printf '%s\n' "Validate failed: ${errorMessage}" >&2
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
return 0
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#######################################
|
|
53
|
+
# Let user input MCC CID and developer token for cronjob(s).
|
|
54
|
+
# Globals:
|
|
55
|
+
# MCC_CIDS
|
|
56
|
+
# DEVELOPER_TOKEN
|
|
57
|
+
# Arguments:
|
|
58
|
+
# None
|
|
59
|
+
#######################################
|
|
60
|
+
set_google_ads_account() {
|
|
61
|
+
printf '%s\n' "Setting up Google Ads account information..."
|
|
62
|
+
local developToken mccCids
|
|
63
|
+
while :; do
|
|
64
|
+
# Developer token
|
|
65
|
+
while [[ -z ${developToken} ]]; do
|
|
66
|
+
printf '%s' " Enter the developer token[${DEVELOPER_TOKEN}]: "
|
|
67
|
+
read -r input
|
|
68
|
+
developToken="${input:-${DEVELOPER_TOKEN}}"
|
|
69
|
+
done
|
|
70
|
+
DEVELOPER_TOKEN="${developToken}"
|
|
71
|
+
mccCids=""
|
|
72
|
+
# MCC CIDs
|
|
73
|
+
while :; do
|
|
74
|
+
printf '%s' " Enter the MCC CID: "
|
|
75
|
+
read -r input
|
|
76
|
+
if [[ -z ${input} ]]; then
|
|
77
|
+
continue
|
|
78
|
+
fi
|
|
79
|
+
input="$(printf '%s' "${input}" | sed -r 's/-//g')"
|
|
80
|
+
printf '%s' " validating ${input}...... "
|
|
81
|
+
validate_googleads_account ${input} ${DEVELOPER_TOKEN}
|
|
82
|
+
if [[ $? -eq 1 ]]; then
|
|
83
|
+
printf '%s\n' "failed.
|
|
84
|
+
Press 'd' to re-enter developer token ["${developToken}"] or
|
|
85
|
+
'C' to continue with this MCC CID or
|
|
86
|
+
any other key to enter another MCC CID..."
|
|
87
|
+
local any
|
|
88
|
+
read -n1 -s any
|
|
89
|
+
if [[ "${any}" == "d" ]]; then
|
|
90
|
+
developToken=""
|
|
91
|
+
continue 2
|
|
92
|
+
elif [[ "${any}" == "C" ]]; then
|
|
93
|
+
printf '%s\n' "WARNING! Continue with FAILED MCC ${input}."
|
|
94
|
+
else
|
|
95
|
+
continue
|
|
96
|
+
fi
|
|
97
|
+
else
|
|
98
|
+
printf '%s\n' "succeeded."
|
|
99
|
+
fi
|
|
100
|
+
mccCids+=",${input}"
|
|
101
|
+
printf '%s' " Do you want to add another MCC CID? [Y/n]: "
|
|
102
|
+
read -r input
|
|
103
|
+
if [[ ${input} == 'n' || ${input} == 'N' ]]; then
|
|
104
|
+
break
|
|
105
|
+
fi
|
|
106
|
+
done
|
|
107
|
+
# Left Shift one position to remove the first comma.
|
|
108
|
+
# After shifting, MCC_CIDS would like "11111,22222".
|
|
109
|
+
MCC_CIDS="${mccCids:1}"
|
|
110
|
+
printf '%s\n' "Using Google Ads MCC CIDs: ${MCC_CIDS}."
|
|
111
|
+
break
|
|
112
|
+
done
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
printf '%s\n' "Google Ads Bash Library is loaded."
|
package/bin/install_functions.sh
CHANGED
|
@@ -384,6 +384,15 @@ solution installed [${GCP_PROJECT}]: "
|
|
|
384
384
|
local input result
|
|
385
385
|
read -r input
|
|
386
386
|
input=${input:-"${GCP_PROJECT}"}
|
|
387
|
+
printf '%s' "Checking billing status for [${input}]..."
|
|
388
|
+
result=$(gcloud beta billing projects describe "${input}" \
|
|
389
|
+
--format="csv[no-heading](billingEnabled)")
|
|
390
|
+
if [[ "${result}" != "True" && "${result}" != "true" ]]; then
|
|
391
|
+
printf '%s\n' " there is no billing account."
|
|
392
|
+
return 1
|
|
393
|
+
else
|
|
394
|
+
printf '%s\n' "succeeded."
|
|
395
|
+
fi
|
|
387
396
|
result=$(gcloud config set project "${input}" --user-output-enabled=false \
|
|
388
397
|
2>&1)
|
|
389
398
|
if [[ -z ${result} ]]; then
|
|
@@ -573,7 +582,7 @@ API(s):"
|
|
|
573
582
|
printf '%s\n' "OK. OAuth is required by selected API(s)."
|
|
574
583
|
return 0
|
|
575
584
|
fi
|
|
576
|
-
printf '%s\n' "Selected API(s) require authentication.
|
|
585
|
+
printf '%s\n' "Selected API(s) require authentication. Choose the \
|
|
577
586
|
authentication method:"
|
|
578
587
|
local auths=("Service Account (recommended)" "OAuth")
|
|
579
588
|
select auth in "${auths[@]}"; do
|
|
@@ -604,28 +613,40 @@ check_permissions() {
|
|
|
604
613
|
(( STEP += 1 ))
|
|
605
614
|
printf '%s\n' "Step ${STEP}: Checking current user's access..."
|
|
606
615
|
local role error
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
+
while :; do
|
|
617
|
+
error=0
|
|
618
|
+
for role in "${!GOOGLE_CLOUD_PERMISSIONS[@]}"; do
|
|
619
|
+
printf '%s' " Checking permissions for ${role}... "
|
|
620
|
+
local permissions
|
|
621
|
+
permissions=(${GOOGLE_CLOUD_PERMISSIONS[${role}]})
|
|
622
|
+
local missed
|
|
623
|
+
missed=$(get_number_of_missed_permissions "${permissions[@]}")
|
|
624
|
+
if [[ $missed -gt 0 ]]; then
|
|
625
|
+
message="missed ${missed}, failed"
|
|
626
|
+
error=1
|
|
627
|
+
else
|
|
628
|
+
message='successfully'
|
|
629
|
+
fi
|
|
630
|
+
printf '%s\n' " ${message}."
|
|
631
|
+
done
|
|
632
|
+
if [[ ${error} -gt 0 ]]; then
|
|
633
|
+
printf '%s\n' "Permissions check failed."
|
|
634
|
+
printf '%s\n' "Would you like to login with another account? [Y/n]: "
|
|
635
|
+
local reLogin
|
|
636
|
+
read -r reLogin
|
|
637
|
+
reLogin=${reLogin:-"Y"}
|
|
638
|
+
if [[ ${reLogin} == "Y" || ${reLogin} == "y" ]]; then
|
|
639
|
+
gcloud auth login
|
|
640
|
+
continue
|
|
641
|
+
else
|
|
642
|
+
return 1
|
|
643
|
+
fi
|
|
616
644
|
else
|
|
617
|
-
|
|
645
|
+
echo "OK. Permissions check passed for Google Cloud project \
|
|
646
|
+
[${GCP_PROJECT}]."
|
|
647
|
+
return 0
|
|
618
648
|
fi
|
|
619
|
-
printf '%s\n' " ${message}."
|
|
620
649
|
done
|
|
621
|
-
if [[ ${error} -gt 0 ]]; then
|
|
622
|
-
printf '%s\n' "Permissions check failed."
|
|
623
|
-
return 1
|
|
624
|
-
else
|
|
625
|
-
echo "OK. Permissions check passed for Google Cloud project \
|
|
626
|
-
[${GCP_PROJECT}]."
|
|
627
|
-
return 0
|
|
628
|
-
fi
|
|
629
650
|
}
|
|
630
651
|
|
|
631
652
|
#######################################
|
|
@@ -1031,13 +1052,24 @@ refresh the list:"
|
|
|
1031
1052
|
# Globals:
|
|
1032
1053
|
# GCP_PROJECT
|
|
1033
1054
|
# Arguments:
|
|
1034
|
-
# Bucket name var,
|
|
1055
|
+
# Bucket name var with optional usage, e.g. 'GCS_BUCKET_REPORT:reports'.
|
|
1056
|
+
# The default value is 'GCS_BUCKET'.
|
|
1035
1057
|
# Location var name, default value 'REGION'
|
|
1036
1058
|
# If the second location var is unset, use this var as default value
|
|
1037
1059
|
#######################################
|
|
1038
1060
|
confirm_located_bucket() {
|
|
1039
|
-
local gcsName defaultValue defaultBucketName locationName location
|
|
1040
|
-
|
|
1061
|
+
local gcsName usage defaultValue defaultBucketName locationName location
|
|
1062
|
+
if [[ -z "${1}" ]]; then
|
|
1063
|
+
gcsName="GCS_BUCKET"
|
|
1064
|
+
elif [[ "${1}" == *":"* ]]; then
|
|
1065
|
+
gcsName=$(echo "${1}" | cut -d\: -f1)
|
|
1066
|
+
usage=$(echo "${1}" | cut -d\: -f2)
|
|
1067
|
+
if [[ -n "${usage}" ]]; then
|
|
1068
|
+
usage=" for ${usage}"
|
|
1069
|
+
fi
|
|
1070
|
+
else
|
|
1071
|
+
gcsName="${1}"
|
|
1072
|
+
fi
|
|
1041
1073
|
locationName="${2:-"REGION"}"
|
|
1042
1074
|
defaultValue="${!gcsName}"
|
|
1043
1075
|
defaultBucketName=$(get_default_bucket_name "${GCP_PROJECT}")
|
|
@@ -1052,7 +1084,8 @@ confirm_located_bucket() {
|
|
|
1052
1084
|
|
|
1053
1085
|
(( STEP += 1 ))
|
|
1054
1086
|
if [[ -z "${location}" ]]; then
|
|
1055
|
-
printf '%s\n' "Step ${STEP}: Checking or creating a Cloud Storage
|
|
1087
|
+
printf '%s\n' "Step ${STEP}: Checking or creating a Cloud Storage \
|
|
1088
|
+
Bucket${usage}..."
|
|
1056
1089
|
if [[ "${locationName}" == "REGION" ]]; then
|
|
1057
1090
|
select_functions_location ${locationName}
|
|
1058
1091
|
else
|
|
@@ -1060,8 +1093,8 @@ confirm_located_bucket() {
|
|
|
1060
1093
|
fi
|
|
1061
1094
|
location="${!locationName}"
|
|
1062
1095
|
else
|
|
1063
|
-
printf '%s\n' "Step ${STEP}: Checking or creating a Cloud Storage
|
|
1064
|
-
location [${location}] ..."
|
|
1096
|
+
printf '%s\n' "Step ${STEP}: Checking or creating a Cloud Storage \
|
|
1097
|
+
Bucket${usage} in location [${location}] ..."
|
|
1065
1098
|
fi
|
|
1066
1099
|
declare -g "${locationName}=${location}"
|
|
1067
1100
|
while :; do
|
|
@@ -1129,6 +1162,7 @@ Project. Continuing to enter another bucket..."
|
|
|
1129
1162
|
fi
|
|
1130
1163
|
done
|
|
1131
1164
|
declare -g "${gcsName}=${bucket}"
|
|
1165
|
+
confirm_bucket_lifecycle "${bucket}"
|
|
1132
1166
|
}
|
|
1133
1167
|
|
|
1134
1168
|
#######################################
|
|
@@ -1149,6 +1183,58 @@ confirm_bucket_with_location() {
|
|
|
1149
1183
|
confirm_located_bucket ${gcsName} ${locationName}
|
|
1150
1184
|
}
|
|
1151
1185
|
|
|
1186
|
+
#######################################
|
|
1187
|
+
# Manage the lifecycle of a GCS bucket: setting or removing the GCS lifecycle
|
|
1188
|
+
# rule of 'age'.
|
|
1189
|
+
# See: https://cloud.google.com/storage/docs/lifecycle#age
|
|
1190
|
+
# Arguments:
|
|
1191
|
+
# Bucket name
|
|
1192
|
+
#######################################
|
|
1193
|
+
confirm_bucket_lifecycle() {
|
|
1194
|
+
local bucket bucketMetadata lifecycle
|
|
1195
|
+
bucket="${1}"
|
|
1196
|
+
bucketMetadata="$(get_bucket_metadata "${bucket}")"
|
|
1197
|
+
lifecycle="$(get_value_from_json_string "${bucketMetadata}" "lifecycle")"
|
|
1198
|
+
if [[ -n "${lifecycle}" ]]; then
|
|
1199
|
+
printf '%s\n' "There are lifecycle rules in this bucket: ${lifecycle}."
|
|
1200
|
+
printf '%s' "Would you like to overwrite it? [N/y]:"
|
|
1201
|
+
local confirmContinue
|
|
1202
|
+
read -r confirmContinue
|
|
1203
|
+
confirmContinue=${confirmContinue:-"N"}
|
|
1204
|
+
if [[ ${confirmContinue} == "N" || ${confirmContinue} == "n" ]]; then
|
|
1205
|
+
return 0
|
|
1206
|
+
fi
|
|
1207
|
+
else
|
|
1208
|
+
printf '%s\n' "There is no lifecycle rules in this bucket."
|
|
1209
|
+
printf '%s' "Would you like to create it? [Y/n]:"
|
|
1210
|
+
local confirmContinue
|
|
1211
|
+
read -r confirmContinue
|
|
1212
|
+
confirmContinue=${confirmContinue:-"Y"}
|
|
1213
|
+
if [[ ${confirmContinue} == "N" || ${confirmContinue} == "n" ]]; then
|
|
1214
|
+
return 0
|
|
1215
|
+
fi
|
|
1216
|
+
fi
|
|
1217
|
+
while :; do
|
|
1218
|
+
printf '%s' "Enter the number of days that a file will be kept before it \
|
|
1219
|
+
is automatically removed in the bucket[${bucket}]. (enter 0 to remove all \
|
|
1220
|
+
existing lifecycle rules): "
|
|
1221
|
+
local days
|
|
1222
|
+
read -r days
|
|
1223
|
+
days=${days}
|
|
1224
|
+
if [[ "${days}" =~ ^[0-9]+$ ]]; then
|
|
1225
|
+
local lifecycle
|
|
1226
|
+
if [[ "${days}" == "0" ]]; then
|
|
1227
|
+
lifecycle="{}"
|
|
1228
|
+
else
|
|
1229
|
+
lifecycle='{"rule":[{"action":{"type":"Delete"},"condition":{"age":'\
|
|
1230
|
+
"${days}}}]}"
|
|
1231
|
+
fi
|
|
1232
|
+
gsutil lifecycle set /dev/stdin gs://${bucket} <<< ${lifecycle}
|
|
1233
|
+
return $?
|
|
1234
|
+
fi
|
|
1235
|
+
done
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1152
1238
|
#######################################
|
|
1153
1239
|
# Confirm the monitored folder.
|
|
1154
1240
|
# Globals:
|
|
@@ -1409,20 +1495,18 @@ EOF
|
|
|
1409
1495
|
"client_id=${client_id}" "scope=${scope}")
|
|
1410
1496
|
local auth_url
|
|
1411
1497
|
auth_url="${OAUTH_BASE_URL}auth?${parameters}"
|
|
1412
|
-
printf '%s\n' "3. Open the link in browser and finish authentication
|
|
1413
|
-
${auth_url}"
|
|
1498
|
+
printf '%s\n' "3. Open the link in your browser and finish authentication. \
|
|
1499
|
+
Do not close the redirected page: ${auth_url}"
|
|
1414
1500
|
cat <<EOF
|
|
1415
1501
|
Note:
|
|
1502
|
+
The succeeded OAuth flow will land the browser on an error page - \
|
|
1503
|
+
"This site can't be reached". This is expected behavior. Copy the whole URL and continue.
|
|
1416
1504
|
If the OAuth client is not for a native application, there will be an \
|
|
1417
1505
|
"Error 400: redirect_uri_mismatch" shown up on the page. In this case, press \
|
|
1418
1506
|
"Enter" to start again with a native application OAuth client ID.
|
|
1419
|
-
If there is no local web server serving at ${REDIRECT_URI}, the \
|
|
1420
|
-
succeeded OAuth flow will land the browser on an error page ("This site can't \
|
|
1421
|
-
be reached"). This is an expected behavior. Copy the whole URL and continue.
|
|
1422
1507
|
|
|
1423
1508
|
EOF
|
|
1424
|
-
printf '%s' "4. Copy the
|
|
1425
|
-
and paste here: "
|
|
1509
|
+
printf '%s' "4. Copy the complete URL from your browser and paste here: "
|
|
1426
1510
|
read -r auth_code
|
|
1427
1511
|
if [[ -z ${auth_code} ]]; then
|
|
1428
1512
|
printf '%s\n\n' "No authorization code. Starting from beginning again..."
|
|
@@ -1507,6 +1591,7 @@ set_authentication_env_for_cloud_functions() {
|
|
|
1507
1591
|
create_or_update_cloud_scheduler_for_pubsub(){
|
|
1508
1592
|
check_authentication
|
|
1509
1593
|
quit_if_failed $?
|
|
1594
|
+
local location_flag="--location=${REGION}"
|
|
1510
1595
|
local scheduler_flag=()
|
|
1511
1596
|
scheduler_flag+=(--schedule="$2")
|
|
1512
1597
|
scheduler_flag+=(--time-zone="$3")
|
|
@@ -1514,13 +1599,13 @@ create_or_update_cloud_scheduler_for_pubsub(){
|
|
|
1514
1599
|
scheduler_flag+=(--message-body="$5")
|
|
1515
1600
|
local exist_job
|
|
1516
1601
|
exist_job=($(gcloud scheduler jobs list --filter="name~${1}" \
|
|
1517
|
-
--format="value(state)"))
|
|
1602
|
+
--format="value(state)" "${location_flag}"))
|
|
1518
1603
|
local action needPause
|
|
1519
1604
|
if [[ ${#exist_job[@]} -gt 0 ]]; then
|
|
1520
1605
|
action="update"
|
|
1521
1606
|
scheduler_flag+=(--update-attributes=$6)
|
|
1522
1607
|
if [[ "${exist_job[0]}" == "PAUSED" ]]; then
|
|
1523
|
-
gcloud scheduler jobs resume "${1}"
|
|
1608
|
+
gcloud scheduler jobs resume "${1}" "${location_flag}"
|
|
1524
1609
|
if [[ $? -gt 0 ]]; then
|
|
1525
1610
|
printf '%s\n' "Failed to resume paused Cloud Scheduler job [${1}]."
|
|
1526
1611
|
return 1
|
|
@@ -1531,9 +1616,9 @@ create_or_update_cloud_scheduler_for_pubsub(){
|
|
|
1531
1616
|
action="create"
|
|
1532
1617
|
scheduler_flag+=(--attributes=$6)
|
|
1533
1618
|
fi
|
|
1534
|
-
gcloud scheduler jobs ${action} pubsub "$1" "${scheduler_flag[@]}"
|
|
1619
|
+
gcloud scheduler jobs ${action} pubsub "$1" "${scheduler_flag[@]}" "${location_flag}"
|
|
1535
1620
|
if [[ "${needPause}" == "true" ]]; then
|
|
1536
|
-
gcloud scheduler jobs pause "${1}"
|
|
1621
|
+
gcloud scheduler jobs pause "${1}" "${location_flag}"
|
|
1537
1622
|
fi
|
|
1538
1623
|
}
|
|
1539
1624
|
|
|
@@ -1613,7 +1698,9 @@ customized_install() {
|
|
|
1613
1698
|
local tasks=("$@")
|
|
1614
1699
|
local task
|
|
1615
1700
|
for task in "${tasks[@]}"; do
|
|
1616
|
-
|
|
1701
|
+
local cmd
|
|
1702
|
+
eval "cmd=(${task})"
|
|
1703
|
+
"${cmd[@]}"
|
|
1617
1704
|
quit_if_failed $?
|
|
1618
1705
|
done
|
|
1619
1706
|
}
|
|
@@ -1921,3 +2008,11 @@ join_string_array() {
|
|
|
1921
2008
|
shift
|
|
1922
2009
|
printf %s "$first" "${@/#/$separator}"
|
|
1923
2010
|
}
|
|
2011
|
+
|
|
2012
|
+
# Import other bash files.
|
|
2013
|
+
_SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2014
|
+
source "${_SELF}/google_ads.sh"
|
|
2015
|
+
source "${_SELF}/bigquery.sh"
|
|
2016
|
+
source "${_SELF}/apps_scripts.sh"
|
|
2017
|
+
|
|
2018
|
+
printf '%s\n' "Common Bash Library is loaded."
|