forked from Bank-Builder/ss-tool
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathss-tool.sh
More file actions
executable file
·329 lines (287 loc) · 10.7 KB
/
ss-tool.sh
File metadata and controls
executable file
·329 lines (287 loc) · 10.7 KB
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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#!/bin/bash
#-----------------------------------------------------------------------
# Copyright (c) 2019, Andrew Turpin
# License MIT: https://opensource.org/licenses/MIT
#-----------------------------------------------------------------------
# Globals
_version="0.7"
_silent="0"
_configFile="ss-tool.conf"
_cleanup="0"
_here=$(pwd)
_db="db"
_database="canonical"
_git_ref="$(date +%Y%m%d-%H%M)"
_push_git="0"
_fw_path=""
_fw_schema=""
_token=""
_gitUsername="Andrew Turpin"
_gitEmail=""
_canonical_flyway="migrations"
function displayHelp(){
echo "Usage: ss-tool [OPTION]...";
echo " Clones the repositories of multiple microservices as per the ss.conf file";
echo " and drops & recreates these discrete schemas into a single canonical database";
echo " which it then round-trips back into the canonical repository";
echo " ";
echo " OPTIONS:";
echo " -f, --file supply optional file name of alternative ss-tool.conf file";
echo " -s, --silent does not display verbose details";
echo " -c, --cleanup removes all git cloned sub-directories & docker db when done";
echo " -g, --git-ref add an optional custom git reference eg 243 to match issue 243";
echo " -p, --push-git push to GitHub, default behaviour creates branch but does not push";
echo " -t, --token the authorization token to use when pulling from a git repo";
echo " -e, --email the email to use for GitHub configuration when pushing";
echo " -u, --username the user name to use for GitHub configuration when pushing";
echo " --help display this help and exit";
echo " --version display version and exit";
echo "";
echo "";
echo " EXAMPLE(s):";
echo " ss-tool --cleanup -g 243 -u 'user name' -e 'fake.email@replace.me.com'";
echo " will remove all git cloned repositories & docker db when done";
echo " and add a git-ref of '243-ss_tool-db-auto-update' when pushing the changes";
echo " also, the branch will show as being pushed by 'user name' (fake.email@replace.me.com) on GitHub";
echo "";
echo " ss-tool.conf:";
echo " [canonical-database] section";
echo " [<microservice>] section(s) giving details of repo with amongst other settings, ";
echo " the source path to the Flyway SQL scripts for";
echo " the micro-service schemas";
echo "";
}
function displayVersion(){
echo "ss-tool (bank-builder utils) version $_version";
echo "Copyright (C) 2019, Andrew Turpin";
echo "License MIT: https://opensource.org/licenses/MIT";
echo "";
}
function trim(){
echo $1 | xargs
}
function msg(){
if [ "$_silent" != "1" ]; then echo "$1"; fi
}
function evaluate(){
# executes by eval but without outputting to screen and returns exit code
if [ "$_silent" == "1" ] || [ "$2" == "SILENT" ]; then
eval "$1" > /dev/null 2>&1
else # don't redirect stdout to null & error to stdout
eval "$1"
fi
return $?
}
function cleanUp(){
msg "cleanup:"
msg "----------"
msg "iterating through and removing cloned repo sub-directories"
evaluate "cd $_here"
evaluate "docker-compose down -v --remove-orphans";
evaluate "rm -rf flyway_data";
msg "... deleted flyway_data";
msg "----------"
}
function git_folder(){
#takes git clone string as parameter
ff=$( echo "$1" |cut -d'/' -f2 );
ff=$( echo "$ff" |cut -d'.' -f1 );
echo "$ff"; #function returns the git folder name
}
function clone(){
source=$1
folder=$(git_folder "$source");
evaluate "cd $_here"
if [ ! -d "flyway_data/" ]; then
evaluate "mkdir flyway_data"
fi;
if [ -d "flyway_data/$folder" ]; then
msg "flyway_data/$folder exists, skipping clone"
else
evaluate "cd flyway_data"
if [ -z "$_token" ]; then
# use git clone
evaluate "$source";
else
# https://github.blog/2012-09-21-easier-builds-and-deployments-using-git-over-https-and-oauth/
# using git pull so that token credentials are not persisted
evaluate "mkdir $folder"
evaluate "cd $folder"
evaluate "git init"
gitpull="https://$_token@github.com/"$( echo "$source" | rev | cut -d':' -f1 | rev );
evaluate "git pull $gitpull";
evaluate "git remote add origin $gitpull"
fi;
evaluate "cd $_here"
fi;
}
docker_compose_template() {
cat <<EOF
version: '3'
services:
migrate-${schema}:
container_name: "compose-flyway-${schema}"
image: "flyway/flyway:latest"
command: -url=jdbc:postgresql://postgresql:5432/${_database} -schemas=${flywaySchemaConf} -table=${schema}_versions -baselineOnMigrate=true -baselineVersion=0 -locations=filesystem:/flyway/sql/${schema} -user=postgres -password=postgres -connectRetries=60 migrate
volumes:
- ./flyway_data/${flywayLocationConf}:/flyway/sql/${schema}
depends_on:
- postgresql
EOF
}
function cleanSchemaCreate(){
for filename in $1/*.sql; do
msg "checking $filename"
sed -i 's/CREATE SCHEMA/-- CREATE SCHEMA/g' $filename
sed -i 's/DROP SCHEMA/-- DROP SCHEMA/g' $filename
done
}
function processConfig(){
conf="$1"
IFS=$'\n' # make newlines the only separator
#for line in $(cat $conf)
while read line
do
line=$(trim $line)
confLabel=$( echo "$line" |cut -d'=' -f1 );
confValue=$( echo "$line" |cut -d'=' -f2 );
if [[ ${confLabel:0:1} != "#" ]] ; then #not a comment nor a blank line
tmp=${confLabel#*[} # remove prefix ending in "["
section=${tmp%]*} # remove suffix starting with "]"
if [ "$confLabel" == "[$section]" ]; then # [section] header
header=$( echo "$section" |cut -d':' -f1 );
schema=$( echo "$section" |cut -d':' -f2 );
msg " "
else # label=value
if [ "$confLabel" == "source" ] && [ "$confValue" != "" ]; then
folder=$(git_folder "$confValue")
echo "---$folder---"
if [ "$header" == "canonical" ]; then _canonical_folder="$folder"; fi;
echo $(clone "$confValue") #clones the git repo from source tag in conf file
msg "$folder cloned ..."
read line
flywayLocationConf=$( echo "$line" |cut -d'=' -f2 );
read line
flywaySchemaConf=$( echo "$line" |cut -d'=' -f2 );
if [ "$header" == "canonical" ]; then
_canonical_sql="$flywaySchemaConf";
_canonical_flyway="$flywayLocationConf";
fi
if [ "$header" == "microservice" ]; then
cleanSchemaCreate "flyway_data/$flywayLocationConf"
_docker_compose_overides="$_docker_compose_overides -f flyway_data/$schema.yml";
_microservices_list="$_microservices_list$schema "
fi
OLDIFS="${IFS}"
IFS=
docker_compose_template > flyway_data/$schema.yml
IFS="${OLDIFS}"
msg "$folder docker-compose created ..."
fi
fi;
fi;
done < $conf
#done
}
# __Main__
while [[ "$#" > 0 ]]; do
case $1 in
--help)
displayHelp; exit 0;;
--version)
displayVersion; exit 0;;
-f|--file)
_configFile="$2";
shift;;
-s|--silent)
_silent="1"
;;
-c|--cleanup)
_cleanup="1";
;;
-p|--push-git)
_push_git="1";
;;
-g|--git-ref)
_git_ref="$2";
shift;;
-t|--token)
_token="$2";
shift;;
-e|--email)
_gitEmail="$2";
shift;;
-u|--username)
_gitUsername="$2";
shift;;
*) echo "Unknown parameter passed: $1"; exit 1;;
esac;
shift;
done
if [ -n "$_configFile" ]; then
if [ "$_silent" == "0" ]; then
msg "ss-tool version $_version"
msg "======================";
fi
processConfig $_configFile
msg "======================";
msg ""
msg "Starting postgres & flyway migrations for each microservice ... "
_docker_compose_cmd="docker-compose -f docker-compose.yml $_docker_compose_overides up -d"
msg "$_docker_compose_cmd"
evaluate "$_docker_compose_cmd"
msg "Sleeping for 15!"
sleep 15 # wait for psql/flyways processes inside the docker containers to run etc. before trying to connect
msg "Done Sleeping!"
OLDIFS="${IFS}"
IFS=' '
for i in $(echo $_microservices_list | sed "s/,/ /g")
do
error_count=$(docker logs compose-flyway-$i 2>&1 | grep "ERROR" | wc -l)
if [ "$error_count" -gt 0 ]; then
msg ""
msg "FAILED:: $error_count errors in $i flyway logs";
msg " View these by running 'docker logs compose-flyway-$i '"
exit 0;
fi
done
IFS="${OLDIFS}"
_full_canonical_path="$_here/flyway_data/$_canonical_folder"
if [ -n "$_canonical_flyway" ]; then
evaluate "mkdir -p $_here/flyway_data/$_canonical_folder/$_canonical_flyway"
_full_canonical_path="$_full_canonical_path/$_canonical_flyway/$_canonical_sql";
else
evaluate "mkdir -p $_here/flyway_data/$_canonical_folder"
_full_canonical_path="$_full_canonical_path/$_canonical_sql";
fi
evaluate "docker exec -u postgres ss-tool_postgresql_1 pg_dump -d canonical --schema-only > $_full_canonical_path"
if [ $_push_git == "1" ]; then
if [ -z "$_token" ]; then
msg "Pushing is only allowed with private repos"
else
evaluate "cd $_here/flyway_data/$_canonical_folder"
if [ -n "$_gitEmail" ]; then
evaluate "git config --local user.email $_gitEmail"
fi
if [ -n "$_gitUsername" ]; then
evaluate "git config --local user.name $_gitUsername"
fi
evaluate "git checkout -b $_git_ref-ss_tool-db-auto-update"
if [ -n "$_canonical_flyway" ]; then
evaluate "git add $_canonical_flyway/$_canonical_sql"
else
evaluate "git add $_canonical_sql"
fi
evaluate "git commit -m $_git_ref-ss_tool-db-auto-update"
evaluate "git push --set-upstream origin $_git_ref-ss_tool-db-auto-update"
fi
fi
evaluate "cd $_here"
if [ "$_cleanup" == "1" ]; then cleanUp; fi;
msg ""
msg "Done! SQL for Canonical DB is at: '$_full_canonical_path'"
exit 0;
fi;
echo "Try ss-tool --help for help";
echo "";
#FINISH