proxsync 2.0.3__tar.gz → 2.0.4__tar.gz
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.
- {proxsync-2.0.3/proxsync.egg-info → proxsync-2.0.4}/PKG-INFO +1 -1
- {proxsync-2.0.3 → proxsync-2.0.4/proxsync.egg-info}/PKG-INFO +1 -1
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync.py +27 -1
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/filtersets.py +25 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/views.py +8 -7
- {proxsync-2.0.3 → proxsync-2.0.4}/pyproject.toml +1 -1
- {proxsync-2.0.3 → proxsync-2.0.4}/MANIFEST.in +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/README.md +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/config.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pbs_sync.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/proxsync.egg-info/SOURCES.txt +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/proxsync.egg-info/dependency_links.txt +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/proxsync.egg-info/requires.txt +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/proxsync.egg-info/top_level.txt +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/api/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/api/serializers.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/api/urls.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/api/views.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/apps.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/choices.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/forms.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/management/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/management/commands/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/management/commands/pve_sync.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/management/commands/run_scheduled_syncs.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0001_initial.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0002_pvepluginsettings.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0003_netboxmodel_timestamps.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0004_model_verbose_names.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0005_align_netboxmodel_timestamps.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0006_pbsserverconfig_and_more.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0007_rename_verbose_names_to_proxmox_sync.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0008_pbsserverconfig_sync_schedule.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0009_add_every_3h_schedule.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0010_pvedriftevent.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0011_pveclusterconfig_notify_on_sync.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0012_pvedriftevent_tags_and_index_renames.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0013_pluginsettings_log_retention.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0014_vmprovisioninglog.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0015_pvevmtasklog.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0016_pvevmtasklog_status_textfield.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/models.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/navigation.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/signals.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/sync/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/sync/config_bridge.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/sync/engine.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/tables.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/tasks.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/template_content.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/dashboard.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/inc/vm_sync_button.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/inc/vm_task_log_panel.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pbsserverconfig.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pvebackupstatus.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pveclusterconfig.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pvedriftevent.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pvesyncjob.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pvevmtasklog_list.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/pvewebhookevent.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/settings.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/vm_provisioning_combined.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/vm_provisioning_log.html +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templatetags/__init__.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templatetags/pve_sync_tags.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/urls.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/utils.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/view_helpers.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/setup.cfg +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/state_db.py +0 -0
- {proxsync-2.0.3 → proxsync-2.0.4}/tests/test_plugin_contracts.py +0 -0
|
@@ -1235,6 +1235,23 @@ class OptimizedPVEToNetBoxSync:
|
|
|
1235
1235
|
print(f"⚠️ 清理孤兒 VM 失敗: {exc}")
|
|
1236
1236
|
traceback.print_exc()
|
|
1237
1237
|
|
|
1238
|
+
def _apply_log_retention(self):
|
|
1239
|
+
"""依 PvePluginSettings.log_retention_days 清理過期記錄。"""
|
|
1240
|
+
try:
|
|
1241
|
+
import datetime as _dt
|
|
1242
|
+
from django.utils import timezone
|
|
1243
|
+
from pve_sync_plugin.models import PveDriftEvent, PvePluginSettings, PveVmTaskLog
|
|
1244
|
+
days = PvePluginSettings.load().log_retention_days
|
|
1245
|
+
if not days:
|
|
1246
|
+
return
|
|
1247
|
+
cutoff = timezone.now() - _dt.timedelta(days=days)
|
|
1248
|
+
d_del, _ = PveDriftEvent.objects.filter(created__lt=cutoff).delete()
|
|
1249
|
+
t_del, _ = PveVmTaskLog.objects.filter(start_time__lt=cutoff).delete()
|
|
1250
|
+
if d_del or t_del:
|
|
1251
|
+
print(f" 🧹 Log 清理:刪除 {d_del} 筆漂移事件、{t_del} 筆操作記錄(>{days} 天)")
|
|
1252
|
+
except Exception as exc:
|
|
1253
|
+
print(f" ⚠️ Log 清理失敗: {exc}")
|
|
1254
|
+
|
|
1238
1255
|
def sync_vm_tasks(self):
|
|
1239
1256
|
"""從 PVE 各節點抓取 VM 操作記錄(建立/刪除/Clone/遷移)並同步到 NetBox。"""
|
|
1240
1257
|
try:
|
|
@@ -1271,7 +1288,15 @@ class OptimizedPVEToNetBoxSync:
|
|
|
1271
1288
|
# 只通知最近 2 小時內的操作(避免首次匯入時大量通知)
|
|
1272
1289
|
notify_cutoff = time.time() - 7200
|
|
1273
1290
|
|
|
1274
|
-
|
|
1291
|
+
# 從上次已存記錄的最新時間起算(+1 秒避免邊界重複);首次則抓 30 天
|
|
1292
|
+
latest = PveVmTaskLog.objects.filter(
|
|
1293
|
+
cluster_name=self.cluster_name
|
|
1294
|
+
).order_by("-start_time").values_list("start_time", flat=True).first()
|
|
1295
|
+
if latest:
|
|
1296
|
+
import calendar
|
|
1297
|
+
since_ts = int(calendar.timegm(latest.utctimetuple())) + 1
|
|
1298
|
+
else:
|
|
1299
|
+
since_ts = int(time.time()) - 30 * 86400
|
|
1275
1300
|
new_count = 0
|
|
1276
1301
|
|
|
1277
1302
|
for node_name in self.pve_cache.get("vms_by_node", {}):
|
|
@@ -1931,6 +1956,7 @@ class OptimizedPVEToNetBoxSync:
|
|
|
1931
1956
|
vms_success, success_count, total_count = self.sync_pve_virtual_machines(devices, cluster)
|
|
1932
1957
|
print("\n同步 VM 操作記錄...")
|
|
1933
1958
|
self.sync_vm_tasks()
|
|
1959
|
+
self._apply_log_retention()
|
|
1934
1960
|
elapsed = time.time() - start_time
|
|
1935
1961
|
self.stats['elapsed_time'] = elapsed
|
|
1936
1962
|
self.stats['total_vms'] = total_count
|
|
@@ -10,6 +10,7 @@ from .choices import (
|
|
|
10
10
|
SyncJobStatusChoices,
|
|
11
11
|
SyncJobTriggerChoices,
|
|
12
12
|
SyncScheduleChoices,
|
|
13
|
+
VmTaskTypeChoices,
|
|
13
14
|
WebhookEventChoices,
|
|
14
15
|
)
|
|
15
16
|
from .models import (
|
|
@@ -18,6 +19,7 @@ from .models import (
|
|
|
18
19
|
PveClusterConfig,
|
|
19
20
|
PveDriftEvent,
|
|
20
21
|
PveSyncJob,
|
|
22
|
+
PveVmTaskLog,
|
|
21
23
|
PveWebhookEvent,
|
|
22
24
|
)
|
|
23
25
|
|
|
@@ -120,6 +122,29 @@ class PveDriftEventFilterSet(NetBoxModelFilterSet):
|
|
|
120
122
|
return queryset.filter(vm_name__icontains=value) | queryset.filter(cluster_name__icontains=value)
|
|
121
123
|
|
|
122
124
|
|
|
125
|
+
class PveVmTaskLogFilterSet(NetBoxModelFilterSet):
|
|
126
|
+
"""Filter VM task logs by type, operator, cluster, and VM."""
|
|
127
|
+
|
|
128
|
+
task_type = django_filters.MultipleChoiceFilter(choices=VmTaskTypeChoices.choices)
|
|
129
|
+
vmid = django_filters.NumberFilter()
|
|
130
|
+
cluster_name = django_filters.CharFilter(lookup_expr="icontains")
|
|
131
|
+
operator = django_filters.CharFilter(lookup_expr="icontains")
|
|
132
|
+
node = django_filters.CharFilter(lookup_expr="icontains")
|
|
133
|
+
|
|
134
|
+
class Meta:
|
|
135
|
+
model = PveVmTaskLog
|
|
136
|
+
fields = ["id", "vmid", "task_type", "cluster_name", "operator", "node"]
|
|
137
|
+
|
|
138
|
+
def search(self, queryset, name, value):
|
|
139
|
+
if not value.strip():
|
|
140
|
+
return queryset
|
|
141
|
+
return (
|
|
142
|
+
queryset.filter(vm_name__icontains=value)
|
|
143
|
+
| queryset.filter(operator__icontains=value)
|
|
144
|
+
| queryset.filter(cluster_name__icontains=value)
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
123
148
|
class PveBackupStatusFilterSet(NetBoxModelFilterSet):
|
|
124
149
|
"""Filter backup statuses by state."""
|
|
125
150
|
|
|
@@ -30,6 +30,7 @@ from .filtersets import (
|
|
|
30
30
|
PveClusterConfigFilterSet,
|
|
31
31
|
PveDriftEventFilterSet,
|
|
32
32
|
PveSyncJobFilterSet,
|
|
33
|
+
PveVmTaskLogFilterSet,
|
|
33
34
|
PveWebhookEventFilterSet,
|
|
34
35
|
)
|
|
35
36
|
from .forms import (
|
|
@@ -351,6 +352,7 @@ class PveDriftEventBulkDeleteView(generic.BulkDeleteView):
|
|
|
351
352
|
class PveVmTaskLogListView(generic.ObjectListView):
|
|
352
353
|
queryset = PveVmTaskLog.objects.order_by("-start_time")
|
|
353
354
|
table = PveVmTaskLogTable
|
|
355
|
+
filterset = PveVmTaskLogFilterSet
|
|
354
356
|
template_name = "pve_sync/pvevmtasklog_list.html"
|
|
355
357
|
|
|
356
358
|
|
|
@@ -666,13 +668,12 @@ class VmPlannerCheckIpApi(PermissionRequiredMixin, View):
|
|
|
666
668
|
ip_str = str(ip_obj)
|
|
667
669
|
|
|
668
670
|
# ── 1. IPAM check (authoritative) ──
|
|
669
|
-
#
|
|
670
|
-
#
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
break
|
|
671
|
+
# Filter by host bits using __net_host_contained: finds any /N record
|
|
672
|
+
# whose host address matches ip_str, without a full table scan.
|
|
673
|
+
ipam_qs = NetBoxIPAddress.objects.filter(
|
|
674
|
+
address__net_host_contained=ip_str
|
|
675
|
+
).values_list("address", flat=True).first()
|
|
676
|
+
ipam_entry = str(ipam_qs) if ipam_qs else None
|
|
676
677
|
|
|
677
678
|
if ipam_entry:
|
|
678
679
|
return JsonResponse({
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/management/commands/run_scheduled_syncs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0005_align_netboxmodel_timestamps.py
RENAMED
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0006_pbsserverconfig_and_more.py
RENAMED
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0008_pbsserverconfig_sync_schedule.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0011_pveclusterconfig_notify_on_sync.py
RENAMED
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0013_pluginsettings_log_retention.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/migrations/0016_pvevmtasklog_status_textfield.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/inc/vm_sync_button.html
RENAMED
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/inc/vm_task_log_panel.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/vm_provisioning_combined.html
RENAMED
|
File without changes
|
{proxsync-2.0.3 → proxsync-2.0.4}/pve_sync_plugin/templates/pve_sync/vm_provisioning_log.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|