observability.svc.plus/files/postgres/pgb-user
2026-02-01 20:53:55 +08:00

103 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
set -uo pipefail
#==============================================================#
# File : pgb-user
# Desc : add user to pgbouncer pool
# Ctime : 2021-03-29
# Mtime : 2025-01-20
# Path : /pg/bin/pgb-user
# Deps : psql, sed
# License : Apache-2.0 @ https://pigsty.io/docs/about/license/
# Copyright : 2018-2026 Ruohang Feng / Vonng (rh@vonng.com)
#==============================================================#
PROG_NAME="$(basename $0)"
PROG_DIR="$(cd $(dirname $0) && pwd)"
PATH=/usr/pgsql/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:$PATH
#--------------------------------------------------------------#
# use AUTO or "" as password will fetch from database
# use NULL as password will set empty password ""
# enc method will be fetched from password_encryption parameter
# md5 passwords will be calc by pg md5 salt algorithm
# scram pwd cannot be calculated, use plain-text instead
#--------------------------------------------------------------#
#--------------------------------------------------------------#
# Test Cases
# pgb-user dbp_vonng
# pgb-user dbp_vonng auto
# pgb-user dbp_vonngNE auto # Not Exist Error
# pgb-user dbp_vonng null
# pgb-user dbp_vonng md596bceae83ba2937778af09adf00ae738
# pgb-user dbp_vonng md596bceae83ba29377
# pgb-user dbp_vonng Test.Password
#--------------------------------------------------------------#
#--------------------------------------------------------------#
# Name: pgbouncer_create_user
# Desc: Add or modify pgbouncer userlist
# Arg1: username (required)
# Arg2: password (optional)
# Note: Run this as dbsu (postgres)
#--------------------------------------------------------------#
function pgbouncer_create_user() {
local username=$1
local password=${2-''}
local userlist=${3-'/etc/pgbouncer/userlist.txt'}
local entry="\"${username}\" \"\"" # "username" ""
mkdir -p /etc/pgbouncer/
touch ${userlist}
case ${password} in
NULL | null) # force empty password
entry="\"${username}\" \"\"" # "username" ""
echo "use nil md5pwd: ${entry}"
;;
AUTO | auto | "") # fetch db password
entry=$(psql -AXtwq -U postgres -d postgres -c "SELECT concat('\"', rolname, '\" \"', rolpassword, '\"') FROM pg_authid WHERE rolname = '${username}'")
if [[ ! -z ${entry} ]]; then
echo "password fetched via postgres: ${entry}"
else
echo "password fetching failed for ${username} ${password}"
exit 1
fi
;;
*)
pwdenc=$(psql -AXtwq -U postgres -d postgres -c "SHOW password_encryption;" 2>/dev/null)
case $pwdenc in
md5)
if [[ ${password} == md5* ]] && [[ ${#password} == 35 ]]; then # just use the md5password
entry="\"${username}\" \"${password}\""
echo "md5pwd given: ${entry}"
else
local md5_mon_pass="md5$(echo -n "${password}${username}" | md5sum | awk '{print $1}')"
entry="\"${username}\" \"${md5_mon_pass}\""
echo "md5pwd calculated: ${entry}"
fi
;;
scram-sha-256)
entry="\"${username}\" \"${password}\""
echo "SCRAM pwd cannot be calculated, use AUTO to fetch from postgres"
;;
esac
;;
esac
# if username already exists
if grep -q ${username} ${userlist}; then
sed -i "/^\"${username}\"[[:blank:]]*.*$/d" ${userlist}
fi
# write the "username" "password" to userlist
echo "${entry}" >> ${userlist};
cat ${userlist} | sort -r | uniq > "${userlist}e";
mv -f "${userlist}e" "${userlist}"
}
#--------------------------------------------------------------#
# Main #
#--------------------------------------------------------------#
pgbouncer_create_user $@