#!/bin/bash # # Oracle Backup Monitor for Proxmox with PVE::Notify # Monitors Oracle backups and sends notifications via Proxmox notification system # # Location: /opt/scripts/oracle-backup-monitor-proxmox.sh (on Proxmox host) # Schedule: Add to cron for daily execution # # This script is SELF-SUFFICIENT: # - Automatically creates notification templates if they don't exist # - Uses Proxmox native notification system (same as HA alerts) # - No email configuration needed - uses existing Proxmox setup # # Installation: # cp oracle-backup-monitor-proxmox.sh /opt/scripts/ # chmod +x /opt/scripts/oracle-backup-monitor-proxmox.sh # /opt/scripts/oracle-backup-monitor-proxmox.sh --install # Creates templates # crontab -e # Add: 0 9 * * * /opt/scripts/oracle-backup-monitor-proxmox.sh # # Author: Claude (based on ha-monitor.sh pattern) # Version: 1.0 set -euo pipefail # Configuration PRIMARY_HOST="10.0.20.36" PRIMARY_PORT="22122" PRIMARY_USER="Administrator" BACKUP_PATH="/mnt/pve/oracle-backups/ROA/autobackup" MAX_FULL_AGE_HOURS=25 MAX_CUMULATIVE_AGE_HOURS=7 TEMPLATE_DIR="/usr/share/pve-manager/templates/default" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # Function to create notification templates create_templates() { echo -e "${GREEN}Creating Oracle backup notification templates...${NC}" # Create templates directory if needed mkdir -p "$TEMPLATE_DIR" # Subject template cat > "$TEMPLATE_DIR/oracle-backup-subject.txt.hbs" <<'EOF' Oracle Backup {{severity}} - {{node}} EOF # Text body template cat > "$TEMPLATE_DIR/oracle-backup-body.txt.hbs" <<'EOF' Oracle Backup {{severity}} - {{node}} {{status}} ======================================== {{#if errors}} CRITICAL ISSUES: {{#each errors}} - {{this}} {{/each}} {{/if}} {{#if warnings}} WARNINGS: {{#each warnings}} - {{this}} {{/each}} {{/if}} ======================================== BACKUP STATUS: FULL: {{full_backup_age}}h old {{#if full_backup_ok}}OK{{else}}TOO OLD{{/if}} (limit: 25h) CUMULATIVE: {{cumulative_backup_age}}h old {{#if cumulative_backup_ok}}OK{{else}}TOO OLD{{/if}} (limit: 7h) Total: {{total_backups}} files | Size: {{total_size_gb}}GB | Disk: {{disk_usage}}% {{#if backup_list}} LATEST BACKUPS (last 5): {{#each backup_list}} - {{this}} {{/each}} {{/if}} ======================================== Next check: {{date}} + 24h | Proxmox Monitoring EOF # HTML body template (identical to text for compatibility) cat > "$TEMPLATE_DIR/oracle-backup-body.html.hbs" <<'EOF' Oracle Backup {{severity}} - {{node}} {{status}} ======================================== {{#if errors}} CRITICAL ISSUES: {{#each errors}} - {{this}} {{/each}} {{/if}} {{#if warnings}} WARNINGS: {{#each warnings}} - {{this}} {{/each}} {{/if}} ======================================== BACKUP STATUS: FULL: {{full_backup_age}}h old {{#if full_backup_ok}}OK{{else}}TOO OLD{{/if}} (limit: 25h) CUMULATIVE: {{cumulative_backup_age}}h old {{#if cumulative_backup_ok}}OK{{else}}TOO OLD{{/if}} (limit: 7h) Total: {{total_backups}} files | Size: {{total_size_gb}}GB | Disk: {{disk_usage}}% {{#if backup_list}} LATEST BACKUPS (last 5): {{#each backup_list}} - {{this}} {{/each}} {{/if}} ======================================== Next check: {{date}} + 24h | Proxmox Monitoring EOF echo -e "${GREEN}Templates created successfully in $TEMPLATE_DIR${NC}" } # Function to send notification via PVE::Notify send_pve_notification() { local severity="$1" local status="$2" local data="$3" # Create Perl script to call PVE::Notify cat > /tmp/oracle-notify.pl <<'PERL_SCRIPT' #!/usr/bin/perl use strict; use warnings; use PVE::Notify; use JSON; my $json_data = do { local $/; }; my $data = decode_json($json_data); my $severity = $data->{severity} // 'info'; my $template_name = 'oracle-backup'; # Add fields for matching rules my $fields = { type => 'oracle-backup', severity => $severity, hostname => $data->{hostname}, }; # Send notification eval { PVE::Notify::notify( $severity, $template_name, $data, $fields ); }; if ($@) { print "Error sending notification: $@\n"; exit 1; } print "Notification sent successfully\n"; PERL_SCRIPT chmod +x /tmp/oracle-notify.pl # Send notification echo "$data" | perl /tmp/oracle-notify.pl rm -f /tmp/oracle-notify.pl } # Function to check backups check_backups() { local status="OK" local errors=() local warnings=() echo "Checking Oracle backups..." # Get backup list local backup_files=$(ls -lth "$BACKUP_PATH"/*.BKP 2>/dev/null | head -10 || echo "") if [ -z "$backup_files" ]; then status="ERROR" errors+=("No backup files found in $BACKUP_PATH") else # Count backups local total_backups=$(ls "$BACKUP_PATH"/*.BKP 2>/dev/null | wc -l) local total_size=$(du -shc "$BACKUP_PATH"/*.BKP 2>/dev/null | tail -1 | awk '{print $1}') # Check FULL backup age local latest_full=$(ls -t "$BACKUP_PATH"/*FULL*.BKP 2>/dev/null | head -1 || echo "") local full_age_hours="N/A" local full_backup_ok=false if [ -n "$latest_full" ]; then local full_timestamp=$(stat -c %Y "$latest_full") local current_timestamp=$(date +%s) full_age_hours=$(( (current_timestamp - full_timestamp) / 3600 )) if [ "$full_age_hours" -gt "$MAX_FULL_AGE_HOURS" ]; then status="WARNING" warnings+=("FULL backup is $full_age_hours hours old (threshold: $MAX_FULL_AGE_HOURS)") else full_backup_ok=true fi else status="ERROR" errors+=("No FULL backup found") fi # Check CUMULATIVE backup age local latest_cumulative=$(ls -t "$BACKUP_PATH"/*INCR*.BKP "$BACKUP_PATH"/*INCREMENTAL*.BKP "$BACKUP_PATH"/*CUMULATIVE*.BKP 2>/dev/null | head -1 || echo "") local cumulative_age_hours="N/A" local cumulative_backup_ok=false if [ -n "$latest_cumulative" ]; then local cumulative_timestamp=$(stat -c %Y "$latest_cumulative") local current_timestamp=$(date +%s) cumulative_age_hours=$(( (current_timestamp - cumulative_timestamp) / 3600 )) if [ "$cumulative_age_hours" -gt "$MAX_CUMULATIVE_AGE_HOURS" ]; then if [ "$status" != "ERROR" ]; then status="WARNING"; fi warnings+=("CUMULATIVE backup is $cumulative_age_hours hours old (threshold: $MAX_CUMULATIVE_AGE_HOURS)") else cumulative_backup_ok=true fi fi # Check disk usage local disk_usage=$(df "$BACKUP_PATH" | tail -1 | awk '{print int($5)}') if [ "$disk_usage" -gt 90 ]; then status="ERROR" errors+=("Disk usage critical: ${disk_usage}%") elif [ "$disk_usage" -gt 80 ]; then if [ "$status" != "ERROR" ]; then status="WARNING"; fi warnings+=("Disk usage high: ${disk_usage}%") fi # Prepare notification data local severity="info" [ "$status" = "WARNING" ] && severity="warning" [ "$status" = "ERROR" ] && severity="error" # Convert arrays to JSON arrays local errors_json=$(printf '%s\n' "${errors[@]}" | jq -R . | jq -s .) local warnings_json=$(printf '%s\n' "${warnings[@]}" | jq -R . | jq -s .) local backup_list_json=$(echo "$backup_files" | head -5 | jq -R . | jq -s .) # Create JSON data local json_data=$(cat < Notifications > Add matching rules for 'oracle-backup'" ;; --help) echo "Oracle Backup Monitor for Proxmox" echo "Usage:" echo " $0 - Check backups and send alerts if issues found" echo " $0 --install - Create notification templates" echo " $0 --help - Show this help" ;; *) # Check if templates exist, create if missing if [ ! -f "$TEMPLATE_DIR/oracle-backup-subject.txt.hbs" ]; then echo -e "${YELLOW}Templates not found, creating...${NC}" create_templates echo "" fi # Run backup check check_backups ;; esac } # Check dependencies if ! command -v jq &> /dev/null; then echo -e "${RED}Error: jq is not installed${NC}" echo "Install with: apt-get install jq" exit 1 fi main "$@"