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.
- config.py +337 -0
- pbs_sync.py +244 -0
- proxsync-2.0.0.dist-info/METADATA +468 -0
- proxsync-2.0.0.dist-info/RECORD +59 -0
- proxsync-2.0.0.dist-info/WHEEL +5 -0
- proxsync-2.0.0.dist-info/top_level.txt +5 -0
- pve_sync.py +1804 -0
- pve_sync_plugin/__init__.py +46 -0
- pve_sync_plugin/api/__init__.py +1 -0
- pve_sync_plugin/api/serializers.py +161 -0
- pve_sync_plugin/api/urls.py +27 -0
- pve_sync_plugin/api/views.py +94 -0
- pve_sync_plugin/apps.py +5 -0
- pve_sync_plugin/choices.py +57 -0
- pve_sync_plugin/filtersets.py +137 -0
- pve_sync_plugin/forms.py +219 -0
- pve_sync_plugin/management/__init__.py +1 -0
- pve_sync_plugin/management/commands/__init__.py +1 -0
- pve_sync_plugin/management/commands/pve_sync.py +182 -0
- pve_sync_plugin/management/commands/run_scheduled_syncs.py +109 -0
- pve_sync_plugin/migrations/0001_initial.py +234 -0
- pve_sync_plugin/migrations/0002_pvepluginsettings.py +42 -0
- pve_sync_plugin/migrations/0003_netboxmodel_timestamps.py +148 -0
- pve_sync_plugin/migrations/0004_model_verbose_names.py +34 -0
- pve_sync_plugin/migrations/0005_align_netboxmodel_timestamps.py +111 -0
- pve_sync_plugin/migrations/0006_pbsserverconfig_and_more.py +124 -0
- pve_sync_plugin/migrations/0007_rename_verbose_names_to_proxmox_sync.py +26 -0
- pve_sync_plugin/migrations/0008_pbsserverconfig_sync_schedule.py +26 -0
- pve_sync_plugin/migrations/0009_add_every_3h_schedule.py +39 -0
- pve_sync_plugin/migrations/0010_pvedriftevent.py +62 -0
- pve_sync_plugin/migrations/0011_pveclusterconfig_notify_on_sync.py +19 -0
- pve_sync_plugin/migrations/0012_pvedriftevent_tags_and_index_renames.py +39 -0
- pve_sync_plugin/migrations/0013_pluginsettings_log_retention.py +19 -0
- pve_sync_plugin/migrations/__init__.py +1 -0
- pve_sync_plugin/models.py +461 -0
- pve_sync_plugin/navigation.py +94 -0
- pve_sync_plugin/signals.py +24 -0
- pve_sync_plugin/sync/__init__.py +8 -0
- pve_sync_plugin/sync/config_bridge.py +221 -0
- pve_sync_plugin/sync/engine.py +50 -0
- pve_sync_plugin/tables.py +278 -0
- pve_sync_plugin/tasks.py +440 -0
- pve_sync_plugin/template_content.py +44 -0
- pve_sync_plugin/templates/pve_sync/dashboard.html +400 -0
- pve_sync_plugin/templates/pve_sync/inc/vm_sync_button.html +7 -0
- pve_sync_plugin/templates/pve_sync/pbsserverconfig.html +69 -0
- pve_sync_plugin/templates/pve_sync/pvebackupstatus.html +27 -0
- pve_sync_plugin/templates/pve_sync/pveclusterconfig.html +52 -0
- pve_sync_plugin/templates/pve_sync/pvedriftevent.html +89 -0
- pve_sync_plugin/templates/pve_sync/pvesyncjob.html +197 -0
- pve_sync_plugin/templates/pve_sync/pvewebhookevent.html +42 -0
- pve_sync_plugin/templates/pve_sync/settings.html +79 -0
- pve_sync_plugin/templatetags/__init__.py +1 -0
- pve_sync_plugin/templatetags/pve_sync_tags.py +86 -0
- pve_sync_plugin/urls.py +186 -0
- pve_sync_plugin/utils.py +84 -0
- pve_sync_plugin/view_helpers.py +98 -0
- pve_sync_plugin/views.py +535 -0
- 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
|
+
|