6.7 Backup & Restore Procedures
- Version: 1.0
- Last Updated: December 30, 2025
- Author: Abhavtech Network Engineering
- Status: Production Ready
- Classification: Internal Use
6.7.1 Backup Strategy Overview
Backup Architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ SD-WAN BACKUP ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ vManage Cluster │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ vManage-1 │ │ vManage-2 │ │ vManage-3 │ ← Database backup │ │
│ │ └───────────┘ └───────────┘ └───────────┘ ← Config backup │ │
│ │ │ │ │
│ └───────────────────────│──────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Backup Repository │ │
│ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │
│ │ │ Mumbai NFS │ │ Chennai NFS │ │ AWS S3 │ │ │
│ │ │ (Primary) │ │ (Secondary) │ │ (Offsite) │ │ │
│ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ Backup Types: │
│ ├── Database backup (Neo4j, MongoDB, Elasticsearch) │
│ ├── Configuration backup (templates, policies) │
│ ├── Certificate backup (root CA, device certs) │
│ └── WAN Edge configuration backup │
│ │
│ Schedule: │
│ ├── Full backup: Daily 02:00 IST │
│ ├── Incremental: Every 6 hours │
│ └── Retention: 30 days local, 90 days offsite │
└─────────────────────────────────────────────────────────────────────────────┘
Backup Components
| Component |
Backup Type |
Frequency |
Retention |
Location |
| vManage Database |
Full + Incremental |
Daily/6-hourly |
30/90 days |
NFS + S3 |
| Configuration DB |
Full |
Daily |
30 days |
NFS + S3 |
| Templates |
Export |
Weekly |
90 days |
Git + NFS |
| Policies |
Export |
Weekly |
90 days |
Git + NFS |
| Certificates |
Manual |
Monthly |
Indefinite |
Encrypted vault |
| WAN Edge Config |
Full |
Daily |
30 days |
vManage + NFS |
6.7.2 vManage Backup Procedures
Full Database Backup
# === VMANAGE DATABASE BACKUP ===
# Option 1: Via vManage UI
# Administration > Settings > Configuration Database > Backup
# Option 2: Via API
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/system/device/config/backup" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-d '{
"scheduleOptions": {
"immediate": true
}
}'
# Check backup status
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/system/device/config/backup/status" \
-H "Cookie: JSESSIONID=${SESSION}"
# Download backup file
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/system/device/config/backup/download" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o vmanage_backup_$(date +%Y%m%d).tar.gz
Scheduled Backup Configuration
# === CONFIGURE SCHEDULED BACKUPS ===
# Via vManage API - Configure daily backup at 02:00 IST
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/system/device/config/backup/schedule" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-d '{
"scheduleOptions": {
"frequency": "daily",
"time": "02:00",
"timezone": "Asia/Kolkata"
},
"exportOptions": {
"exportToRemote": true,
"remoteServerType": "nfs",
"remoteServerIP": "10.100.1.200",
"remotePath": "/backups/sdwan/vmanage"
}
}'
Configuration Export
# === EXPORT CONFIGURATION DATABASE ===
# Export all device configurations
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/system/device/config/export" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o config_export_$(date +%Y%m%d).json
# Export specific device configuration
DEVICE_IP="10.100.1.1"
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/system/device/${DEVICE_IP}/config" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o device_config_${DEVICE_IP}_$(date +%Y%m%d).json
Template Backup
# === BACKUP DEVICE TEMPLATES ===
# List all device templates
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/device" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o templates_list.json
# Export specific device template
TEMPLATE_ID="template-uuid-here"
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/device/object/${TEMPLATE_ID}" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o device_template_${TEMPLATE_ID}.json
# === BACKUP FEATURE TEMPLATES ===
# List all feature templates
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/feature" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o feature_templates_list.json
# Export all feature templates
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/feature/bulk" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o all_feature_templates.json
Policy Backup
# === BACKUP ALL POLICIES ===
# Export centralized policies
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/policy/vsmart" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o centralized_policies.json
# Export localized policies
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/policy/vedge" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o localized_policies.json
# Export security policies
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/policy/security" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o security_policies.json
# Export all policy definitions
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/template/policy/definition" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o policy_definitions.json
6.7.3 WAN Edge Backup
Device Configuration Backup
! === WAN EDGE LOCAL BACKUP ===
! Save running config to startup
copy running-config startup-config
! Save to local flash
copy running-config bootflash:config_backup_20251230.cfg
! Export to external server
copy running-config scp://admin@10.100.1.200/backups/wan-edges/
! === VERIFY BACKUP ===
! List backup files
dir bootflash: | include config
! Verify backup contents
more bootflash:config_backup_20251230.cfg | begin hostname
vManage Device Config Backup
# === BACKUP ALL WAN EDGE CONFIGS VIA VMANAGE ===
# Get all WAN Edge device IDs
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/device" \
-H "Cookie: JSESSIONID=${SESSION}" | \
jq -r '.data[] | select(.personality=="vedge") | ."system-ip"' > wan_edges.txt
# Backup each device config
while read DEVICE_IP; do
echo "Backing up ${DEVICE_IP}..."
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/device/config?deviceIP=${DEVICE_IP}" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o "wan_edge_config_${DEVICE_IP}_$(date +%Y%m%d).json"
done < wan_edges.txt
Configuration Archive Script
#!/usr/bin/env python3
"""
SD-WAN Configuration Backup Automation
Abhavtech.com - December 2025
"""
import requests
import json
import os
from datetime import datetime
import boto3
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class SDWANBackup:
"""Automated SD-WAN backup system"""
def __init__(self, vmanage_host: str, username: str, password: str):
self.vmanage_host = vmanage_host
self.base_url = f"https://{vmanage_host}"
self.session = requests.Session()
self.session.verify = False
self.backup_dir = "/opt/sdwan-backups"
self.authenticate(username, password)
def authenticate(self, username: str, password: str):
"""Authenticate to vManage"""
login_url = f"{self.base_url}/j_security_check"
payload = {'j_username': username, 'j_password': password}
self.session.post(login_url, data=payload)
token_url = f"{self.base_url}/dataservice/client/token"
token_response = self.session.get(token_url)
if token_response.status_code == 200:
self.session.headers['X-XSRF-TOKEN'] = token_response.text
def backup_database(self) -> str:
"""Trigger and download database backup"""
print("Starting database backup...")
# Trigger backup
backup_url = f"{self.base_url}/dataservice/system/device/config/backup"
self.session.post(backup_url, json={"scheduleOptions": {"immediate": True}})
# Wait and download
import time
time.sleep(60) # Wait for backup to complete
download_url = f"{self.base_url}/dataservice/system/device/config/backup/download"
response = self.session.get(download_url)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{self.backup_dir}/vmanage_db_{timestamp}.tar.gz"
with open(filename, 'wb') as f:
f.write(response.content)
print(f"Database backup saved: {filename}")
return filename
def backup_templates(self) -> str:
"""Backup all templates"""
print("Backing up templates...")
templates = {}
# Device templates
device_url = f"{self.base_url}/dataservice/template/device"
device_resp = self.session.get(device_url)
templates['device_templates'] = device_resp.json().get('data', [])
# Feature templates
feature_url = f"{self.base_url}/dataservice/template/feature"
feature_resp = self.session.get(feature_url)
templates['feature_templates'] = feature_resp.json().get('data', [])
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{self.backup_dir}/templates_{timestamp}.json"
with open(filename, 'w') as f:
json.dump(templates, f, indent=2)
print(f"Templates backup saved: {filename}")
return filename
def backup_policies(self) -> str:
"""Backup all policies"""
print("Backing up policies...")
policies = {}
# Centralized policies
vsmart_url = f"{self.base_url}/dataservice/template/policy/vsmart"
vsmart_resp = self.session.get(vsmart_url)
policies['centralized'] = vsmart_resp.json().get('data', [])
# Localized policies
vedge_url = f"{self.base_url}/dataservice/template/policy/vedge"
vedge_resp = self.session.get(vedge_url)
policies['localized'] = vedge_resp.json().get('data', [])
# Security policies
security_url = f"{self.base_url}/dataservice/template/policy/security"
security_resp = self.session.get(security_url)
policies['security'] = security_resp.json().get('data', [])
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{self.backup_dir}/policies_{timestamp}.json"
with open(filename, 'w') as f:
json.dump(policies, f, indent=2)
print(f"Policies backup saved: {filename}")
return filename
def backup_device_configs(self) -> str:
"""Backup all device configurations"""
print("Backing up device configurations...")
# Get all devices
devices_url = f"{self.base_url}/dataservice/device"
devices_resp = self.session.get(devices_url)
devices = devices_resp.json().get('data', [])
configs = {}
for device in devices:
device_ip = device.get('system-ip')
hostname = device.get('host-name')
config_url = f"{self.base_url}/dataservice/device/config"
params = {'deviceIP': device_ip}
config_resp = self.session.get(config_url, params=params)
configs[hostname] = {
'system_ip': device_ip,
'config': config_resp.json().get('data', {})
}
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{self.backup_dir}/device_configs_{timestamp}.json"
with open(filename, 'w') as f:
json.dump(configs, f, indent=2)
print(f"Device configs backup saved: {filename}")
return filename
def upload_to_s3(self, filename: str, bucket: str = "abhavtech-sdwan-backups"):
"""Upload backup to S3"""
print(f"Uploading {filename} to S3...")
s3_client = boto3.client('s3')
s3_key = f"backups/{os.path.basename(filename)}"
s3_client.upload_file(filename, bucket, s3_key)
print(f"Uploaded to s3://{bucket}/{s3_key}")
def run_full_backup(self):
"""Execute full backup procedure"""
print("=" * 60)
print("SD-WAN FULL BACKUP")
print(f"Timestamp: {datetime.now().isoformat()}")
print("=" * 60)
# Create backup directory
os.makedirs(self.backup_dir, exist_ok=True)
# Run all backups
db_file = self.backup_database()
templates_file = self.backup_templates()
policies_file = self.backup_policies()
configs_file = self.backup_device_configs()
# Upload to S3
for f in [db_file, templates_file, policies_file, configs_file]:
self.upload_to_s3(f)
print("\n" + "=" * 60)
print("BACKUP COMPLETE")
print("=" * 60)
def main():
backup = SDWANBackup(
vmanage_host="vmanage.abhavtech.com",
username="admin",
password="secure_password"
)
backup.run_full_backup()
if __name__ == "__main__":
main()
6.7.4 Certificate Backup
Certificate Export Procedures
# === BACKUP CERTIFICATES FROM VMANAGE ===
# Export root CA certificate
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/certificate/rootcacert" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o root_ca_cert.pem
# Export vManage certificate
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/certificate/vmanagecert" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o vmanage_cert.pem
# Export device serial file
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/certificate/serialfile" \
-H "Cookie: JSESSIONID=${SESSION}" \
-o serial_file.viptela
# === BACKUP FROM WAN EDGE ===
! Export certificate to flash
show sdwan certificate root-ca-cert > bootflash:root_ca.pem
show sdwan certificate installed > bootflash:device_cert.pem
! Copy to backup server
copy bootflash:root_ca.pem scp://admin@10.100.1.200/backups/certs/
copy bootflash:device_cert.pem scp://admin@10.100.1.200/backups/certs/
Secure Certificate Storage
# Certificate Backup Best Practices
Storage Requirements:
- Encrypted storage (AES-256)
- Access control (need-to-know basis)
- Audit logging
- Multiple copies in different locations
Certificate Types to Backup:
Root CA:
- Frequency: Monthly
- Retention: Indefinite
- Access: Security team only
vManage Certificate:
- Frequency: Monthly
- Retention: 1 year
- Access: Network admins
Device Certificates:
- Frequency: On change
- Retention: 90 days
- Access: Network team
Serial File:
- Frequency: On device add/remove
- Retention: Current + 2 previous
- Access: Network admins
6.7.5 Restore Procedures
vManage Database Restore
# === RESTORE VMANAGE DATABASE ===
# Option 1: Via vManage UI
# Administration > Settings > Configuration Database > Restore
# Option 2: Via API
# Upload backup file
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/system/device/config/restore/upload" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-F "file=@vmanage_backup_20251230.tar.gz"
# Trigger restore
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/system/device/config/restore" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-d '{
"restoreOptions": {
"restoreType": "full"
}
}'
# Monitor restore status
curl -k -X GET "https://vmanage.abhavtech.com/dataservice/system/device/config/restore/status" \
-H "Cookie: JSESSIONID=${SESSION}"
Template Restore
# === RESTORE TEMPLATES ===
# Import device template
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/template/device" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-d @device_template_backup.json
# Import feature templates (bulk)
curl -k -X POST "https://vmanage.abhavtech.com/dataservice/template/feature/bulk" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=${SESSION}" \
-H "X-XSRF-TOKEN: ${TOKEN}" \
-d @all_feature_templates.json
WAN Edge Configuration Restore
! === RESTORE WAN EDGE CONFIGURATION ===
! Method 1: From local backup
copy bootflash:config_backup_20251230.cfg running-config
! Method 2: From SCP server
copy scp://admin@10.100.1.200/backups/wan-edges/IN-MUM-WAN-EDGE-01.cfg running-config
! Method 3: Via vManage template push
! 1. Attach device to template in vManage
! 2. Push configuration
! Verify restoration
show running-config | begin hostname
show sdwan control connections
show sdwan tunnel statistics
Disaster Recovery Restore
┌─────────────────────────────────────────────────────────────────────────────┐
│ DISASTER RECOVERY RESTORE PROCEDURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Assess Damage │
│ ├── Identify failed components │
│ ├── Determine backup availability │
│ └── Estimate recovery time │
│ │
│ Step 2: Infrastructure Recovery │
│ ├── Deploy replacement VMs/hardware │
│ ├── Configure base OS │
│ └── Restore network connectivity │
│ │
│ Step 3: vManage Cluster Restore │
│ ├── Install vManage software │
│ ├── Restore from backup │
│ ├── Verify cluster formation │
│ └── Validate database integrity │
│ │
│ Step 4: Controller Restore │
│ ├── Restore vSmart from backup │
│ ├── Restore vBond from backup │
│ └── Verify control plane connectivity │
│ │
│ Step 5: WAN Edge Recovery │
│ ├── Verify WAN Edges reconnect │
│ ├── Validate tunnel formation │
│ └── Test traffic flow │
│ │
│ Step 6: Validation │
│ ├── Run comprehensive health check │
│ ├── Verify SD-Access integration │
│ └── Test business-critical applications │
│ │
│ RTO Target: 4 hours │
│ RPO Target: 1 hour (6-hourly incremental backups) │
└─────────────────────────────────────────────────────────────────────────────┘
6.7.6 Backup Verification
Backup Integrity Testing
#!/usr/bin/env python3
"""
Backup Verification Script
Abhavtech.com - December 2025
"""
import json
import hashlib
import os
import tarfile
from datetime import datetime
class BackupVerification:
"""Verify backup integrity"""
def __init__(self, backup_dir: str = "/opt/sdwan-backups"):
self.backup_dir = backup_dir
self.verification_results = []
def verify_tar_integrity(self, filename: str) -> bool:
"""Verify tar.gz file integrity"""
try:
with tarfile.open(filename, 'r:gz') as tar:
tar.getnames() # Test file listing
return True
except Exception as e:
print(f"TAR integrity check failed: {e}")
return False
def verify_json_integrity(self, filename: str) -> bool:
"""Verify JSON file integrity"""
try:
with open(filename, 'r') as f:
json.load(f)
return True
except Exception as e:
print(f"JSON integrity check failed: {e}")
return False
def calculate_checksum(self, filename: str) -> str:
"""Calculate SHA256 checksum"""
sha256_hash = hashlib.sha256()
with open(filename, 'rb') as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def verify_backup(self, filename: str) -> dict:
"""Verify single backup file"""
result = {
'filename': filename,
'exists': os.path.exists(filename),
'size': 0,
'checksum': None,
'integrity': False,
'timestamp': datetime.now().isoformat()
}
if not result['exists']:
return result
result['size'] = os.path.getsize(filename)
result['checksum'] = self.calculate_checksum(filename)
if filename.endswith('.tar.gz'):
result['integrity'] = self.verify_tar_integrity(filename)
elif filename.endswith('.json'):
result['integrity'] = self.verify_json_integrity(filename)
else:
result['integrity'] = result['size'] > 0
return result
def verify_all_backups(self) -> list:
"""Verify all backups in directory"""
print("=" * 60)
print("BACKUP VERIFICATION")
print(f"Directory: {self.backup_dir}")
print("=" * 60)
results = []
for filename in os.listdir(self.backup_dir):
filepath = os.path.join(self.backup_dir, filename)
if os.path.isfile(filepath):
result = self.verify_backup(filepath)
results.append(result)
status = "✓ VALID" if result['integrity'] else "✗ INVALID"
print(f"\n{filename}")
print(f" Size: {result['size']:,} bytes")
print(f" Checksum: {result['checksum'][:16]}...")
print(f" Status: {status}")
# Generate verification report
report = {
'timestamp': datetime.now().isoformat(),
'backup_directory': self.backup_dir,
'total_backups': len(results),
'valid_backups': sum(1 for r in results if r['integrity']),
'invalid_backups': sum(1 for r in results if not r['integrity']),
'details': results
}
print("\n" + "=" * 60)
print(f"SUMMARY: {report['valid_backups']}/{report['total_backups']} backups valid")
print("=" * 60)
return report
def main():
verifier = BackupVerification()
report = verifier.verify_all_backups()
# Save report
report_file = f"backup_verification_{datetime.now().strftime('%Y%m%d')}.json"
with open(report_file, 'w') as f:
json.dump(report, f, indent=2)
print(f"\nReport saved: {report_file}")
if __name__ == "__main__":
main()
Monthly Restore Testing
# Monthly Restore Test Procedure
Schedule: First Saturday of each month, 02:00-06:00 IST
Pre-Test Checklist:
- [ ] Latest backup available
- [ ] Lab environment prepared
- [ ] Test team notified
- [ ] Rollback procedure documented
Restore Test Steps:
1. Lab vManage Restore:
Duration: 60 minutes
Steps:
- Deploy fresh vManage VM
- Restore database from backup
- Verify cluster health
- Check all templates present
- Validate policy definitions
2. Template Verification:
Duration: 30 minutes
Steps:
- Count templates match production
- Verify template parameters
- Check device associations
3. Device Config Restore:
Duration: 30 minutes
Steps:
- Apply template to lab device
- Verify configuration matches
- Check control connections
- Test tunnel formation
4. Certificate Restore:
Duration: 15 minutes
Steps:
- Restore root CA
- Verify certificate chain
- Test device authentication
Test Success Criteria:
- Database restore completes without errors
- All templates restored correctly
- Device accepts restored configuration
- Control plane establishes
- Certificate authentication works
Documentation:
- Record restore duration
- Note any issues encountered
- Update procedures if needed
- Report to management
6.7.7 Backup Schedule
Automated Backup Schedule
# SD-WAN Backup Schedule - Abhavtech.com
Daily Backups (02:00 IST):
vManage Database:
Type: Full backup
Retention: 30 days local, 90 days S3
Location: /backups/sdwan/vmanage/
Notification: sdwan-ops@abhavtech.com
WAN Edge Configs:
Type: Configuration export
Retention: 30 days
Location: /backups/sdwan/wan-edges/
Notification: On failure only
Incremental Backups (Every 6 hours):
vManage Database:
Type: Incremental
Times: 08:00, 14:00, 20:00, 02:00
Retention: 7 days
Location: /backups/sdwan/incremental/
Weekly Backups (Sunday 03:00 IST):
Templates:
Type: Full export
Retention: 90 days
Location: /backups/sdwan/templates/
Policies:
Type: Full export
Retention: 90 days
Location: /backups/sdwan/policies/
Git Repository:
Type: Git push
Destination: GitLab sdwan-config repo
Branch: backup/weekly
Monthly Tasks (First Sunday 04:00 IST):
Certificate Backup:
Type: Manual verification
Owner: Security team
Location: Encrypted vault
Restore Test:
Type: Lab restore
Duration: 4 hours
Owner: Network team
Cleanup:
Action: Remove backups older than retention
Verify: S3 lifecycle policies active
Cron Configuration
# /etc/cron.d/sdwan-backup
# Daily full backup at 02:00 IST
0 2 * * * root /opt/scripts/sdwan_backup.py --type full >> /var/log/sdwan-backup.log 2>&1
# Incremental backup every 6 hours
0 8,14,20 * * * root /opt/scripts/sdwan_backup.py --type incremental >> /var/log/sdwan-backup.log 2>&1
# Weekly template/policy backup on Sunday 03:00
0 3 * * 0 root /opt/scripts/sdwan_backup.py --type templates >> /var/log/sdwan-backup.log 2>&1
0 3 * * 0 root /opt/scripts/sdwan_backup.py --type policies >> /var/log/sdwan-backup.log 2>&1
# Backup verification daily at 06:00
0 6 * * * root /opt/scripts/verify_backups.py >> /var/log/sdwan-backup-verify.log 2>&1
# Cleanup old backups monthly
0 5 1 * * root /opt/scripts/cleanup_backups.sh >> /var/log/sdwan-backup-cleanup.log 2>&1
6.7.8 Backup Monitoring
Backup Health Dashboard
#!/usr/bin/env python3
"""
Backup Monitoring Dashboard
Abhavtech.com - December 2025
"""
import os
import json
from datetime import datetime, timedelta
class BackupMonitor:
"""Monitor backup health and status"""
def __init__(self, backup_dir: str = "/opt/sdwan-backups"):
self.backup_dir = backup_dir
def get_latest_backup(self, prefix: str) -> dict:
"""Get latest backup matching prefix"""
backups = []
for filename in os.listdir(self.backup_dir):
if filename.startswith(prefix):
filepath = os.path.join(self.backup_dir, filename)
mtime = os.path.getmtime(filepath)
backups.append({
'filename': filename,
'path': filepath,
'size': os.path.getsize(filepath),
'modified': datetime.fromtimestamp(mtime)
})
if not backups:
return None
return max(backups, key=lambda x: x['modified'])
def check_backup_freshness(self, backup: dict, max_age_hours: int) -> bool:
"""Check if backup is within acceptable age"""
if not backup:
return False
age = datetime.now() - backup['modified']
return age < timedelta(hours=max_age_hours)
def generate_status_report(self) -> dict:
"""Generate comprehensive backup status"""
report = {
'timestamp': datetime.now().isoformat(),
'status': 'HEALTHY',
'components': []
}
# Check database backup
db_backup = self.get_latest_backup('vmanage_db_')
db_status = {
'component': 'vManage Database',
'latest_backup': db_backup['filename'] if db_backup else None,
'age_hours': (datetime.now() - db_backup['modified']).total_seconds() / 3600 if db_backup else None,
'size_mb': db_backup['size'] / (1024*1024) if db_backup else 0,
'healthy': self.check_backup_freshness(db_backup, 24)
}
report['components'].append(db_status)
# Check template backup
template_backup = self.get_latest_backup('templates_')
template_status = {
'component': 'Templates',
'latest_backup': template_backup['filename'] if template_backup else None,
'age_hours': (datetime.now() - template_backup['modified']).total_seconds() / 3600 if template_backup else None,
'size_mb': template_backup['size'] / (1024*1024) if template_backup else 0,
'healthy': self.check_backup_freshness(template_backup, 168) # 7 days
}
report['components'].append(template_status)
# Check policy backup
policy_backup = self.get_latest_backup('policies_')
policy_status = {
'component': 'Policies',
'latest_backup': policy_backup['filename'] if policy_backup else None,
'age_hours': (datetime.now() - policy_backup['modified']).total_seconds() / 3600 if policy_backup else None,
'size_mb': policy_backup['size'] / (1024*1024) if policy_backup else 0,
'healthy': self.check_backup_freshness(policy_backup, 168)
}
report['components'].append(policy_status)
# Check device configs
config_backup = self.get_latest_backup('device_configs_')
config_status = {
'component': 'Device Configs',
'latest_backup': config_backup['filename'] if config_backup else None,
'age_hours': (datetime.now() - config_backup['modified']).total_seconds() / 3600 if config_backup else None,
'size_mb': config_backup['size'] / (1024*1024) if config_backup else 0,
'healthy': self.check_backup_freshness(config_backup, 24)
}
report['components'].append(config_status)
# Overall status
unhealthy = [c for c in report['components'] if not c['healthy']]
if len(unhealthy) > 0:
report['status'] = 'WARNING' if len(unhealthy) < 2 else 'CRITICAL'
return report
def print_dashboard(self):
"""Print dashboard to console"""
report = self.generate_status_report()
print("=" * 70)
print("SD-WAN BACKUP STATUS DASHBOARD")
print(f"Generated: {report['timestamp']}")
print(f"Overall Status: {report['status']}")
print("=" * 70)
print(f"\n{'Component':<20} {'Latest Backup':<30} {'Age (hrs)':<10} {'Size (MB)':<10} {'Status':<10}")
print("-" * 80)
for comp in report['components']:
status = "✓ OK" if comp['healthy'] else "✗ STALE"
age = f"{comp['age_hours']:.1f}" if comp['age_hours'] else "N/A"
size = f"{comp['size_mb']:.1f}" if comp['size_mb'] else "0"
backup = comp['latest_backup'][:28] + ".." if comp['latest_backup'] and len(comp['latest_backup']) > 30 else (comp['latest_backup'] or "MISSING")
print(f"{comp['component']:<20} {backup:<30} {age:<10} {size:<10} {status:<10}")
def main():
monitor = BackupMonitor()
monitor.print_dashboard()
if __name__ == "__main__":
main()
Document Control
| Version |
Date |
Author |
Changes |
| 1.0 |
December 30, 2025 |
Abhavtech |
Initial backup & restore procedures |
Document Classification: Internal Use
Next Review Date: March 30, 2026