#!/bin/bash
# Script to automate Proxmox PVE node backups to a PBS machine.
#
# Author: Xavi Lleó
# Copyright (c) 2025 Verdnatura S.L. All rights reserved.
# Version: 1.0.3
# ¿Juan Wants add GPL License?
#
# A configuration file is required in the user's home directory who runs this command.
# The file should be sourced using CONFIG_FILE before execution.
#
# Example of a configuration file:
# 
# Default values
# USER_API="root@pam!api"
# USER="root@pam"
# IP_PBS="192.168.1.250"
# POOL="backup-pool"
# BACKUP_ITEMS="etc-pve.pxar:/etc/pve,interfaces.pxar:/etc/network"
# LOG_FILE="/var/log/proxmox-backup-node-pve.log"
# KEY_FILE="mykeyfile.key" #In case you want encrypted backups
# PBS_PASSWORD='mypass or api token'
# PBS_FINGERPRINT='b0:69:24:75:f0:92:a2:72:37:7c:c1:cb:0d:ba:8e:14:EE:XX:AA:MM:PP:LL:EE:e4:2b:07:02:18:86:9a:df:45'
#
# If you prefer to use switches in a one-liner, refer to the help section (--help) for available options.
# Remember to add the port after the IP address when using an API user for authentication.
# Example: IP_PBS="192.168.1.250:8007"


CONFIG_FILE="$HOME/.backup_config.conf"

# https://pbs.proxmox.com/docs/backup-client.html#environment-variables
export PBS_PASSWORD
export PBS_FINGERPRINT

if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
else
    echo "Error: Configuration file not found at $CONFIG_FILE"
    exit 1
fi

show_help() {
    echo "Usage: $0 [options]"
    echo
    echo "Options:"
    echo "  --standard       Perform a standard backup."
    echo "  --encrypt        Perform an encrypted backup (requires a key file)."
    echo "  --ip             Repository IP address (overrides configuration)."
    echo "  --pool           Name of the backup pool (overrides configuration)."
    echo "  --items          List of backup items in 'name1:source1,name2:source2' format."
    echo "  --user-api       Specify user API credentials for backup."
    echo "  --user           Specify user credentials for backup."
    echo "  --help           Show this help."
    exit 0
}

exit_from_repo() {
    proxmox-backup-client logout --repository "$REPOSITORY" 2>>"$LOG_FILE" && echo "$(date '+%Y-%m-%d %H:%M:%S') - Logged out from repository $REPOSITORY" | tee -a "$LOG_FILE"
}

# Check if PBS_PASSWORD and PBS_FINGERPRINT are set
if [ -z "$PBS_PASSWORD" ] || [ -z "$PBS_FINGERPRINT" ]; then
    echo "Error: PBS_PASSWORD or PBS_FINGERPRINT is not set."
    exit 1
fi

while [[ $# -gt 0 ]]; do
    case "$1" in
        --standard)
            MODE="standard"
            ;;
        --encrypt)
            MODE="encrypt"
            ;;
        --ip)
            IP_PBS="$2"
            shift
            ;;
        --pool)
            POOL="$2"
            shift
            ;;
        --items)
            BACKUP_ITEMS="$2"
            shift
            ;;
        --user-api)
            USER_API="$2"
            shift
            ;;
        --user)
            USER="$2"
            shift
            ;;
        --help)
            show_help
            ;;
        *)
            echo "Error: Unrecognized option '$1'"
            show_help
            ;;
    esac
    shift
done

if [ -z "$MODE" ]; then
    echo "You must specify --standard or --encrypt."
    show_help
fi

if [ -n "$USER_API" ]; then
    REPOSITORY="$USER_API@$IP_PBS:$POOL"
else
    REPOSITORY="$USER@$IP_PBS:$POOL"
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting backup to repository $REPOSITORY" | tee -a "$LOG_FILE"
for item in $(echo "$BACKUP_ITEMS" | tr ',' '\n'); do
    BACKUP_NAME=$(echo "$item" | cut -d':' -f1)
    TARGET_DIR=$(echo "$item" | cut -d':' -f2)
    
    if [ "$MODE" == "encrypt" ]; then
        if [ ! -f "$KEY_FILE" ]; then
            echo "The key file $KEY_FILE does not exist." | tee -a "$LOG_FILE"
            exit 1
        fi
        
        proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --crypt-mode encrypt --keyfile "$KEY_FILE" --backup-type 'host' 2>>"$LOG_FILE"
    else
        proxmox-backup-client backup "$BACKUP_NAME:$TARGET_DIR" --repository "$REPOSITORY" --backup-type 'host' 2>>"$LOG_FILE"
    fi

    if [ $? -ne 0 ]; then
        echo "Backup failed for $BACKUP_NAME" | tee -a "$LOG_FILE"
        exit 1
    fi
    sleep 5
done

if [ $? -eq 0 ]; then
    exit_from_repo
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Backup completed successfully. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE"
else
    exit_from_repo
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') - Error during backup. You can check the log at $LOG_FILE\n" | tee -a "$LOG_FILE"
    exit 1
fi