libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

libeufin-dbconfig (8159B)


      1 #!/bin/bash
      2 # This file is part of GNU TALER.
      3 # Copyright (C) 2023,2024,2025 Taler Systems SA
      4 #
      5 # TALER is free software; you can redistribute it and/or modify it under the
      6 # terms of the GNU Lesser General Public License as published by the Free Software
      7 # Foundation; either version 2.1, or (at your option) any later version.
      8 #
      9 # TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11 # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU Lesser General Public License along with
     14 # TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 #
     16 # @author Christian Grothoff
     17 # @author Florian Dold
     18 
     19 # Error checking on
     20 set -eu
     21 
     22 # 1 is true, 0 is false
     23 RESET_DB=0
     24 FORCE_PERMS=0
     25 SKIP_INIT=0
     26 SKIP_NEXUS=0
     27 SKIP_BANK=0
     28 NEXUS_DBUSER="libeufin-nexus"
     29 BANK_DBUSER="libeufin-bank"
     30 NEXUS_CFGFILE="/etc/libeufin/libeufin-nexus.conf"
     31 BANK_CFGFILE="/etc/libeufin/libeufin-bank.conf"
     32 
     33 function exit_fail() {
     34   echo "$@" >&2
     35   exit 1
     36 }
     37 
     38 short_opts=c:b:hrn:psu:v:
     39 long_opts=bank-config:,help,nexus-config:,reset,skip,permissions,nexus-user:,bank-user:,only-nexus,only-bank
     40 if ! VALID_ARGS=$(getopt -o "$short_opts" -l "$long_opts" -n "$0" -- "$@"); then
     41   exit 1
     42 fi
     43 
     44 eval set -- "$VALID_ARGS"
     45 
     46 function usage {
     47   cat - <<EOF
     48 libeufin-dbconfig
     49 Setup databases for libeufin components.
     50 Arguments mandatory for long options are also mandatory for short options.
     51   -c, --config=FILE           use CONFIGFILE for the Bank and Nexus configuration file (default: $BANK_CFGFILE and $NEXUS_CFGFILE)
     52   -b, --bank-config=FILE      use CONFIGFILE for the Bank configuration file (default: $BANK_CFGFILE)
     53   -h, --help                  print this help
     54   -r, --reset                 reset database (dangerous)
     55   -s, --skip                  skip database initialization
     56   -n, --nexus-config=FILE     use CONFIGFILE for the Nexus configuration file (default: $NEXUS_CFGFILE)
     57   -p, --permissions           force permission setup even without database initialization
     58   -u, --nexus-user=NEXUS_USER libeufin-nexus to be run by USER (default: $NEXUS_DBUSER)
     59   -v, --bank-user=BANK_USER   libeufin-bank to be run by USER (default: $BANK_DBUSER)
     60   --only-nexus                run only for libeufin-nexus db
     61   --only-bank                 run only for libeufin-bank db
     62 EOF
     63 }
     64 
     65 # Parse command-line options
     66 while true; do
     67   case "$1" in
     68   -c | --config)
     69     BANK_CFGFILE="$2"
     70     NEXUS_CFGFILE="$2"
     71     shift 2
     72     ;;
     73   -b | --bank-config)
     74     BANK_CFGFILE="$2"
     75     shift 2
     76     ;;
     77   -h | --help)
     78     usage
     79     exit 0
     80     ;;
     81   -r | --reset)
     82     RESET_DB="1"
     83     shift
     84     ;;
     85   -s | --skip)
     86     SKIP_INIT="1"
     87     shift
     88     ;;
     89   -n | --nexus-config)
     90     NEXUS_CFGFILE="$2"
     91     shift 2
     92     ;;
     93   -p | --permissions)
     94     FORCE_PERMS="1"
     95     shift
     96     ;;
     97   --only-nexus)
     98     SKIP_BANK="1"
     99     shift
    100     ;;
    101   --only-bank)
    102     SKIP_NEXUS="1"
    103     shift
    104     ;;
    105   -u | --nexus-user)
    106     NEXUS_DBUSER="$2"
    107     shift 2
    108     ;;
    109   -v | --bank-user)
    110     BANK_DBUSER="$2"
    111     shift 2
    112     ;;
    113   --)
    114     shift
    115     break
    116     ;;
    117   *)
    118     usage
    119     exit 1
    120     ;;
    121   esac
    122 done
    123 
    124 if ! id postgres >/dev/null; then
    125   exit_fail "Could not find 'postgres' user. Please install Postgresql first"
    126 fi
    127 
    128 if [ "$(id -u)" -ne 0 ]; then
    129   exit_fail "This script must be run as root"
    130 fi
    131 
    132 # Check tools availability if they are going to be used
    133 function check_availability {
    134   if ! $1 --help 1>/dev/null; then
    135     exit_fail "Required '$1' not found. Please fix your installation."
    136   fi
    137   which "$1"
    138 }
    139 if [ 0 = "$SKIP_INIT" ]; then
    140   if [ 0 = "$SKIP_BANK" ]; then
    141     BANK_DBINIT=$(check_availability libeufin-bank-dbinit)
    142   fi
    143   if [ 0 = "$SKIP_NEXUS" ]; then
    144     NEXUS_DBINIT=$(check_availability libeufin-nexus-dbinit)
    145   fi
    146 fi
    147 
    148 # Check OS users exist
    149 function check_os_user {
    150   if ! id "$1" >/dev/null; then
    151     exit_fail "Could not find '$1' user. Cannot continue"
    152   fi
    153 }
    154 if [ 0 = "$SKIP_BANK" ]; then check_os_user "$BANK_DBUSER"; fi
    155 if [ 0 = "$SKIP_NEXUS" ]; then check_os_user "$NEXUS_DBUSER"; fi
    156 
    157 # Create DB users matching OS users names
    158 function create_db_user {
    159   echo "Setting up database user '$1'." 1>&2
    160   if ! sudo -i -u postgres createuser "$1" 2>/dev/null; then
    161     echo "Database user '$1' already existed. Continuing anyway." 1>&2
    162   fi
    163 }
    164 if [ 0 = "$SKIP_BANK" ]; then create_db_user "$BANK_DBUSER"; fi
    165 if [ 0 = "$SKIP_NEXUS" ]; then create_db_user "$NEXUS_DBUSER"; fi
    166 
    167 # Check database name
    168 function get_db_name {
    169   if ! echo "$1" | grep "\(postgres\|postgresql\)://" >/dev/null; then
    170     exit_fail "Invalid libeufin-$2 database configuration value '$1'."
    171   fi
    172 
    173   # Remove URI, host and query from postgres URI.
    174   echo "$1" | sed -e 's|.*://.*/||' -e 's|?.*||'
    175 }
    176 if [ 0 = "$SKIP_BANK" ]; then
    177   BANK_DBNAME=$(get_db_name "$(libeufin-bank config get -c "$BANK_CFGFILE" libeufin-bankdb-postgres CONFIG)" "bank")
    178 fi
    179 if [ 0 = "$SKIP_NEXUS" ]; then
    180   NEXUS_DBNAME=$(get_db_name "$(libeufin-nexus config get -c "$NEXUS_CFGFILE" nexus-postgres CONFIG 2>/dev/null || libeufin-nexus config get -c "$NEXUS_CFGFILE" libeufin-nexusdb-postgres CONFIG)" "nexus")
    181 fi
    182 
    183 # If using both components they must use the same database
    184 if [[ 0 == "$SKIP_BANK" && 0 == "$SKIP_NEXUS" && $NEXUS_DBNAME != "$BANK_DBNAME" ]]; then
    185   exit_fail "Database names for libeufin-bank and libeufin-nexus must match ($NEXUS_DBNAME vs $BANK_DBNAME)"
    186 fi
    187 
    188 if [ 0 = "$SKIP_BANK" ]; then
    189   DBNAME=$BANK_DBNAME
    190   DBUSER=$BANK_DBUSER
    191 else
    192   DBNAME=$NEXUS_DBNAME
    193   DBUSER=$NEXUS_DBUSER
    194 fi
    195 
    196 if sudo -i -u postgres psql "$DBNAME" </dev/null 2>/dev/null; then
    197   if [ 1 = "$RESET_DB" ]; then
    198     echo "Deleting existing database '$DBNAME'." 1>&2
    199     if ! sudo -i -u postgres dropdb "$DBNAME"; then
    200       exit_fail "Failed to delete existing database '$DBNAME'"
    201     fi
    202     DO_CREATE=1
    203   else
    204     echo "Database '$DBNAME' already exists, continuing anyway."
    205     DO_CREATE=0
    206   fi
    207 else
    208   DO_CREATE=1
    209 fi
    210 
    211 if [ 1 = "$DO_CREATE" ]; then
    212   echo "Creating database '$DBNAME'." 1>&2
    213   if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME"; then
    214     exit_fail "Failed to create database '$DBNAME'"
    215   fi
    216 fi
    217 
    218 function grant_db_access {
    219   if ! echo "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO \"$1\"" |
    220     sudo -i -u postgres psql "$DBNAME"; then
    221     exit_fail "Failed to grant access to database '$DBNAME' to '$1'."
    222   fi
    223 }
    224 function grant_schema_access {
    225   if ! echo "GRANT ALL ON SCHEMA $2 TO \"$1\"" |
    226     sudo -i -u postgres psql "$DBNAME"; then
    227     exit_fail "Failed to grant usage privilege on schema '$2' to '$1'."
    228   fi
    229   if ! echo "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA $2 TO \"$1\"" |
    230     sudo -i -u postgres psql "$DBNAME"; then
    231     exit_fail "Failed to grant access to schema '$2' to '$1'."
    232   fi
    233 }
    234 
    235 # Init database with one of the users to create the _v schema
    236 if [ 0 = "$SKIP_INIT" ]; then
    237   if [ 0 = "$SKIP_BANK" ]; then
    238     echo "Initializing database '$DBNAME' for libeufin-bank." 1>&2
    239     sudo -u "$BANK_DBUSER" "$BANK_DBINIT" -c "$BANK_CFGFILE"
    240   else
    241     echo "Initializing database '$DBNAME' for libeufin-nexus." 1>&2
    242     sudo -u "$NEXUS_DBUSER" "$NEXUS_DBINIT" -c "$NEXUS_CFGFILE"
    243   fi
    244 fi
    245 
    246 # nexus permission to access db and _v schema if bank init the database
    247 if [[ 0 == "$SKIP_INIT" || 1 == "$FORCE_PERMS" ]] && [[ 0 == "$SKIP_BANK" && 0 == "$SKIP_NEXUS" ]]; then
    248   echo "Setting postgres permissions for '$NEXUS_DBUSER'" 1>&2
    249   grant_db_access "$NEXUS_DBUSER"
    250   grant_schema_access "$NEXUS_DBUSER" "_v"
    251   grant_schema_access "$NEXUS_DBUSER" "libeufin_bank"
    252 fi
    253 
    254 # DB initialization for nexus if both component are setup
    255 if [[ 0 == "$SKIP_INIT" && 0 == "$SKIP_BANK" && 0 == "$SKIP_NEXUS" ]]; then
    256   echo "Initializing database '$DBNAME' for libeufin-nexus." 1>&2
    257   sudo -u "$NEXUS_DBUSER" "$NEXUS_DBINIT" -c "$NEXUS_CFGFILE"
    258 fi
    259 
    260 # bank permission to access nexus schema if both component are setup
    261 if [[ 0 == "$SKIP_INIT" || 1 == "$FORCE_PERMS" ]] && [[ 0 == "$SKIP_BANK" && 0 == "$SKIP_NEXUS" ]]; then
    262   echo "Setting postgres permissions for '$BANK_DBUSER'" 1>&2
    263   grant_schema_access "$BANK_DBUSER" "libeufin_nexus"
    264 fi
    265 
    266 echo "Database configuration finished." 1>&2