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,124 @@
1
+ # Generated by Django 6.0.5 on 2026-06-13 13:52
2
+
3
+ import django.db.models.deletion
4
+ import netbox.models.deletion
5
+ import taggit.managers
6
+ import utilities.json
7
+ from django.db import migrations, models
8
+
9
+
10
+ class Migration(migrations.Migration):
11
+
12
+ dependencies = [
13
+ ('dcim', '0236_moduletype_component_counts'),
14
+ ('extras', '0138_customfieldchoiceset_choice_colors'),
15
+ ('pve_sync_plugin', '0005_align_netboxmodel_timestamps'),
16
+ ]
17
+
18
+ operations = [
19
+ migrations.CreateModel(
20
+ name='PbsServerConfig',
21
+ fields=[
22
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
23
+ ('created', models.DateTimeField(auto_now_add=True, null=True)),
24
+ ('last_updated', models.DateTimeField(auto_now=True, null=True)),
25
+ ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
26
+ ('name', models.CharField(max_length=100, unique=True)),
27
+ ('description', models.TextField(blank=True)),
28
+ ('pbs_host', models.CharField(max_length=200)),
29
+ ('pbs_token_name', models.CharField(max_length=100)),
30
+ ('pbs_token_secret', models.CharField(max_length=200)),
31
+ ('pbs_verify_ssl', models.BooleanField(default=False)),
32
+ ('pbs_node_name', models.CharField(max_length=100)),
33
+ ('enabled', models.BooleanField(default=True)),
34
+ ('last_sync', models.DateTimeField(blank=True, null=True)),
35
+ ('last_sync_status', models.CharField(blank=True, max_length=20)),
36
+ ],
37
+ options={
38
+ 'verbose_name': 'PBS Server Config',
39
+ 'verbose_name_plural': 'PBS Server Configs',
40
+ 'ordering': ['name'],
41
+ },
42
+ bases=(netbox.models.deletion.DeleteMixin, models.Model),
43
+ ),
44
+ migrations.RenameIndex(
45
+ model_name='pvesyncjob',
46
+ new_name='pve_sync_pl_status_75c10e_idx',
47
+ old_name='pve_sync_pv_status_1b8f8d_idx',
48
+ ),
49
+ migrations.RenameIndex(
50
+ model_name='pvesyncjob',
51
+ new_name='pve_sync_pl_cluster_f5f1cc_idx',
52
+ old_name='pve_sync_pv_cluster_c7bb8f_idx',
53
+ ),
54
+ migrations.RenameIndex(
55
+ model_name='pvewebhookevent',
56
+ new_name='pve_sync_pl_event_t_5411b8_idx',
57
+ old_name='pve_sync_pv_event_t_5a9362_idx',
58
+ ),
59
+ migrations.RenameIndex(
60
+ model_name='pvewebhookevent',
61
+ new_name='pve_sync_pl_vmid_e99644_idx',
62
+ old_name='pve_sync_pv_vmid_90e5c1_idx',
63
+ ),
64
+ migrations.RenameIndex(
65
+ model_name='pvewebhookevent',
66
+ new_name='pve_sync_pl_receive_1176ec_idx',
67
+ old_name='pve_sync_pv_receive_ce4cf2_idx',
68
+ ),
69
+ migrations.RemoveField(
70
+ model_name='pvepluginsettings',
71
+ name='pve_api_host',
72
+ ),
73
+ migrations.RemoveField(
74
+ model_name='pvepluginsettings',
75
+ name='pve_api_secret',
76
+ ),
77
+ migrations.RemoveField(
78
+ model_name='pvepluginsettings',
79
+ name='pve_api_token',
80
+ ),
81
+ migrations.RemoveField(
82
+ model_name='pvepluginsettings',
83
+ name='pve_api_user',
84
+ ),
85
+ migrations.RemoveField(
86
+ model_name='pvepluginsettings',
87
+ name='pve_api_verify_ssl',
88
+ ),
89
+ migrations.AddField(
90
+ model_name='pvebackupstatus',
91
+ name='tags',
92
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
93
+ ),
94
+ migrations.AddField(
95
+ model_name='pveclusterconfig',
96
+ name='tags',
97
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
98
+ ),
99
+ migrations.AddField(
100
+ model_name='pvepluginsettings',
101
+ name='tags',
102
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
103
+ ),
104
+ migrations.AddField(
105
+ model_name='pvesyncjob',
106
+ name='tags',
107
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
108
+ ),
109
+ migrations.AddField(
110
+ model_name='pvewebhookevent',
111
+ name='tags',
112
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
113
+ ),
114
+ migrations.AddField(
115
+ model_name='pbsserverconfig',
116
+ name='netbox_site',
117
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pbs_servers', to='dcim.site'),
118
+ ),
119
+ migrations.AddField(
120
+ model_name='pbsserverconfig',
121
+ name='tags',
122
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
123
+ ),
124
+ ]
@@ -0,0 +1,26 @@
1
+ from django.db import migrations
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+
6
+ dependencies = [
7
+ ("pve_sync_plugin", "0006_pbsserverconfig_and_more"),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AlterModelOptions(
12
+ name="pvesyncjob",
13
+ options={
14
+ "ordering": ["-start_time"],
15
+ "verbose_name": "Proxmox Sync Job",
16
+ "verbose_name_plural": "Proxmox Sync Jobs",
17
+ },
18
+ ),
19
+ migrations.AlterModelOptions(
20
+ name="pvepluginsettings",
21
+ options={
22
+ "verbose_name": "Proxmox Sync Settings",
23
+ "verbose_name_plural": "Proxmox Sync Settings",
24
+ },
25
+ ),
26
+ ]
@@ -0,0 +1,26 @@
1
+ from django.db import migrations, models
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+
6
+ dependencies = [
7
+ ('pve_sync_plugin', '0007_rename_verbose_names_to_proxmox_sync'),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AddField(
12
+ model_name='pbsserverconfig',
13
+ name='sync_schedule',
14
+ field=models.CharField(
15
+ choices=[
16
+ ('disabled', 'Disabled'),
17
+ ('hourly', 'Hourly'),
18
+ ('every_6h', 'Every 6 hours'),
19
+ ('daily', 'Daily'),
20
+ ('weekly', 'Weekly'),
21
+ ],
22
+ default='disabled',
23
+ max_length=20,
24
+ ),
25
+ ),
26
+ ]
@@ -0,0 +1,39 @@
1
+ from django.db import migrations, models
2
+
3
+
4
+ SCHEDULE_CHOICES = [
5
+ ('disabled', 'Disabled'),
6
+ ('hourly', 'Hourly'),
7
+ ('every_3h', 'Every 3 hours'),
8
+ ('every_6h', 'Every 6 hours'),
9
+ ('daily', 'Daily'),
10
+ ('weekly', 'Weekly'),
11
+ ]
12
+
13
+
14
+ class Migration(migrations.Migration):
15
+
16
+ dependencies = [
17
+ ('pve_sync_plugin', '0008_pbsserverconfig_sync_schedule'),
18
+ ]
19
+
20
+ operations = [
21
+ migrations.AlterField(
22
+ model_name='pveclusterconfig',
23
+ name='sync_schedule',
24
+ field=models.CharField(
25
+ choices=SCHEDULE_CHOICES,
26
+ default='disabled',
27
+ max_length=20,
28
+ ),
29
+ ),
30
+ migrations.AlterField(
31
+ model_name='pbsserverconfig',
32
+ name='sync_schedule',
33
+ field=models.CharField(
34
+ choices=SCHEDULE_CHOICES,
35
+ default='disabled',
36
+ max_length=20,
37
+ ),
38
+ ),
39
+ ]
@@ -0,0 +1,62 @@
1
+ import django.db.models.deletion
2
+ import django.utils.timezone
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('pve_sync_plugin', '0009_add_every_3h_schedule'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name='PveDriftEvent',
15
+ fields=[
16
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
17
+ ('created', models.DateTimeField(auto_now_add=True, null=True)),
18
+ ('last_updated', models.DateTimeField(auto_now=True, null=True)),
19
+ ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=None)),
20
+ ('vm_name', models.CharField(max_length=200)),
21
+ ('vmid', models.IntegerField()),
22
+ ('cluster_name', models.CharField(max_length=100)),
23
+ ('drift_type', models.CharField(
24
+ choices=[
25
+ ('hardware', '硬體配置變更'),
26
+ ('migration', 'VM 遷移'),
27
+ ('ip_change', 'IP 位址變更'),
28
+ ('tag_change', '標籤變更'),
29
+ ],
30
+ max_length=30,
31
+ )),
32
+ ('field_name', models.CharField(max_length=100, verbose_name='欄位')),
33
+ ('old_value', models.TextField(blank=True, verbose_name='舊值')),
34
+ ('new_value', models.TextField(blank=True, verbose_name='新值')),
35
+ ('notified_telegram', models.BooleanField(default=False)),
36
+ ('sync_job', models.ForeignKey(
37
+ blank=True,
38
+ null=True,
39
+ on_delete=django.db.models.deletion.SET_NULL,
40
+ related_name='drift_events',
41
+ to='pve_sync_plugin.pvesyncjob',
42
+ )),
43
+ ],
44
+ options={
45
+ 'verbose_name': 'VM Drift Event',
46
+ 'verbose_name_plural': 'VM Drift Events',
47
+ 'ordering': ['-created'],
48
+ },
49
+ ),
50
+ migrations.AddIndex(
51
+ model_name='pvedriftevent',
52
+ index=models.Index(fields=['vmid', 'cluster_name'], name='pvesync_drift_vm_idx'),
53
+ ),
54
+ migrations.AddIndex(
55
+ model_name='pvedriftevent',
56
+ index=models.Index(fields=['drift_type'], name='pvesync_drift_type_idx'),
57
+ ),
58
+ migrations.AddIndex(
59
+ model_name='pvedriftevent',
60
+ index=models.Index(fields=['created'], name='pvesync_drift_created_idx'),
61
+ ),
62
+ ]
@@ -0,0 +1,19 @@
1
+ from django.db import migrations, models
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+
6
+ dependencies = [
7
+ ('pve_sync_plugin', '0010_pvedriftevent'),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AddField(
12
+ model_name='pveclusterconfig',
13
+ name='notify_on_sync',
14
+ field=models.BooleanField(
15
+ default=True,
16
+ help_text='同步時是否發送 Telegram 通知(含同步開始/完成、漂移偵測等)',
17
+ ),
18
+ ),
19
+ ]
@@ -0,0 +1,39 @@
1
+ import taggit.managers
2
+ import utilities.json
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('extras', '0138_customfieldchoiceset_choice_colors'),
10
+ ('pve_sync_plugin', '0011_pveclusterconfig_notify_on_sync'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.RenameIndex(
15
+ model_name='pvedriftevent',
16
+ new_name='pve_sync_pl_vmid_64cef6_idx',
17
+ old_name='pvesync_drift_vm_idx',
18
+ ),
19
+ migrations.RenameIndex(
20
+ model_name='pvedriftevent',
21
+ new_name='pve_sync_pl_drift_t_4c2f0c_idx',
22
+ old_name='pvesync_drift_type_idx',
23
+ ),
24
+ migrations.RenameIndex(
25
+ model_name='pvedriftevent',
26
+ new_name='pve_sync_pl_created_5440dd_idx',
27
+ old_name='pvesync_drift_created_idx',
28
+ ),
29
+ migrations.AddField(
30
+ model_name='pvedriftevent',
31
+ name='tags',
32
+ field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
33
+ ),
34
+ migrations.AlterField(
35
+ model_name='pvedriftevent',
36
+ name='custom_field_data',
37
+ field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
38
+ ),
39
+ ]
@@ -0,0 +1,19 @@
1
+ from django.db import migrations, models
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+
6
+ dependencies = [
7
+ ("pve_sync_plugin", "0012_pvedriftevent_tags_and_index_renames"),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AddField(
12
+ model_name="pvepluginsettings",
13
+ name="log_retention_days",
14
+ field=models.PositiveIntegerField(
15
+ default=90,
16
+ help_text="保留同步 Log 及 State DB 歷史資料天數(0 = 不自動清除)",
17
+ ),
18
+ ),
19
+ ]
@@ -0,0 +1 @@
1
+