Files
Linux-Server-Management-Too…/lib/plesk-helpers.sh
T
cschantz 83ad5a0b9c Add plesk_list_users() function for Plesk user discovery
Issue: list_plesk_users() in user-manager.sh was trying to query MySQL
but the query was failing, resulting in 0 users detected on Plesk.

Fix:
1. Added plesk_list_users() to plesk-helpers.sh that uses:
   - Plesk CLI: 'plesk bin client --list' (primary)
   - Fallback: Scan /var/www/vhosts directories

2. Updated list_plesk_users() in user-manager.sh to:
   - First try plesk_list_users() if available
   - Then try MySQL query
   - Last resort: directory scan

This should now detect Plesk users from either Plesk API or
filesystem fallback.

Testing: Will verify on Plesk server
2025-12-24 16:29:27 -05:00

491 lines
14 KiB
Bash

#!/bin/bash
#############################################################################
# Plesk Helper Functions
# Provides Plesk-specific utilities for domain, user, and resource discovery
#############################################################################
# Source common functions if not already loaded
if [ -z "$TOOLKIT_BASE_DIR" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common-functions.sh"
fi
#############################################################################
# PLESK CLI HELPERS
#############################################################################
# Check if Plesk CLI is available
plesk_cli_available() {
[ -x "/usr/local/psa/bin/plesk" ]
}
# Execute Plesk CLI command with error handling
plesk_exec() {
if ! plesk_cli_available; then
print_error "Plesk CLI not available"
return 1
fi
/usr/local/psa/bin/plesk "$@" 2>/dev/null
}
#############################################################################
# DOMAIN DISCOVERY
#############################################################################
# Get list of all domains
# Returns: One domain per line
plesk_list_domains() {
if plesk_cli_available; then
plesk_exec bin domain --list 2>/dev/null
else
# Fallback: scan vhosts directory
ls -1 /var/www/vhosts/ 2>/dev/null | \
grep -v "^system$\|^chroot$\|^\.skel$\|^default$\|^fs$" | \
grep -v "^\." || true
fi
}
#############################################################################
# USER DISCOVERY
#############################################################################
# Get list of all Plesk users (clients)
# Returns: One username per line
plesk_list_users() {
if plesk_cli_available; then
# Try to get client logins from Plesk
plesk_exec bin client --list 2>/dev/null | tail -n +3 | awk '{print $1}' | grep -v "^$"
else
# Fallback: Get unique owners from vhosts directories
find /var/www/vhosts -maxdepth 1 -type d -printf "%f\n" 2>/dev/null | \
grep -v "^system$\|^chroot$\|^\.skel$\|^default$\|^fs$\|^fs-passwd$" | \
grep -v "^\." || true
fi
}
# Get domain info
# Usage: plesk_domain_info DOMAIN
plesk_domain_info() {
local domain="$1"
[ -z "$domain" ] && return 1
plesk_exec bin domain --info "$domain" 2>/dev/null
}
# Get domain document root
# Usage: plesk_get_docroot DOMAIN
# Returns: /var/www/vhosts/DOMAIN/httpdocs
plesk_get_docroot() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_domain_info "$domain" | grep -oP "www root:\s+\K.*" 2>/dev/null | head -1
else
# Fallback: standard path
local docroot="/var/www/vhosts/$domain/httpdocs"
[ -d "$docroot" ] && echo "$docroot"
fi
}
# Get domain log directory
# Usage: plesk_get_logdir DOMAIN
# Returns: /var/www/vhosts/system/DOMAIN/logs (current) or /var/www/vhosts/DOMAIN/logs (future)
plesk_get_logdir() {
local domain="$1"
[ -z "$domain" ] && return 1
# Check new location first (Plesk 18.0.50+)
if [ -d "/var/www/vhosts/$domain/logs" ]; then
echo "/var/www/vhosts/$domain/logs"
return 0
fi
# Check old location (Plesk 17.x - 18.0.49)
if [ -d "/var/www/vhosts/system/$domain/logs" ]; then
echo "/var/www/vhosts/system/$domain/logs"
return 0
fi
return 1
}
# Get all domain log directories
# Returns: One log directory path per line for all domains
plesk_get_all_logdirs() {
local logdirs=()
# Try new location (Plesk 18.0.50+)
while IFS= read -r dir; do
[ -d "$dir" ] && logdirs+=("$dir")
done < <(find /var/www/vhosts/*/logs -maxdepth 0 -type d 2>/dev/null | grep -v "/system/")
# Try old location (Plesk 17.x - 18.0.49)
while IFS= read -r dir; do
[ -d "$dir" ] && logdirs+=("$dir")
done < <(find /var/www/vhosts/system/*/logs -maxdepth 0 -type d 2>/dev/null)
# Remove duplicates and print
printf '%s\n' "${logdirs[@]}" | sort -u
}
# Get domain access log path
# Usage: plesk_get_access_log DOMAIN [ssl]
# Returns: Full path to access log
plesk_get_access_log() {
local domain="$1"
local ssl="${2:-}"
local logdir
logdir=$(plesk_get_logdir "$domain")
[ -z "$logdir" ] && return 1
if [ "$ssl" = "ssl" ]; then
echo "$logdir/access_ssl_log"
else
echo "$logdir/access_log"
fi
}
# Get domain error log path
# Usage: plesk_get_error_log DOMAIN
plesk_get_error_log() {
local domain="$1"
local logdir
logdir=$(plesk_get_logdir "$domain")
[ -z "$logdir" ] && return 1
echo "$logdir/error_log"
}
#############################################################################
# USER/SUBSCRIPTION MANAGEMENT
#############################################################################
# Get list of all subscriptions
plesk_list_subscriptions() {
if plesk_cli_available; then
plesk_exec bin subscription --list 2>/dev/null
else
plesk_list_domains
fi
}
# Get subscription owner for domain
# Usage: plesk_get_owner DOMAIN
plesk_get_owner() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin subscription --info "$domain" 2>/dev/null | \
grep -oP "Owner's login:\s+\K.*" | head -1
else
# Fallback: check directory ownership
stat -c "%U" "/var/www/vhosts/$domain" 2>/dev/null
fi
}
#############################################################################
# DATABASE DISCOVERY
#############################################################################
# List all databases
plesk_list_databases() {
if plesk_cli_available; then
plesk_exec bin database --list 2>/dev/null
else
# Fallback: query MySQL directly
mysql -e "SHOW DATABASES;" 2>/dev/null | grep -v "Database\|information_schema\|performance_schema\|mysql\|sys"
fi
}
# List databases for specific domain
# Usage: plesk_list_domain_databases DOMAIN
plesk_list_domain_databases() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin database --list -domain "$domain" 2>/dev/null
else
# Fallback: guess based on naming convention (domain_dbname)
local db_prefix=$(echo "$domain" | tr '.' '_' | tr '-' '_')
plesk_list_databases | grep "^${db_prefix}_"
fi
}
#############################################################################
# PHP VERSION DETECTION
#############################################################################
# List all available PHP handlers
plesk_list_php_handlers() {
if plesk_cli_available; then
plesk_exec bin php_handler --list 2>/dev/null
else
# Fallback: scan for PHP binaries
find /opt/plesk/php/*/bin/php -type f -executable 2>/dev/null
fi
}
# Get PHP version for domain
# Usage: plesk_get_domain_php DOMAIN
plesk_get_domain_php() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin site --info "$domain" 2>/dev/null | \
grep -oP "PHP version:\s+\K.*" | head -1
else
# Fallback: check php-fpm socket config
local php_ini="/var/www/vhosts/system/$domain/etc/php.ini"
if [ -f "$php_ini" ]; then
grep "^; configuration file" "$php_ini" | grep -oP '\d+\.\d+' | head -1
fi
fi
}
# Detect all Plesk-managed PHP versions
plesk_detect_php_versions() {
local versions=()
# Scan /opt/plesk/php/
for php_bin in /opt/plesk/php/*/bin/php; do
if [ -x "$php_bin" ]; then
local version=$("$php_bin" -v 2>/dev/null | grep -oP '^PHP \K[\d.]+' | head -1)
[ -n "$version" ] && versions+=("$version")
fi
done
# Remove duplicates
printf '%s\n' "${versions[@]}" | sort -u -V
}
#############################################################################
# PHP-FPM POOL DISCOVERY
#############################################################################
# Find all PHP-FPM pool sockets
plesk_list_fpm_sockets() {
find /var/www/vhosts/system/*/php-fpm.sock -type s 2>/dev/null
}
# Get PHP-FPM socket for domain
# Usage: plesk_get_fpm_socket DOMAIN
plesk_get_fpm_socket() {
local domain="$1"
[ -z "$domain" ] && return 1
local socket="/var/www/vhosts/system/$domain/php-fpm.sock"
[ -S "$socket" ] && echo "$socket"
}
#############################################################################
# CONFIGURATION FILE DISCOVERY
#############################################################################
# Get domain config directory
# Usage: plesk_get_confdir DOMAIN
plesk_get_confdir() {
local domain="$1"
[ -z "$domain" ] && return 1
local confdir="/var/www/vhosts/system/$domain/conf"
[ -d "$confdir" ] && echo "$confdir"
}
# Get Apache vhost config
# Usage: plesk_get_httpd_conf DOMAIN
plesk_get_httpd_conf() {
local domain="$1"
local confdir
confdir=$(plesk_get_confdir "$domain")
[ -z "$confdir" ] && return 1
echo "$confdir/httpd.conf"
}
# Get Nginx config
# Usage: plesk_get_nginx_conf DOMAIN
plesk_get_nginx_conf() {
local domain="$1"
local confdir
confdir=$(plesk_get_confdir "$domain")
[ -z "$confdir" ] && return 1
echo "$confdir/nginx.conf"
}
# Get PHP config (php.ini)
# Usage: plesk_get_php_ini DOMAIN
plesk_get_php_ini() {
local domain="$1"
[ -z "$domain" ] && return 1
local php_ini="/var/www/vhosts/system/$domain/etc/php.ini"
[ -f "$php_ini" ] && echo "$php_ini"
}
#############################################################################
# MAIL FUNCTIONS
#############################################################################
# Get mailbox directory for user@domain
# Usage: plesk_get_mailbox_dir DOMAIN USERNAME
plesk_get_mailbox_dir() {
local domain="$1"
local username="$2"
[ -z "$domain" ] || [ -z "$username" ] && return 1
local maildir="/var/qmail/mailnames/$domain/$username/Maildir"
[ -d "$maildir" ] && echo "$maildir"
}
# List all mailboxes for domain
# Usage: plesk_list_mailboxes DOMAIN
plesk_list_mailboxes() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin mail --list "$domain" 2>/dev/null
else
# Fallback: scan mailnames directory
[ -d "/var/qmail/mailnames/$domain" ] && \
ls -1 /var/qmail/mailnames/$domain/ 2>/dev/null
fi
}
#############################################################################
# SERVICE MANAGEMENT
#############################################################################
# Restart Apache
plesk_restart_apache() {
if plesk_cli_available; then
plesk_exec bin service_node --restart httpd
else
systemctl restart httpd 2>/dev/null || service httpd restart 2>/dev/null
fi
}
# Restart Nginx
plesk_restart_nginx() {
if plesk_cli_available; then
plesk_exec bin service_node --restart nginx
else
systemctl restart nginx 2>/dev/null || service nginx restart 2>/dev/null
fi
}
# Restart PHP-FPM for all versions
plesk_restart_phpfpm() {
if plesk_cli_available; then
# Restart all Plesk PHP-FPM services
for service in /etc/systemd/system/plesk-php*-fpm.service; do
[ -f "$service" ] && systemctl restart "$(basename "$service")" 2>/dev/null
done
else
systemctl restart php-fpm 2>/dev/null || service php-fpm restart 2>/dev/null
fi
}
#############################################################################
# UTILITY FUNCTIONS
#############################################################################
# Check if domain exists in Plesk
# Usage: plesk_domain_exists DOMAIN
plesk_domain_exists() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_domain_info "$domain" > /dev/null 2>&1
return $?
else
[ -d "/var/www/vhosts/$domain" ] || [ -d "/var/www/vhosts/system/$domain" ]
fi
}
# Get Plesk version
plesk_get_version() {
if [ -f "/usr/local/psa/version" ]; then
head -1 /usr/local/psa/version
else
echo "unknown"
fi
}
# Check if Plesk version is 18.0.50 or higher (new log location)
plesk_is_new_log_structure() {
local version
version=$(plesk_get_version)
# Parse version (format: 18.0.50)
local major minor patch
major=$(echo "$version" | cut -d'.' -f1)
minor=$(echo "$version" | cut -d'.' -f2)
patch=$(echo "$version" | cut -d'.' -f3)
# Check if >= 18.0.50
if [ "$major" -gt 18 ]; then
return 0
elif [ "$major" -eq 18 ] && [ "$minor" -gt 0 ]; then
return 0
elif [ "$major" -eq 18 ] && [ "$minor" -eq 0 ] && [ "${patch:-0}" -ge 50 ]; then
return 0
fi
return 1
}
# Get all domain names and document roots as TSV
# Format: DOMAIN\t/path/to/httpdocs
plesk_list_domains_with_docroots() {
local domain docroot
while IFS= read -r domain; do
docroot=$(plesk_get_docroot "$domain")
[ -n "$docroot" ] && echo -e "$domain\t$docroot"
done < <(plesk_list_domains)
}
# Export all functions
export -f plesk_cli_available
export -f plesk_exec
export -f plesk_list_domains
export -f plesk_domain_info
export -f plesk_get_docroot
export -f plesk_get_logdir
export -f plesk_get_all_logdirs
export -f plesk_get_access_log
export -f plesk_get_error_log
export -f plesk_list_subscriptions
export -f plesk_get_owner
export -f plesk_list_databases
export -f plesk_list_domain_databases
export -f plesk_list_php_handlers
export -f plesk_get_domain_php
export -f plesk_detect_php_versions
export -f plesk_list_fpm_sockets
export -f plesk_get_fpm_socket
export -f plesk_get_confdir
export -f plesk_get_httpd_conf
export -f plesk_get_nginx_conf
export -f plesk_get_php_ini
export -f plesk_get_mailbox_dir
export -f plesk_list_mailboxes
export -f plesk_restart_apache
export -f plesk_restart_nginx
export -f plesk_restart_phpfpm
export -f plesk_domain_exists
export -f plesk_get_version
export -f plesk_is_new_log_structure
export -f plesk_list_domains_with_docroots