proxsync 2.0.0__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.
Files changed (59) hide show
  1. config.py +337 -0
  2. pbs_sync.py +244 -0
  3. proxsync-2.0.0.dist-info/METADATA +468 -0
  4. proxsync-2.0.0.dist-info/RECORD +59 -0
  5. proxsync-2.0.0.dist-info/WHEEL +5 -0
  6. proxsync-2.0.0.dist-info/top_level.txt +5 -0
  7. pve_sync.py +1804 -0
  8. pve_sync_plugin/__init__.py +46 -0
  9. pve_sync_plugin/api/__init__.py +1 -0
  10. pve_sync_plugin/api/serializers.py +161 -0
  11. pve_sync_plugin/api/urls.py +27 -0
  12. pve_sync_plugin/api/views.py +94 -0
  13. pve_sync_plugin/apps.py +5 -0
  14. pve_sync_plugin/choices.py +57 -0
  15. pve_sync_plugin/filtersets.py +137 -0
  16. pve_sync_plugin/forms.py +219 -0
  17. pve_sync_plugin/management/__init__.py +1 -0
  18. pve_sync_plugin/management/commands/__init__.py +1 -0
  19. pve_sync_plugin/management/commands/pve_sync.py +182 -0
  20. pve_sync_plugin/management/commands/run_scheduled_syncs.py +109 -0
  21. pve_sync_plugin/migrations/0001_initial.py +234 -0
  22. pve_sync_plugin/migrations/0002_pvepluginsettings.py +42 -0
  23. pve_sync_plugin/migrations/0003_netboxmodel_timestamps.py +148 -0
  24. pve_sync_plugin/migrations/0004_model_verbose_names.py +34 -0
  25. pve_sync_plugin/migrations/0005_align_netboxmodel_timestamps.py +111 -0
  26. pve_sync_plugin/migrations/0006_pbsserverconfig_and_more.py +124 -0
  27. pve_sync_plugin/migrations/0007_rename_verbose_names_to_proxmox_sync.py +26 -0
  28. pve_sync_plugin/migrations/0008_pbsserverconfig_sync_schedule.py +26 -0
  29. pve_sync_plugin/migrations/0009_add_every_3h_schedule.py +39 -0
  30. pve_sync_plugin/migrations/0010_pvedriftevent.py +62 -0
  31. pve_sync_plugin/migrations/0011_pveclusterconfig_notify_on_sync.py +19 -0
  32. pve_sync_plugin/migrations/0012_pvedriftevent_tags_and_index_renames.py +39 -0
  33. pve_sync_plugin/migrations/0013_pluginsettings_log_retention.py +19 -0
  34. pve_sync_plugin/migrations/__init__.py +1 -0
  35. pve_sync_plugin/models.py +461 -0
  36. pve_sync_plugin/navigation.py +94 -0
  37. pve_sync_plugin/signals.py +24 -0
  38. pve_sync_plugin/sync/__init__.py +8 -0
  39. pve_sync_plugin/sync/config_bridge.py +221 -0
  40. pve_sync_plugin/sync/engine.py +50 -0
  41. pve_sync_plugin/tables.py +278 -0
  42. pve_sync_plugin/tasks.py +440 -0
  43. pve_sync_plugin/template_content.py +44 -0
  44. pve_sync_plugin/templates/pve_sync/dashboard.html +400 -0
  45. pve_sync_plugin/templates/pve_sync/inc/vm_sync_button.html +7 -0
  46. pve_sync_plugin/templates/pve_sync/pbsserverconfig.html +69 -0
  47. pve_sync_plugin/templates/pve_sync/pvebackupstatus.html +27 -0
  48. pve_sync_plugin/templates/pve_sync/pveclusterconfig.html +52 -0
  49. pve_sync_plugin/templates/pve_sync/pvedriftevent.html +89 -0
  50. pve_sync_plugin/templates/pve_sync/pvesyncjob.html +197 -0
  51. pve_sync_plugin/templates/pve_sync/pvewebhookevent.html +42 -0
  52. pve_sync_plugin/templates/pve_sync/settings.html +79 -0
  53. pve_sync_plugin/templatetags/__init__.py +1 -0
  54. pve_sync_plugin/templatetags/pve_sync_tags.py +86 -0
  55. pve_sync_plugin/urls.py +186 -0
  56. pve_sync_plugin/utils.py +84 -0
  57. pve_sync_plugin/view_helpers.py +98 -0
  58. pve_sync_plugin/views.py +535 -0
  59. state_db.py +543 -0
