Files
pwcli/bin/pwdb
T

249 lines
6.1 KiB
Bash
Executable File

#!/bin/bash
set -e
DATABASE=photowall
DB_PROD=production-cluster.cluster-cfl0zi9wi0ze.eu-west-1.rds.amazonaws.com
DB_STAGE=staging-new-cluster.cluster-cfl0zi9wi0ze.eu-west-1.rds.amazonaws.com
DB_LOCAL=localhost
DUMP_FILE=~/photowall.sql
JOBS=1
throw_err()
{
echo && echo " *** Error: $1" && usage 1
}
graceful_exit()
{
echo && echo "$1" && exit 0
}
usage()
{
echo
cat <<- EOF
Usage: $0 [OPTION]... [COMMAND] [SOURCE] <TARGET>
Commands:
dump <source> dump database photowall from SOURCE
sync <source> <target> sync database photowall from SOURCE database to TARGET database
Options:
-d, --dry-run don't actually run any commands, just print them
-h, --help display this help message
-j, --jobs <num> (DEFAULT: 1) number of processes to use when restoring the dump
-p, --production tells if the restored database is production like (stage or prod).
If set, additional grants will be handled
EOF
exit ${1:-0}
}
db_exec()
{
echo "psql -h $TARGET -xU root -d ${2:-postgres} -c \"$1\""
if [ -z "$DRY_RUN" ]
then
psql -h $TARGET -xU root -d ${2:-postgres} -c "$1"
fi
}
confirm_sync()
{
cat <<- EOF
$(tput blink)
!!! WARNING !!!$(tput sgr0)$(tput bold)
DATABASE ${DATABASE}
ON ${TARGET}
WILL BE DROPPED AND REPLACED WITH THE ONE
FROM ${SOURCE}$(tput sgr0)$(tput blink)
!!! WARNING !!!$(tput sgr0)
EOF
read -rep "Are you sure this is what you want? [y/N] " -n 1 -r
[[ ! $REPLY =~ ^[Yy]$ ]] && graceful_exit "Quitting..." || true
}
create_dump()
{
echo "* Dumping database ${DATABASE} on ${SOURCE} to ${DUMP_FILE}"
echo
echo "pg_dump -h ${SOURCE} -d ${DATABASE} -U root -Fc > ${DUMP_FILE}"
if [ -z "$DRY_RUN" ]
then
pg_dump -h $SOURCE -d $DATABASE -U root -Fc > ${DUMP_FILE}
fi
}
dump()
{
## Check if dump file already exists
if [ -f "$DUMP_FILE" ]
then
FDATA=$(date -r $DUMP_FILE "+%Y-%m-%d %H:%M:%S")
echo
echo "File $DUMP_FILE ($FDATA) already exists."
read -rep "Use that instead? [y/N/q] " -n 1 -r
case "$REPLY" in
[yY])
echo
echo "* Using existing dump file ($FDATA)"
;;
[nN])
echo
create_dump
;;
*)
graceful_exit "Quitting..."
;;
esac
else
echo '* Dump file not found'
echo
create_dump
fi
}
provision()
{
db_exec "
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'photowall'
AND pid <> pg_backend_pid();"
echo "dropdb -h $TARGET -U root --if-exists photowall"
echo "createdb -h $TARGET -U root --encoding=UTF8 photowall"
if [ -z "$DRY_RUN" ]
then
dropdb -h $TARGET -U root --if-exists photowall
createdb -h $TARGET -U root --encoding=UTF8 photowall
fi
db_exec 'CREATE EXTENSION IF NOT EXISTS unaccent SCHEMA pg_catalog;' photowall
}
restore()
{
provision
echo "pg_restore -h $TARGET -U root --no-owner --no-acl -j $JOBS -d photowall $DUMP_FILE"
if [ -z "$DRY_RUN" ]
then
pg_restore -h $TARGET -U root --no-owner --no-acl -d photowall $DUMP_FILE
fi
}
set_grants()
{
db_exec 'REVOKE TEMPORARY ON DATABASE photowall FROM public';
SQL=$(cat <<- 'EOF'
REVOKE ALL ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA public TO photowall;
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO photowall;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO photowall;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES TO photowall;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO photowall;
EOF
)
db_exec "$SQL" photowall
if [ ! -z $PRODUCTION ]
then
for x in $(cat <<-EOF
v_analytics_products
v_analytics_inquiries
v_analytics_discounts
v_analytics_product_categories
v_analytics_orders_not_delivered
v_analytics_orders_rows_not_delivered
v_analytics_order_rows
v_analytics_orders2
v_analytics_contract_customer_discounts
EOF
)
do
db_exec "GRANT SELECT ON ${x} TO datastudio;" photowall
done
for x in $(cat <<-EOF
v_funnel_collections
v_funnel_discounts
v_funnel_order_rows
v_funnel_orders
v_funnel_pricelist
EOF
)
do
db_exec "GRANT SELECT ON ${x} TO funnel;" photowall
done
fi
}
set_source()
{
SOURCE="$1"
SOURCE_HASH=$(echo "${SOURCE}${DATABASE}" | md5sum | cut -d' ' -f1)
DUMP_FILE="/tmp/${DATABASE}-${SOURCE_HASH:0:10}.sql"
}
# Handle arguments
PARAMS=""
while (( "$#" )); do
case "$1" in
-d|--dry-run)
DRY_RUN=1
shift
;;
-h|--help)
usage
;;
-j|--jobs)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
JOBS="$2"
shift 2
else
throw_err "Argument for ${1} is missing"
fi
;;
-p|--production)
PRODUCTION=1
shift 1
;;
-*|--*=)
throw_err "Unsupported flag ${1}"
;;
*)
PARAMS="${PARAMS} ${1}"
shift
;;
esac
done
# reset positional arguments
eval set -- "${PARAMS}"
[ -z "$2" ] && throw_err "Source server URL is missing" || set_source "$2"
case "$1" in
dump)
dump
;;
sync)
[ -z $3 ] && throw_err "Target server URL is missing"
TARGET="$3"
confirm_sync
dump
restore
set_grants
;;
*)
throw_err "${1} is not a valid command"
;;
esac
[ -z "$1" ] && throw_err "No command given"