django-cfg 1.2.15__py3-none-any.whl → 1.2.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/maintenance/README.md +305 -0
- django_cfg/apps/maintenance/__init__.py +27 -0
- django_cfg/apps/maintenance/admin/__init__.py +28 -0
- django_cfg/apps/maintenance/admin/deployments_admin.py +251 -0
- django_cfg/apps/maintenance/admin/events_admin.py +374 -0
- django_cfg/apps/maintenance/admin/monitoring_admin.py +215 -0
- django_cfg/apps/maintenance/admin/sites_admin.py +464 -0
- django_cfg/apps/maintenance/apps.py +105 -0
- django_cfg/apps/maintenance/management/__init__.py +0 -0
- django_cfg/apps/maintenance/management/commands/__init__.py +0 -0
- django_cfg/apps/maintenance/management/commands/maintenance.py +375 -0
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +168 -0
- django_cfg/apps/maintenance/managers/__init__.py +20 -0
- django_cfg/apps/maintenance/managers/deployments.py +287 -0
- django_cfg/apps/maintenance/managers/events.py +374 -0
- django_cfg/apps/maintenance/managers/monitoring.py +301 -0
- django_cfg/apps/maintenance/managers/sites.py +335 -0
- django_cfg/apps/maintenance/migrations/0001_initial.py +939 -0
- django_cfg/apps/maintenance/migrations/__init__.py +0 -0
- django_cfg/apps/maintenance/models/__init__.py +27 -0
- django_cfg/apps/maintenance/models/cloudflare.py +316 -0
- django_cfg/apps/maintenance/models/maintenance.py +334 -0
- django_cfg/apps/maintenance/models/monitoring.py +393 -0
- django_cfg/apps/maintenance/models/sites.py +419 -0
- django_cfg/apps/maintenance/serializers/__init__.py +60 -0
- django_cfg/apps/maintenance/serializers/actions.py +310 -0
- django_cfg/apps/maintenance/serializers/base.py +44 -0
- django_cfg/apps/maintenance/serializers/deployments.py +209 -0
- django_cfg/apps/maintenance/serializers/events.py +210 -0
- django_cfg/apps/maintenance/serializers/monitoring.py +278 -0
- django_cfg/apps/maintenance/serializers/sites.py +213 -0
- django_cfg/apps/maintenance/services/README.md +168 -0
- django_cfg/apps/maintenance/services/__init__.py +21 -0
- django_cfg/apps/maintenance/services/cloudflare_client.py +441 -0
- django_cfg/apps/maintenance/services/dns_manager.py +497 -0
- django_cfg/apps/maintenance/services/maintenance_manager.py +504 -0
- django_cfg/apps/maintenance/services/site_sync.py +448 -0
- django_cfg/apps/maintenance/services/sync_command_service.py +330 -0
- django_cfg/apps/maintenance/services/worker_manager.py +264 -0
- django_cfg/apps/maintenance/signals.py +38 -0
- django_cfg/apps/maintenance/urls.py +36 -0
- django_cfg/apps/maintenance/views/__init__.py +18 -0
- django_cfg/apps/maintenance/views/base.py +61 -0
- django_cfg/apps/maintenance/views/deployments.py +175 -0
- django_cfg/apps/maintenance/views/events.py +204 -0
- django_cfg/apps/maintenance/views/monitoring.py +213 -0
- django_cfg/apps/maintenance/views/sites.py +338 -0
- django_cfg/apps/urls.py +5 -1
- django_cfg/core/config.py +34 -3
- django_cfg/core/generation.py +15 -10
- django_cfg/models/cloudflare.py +316 -0
- django_cfg/models/revolution.py +1 -1
- django_cfg/models/tasks.py +1 -1
- django_cfg/modules/base.py +12 -5
- django_cfg/modules/django_unfold/dashboard.py +16 -1
- {django_cfg-1.2.15.dist-info → django_cfg-1.2.17.dist-info}/METADATA +2 -1
- {django_cfg-1.2.15.dist-info → django_cfg-1.2.17.dist-info}/RECORD +61 -13
- {django_cfg-1.2.15.dist-info → django_cfg-1.2.17.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.15.dist-info → django_cfg-1.2.17.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.15.dist-info → django_cfg-1.2.17.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,419 @@
|
|
1
|
+
"""
|
2
|
+
Multi-site management models.
|
3
|
+
|
4
|
+
Models for managing multiple Cloudflare sites with ORM-like interface.
|
5
|
+
Following CRITICAL_REQUIREMENTS - proper typing, no raw Dict usage.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from django.db import models
|
9
|
+
from django.contrib.auth import get_user_model
|
10
|
+
from django.core.validators import URLValidator
|
11
|
+
from django.core.exceptions import ValidationError
|
12
|
+
from django.utils import timezone
|
13
|
+
from typing import Optional, List, Dict, Any
|
14
|
+
from datetime import timedelta
|
15
|
+
import re
|
16
|
+
|
17
|
+
User = get_user_model()
|
18
|
+
|
19
|
+
|
20
|
+
class CloudflareSite(models.Model):
|
21
|
+
"""
|
22
|
+
Individual Cloudflare site configuration.
|
23
|
+
|
24
|
+
Represents a single site/domain managed through Cloudflare with
|
25
|
+
maintenance mode capabilities and monitoring.
|
26
|
+
"""
|
27
|
+
|
28
|
+
class SiteEnvironment(models.TextChoices):
|
29
|
+
"""Site environment types."""
|
30
|
+
PRODUCTION = "production", "Production"
|
31
|
+
STAGING = "staging", "Staging"
|
32
|
+
DEVELOPMENT = "development", "Development"
|
33
|
+
TESTING = "testing", "Testing"
|
34
|
+
|
35
|
+
class SiteStatus(models.TextChoices):
|
36
|
+
"""Site operational status."""
|
37
|
+
ACTIVE = "active", "Active"
|
38
|
+
MAINTENANCE = "maintenance", "Under Maintenance"
|
39
|
+
OFFLINE = "offline", "Offline"
|
40
|
+
UNKNOWN = "unknown", "Unknown"
|
41
|
+
|
42
|
+
# === Basic Information ===
|
43
|
+
name = models.CharField(
|
44
|
+
max_length=100,
|
45
|
+
help_text="Friendly site name for identification"
|
46
|
+
)
|
47
|
+
domain = models.CharField(
|
48
|
+
max_length=253,
|
49
|
+
unique=True,
|
50
|
+
help_text="Domain name (e.g., example.com)"
|
51
|
+
)
|
52
|
+
description = models.TextField(
|
53
|
+
blank=True,
|
54
|
+
help_text="Site description or notes"
|
55
|
+
)
|
56
|
+
|
57
|
+
# === Cloudflare Configuration ===
|
58
|
+
zone_id = models.CharField(
|
59
|
+
max_length=32,
|
60
|
+
unique=True,
|
61
|
+
help_text="Cloudflare Zone ID"
|
62
|
+
)
|
63
|
+
account_id = models.CharField(
|
64
|
+
max_length=32,
|
65
|
+
help_text="Cloudflare Account ID"
|
66
|
+
)
|
67
|
+
api_token = models.CharField(
|
68
|
+
max_length=200,
|
69
|
+
help_text="Site-specific or account API token"
|
70
|
+
)
|
71
|
+
|
72
|
+
# === Site Classification ===
|
73
|
+
environment = models.CharField(
|
74
|
+
max_length=20,
|
75
|
+
choices=SiteEnvironment.choices,
|
76
|
+
default=SiteEnvironment.PRODUCTION,
|
77
|
+
help_text="Site environment type"
|
78
|
+
)
|
79
|
+
project = models.CharField(
|
80
|
+
max_length=100,
|
81
|
+
blank=True,
|
82
|
+
help_text="Project or client name"
|
83
|
+
)
|
84
|
+
tags = models.JSONField(
|
85
|
+
default=list,
|
86
|
+
blank=True,
|
87
|
+
help_text="Custom tags for filtering and organization"
|
88
|
+
)
|
89
|
+
|
90
|
+
# === Current State ===
|
91
|
+
current_status = models.CharField(
|
92
|
+
max_length=20,
|
93
|
+
choices=SiteStatus.choices,
|
94
|
+
default=SiteStatus.UNKNOWN,
|
95
|
+
help_text="Current operational status"
|
96
|
+
)
|
97
|
+
maintenance_active = models.BooleanField(
|
98
|
+
default=False,
|
99
|
+
help_text="Whether maintenance mode is currently active"
|
100
|
+
)
|
101
|
+
last_status_check = models.DateTimeField(
|
102
|
+
null=True,
|
103
|
+
blank=True,
|
104
|
+
help_text="When status was last checked"
|
105
|
+
)
|
106
|
+
|
107
|
+
# === Maintenance Configuration ===
|
108
|
+
worker_name = models.CharField(
|
109
|
+
max_length=100,
|
110
|
+
default="maintenance-mode",
|
111
|
+
help_text="Cloudflare Worker name for maintenance mode"
|
112
|
+
)
|
113
|
+
maintenance_template = models.CharField(
|
114
|
+
max_length=50,
|
115
|
+
default="modern",
|
116
|
+
help_text="Maintenance page template"
|
117
|
+
)
|
118
|
+
custom_maintenance_message = models.TextField(
|
119
|
+
blank=True,
|
120
|
+
help_text="Custom maintenance message for this site"
|
121
|
+
)
|
122
|
+
|
123
|
+
# === Monitoring Settings ===
|
124
|
+
monitoring_enabled = models.BooleanField(
|
125
|
+
default=True,
|
126
|
+
help_text="Enable health monitoring for this site"
|
127
|
+
)
|
128
|
+
health_check_url = models.URLField(
|
129
|
+
blank=True,
|
130
|
+
help_text="Custom health check URL (defaults to domain/health/)"
|
131
|
+
)
|
132
|
+
check_interval = models.PositiveIntegerField(
|
133
|
+
default=300, # 5 minutes
|
134
|
+
help_text="Health check interval in seconds"
|
135
|
+
)
|
136
|
+
|
137
|
+
# === Access Control ===
|
138
|
+
owner = models.ForeignKey(
|
139
|
+
User,
|
140
|
+
on_delete=models.CASCADE,
|
141
|
+
related_name='owned_sites',
|
142
|
+
help_text="Site owner"
|
143
|
+
)
|
144
|
+
allowed_users = models.ManyToManyField(
|
145
|
+
User,
|
146
|
+
blank=True,
|
147
|
+
related_name='accessible_sites',
|
148
|
+
help_text="Users with access to manage this site"
|
149
|
+
)
|
150
|
+
|
151
|
+
# === Metadata ===
|
152
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
153
|
+
updated_at = models.DateTimeField(auto_now=True)
|
154
|
+
last_maintenance_at = models.DateTimeField(
|
155
|
+
null=True,
|
156
|
+
blank=True,
|
157
|
+
help_text="When maintenance was last activated"
|
158
|
+
)
|
159
|
+
|
160
|
+
# === Custom Manager ===
|
161
|
+
from ..managers.sites import CloudflareSiteManager
|
162
|
+
objects = CloudflareSiteManager()
|
163
|
+
|
164
|
+
class Meta:
|
165
|
+
ordering = ['name']
|
166
|
+
verbose_name = "Cloudflare Site"
|
167
|
+
verbose_name_plural = "Cloudflare Sites"
|
168
|
+
indexes = [
|
169
|
+
models.Index(fields=['owner', 'environment']),
|
170
|
+
models.Index(fields=['project', 'environment']),
|
171
|
+
models.Index(fields=['current_status']),
|
172
|
+
models.Index(fields=['maintenance_active']),
|
173
|
+
models.Index(fields=['domain']),
|
174
|
+
]
|
175
|
+
|
176
|
+
def __str__(self) -> str:
|
177
|
+
status_emoji = {
|
178
|
+
self.SiteStatus.ACTIVE: "🟢",
|
179
|
+
self.SiteStatus.MAINTENANCE: "🔧",
|
180
|
+
self.SiteStatus.OFFLINE: "🔴",
|
181
|
+
self.SiteStatus.UNKNOWN: "❓"
|
182
|
+
}.get(self.current_status, "❓")
|
183
|
+
|
184
|
+
return f"{status_emoji} {self.name} ({self.domain})"
|
185
|
+
|
186
|
+
@property
|
187
|
+
def is_production(self) -> bool:
|
188
|
+
"""Check if this is a production site."""
|
189
|
+
return self.environment == self.SiteEnvironment.PRODUCTION
|
190
|
+
|
191
|
+
@property
|
192
|
+
def maintenance_duration(self) -> Optional[timedelta]:
|
193
|
+
"""Calculate current maintenance duration."""
|
194
|
+
if self.maintenance_active and self.last_maintenance_at:
|
195
|
+
return timezone.now() - self.last_maintenance_at
|
196
|
+
return None
|
197
|
+
|
198
|
+
@property
|
199
|
+
def health_check_endpoint(self) -> str:
|
200
|
+
"""Get health check URL for this site."""
|
201
|
+
if self.health_check_url:
|
202
|
+
return self.health_check_url
|
203
|
+
|
204
|
+
# Default health check endpoint
|
205
|
+
protocol = "https" if self.is_production else "http"
|
206
|
+
return f"{protocol}://{self.domain}/health/"
|
207
|
+
|
208
|
+
def has_tag(self, tag: str) -> bool:
|
209
|
+
"""Check if site has specific tag."""
|
210
|
+
return tag in (self.tags or [])
|
211
|
+
|
212
|
+
def add_tag(self, tag: str) -> None:
|
213
|
+
"""Add tag to site."""
|
214
|
+
if not self.tags:
|
215
|
+
self.tags = []
|
216
|
+
if tag not in self.tags:
|
217
|
+
self.tags.append(tag)
|
218
|
+
self.save(update_fields=['tags', 'updated_at'])
|
219
|
+
|
220
|
+
def remove_tag(self, tag: str) -> None:
|
221
|
+
"""Remove tag from site."""
|
222
|
+
if self.tags and tag in self.tags:
|
223
|
+
self.tags.remove(tag)
|
224
|
+
self.save(update_fields=['tags', 'updated_at'])
|
225
|
+
|
226
|
+
def enable_maintenance(self, user: Optional[User] = None) -> None:
|
227
|
+
"""Enable maintenance mode for this site."""
|
228
|
+
self.maintenance_active = True
|
229
|
+
self.current_status = self.SiteStatus.MAINTENANCE
|
230
|
+
self.last_maintenance_at = timezone.now()
|
231
|
+
self.save(update_fields=[
|
232
|
+
'maintenance_active',
|
233
|
+
'current_status',
|
234
|
+
'last_maintenance_at',
|
235
|
+
'updated_at'
|
236
|
+
])
|
237
|
+
|
238
|
+
def disable_maintenance(self) -> None:
|
239
|
+
"""Disable maintenance mode for this site."""
|
240
|
+
self.maintenance_active = False
|
241
|
+
self.current_status = self.SiteStatus.ACTIVE
|
242
|
+
self.save(update_fields=[
|
243
|
+
'maintenance_active',
|
244
|
+
'current_status',
|
245
|
+
'updated_at'
|
246
|
+
])
|
247
|
+
|
248
|
+
def update_status(self, status: str) -> None:
|
249
|
+
"""Update site status."""
|
250
|
+
self.current_status = status
|
251
|
+
self.last_status_check = timezone.now()
|
252
|
+
self.save(update_fields=[
|
253
|
+
'current_status',
|
254
|
+
'last_status_check',
|
255
|
+
'updated_at'
|
256
|
+
])
|
257
|
+
|
258
|
+
def clean(self) -> None:
|
259
|
+
"""Validate model data."""
|
260
|
+
super().clean()
|
261
|
+
|
262
|
+
# Validate domain format
|
263
|
+
domain_pattern = re.compile(
|
264
|
+
r'^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?'
|
265
|
+
r'(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$'
|
266
|
+
)
|
267
|
+
if not domain_pattern.match(self.domain):
|
268
|
+
raise ValidationError({'domain': 'Invalid domain format'})
|
269
|
+
|
270
|
+
# Validate zone_id format (Cloudflare zone IDs are 32 chars)
|
271
|
+
if len(self.zone_id) != 32:
|
272
|
+
raise ValidationError({'zone_id': 'Zone ID must be 32 characters'})
|
273
|
+
|
274
|
+
# Validate worker name
|
275
|
+
worker_pattern = re.compile(r'^[a-zA-Z0-9\-_]+$')
|
276
|
+
if not worker_pattern.match(self.worker_name):
|
277
|
+
raise ValidationError({
|
278
|
+
'worker_name': 'Worker name can only contain letters, numbers, hyphens, and underscores'
|
279
|
+
})
|
280
|
+
|
281
|
+
# Validate check interval
|
282
|
+
if self.check_interval < 30:
|
283
|
+
raise ValidationError({'check_interval': 'Check interval must be at least 30 seconds'})
|
284
|
+
|
285
|
+
|
286
|
+
class SiteGroup(models.Model):
|
287
|
+
"""
|
288
|
+
Logical grouping of sites for bulk operations.
|
289
|
+
|
290
|
+
Allows organizing sites by project, client, environment, or any other
|
291
|
+
criteria for efficient bulk maintenance operations.
|
292
|
+
"""
|
293
|
+
|
294
|
+
# === Basic Information ===
|
295
|
+
name = models.CharField(
|
296
|
+
max_length=100,
|
297
|
+
help_text="Group name"
|
298
|
+
)
|
299
|
+
description = models.TextField(
|
300
|
+
blank=True,
|
301
|
+
help_text="Group description"
|
302
|
+
)
|
303
|
+
|
304
|
+
# === Relationships ===
|
305
|
+
sites = models.ManyToManyField(
|
306
|
+
CloudflareSite,
|
307
|
+
related_name='groups',
|
308
|
+
help_text="Sites in this group"
|
309
|
+
)
|
310
|
+
owner = models.ForeignKey(
|
311
|
+
User,
|
312
|
+
on_delete=models.CASCADE,
|
313
|
+
help_text="Group owner"
|
314
|
+
)
|
315
|
+
|
316
|
+
# === Group Settings ===
|
317
|
+
auto_maintenance_rules = models.JSONField(
|
318
|
+
default=dict,
|
319
|
+
blank=True,
|
320
|
+
help_text="Automatic maintenance rules for this group"
|
321
|
+
)
|
322
|
+
notification_settings = models.JSONField(
|
323
|
+
default=dict,
|
324
|
+
blank=True,
|
325
|
+
help_text="Notification preferences for group events"
|
326
|
+
)
|
327
|
+
|
328
|
+
# === Metadata ===
|
329
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
330
|
+
updated_at = models.DateTimeField(auto_now=True)
|
331
|
+
|
332
|
+
# === Custom Manager ===
|
333
|
+
from ..managers.sites import SiteGroupManager
|
334
|
+
objects = SiteGroupManager()
|
335
|
+
|
336
|
+
class Meta:
|
337
|
+
ordering = ['name']
|
338
|
+
unique_together = ['name', 'owner']
|
339
|
+
verbose_name = "Site Group"
|
340
|
+
verbose_name_plural = "Site Groups"
|
341
|
+
indexes = [
|
342
|
+
models.Index(fields=['owner', 'name']),
|
343
|
+
]
|
344
|
+
|
345
|
+
def __str__(self) -> str:
|
346
|
+
return f"{self.name} ({self.sites.count()} sites)"
|
347
|
+
|
348
|
+
@property
|
349
|
+
def sites_count(self) -> int:
|
350
|
+
"""Count of sites in this group."""
|
351
|
+
return self.sites.count()
|
352
|
+
|
353
|
+
@property
|
354
|
+
def active_sites_count(self) -> int:
|
355
|
+
"""Count of active sites in this group."""
|
356
|
+
return self.sites.filter(current_status=CloudflareSite.SiteStatus.ACTIVE).count()
|
357
|
+
|
358
|
+
@property
|
359
|
+
def maintenance_sites_count(self) -> int:
|
360
|
+
"""Count of sites in maintenance in this group."""
|
361
|
+
return self.sites.filter(maintenance_active=True).count()
|
362
|
+
|
363
|
+
def get_sites_by_environment(self, environment: str) -> models.QuerySet:
|
364
|
+
"""Get sites in this group by environment."""
|
365
|
+
return self.sites.filter(environment=environment)
|
366
|
+
|
367
|
+
def get_sites_by_status(self, status: str) -> models.QuerySet:
|
368
|
+
"""Get sites in this group by status."""
|
369
|
+
return self.sites.filter(current_status=status)
|
370
|
+
|
371
|
+
def add_sites(self, sites: List[CloudflareSite]) -> None:
|
372
|
+
"""Add multiple sites to this group."""
|
373
|
+
self.sites.add(*sites)
|
374
|
+
|
375
|
+
def remove_sites(self, sites: List[CloudflareSite]) -> None:
|
376
|
+
"""Remove multiple sites from this group."""
|
377
|
+
self.sites.remove(*sites)
|
378
|
+
|
379
|
+
def enable_maintenance_for_all(self, user: Optional[User] = None) -> Dict[str, Any]:
|
380
|
+
"""Enable maintenance for all sites in group."""
|
381
|
+
results = {
|
382
|
+
'total': 0,
|
383
|
+
'successful': [],
|
384
|
+
'failed': []
|
385
|
+
}
|
386
|
+
|
387
|
+
for site in self.sites.all():
|
388
|
+
results['total'] += 1
|
389
|
+
try:
|
390
|
+
site.enable_maintenance(user)
|
391
|
+
results['successful'].append(site.domain)
|
392
|
+
except Exception as e:
|
393
|
+
results['failed'].append({
|
394
|
+
'site': site.domain,
|
395
|
+
'error': str(e)
|
396
|
+
})
|
397
|
+
|
398
|
+
return results
|
399
|
+
|
400
|
+
def disable_maintenance_for_all(self) -> Dict[str, Any]:
|
401
|
+
"""Disable maintenance for all sites in group."""
|
402
|
+
results = {
|
403
|
+
'total': 0,
|
404
|
+
'successful': [],
|
405
|
+
'failed': []
|
406
|
+
}
|
407
|
+
|
408
|
+
for site in self.sites.filter(maintenance_active=True):
|
409
|
+
results['total'] += 1
|
410
|
+
try:
|
411
|
+
site.disable_maintenance()
|
412
|
+
results['successful'].append(site.domain)
|
413
|
+
except Exception as e:
|
414
|
+
results['failed'].append({
|
415
|
+
'site': site.domain,
|
416
|
+
'error': str(e)
|
417
|
+
})
|
418
|
+
|
419
|
+
return results
|
@@ -0,0 +1,60 @@
|
|
1
|
+
"""
|
2
|
+
Maintenance app serializers.
|
3
|
+
|
4
|
+
Decomposed serializers for better organization and maintainability.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .base import UserSerializer, APIResponseSerializer
|
8
|
+
from .sites import (
|
9
|
+
CloudflareSiteSerializer, CloudflareSiteCreateSerializer, CloudflareSiteListSerializer,
|
10
|
+
SiteGroupSerializer, SiteGroupCreateSerializer
|
11
|
+
)
|
12
|
+
from .events import (
|
13
|
+
MaintenanceEventSerializer, MaintenanceEventCreateSerializer, MaintenanceEventListSerializer,
|
14
|
+
MaintenanceEventUpdateSerializer, MaintenanceLogSerializer
|
15
|
+
)
|
16
|
+
from .monitoring import (
|
17
|
+
MonitoringTargetSerializer, MonitoringTargetCreateSerializer, HealthCheckResultSerializer
|
18
|
+
)
|
19
|
+
from .deployments import (
|
20
|
+
CloudflareDeploymentSerializer, CloudflareDeploymentListSerializer
|
21
|
+
)
|
22
|
+
from .actions import (
|
23
|
+
BulkMaintenanceActionSerializer, SiteFilterSerializer, SiteGroupActionSerializer,
|
24
|
+
BulkOperationResultSerializer
|
25
|
+
)
|
26
|
+
|
27
|
+
__all__ = [
|
28
|
+
# Base
|
29
|
+
'UserSerializer',
|
30
|
+
'APIResponseSerializer',
|
31
|
+
'BulkOperationResultSerializer',
|
32
|
+
|
33
|
+
# Sites
|
34
|
+
'CloudflareSiteSerializer',
|
35
|
+
'CloudflareSiteCreateSerializer',
|
36
|
+
'CloudflareSiteListSerializer',
|
37
|
+
'SiteGroupSerializer',
|
38
|
+
'SiteGroupCreateSerializer',
|
39
|
+
|
40
|
+
# Events
|
41
|
+
'MaintenanceEventSerializer',
|
42
|
+
'MaintenanceEventCreateSerializer',
|
43
|
+
'MaintenanceEventListSerializer',
|
44
|
+
'MaintenanceEventUpdateSerializer',
|
45
|
+
'MaintenanceLogSerializer',
|
46
|
+
|
47
|
+
# Monitoring
|
48
|
+
'MonitoringTargetSerializer',
|
49
|
+
'MonitoringTargetCreateSerializer',
|
50
|
+
'HealthCheckResultSerializer',
|
51
|
+
|
52
|
+
# Deployments
|
53
|
+
'CloudflareDeploymentSerializer',
|
54
|
+
'CloudflareDeploymentListSerializer',
|
55
|
+
|
56
|
+
# Actions
|
57
|
+
'BulkMaintenanceActionSerializer',
|
58
|
+
'SiteFilterSerializer',
|
59
|
+
'SiteGroupActionSerializer',
|
60
|
+
]
|