@@ -0,0 +1,234 @@
1
+ # Generated for the PVE-NetBox Sync plugin.
2
+
3
+ from django.conf import settings
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ initial = True
11
+
12
+ dependencies = [
13
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14
+ ("dcim", "__latest__"),
15
+ ("virtualization", "__latest__"),
16
+ ]
17
+
18
+ operations = [
19
+ migrations.CreateModel(
20
+ name="PveClusterConfig",
21
+ fields=[
22
+ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
23
+ ("name", models.CharField(max_length=100, unique=True)),
24
+ ("description", models.TextField(blank=True)),
25
+ ("pve_host", models.CharField(max_length=200)),
26
+ ("pve_user", models.CharField(max_length=100)),
27
+ ("pve_token", models.CharField(max_length=100)),
28
+ ("pve_secret", models.CharField(max_length=200)),
29
+ ("pve_verify_ssl", models.BooleanField(default=False)),
30
+ ("enabled", models.BooleanField(default=True)),
31
+ (
32
+ "sync_schedule",
33
+ models.CharField(
34
+ choices=[
35
+ ("disabled", "Disabled"),
36
+ ("hourly", "Hourly"),
37
+ ("every_6h", "Every 6 hours"),
38
+ ("daily", "Daily"),
39
+ ("weekly", "Weekly"),
40
+ ],
41
+ default="disabled",
42
+ max_length=20,
43
+ ),
44
+ ),
45
+ ("last_sync", models.DateTimeField(blank=True, null=True)),
46
+ ("last_sync_status", models.CharField(blank=True, max_length=20)),
47
+ ("created_at", models.DateTimeField(auto_now_add=True)),
48
+ ("updated_at", models.DateTimeField(auto_now=True)),
49
+ (
50
+ "netbox_cluster",
51
+ models.ForeignKey(
52
+ blank=True,
53
+ null=True,
54
+ on_delete=django.db.models.deletion.SET_NULL,
55
+ related_name="pve_sync_config",
56
+ to="virtualization.cluster",
57
+ ),
58
+ ),
59
+ (
60
+ "netbox_cluster_type",
61
+ models.ForeignKey(
62
+ blank=True,
63
+ null=True,
64
+ on_delete=django.db.models.deletion.SET_NULL,
65
+ to="virtualization.clustertype",
66
+ ),
67
+ ),
68
+ (
69
+ "netbox_site",
70
+ models.ForeignKey(
71
+ blank=True,
72
+ null=True,
73
+ on_delete=django.db.models.deletion.SET_NULL,
74
+ related_name="pve_clusters",
75
+ to="dcim.site",
76
+ ),
77
+ ),
78
+ ],
79
+ options={"ordering": ["name"]},
80
+ ),
81
+ migrations.CreateModel(
82
+ name="PveSyncJob",
83
+ fields=[
84
+ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
85
+ ("cluster_name", models.CharField(default="default", help_text="同步的集群名称", max_length=100)),
86
+ (
87
+ "status",
88
+ models.CharField(
89
+ choices=[
90
+ ("pending", "Pending"),
91
+ ("running", "Running"),
92
+ ("success", "Success"),
93
+ ("failed", "Failed"),
94
+ ("partial", "Partial Success"),
95
+ ],
96
+ default="pending",
97
+ max_length=20,
98
+ ),
99
+ ),
100
+ ("start_time", models.DateTimeField(auto_now_add=True)),
101
+ ("end_time", models.DateTimeField(blank=True, null=True)),
102
+ ("total_vms", models.IntegerField(default=0)),
103
+ ("success_vms", models.IntegerField(default=0)),
104
+ ("failed_vms", models.IntegerField(default=0)),
105
+ ("nodes_offline", models.IntegerField(default=0)),
106
+ ("config_drifts", models.IntegerField(default=0)),
107
+ ("tag_changes", models.IntegerField(default=0)),
108
+ ("resource_alerts", models.IntegerField(default=0)),
109
+ ("details", models.JSONField(blank=True, default=dict)),
110
+ (
111
+ "trigger",
112
+ models.CharField(
113
+ choices=[
114
+ ("manual", "Manual"),
115
+ ("scheduled", "Scheduled"),
116
+ ("webhook", "Webhook"),
117
+ ("api", "API Call"),
118
+ ],
119
+ default="manual",
120
+ max_length=20,
121
+ ),
122
+ ),
123
+ (
124
+ "triggered_by",
125
+ models.ForeignKey(
126
+ blank=True,
127
+ null=True,
128
+ on_delete=django.db.models.deletion.SET_NULL,
129
+ related_name="pve_sync_jobs",
130
+ to=settings.AUTH_USER_MODEL,
131
+ ),
132
+ ),
133
+ ],
134
+ options={"ordering": ["-start_time"]},
135
+ ),
136
+ migrations.CreateModel(
137
+ name="PveBackupStatus",
138
+ fields=[
139
+ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
140
+ ("last_backup", models.DateTimeField(blank=True, null=True)),
141
+ ("backup_size", models.BigIntegerField(blank=True, help_text="字节", null=True)),
142
+ (
143
+ "backup_status",
144
+ models.CharField(
145
+ choices=[
146
+ ("success", "Success"),
147
+ ("failed", "Failed"),
148
+ ("running", "Running"),
149
+ ("unknown", "Unknown"),
150
+ ],
151
+ default="unknown",
152
+ max_length=20,
153
+ ),
154
+ ),
155
+ ("backup_path", models.CharField(blank=True, max_length=500)),
156
+ ("next_backup", models.DateTimeField(blank=True, null=True)),
157
+ ("pve_backup_id", models.CharField(blank=True, max_length=100, null=True, unique=True)),
158
+ ("updated_at", models.DateTimeField(auto_now=True)),
159
+ (
160
+ "vm",
161
+ models.OneToOneField(
162
+ on_delete=django.db.models.deletion.CASCADE,
163
+ related_name="pve_backup_status",
164
+ to="virtualization.virtualmachine",
165
+ ),
166
+ ),
167
+ ],
168
+ options={
169
+ "verbose_name": "PVE Backup Status",
170
+ "verbose_name_plural": "PVE Backup Statuses",
171
+ },
172
+ ),
173
+ migrations.CreateModel(
174
+ name="PveWebhookEvent",
175
+ fields=[
176
+ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
177
+ (
178
+ "event_type",
179
+ models.CharField(
180
+ choices=[
181
+ ("vm-started", "VM Started"),
182
+ ("vm-stopped", "VM Stopped"),
183
+ ("vm-migrated", "VM Migrated"),
184
+ ("node-online", "Node Online"),
185
+ ("node-offline", "Node Offline"),
186
+ ("backup-done", "Backup Completed"),
187
+ ("backup-failed", "Backup Failed"),
188
+ ("configuration-change", "Configuration Change"),
189
+ ],
190
+ max_length=50,
191
+ ),
192
+ ),
193
+ ("node", models.CharField(blank=True, max_length=100, null=True)),
194
+ ("vmid", models.IntegerField(blank=True, null=True)),
195
+ ("vm_name", models.CharField(blank=True, max_length=200, null=True)),
196
+ ("raw_data", models.JSONField(default=dict)),
197
+ ("processed", models.BooleanField(default=False)),
198
+ ("processed_at", models.DateTimeField(blank=True, null=True)),
199
+ ("processing_error", models.TextField(blank=True)),
200
+ ("received_at", models.DateTimeField(auto_now_add=True)),
201
+ (
202
+ "sync_job",
203
+ models.ForeignKey(
204
+ blank=True,
205
+ null=True,
206
+ on_delete=django.db.models.deletion.SET_NULL,
207
+ related_name="webhook_events",
208
+ to="pve_sync_plugin.pvesyncjob",
209
+ ),
210
+ ),
211
+ ],
212
+ options={"ordering": ["-received_at"]},
213
+ ),
214
+ migrations.AddIndex(
215
+ model_name="pvesyncjob",
216
+ index=models.Index(fields=["status", "start_time"], name="pve_sync_pv_status_1b8f8d_idx"),
217
+ ),
218
+ migrations.AddIndex(
219
+ model_name="pvesyncjob",
220
+ index=models.Index(fields=["cluster_name"], name="pve_sync_pv_cluster_c7bb8f_idx"),
221
+ ),
222
+ migrations.AddIndex(
223
+ model_name="pvewebhookevent",
224
+ index=models.Index(fields=["event_type", "processed"], name="pve_sync_pv_event_t_5a9362_idx"),
225
+ ),
226
+ migrations.AddIndex(
227
+ model_name="pvewebhookevent",
228
+ index=models.Index(fields=["vmid"], name="pve_sync_pv_vmid_90e5c1_idx"),
229
+ ),
230
+ migrations.AddIndex(
231
+ model_name="pvewebhookevent",
232
+ index=models.Index(fields=["received_at"], name="pve_sync_pv_receive_ce4cf2_idx"),
233
+ ),
234
+ ]
@@ -0,0 +1,42 @@
1
+ # Generated for editable PVE Sync plugin settings.
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("pve_sync_plugin", "0001_initial"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name="PvePluginSettings",
15
+ fields=[
16
+ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
17
+ ("pve_api_host", models.CharField(blank=True, max_length=200)),
18
+ ("pve_api_user", models.CharField(default="root@pam", max_length=100)),
19
+ ("pve_api_token", models.CharField(blank=True, max_length=100)),
20
+ ("pve_api_secret", models.CharField(blank=True, max_length=200)),
21
+ ("pve_api_verify_ssl", models.BooleanField(default=False)),
22
+ ("netbox_url", models.URLField(blank=True)),
23
+ ("netbox_token", models.CharField(blank=True, max_length=200)),
24
+ ("telegram_bot_token", models.CharField(blank=True, max_length=200)),
25
+ ("telegram_chat_id", models.CharField(blank=True, max_length=100)),
26
+ ("webhook_secret", models.CharField(blank=True, max_length=200)),
27
+ ("default_cluster_name", models.CharField(default="default", max_length=100)),
28
+ ("default_netbox_cluster", models.CharField(default="Proxmox Cluster", max_length=100)),
29
+ ("default_site", models.CharField(default="Main Datacenter", max_length=100)),
30
+ ("default_cluster_type", models.CharField(default="Proxmox", max_length=100)),
31
+ ("default_node_role", models.CharField(default="PVE", max_length=100)),
32
+ ("default_node_type", models.CharField(default="Standard Server", max_length=100)),
33
+ ("state_db_path", models.CharField(default="/var/lib/netbox/pve-sync-state.db", max_length=500)),
34
+ ("enable_backup_sync", models.BooleanField(default=True)),
35
+ ("updated_at", models.DateTimeField(auto_now=True)),
36
+ ],
37
+ options={
38
+ "verbose_name": "PVE Sync Settings",
39
+ "verbose_name_plural": "PVE Sync Settings",
40
+ },
41
+ ),
42
+ ]
@@ -0,0 +1,148 @@
1
+ from django.db import migrations, models
2
+ from django.utils import timezone
3
+
4
+ try:
5
+ from utilities.json import CustomFieldJSONEncoder
6
+ except ModuleNotFoundError:
7
+ CustomFieldJSONEncoder = None
8
+
9
+
10
+ class Migration(migrations.Migration):
11
+
12
+ dependencies = [
13
+ ("pve_sync_plugin", "0002_pvepluginsettings"),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.RenameField(
18
+ model_name="pveclusterconfig",
19
+ old_name="created_at",
20
+ new_name="created",
21
+ ),
22
+ migrations.RenameField(
23
+ model_name="pveclusterconfig",
24
+ old_name="updated_at",
25
+ new_name="last_updated",
26
+ ),
27
+ migrations.AddField(
28
+ model_name="pvesyncjob",
29
+ name="created",
30
+ field=models.DateTimeField(default=timezone.now),
31
+ preserve_default=False,
32
+ ),
33
+ migrations.AddField(
34
+ model_name="pvesyncjob",
35
+ name="last_updated",
36
+ field=models.DateTimeField(default=timezone.now),
37
+ preserve_default=False,
38
+ ),
39
+ migrations.AddField(
40
+ model_name="pvewebhookevent",
41
+ name="created",
42
+ field=models.DateTimeField(default=timezone.now),
43
+ preserve_default=False,
44
+ ),
45
+ migrations.AddField(
46
+ model_name="pvewebhookevent",
47
+ name="last_updated",
48
+ field=models.DateTimeField(default=timezone.now),
49
+ preserve_default=False,
50
+ ),
51
+ migrations.AddField(
52
+ model_name="pvebackupstatus",
53
+ name="created",
54
+ field=models.DateTimeField(default=timezone.now),
55
+ preserve_default=False,
56
+ ),
57
+ migrations.RenameField(
58
+ model_name="pvebackupstatus",
59
+ old_name="updated_at",
60
+ new_name="last_updated",
61
+ ),
62
+ migrations.AddField(
63
+ model_name="pvepluginsettings",
64
+ name="created",
65
+ field=models.DateTimeField(default=timezone.now),
66
+ preserve_default=False,
67
+ ),
68
+ migrations.RenameField(
69
+ model_name="pvepluginsettings",
70
+ old_name="updated_at",
71
+ new_name="last_updated",
72
+ ),
73
+ migrations.AlterField(
74
+ model_name="pveclusterconfig",
75
+ name="created",
76
+ field=models.DateTimeField(auto_now_add=True, null=True),
77
+ ),
78
+ migrations.AlterField(
79
+ model_name="pveclusterconfig",
80
+ name="last_updated",
81
+ field=models.DateTimeField(auto_now=True, null=True),
82
+ ),
83
+ migrations.AlterField(
84
+ model_name="pvesyncjob",
85
+ name="created",
86
+ field=models.DateTimeField(auto_now_add=True, null=True),
87
+ ),
88
+ migrations.AlterField(
89
+ model_name="pvesyncjob",
90
+ name="last_updated",
91
+ field=models.DateTimeField(auto_now=True, null=True),
92
+ ),
93
+ migrations.AlterField(
94
+ model_name="pvewebhookevent",
95
+ name="created",
96
+ field=models.DateTimeField(auto_now_add=True, null=True),
97
+ ),
98
+ migrations.AlterField(
99
+ model_name="pvewebhookevent",
100
+ name="last_updated",
101
+ field=models.DateTimeField(auto_now=True, null=True),
102
+ ),
103
+ migrations.AlterField(
104
+ model_name="pvebackupstatus",
105
+ name="created",
106
+ field=models.DateTimeField(auto_now_add=True, null=True),
107
+ ),
108
+ migrations.AlterField(
109
+ model_name="pvebackupstatus",
110
+ name="last_updated",
111
+ field=models.DateTimeField(auto_now=True, null=True),
112
+ ),
113
+ migrations.AlterField(
114
+ model_name="pvepluginsettings",
115
+ name="created",
116
+ field=models.DateTimeField(auto_now_add=True, null=True),
117
+ ),
118
+ migrations.AlterField(
119
+ model_name="pvepluginsettings",
120
+ name="last_updated",
121
+ field=models.DateTimeField(auto_now=True, null=True),
122
+ ),
123
+ migrations.AddField(
124
+ model_name="pveclusterconfig",
125
+ name="custom_field_data",
126
+ field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder),
127
+ ),
128
+ migrations.AddField(
129
+ model_name="pvesyncjob",
130
+ name="custom_field_data",
131
+ field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder),
132
+ ),
133
+ migrations.AddField(
134
+ model_name="pvewebhookevent",
135
+ name="custom_field_data",
136
+ field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder),
137
+ ),
138
+ migrations.AddField(
139
+ model_name="pvebackupstatus",
140
+ name="custom_field_data",
141
+ field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder),
142
+ ),
143
+ migrations.AddField(
144
+ model_name="pvepluginsettings",
145
+ name="custom_field_data",
146
+ field=models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder),
147
+ ),
148
+ ]
@@ -0,0 +1,34 @@
1
+ from django.db import migrations
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+ dependencies = [
6
+ ("pve_sync_plugin", "0003_netboxmodel_timestamps"),
7
+ ]
8
+
9
+ operations = [
10
+ migrations.AlterModelOptions(
11
+ name="pveclusterconfig",
12
+ options={
13
+ "ordering": ["name"],
14
+ "verbose_name": "PVE Cluster Config",
15
+ "verbose_name_plural": "PVE Cluster Configs",
16
+ },
17
+ ),
18
+ migrations.AlterModelOptions(
19
+ name="pvesyncjob",
20
+ options={
21
+ "ordering": ["-start_time"],
22
+ "verbose_name": "PVE Sync Job",
23
+ "verbose_name_plural": "PVE Sync Jobs",
24
+ },
25
+ ),
26
+ migrations.AlterModelOptions(
27
+ name="pvewebhookevent",
28
+ options={
29
+ "ordering": ["-received_at"],
30
+ "verbose_name": "PVE Webhook Event",
31
+ "verbose_name_plural": "PVE Webhook Events",
32
+ },
33
+ ),
34
+ ]
@@ -0,0 +1,111 @@
1
+ from django.db import migrations, models
2
+ from django.utils.translation import gettext_lazy as _
3
+
4
+
5
+ class Migration(migrations.Migration):
6
+ dependencies = [
7
+ ("pve_sync_plugin", "0004_model_verbose_names"),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AlterField(
12
+ model_name="pvebackupstatus",
13
+ name="created",
14
+ field=models.DateTimeField(
15
+ auto_now_add=True,
16
+ blank=True,
17
+ null=True,
18
+ verbose_name=_("created"),
19
+ ),
20
+ ),
21
+ migrations.AlterField(
22
+ model_name="pvebackupstatus",
23
+ name="last_updated",
24
+ field=models.DateTimeField(
25
+ auto_now=True,
26
+ blank=True,
27
+ null=True,
28
+ verbose_name=_("last updated"),
29
+ ),
30
+ ),
31
+ migrations.AlterField(
32
+ model_name="pveclusterconfig",
33
+ name="created",
34
+ field=models.DateTimeField(
35
+ auto_now_add=True,
36
+ blank=True,
37
+ null=True,
38
+ verbose_name=_("created"),
39
+ ),
40
+ ),
41
+ migrations.AlterField(
42
+ model_name="pveclusterconfig",
43
+ name="last_updated",
44
+ field=models.DateTimeField(
45
+ auto_now=True,
46
+ blank=True,
47
+ null=True,
48
+ verbose_name=_("last updated"),
49
+ ),
50
+ ),
51
+ migrations.AlterField(
52
+ model_name="pvepluginsettings",
53
+ name="created",
54
+ field=models.DateTimeField(
55
+ auto_now_add=True,
56
+ blank=True,
57
+ null=True,
58
+ verbose_name=_("created"),
59
+ ),
60
+ ),
61
+ migrations.AlterField(
62
+ model_name="pvepluginsettings",
63
+ name="last_updated",
64
+ field=models.DateTimeField(
65
+ auto_now=True,
66
+ blank=True,
67
+ null=True,
68
+ verbose_name=_("last updated"),
69
+ ),
70
+ ),
71
+ migrations.AlterField(
72
+ model_name="pvesyncjob",
73
+ name="created",
74
+ field=models.DateTimeField(
75
+ auto_now_add=True,
76
+ blank=True,
77
+ null=True,
78
+ verbose_name=_("created"),
79
+ ),
80
+ ),
81
+ migrations.AlterField(
82
+ model_name="pvesyncjob",
83
+ name="last_updated",
84
+ field=models.DateTimeField(
85
+ auto_now=True,
86
+ blank=True,
87
+ null=True,
88
+ verbose_name=_("last updated"),
89
+ ),
90
+ ),
91
+ migrations.AlterField(
92
+ model_name="pvewebhookevent",
93
+ name="created",
94
+ field=models.DateTimeField(
95
+ auto_now_add=True,
96
+ blank=True,
97
+ null=True,
98
+ verbose_name=_("created"),
99
+ ),
100
+ ),
101
+ migrations.AlterField(
102
+ model_name="pvewebhookevent",
103
+ name="last_updated",
104
+ field=models.DateTimeField(
105
+ auto_now=True,
106
+ blank=True,
107
+ null=True,
108
+ verbose_name=_("last updated"),
109
+ ),
110
+ ),
111
+ ]