forked from IBM/CodeEngine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun
executable file
·290 lines (246 loc) · 10.6 KB
/
run
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#!/bin/bash
# Ensure that jq tool is installed
if ! command -v jq &>/dev/null; then
echo "FAILED - 'jq' tool is not installed"
exit 1
fi
# Ensure that latest versions of used IBM Cloud ClI is installed
ibmcloud update --force
# Ensure that latest versions of used IBM Cloud CLI plugins are installed
echo "Install necessary ibmcloud cli plugins ..."
ibmcloud plugin install cloudant -f
ibmcloud plugin install code-engine -f
# Clean up previous run
function clean() {
echo "=================================================================================="
echo "Cleaning... (FAILED results are expected for NON-existing elements while cleaning)"
(
## first select the project with the name like is was created in last session
# if project does not exist, then there is no need to delete the artifacts
# within the project
ibmcloud ce project select --name ce-sample-cloudant-change-listener-project
if [ $? == 0 ]; then
ibmcloud ce jobrun delete --job cloudant-change-listener-job --force
ibmcloud ce job unbind --name cloudant-change-listener-job --all
ibmcloud ce job delete --name cloudant-change-listener-job --force
ibmcloud ce function unbind --name cloudant-change-listener-function --all
ibmcloud ce function delete --name cloudant-change-listener-function --force
ibmcloud ce configmap delete --name cloudant-change-listener-job-config --force
ibmcloud ce secret delete --name cloudant-change-listener-credentials --force
ibmcloud ce project delete --name ce-sample-cloudant-change-listener-project --force --hard --no-wait
fi
ibmcloud iam service-id-delete ce-sample-cloudant-change-listener-api-credentials --force
ibmcloud resource service-key-delete cloudant-creds-ce-project --force
)
echo Cleaning DONE ...
echo "=================================================================================="
}
clean
# In case this script has been executed with `./run clean`, we stop right after the cleanup
[[ "$1" == "clean" ]] && exit 0
echo "Check if a Cloudant instance 'CE-Cloudant-SampleDB' is properly initialized ..."
COUNTER=0
while ! ibmcloud resource service-instance CE-Cloudant-SampleDB| grep "active"; do
sleep 5
# wait max 3 min to get a cloudant DB instance
COUNTER=$((COUNTER + 1))
if ((COUNTER > 36)); then
echo "FAILED - Cloudant DB instance cannot be created"
exit 1
fi
done
# Obtain the created Cloudant instance
cloudant_instances=$(ibmcloud resource service-instance CE-Cloudant-SampleDB --output JSON)
cloudant_instance_name=$(echo $cloudant_instances | jq -r '.[0]|.name')
cloudant_instance_guid=$(echo $cloudant_instances | jq -r '.[0]|.guid')
if [ -z "$cloudant_instances" ]; then
echo "FAILED - Cloudant DB instances info cannot be retrieved"
exit 1
fi
echo "Obtain the service URL of the newly created Cloudant instance '$cloudant_instance_name' (id: $cloudant_instance_guid) ..."
cloudant_url=$(ibmcloud cloudant url --resource-id $cloudant_instance_guid --output JSON)
echo "$cloudant_url"
if [ -z "$cloudant_url" ]; then
echo "FAILED - Cloudant DB URL cannot be retrieved"
exit 1
fi
echo ""
echo "Create an access token to work with the cloudant DB system "
iam_access_token=$(ibmcloud iam oauth-tokens --output JSON | jq -r '.iam_token')
if [ -z "$iam_access_token" ]; then
echo "FAILED - The IAM access token of the current CLI session could not be obtained"
exit 1
fi
echo ""
echo "Try to delete the sample-db Cloudant database if exists from a previous run "
curl -H "Authorization: $iam_access_token" -X DELETE "$cloudant_url/sample-db"
echo "Creating a new database 'sample-db' within Cloudant instance '$cloudant_instance_name' ..."
echo "using cloudant API https://cloud.ibm.com/apidocs/cloudant#putdatabase"
curl -H "Authorization: $iam_access_token" -X PUT "$cloudant_url/sample-db"
if [ $? != 0 ]; then
echo "FAILED - The creation of the Cloudant database failed"
exit 1
fi
echo "Creating Code Engine project 'ce-sample-cloudant-change-listener-project' ..."
ibmcloud ce proj create --name ce-sample-cloudant-change-listener-project
if [ $? != 0 ]; then
echo "FAILED - The creation of a Code Engine project failed"
exit 1
fi
ce_project_guid=$(ibmcloud ce proj current --output json | jq -r '.guid')
if [ -z "$ce_project_guid" ]; then
echo "FAILED - obtaining the project GUID failed"
exit 1
fi
ce_project_region=$(ibmcloud ce proj current --output json | jq -r '.region_id')
if [ -z "$ce_project_region" ]; then
echo "FAILED - Obtaining the project region failed"
exit 1
fi
echo "Creating the Code Engine function 'cloudant-change-listener-function' ..."
ibmcloud ce fn create \
--name cloudant-change-listener-function \
--runtime nodejs-18 \
--inline-code ./function/function.js
echo "Waiting for the function to get properly initialized ..."
ce_fn_endpoint="null"
ce_fn_endpoint_internal="null"
COUNTER=0
while [ "$ce_fn_endpoint" == "null" ]; do
ce_fn_endpoint=$(ibmcloud ce fn get --name cloudant-change-listener-function -o json | jq -r '.endpoint')
ce_fn_endpoint_internal=$(ibmcloud ce fn get --name cloudant-change-listener-function -o json | jq -r '.endpoint_internal')
sleep 2
# wait max 3 min to get a cloudant DB instance
COUNTER=$((COUNTER + 1))
if ((COUNTER > 90)); then
echo "FAILED - The creation of a Code Engine function failed"
exit 1
fi
done
echo "Function public endpoint: '$ce_fn_endpoint', internal endpoint: '$ce_fn_endpoint_internal'"
echo "Creating a config map to store the event state"
ibmcloud ce configmap create \
--name cloudant-change-listener-job-config \
--from-literal DB_LAST_SEQ=now
if [ $? != 0 ]; then
echo "FAILED - The creation of the Code Engine configmap failed"
exit 1
fi
# See Code Engine docs: Managing user access (https://cloud.ibm.com/docs/codeengine?topic=codeengine-iam#service)
echo "Creating an IAM ServiceID that contains a policy to access the Code Engine project '${ce_project_guid}' ..."
ibmcloud iam service-id-create ce-sample-cloudant-change-listener-api-credentials --description "Service ID to operate towards the Code Engine project ${ce_project_guid}"
if [ $? != 0 ]; then
echo "FAILED - The creation of the IAM serviceID failed"
exit 1
fi
ibmcloud iam service-policy-create ce-sample-cloudant-change-listener-api-credentials --roles Writer --service-name codeengine --service-instance ${ce_project_guid}
if [ $? != 0 ]; then
echo "FAILED - The creation of the IAM serviceID policy failed"
exit 1
fi
ce_api_key=$(ibmcloud iam service-api-key-create codeengine-api-key ce-sample-cloudant-change-listener-api-credentials --description "API key for serviceID ce-${ce_project_guid}-api-credentials for Code Engine project ${ce_project_guid}" --output JSON | jq -r '.apikey')
if [ -z "$ce_api_key" ]; then
echo "FAILED - The creation of the IAM serviceID APIKey failed"
exit 1
fi
echo "Creating a secret that stores a serviceID APIKey to enable the job storing state in a Configmap within the project '$ce_project_guid' ..."
ibmcloud ce secret create \
--name cloudant-change-listener-credentials \
--from-literal CE_API_KEY=$ce_api_key
if [ $? != 0 ]; then
echo "FAILED - The creation of the Code Engine secret failed"
exit 1
fi
echo "Creating the Code Engine daemon job 'cloudant-change-listener-job' ..."
ibmcloud ce job create \
--name cloudant-change-listener-job \
--image icr.io/codeengine/cloudant-change-listener \
--mode daemon \
--env DB_NAME=sample-db \
--env CE_TARGET=$ce_fn_endpoint \
--env CE_PROJECT_ID=$ce_project_guid \
--env CE_REGION=$ce_project_region \
--env-from-configmap cloudant-change-listener-job-config \
--env-from-secret cloudant-change-listener-credentials
if [ $? != 0 ]; then
echo "FAILED - The creation of a Code Engine job failed"
exit 1
fi
echo "Creating the service credential on the Cloudant database to be able to bind the job and the function ..."
ibmcloud resource service-key-create cloudant-creds-ce-project Reader --instance-id $cloudant_instance_guid
if [ $? != 0 ]; then
echo "FAILED - The creation of the service credential on the Cloudant DB failed"
exit 1
fi
echo "Binding the Cloudant credentials to the Code Engine function to enable that the function code can access the DB via Env vars ..."
ibmcloud ce fn bind \
--name cloudant-change-listener-function \
--service-instance-id $cloudant_instance_guid \
--service-credential cloudant-creds-ce-project
if [ $? != 0 ]; then
echo "FAILED - The binding of a service binding of the Cloudant DB to the CE function failed"
exit 1
fi
echo "Binding the Cloudant credentials to the Code Engine job ..."
ibmcloud ce job bind \
--name cloudant-change-listener-job \
--service-instance-id $cloudant_instance_guid \
--service-credential cloudant-creds-ce-project
if [ $? != 0 ]; then
echo "FAILED - the binding of a service binding of the Cloudant DB to the CE job failed"
exit 1
fi
echo "Starting the daemon job ..."
job_run_name=$(ibmcloud ce jobrun submit --job cloudant-change-listener-job --output json | jq -r '.metadata|.name')
echo "with job id = $job_run_name"
if [ -z "$job_run_name" ]; then
echo "FAILED - The submission of the Code Engine daemon job failed"
exit 1
fi
echo "Check whether the job started properly ..."
COUNTER=0
while ! ibmcloud ce jobrun get -n ${job_run_name} | grep "1/1" | grep "Running"; do
sleep 2
COUNTER=$((COUNTER + 1))
if ((COUNTER > 90)); then
echo $(ibmcloud ce jobrun get -n ${job_run_name})
echo "FAILED - The job could not be started"
exit 1
fi
done
sleep 2
echo "Upload a file to the Cloudant database ..."
curl -H "Authorization: $iam_access_token" -X POST "$cloudant_url/sample-db" -H "Content-Type: application/json" --data '{
"_id": "small-appliances:1000043",
"type": "product",
"productid": "1000043",
"brand": "Salter",
"name": "Digital Kitchen Scales"
}'
echo "Verify job receives the Cloudant event by fetching the job run logs ..."
COUNTER=0
while true; do
echo "Waiting on job to detect change"
sleep 5
foundDetectedChange=$(ibmcloud ce jobrun logs -n ${job_run_name} | grep "Detected 1 change(s) in the DB")
foundCalledFunction=$(ibmcloud ce jobrun logs -n ${job_run_name} | grep "Successfully called CE")
if [[ $foundDetectedChange && $foundCalledFunction ]]; then
echo ""
echo "That was a success :)"
break
fi
COUNTER=$((COUNTER + 1))
if ((COUNTER > 20)); then
if [[ ! $foundDetectedChange ]]; then
echo "Testing of the sample failed because the change was not detected"
fi
if [[ ! $foundCalledFunction ]]; then
echo "Testing of the sample failed because the ce function was not called "
fi
# Clean up
clean
exit 1
fi
done
# Clean up
clean