Skip to Content
DocsFeaturesBuilt-in AppsOperationsMaintenance

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

  1. Go to Django Admin: /admin/maintenance/cloudflareapikey/
  2. Add your Cloudflare API token
  3. 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:

  1. Enable Maintenance: Creates Page Rules that redirect domains to maintenance page
    • All Subdomains: *.domain.com/* + domain.com/* (if include_subdomains=True)
    • Specific Subdomains: Individual rules for each subdomain (if include_subdomains=False)
  2. Disable Maintenance: Finds and deletes all maintenance Page Rules for the site
  3. Custom URLs: Supports custom maintenance pages or uses default Django-CFG page
  4. 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

  1. Zone Discovery - Finds all zones in Cloudflare account
  2. Site Creation - Creates Django models for each zone
  3. Configuration Sync - Updates zone_id, account_id automatically
  4. Status Tracking - Tracks maintenance state and history
  5. 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, and maintenance_url are 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

  1. Export site data from old app
  2. Install new maintenance app
  3. Create API keys in admin
  4. Import/recreate sites
  5. Test maintenance operations

The simplified Maintenance app provides efficient site maintenance management with minimal complexity! 🌐