Maintenance App - Simple Cloudflare Site Management
The Maintenance app provides a simple, efficient solution for managing maintenance mode across Cloudflare sites using Page Rules. Built with the KISS principle (Keep It Simple, Stupid), it focuses on core functionality without unnecessary complexity.
Overviewโ
The Maintenance app includes:
- ๐ Multi-Site Management - Manage Cloudflare sites with simple ORM interface
- โก Page Rules Integration - Works with Cloudflare Free plan using Page Rules
- ๐ Bulk Operations - Enable/disable maintenance for multiple sites simultaneously
- ๐ Clean Admin Interface - Django admin integration with Unfold styling
- ๐ฑ CLI Management - Simple management commands for automation
- ๐ Audit Trail - Operation logging for transparency
Architectureโ
Core Modelsโ
# Essential Models (4 total)
CloudflareSite # Site configuration with custom maintenance URLs
CloudflareApiKey # API key management with automatic defaults
MaintenanceLog # Operation audit trail
ScheduledMaintenance # Planned maintenance events
Service Layerโ
# Core Services (4 total)
MaintenanceService # Page Rules based maintenance control
SiteSyncService # Automatic site discovery from Cloudflare
BulkOperationsService # Multi-site operations
ScheduledMaintenanceService # Maintenance scheduling
Management Commandsโ
# CLI Commands (3 total)
maintenance # Site maintenance management
sync_cloudflare # Site discovery and synchronization
process_scheduled_maintenance # Scheduled maintenance processor
Quick Startโ
Enable in Configurationโ
# config.py
from django_cfg import DjangoConfig
class MyProjectConfig(DjangoConfig):
# Enable maintenance app
enable_maintenance: bool = True
Environment Configurationโ
# config.dev.yaml
# No additional configuration needed!
# Just add your Cloudflare API token via admin interface
Run Migrationsโ
python manage.py migrate
Add Cloudflare API Keyโ
- Go to Django Admin:
/admin/maintenance/cloudflareapikey/ - Add your Cloudflare API token
- Sites will be auto-discovered and synced
Site Managementโ
Simple Interfaceโ
from django_cfg.apps.maintenance import CloudflareSite, MaintenanceService
# Get site
site = CloudflareSite.objects.get(domain='example.com')
# Enable maintenance
service = MaintenanceService(site)
log_entry = service.enable_maintenance("Database upgrade")
# Disable maintenance
log_entry = service.disable_maintenance()
# Check status
is_active = service.get_status()
Custom Maintenance URLsโ
# Create site with custom maintenance page
site = CloudflareSite.objects.create(
name="My Site",
domain="example.com",
zone_id="zone_123",
account_id="account_123",
api_key=api_key,
# Custom maintenance URL (optional)
maintenance_url="https://status.mycompany.com/?site=example.com"
)
# If maintenance_url is empty, uses default:
# https://docs.djangocfg.com/maintenance?site=example.com
Subdomain Configurationโ
# Default: Include ALL subdomains (*.example.com)
site = CloudflareSite.objects.create(
name="My Site",
domain="example.com",
api_key=api_key,
include_subdomains=True, # Default: True
subdomain_list="" # Default: empty
)
# Custom: Include SPECIFIC subdomains only
site = CloudflareSite.objects.create(
name="My Site",
domain="example.com",
api_key=api_key,
include_subdomains=False, # Disable wildcard
subdomain_list="api,dashboard,www" # Specific subdomains
)
# This will create Page Rules for:
# - api.example.com/*
# - dashboard.example.com/*
# - www.example.com/*
# (root example.com/* is always included)
Bulk Operationsโ
# Enable maintenance for multiple sites
sites = CloudflareSite.objects.filter(is_active=True)
results = CloudflareSite.objects.bulk_sync_all()
print(f"Synced: {results['synced']}, Errors: {results['errors']}")
# Discover new sites
results = CloudflareSite.objects.discover_all_sites()
print(f"Discovered: {results['created']} new sites")
CLI Managementโ
Basic Commandsโ
# Enable maintenance for specific domain
python manage.py maintenance enable example.com --reason "Database upgrade"
# Disable maintenance
python manage.py maintenance disable example.com
# Check status
python manage.py maintenance status example.com
# List all sites
python manage.py maintenance list
Site Discoveryโ
# Sync sites from Cloudflare
python manage.py sync_cloudflare
# Force full sync
python manage.py sync_cloudflare --force
# Sync specific API key
python manage.py sync_cloudflare --api-key "My API Key"
Admin Interfaceโ
Site Managementโ
The admin interface provides:
- ๐ Site List - Overview with maintenance status badges
- ๐ Action Buttons - Individual site actions (sync, enable/disable maintenance)
- ๐ Bulk Actions - Mass operations from the list view
- ๐ Filtering - Filter by maintenance status, API key, activity
- ๐ Logs - Complete operation history
Available Actionsโ
Individual Site Actions (Detail View)โ
- ๐ Sync with Cloudflare - Update site configuration
- ๐ง Enable Maintenance - Put site in maintenance mode
- โ Disable Maintenance - Remove maintenance mode
Bulk Actions (List View)โ
- ๐ Bulk Sync Sites - Sync multiple sites with Cloudflare
- ๐ Bulk Discover Sites - Discover new sites from Cloudflare
Accessing Adminโ
# Navigate to maintenance admin
http://localhost:8000/admin/maintenance/cloudflaresite/
# Individual actions available in site detail view
# Bulk actions available in site list view
How It Worksโ
Page Rules Technologyโ
The maintenance app uses Cloudflare Page Rules instead of Workers, making it compatible with Cloudflare Free plans:
- Enable Maintenance: Creates Page Rules that redirect domains to maintenance page
- All Subdomains:
*.domain.com/*+domain.com/*(ifinclude_subdomains=True) - Specific Subdomains: Individual rules for each subdomain (if
include_subdomains=False)
- All Subdomains:
- Disable Maintenance: Finds and deletes all maintenance Page Rules for the site
- Custom URLs: Supports custom maintenance pages or uses default Django-CFG page
- Subdomain Support: Flexible configuration for subdomain handling
Automatic Discoveryโ
from django_cfg.apps.maintenance.services import SiteSyncService
# Auto-discover zones from Cloudflare
api_key = CloudflareApiKey.objects.get_default()
sync_service = SiteSyncService(api_key)
# Discover and create/update sites
sites_data = sync_service.sync_zones()
print(f"Processed {len(sites_data)} zones")
What Gets Auto-Configuredโ
- Zone Discovery - Finds all zones in Cloudflare account
- Site Creation - Creates Django models for each zone
- Configuration Sync - Updates zone_id, account_id automatically
- Status Tracking - Tracks maintenance state and history
- Default Subdomain Settings - New sites include all subdomains by default
Important: Sync operations preserve user-configured subdomain settings. Manual changes to
include_subdomains,subdomain_list, andmaintenance_urlare never overwritten by sync operations.
Event Trackingโ
Maintenance Logsโ
from django_cfg.apps.maintenance.models import MaintenanceLog
# All operations are automatically logged
logs = MaintenanceLog.objects.filter(
site__domain='example.com'
).order_by('-created_at')
for log in logs:
print(f"{log.created_at}: {log.action}")
print(f" Status: {log.status}")
print(f" Duration: {log.duration_seconds}s")
if log.error_message:
print(f" Error: {log.error_message}")
Log Statisticsโ
# Get operation statistics
stats = MaintenanceLog.objects.get_stats(days=30)
print(f"Success rate: {stats['success_rate']:.1f}%")
print(f"Average duration: {stats['avg_duration']:.1f}s")
print(f"Total operations: {stats['total']}")
Configurationโ
API Key Managementโ
from django_cfg.apps.maintenance.models import CloudflareApiKey
# Create API key
api_key = CloudflareApiKey.objects.create(
name="Production Key",
api_token="your_cloudflare_token_here",
account_id="auto_discovered", # Auto-filled on first use
is_default=True, # Use as default for new sites
is_active=True
)
# Multiple API keys supported
api_key2 = CloudflareApiKey.objects.create(
name="Development Key",
api_token="dev_token_here",
is_active=True
)
Site Configurationโ
from django_cfg.apps.maintenance.models import CloudflareSite
# Manual site creation
site = CloudflareSite.objects.create(
name="My Production Site",
domain="example.com",
api_key=api_key,
# Optional: auto-discovered if not provided
zone_id="zone_123",
account_id="account_123",
# Custom maintenance page
maintenance_url="https://status.example.com",
# Subdomain configuration (manual)
include_subdomains=False, # Don't use wildcard
subdomain_list="api,dashboard,www", # Specific subdomains
# Site settings
is_active=True
)
# User can modify subdomain settings later via admin or code:
site.include_subdomains = True # Switch to include all subdomains
site.subdomain_list = "" # Clear specific list
site.save()
๐งช Testingโ
Simple Testsโ
from django.test import TestCase
from django_cfg.apps.maintenance import CloudflareSite, MaintenanceService
class MaintenanceTest(TestCase):
def setUp(self):
self.api_key = CloudflareApiKey.objects.create(
name="Test Key",
api_token="test_token",
is_default=True
)
self.site = CloudflareSite.objects.create(
name="Test Site",
domain="test.example.com",
api_key=self.api_key
)
def test_maintenance_cycle(self):
service = MaintenanceService(self.site)
# Test enable
log = service.enable_maintenance("Test reason")
self.assertEqual(log.status, 'success')
# Test status
self.assertTrue(service.get_status())
# Test disable
log = service.disable_maintenance()
self.assertEqual(log.status, 'success')
self.assertFalse(service.get_status())
Test Coverageโ
Current test coverage includes:
- โ Models - All model methods and managers
- โ Services - Core maintenance operations
- โ Utils - Retry logic and error handling
- โ Commands - CLI command functionality
๐ Security Featuresโ
Access Controlโ
- API Token Security - Tokens stored securely in database
- Permission Validation - All operations validate API permissions
- Error Handling - Safe error messages without sensitive data exposure
Input Validationโ
- Domain Validation - Ensures valid domain formats
- API Response Validation - Validates Cloudflare API responses
- URL Validation - Validates custom maintenance URLs
Performanceโ
Optimizationsโ
- Lazy Imports - Models and services loaded on demand
- Retry Logic - Exponential backoff for API failures
- JSON Serialization - Safe handling of datetime objects in logs
- Efficient Queries - Custom managers with optimized querysets
Rate Limitingโ
# Built-in retry with exponential backoff
@retry_on_failure(max_retries=3, base_delay=1.0)
def _create_maintenance_page_rule(self):
# Handles API rate limits automatically
return self.client.page_rules.create(...)
Best Practicesโ
1. Use Descriptive Reasonsโ
# Good: Specific and informative
service.enable_maintenance("Database migration v2.1 - ETA 30 minutes")
# Avoid: Vague messages
service.enable_maintenance("Maintenance")
2. Set Custom Maintenance URLsโ
# Branded maintenance page
site.maintenance_url = "https://status.yourcompany.com/?site=example.com"
site.save()
3. Configure Subdomains Appropriatelyโ
# For most sites: Include all subdomains (default)
site.include_subdomains = True
site.subdomain_list = ""
# For specific control: List only critical subdomains
site.include_subdomains = False
site.subdomain_list = "api,dashboard,www" # Skip dev/test subdomains
# Mixed approach: Add specific subdomains to wildcard
# (not supported - use one approach or the other)
4. Monitor Logsโ
# Check for errors regularly
failed_logs = MaintenanceLog.objects.filter(
status='failed',
created_at__gte=timezone.now() - timedelta(days=1)
)
if failed_logs.exists():
# Alert administrators
send_alert_email(failed_logs)
5. Test in Developmentโ
# Always test maintenance flow
python manage.py maintenance enable dev.example.com --reason "Testing"
# Verify maintenance page loads
python manage.py maintenance disable dev.example.com
๐ Migration from Complex Versionโ
If migrating from the old complex maintenance app:
What's Removedโ
- โ Workers Support - Now uses Page Rules only
- โ Monitoring System - External monitoring removed
- โ Site Groups - Simplified to direct site management
- โ User Ownership - Sites are global, not user-specific
- โ Complex Templates - Uses simple URL redirects
- โ API Endpoints - Admin and CLI only
What's Simplifiedโ
- โ 4 Models instead of 8+ models
- โ Page Rules instead of Worker deployment
- โ Simple CLI instead of complex filtering
- โ Direct Operations instead of async processing
- โ Cloudflare Free compatible
Migration Stepsโ
- Export site data from old app
- Install new maintenance app
- Create API keys in admin
- Import/recreate sites
- Test maintenance operations
Related Documentationโ
- Configuration Guide - Basic Django-CFG setup
- CLI Tools - Command-line usage
- Deployment Guide - Production setup
- Admin Interface - Unfold admin styling
The simplified Maintenance app provides efficient site maintenance management with minimal complexity! ๐