Files
netbox-scripts/check_vchassis_stack_ports.py
IluaAir 02ffa2e460 init
2026-02-04 00:39:18 +03:00

78 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
from dcim.models.devices import Device
from extras.models.tags import Tag
from extras.scripts import ObjectVar, Script
from dcim.models import VirtualChassis, Interface
from netbox.choices import ColorChoices
from utilities.exceptions import AbortScript
class Vchassis_checker(Script):
TAGS = 'sync:vchas_interface'
IFACE_RE = re.compile(r'^(?P<prefix>[A-Za-z]+)\s?(?:(?P<slot>\d+)/)?(?P<rest>\d+/\d+)$')
class Meta(Script.Meta):
commit_default = False
name = 'Переопределение интерфейсов'
description = 'Переопределение интерфейсов у стекированных коммутаторов'
virtual_chassis = ObjectVar(
model=VirtualChassis,
query_params={'tags': None},
)
def run(self, data, commit):
if Tag.objects.filter(name=self.TAGS).exists():
tag = Tag.objects.get(name=self.TAGS)
else:
self.log_warning(f'Отсутствует tag {self.TAGS}')
tag_data = {
'color': ColorChoices.COLOR_LIGHT_BLUE,
'name': self.TAGS,
'slug': self.TAGS.replace(':', '_'),
'description': 'тег для автоматического назначения на синхронизированные интерфейсы vchassis',
}
tag = Tag(**tag_data)
if commit:
tag.save()
self.log_success(f'Создан тег: {self.TAGS}')
vc = data['virtual_chassis']
devices: list[Device] = list(vc.members.all().order_by('vc_position'))
if not vc._state.adding and vc.master and vc.master not in devices:
raise AbortScript(f'В стеке {vc.name} отсутствует мастер')
for device in devices:
interfaces = Interface.objects.filter(device=device)
for iface in interfaces:
m = self.IFACE_RE.match(iface)
# Все интерфейсы всех устройств стека одним запросом
device_ids = [d.pk for d in devices]
interfaces_qs = Interface.objects.filter(device_id__in=device_ids)
if commit:
# Вариант 1: цикл с .save() — вызываются clean(), save(), сигналы и change log (ObjectChange)
for iface in interfaces_qs:
iface.description = f'{iface.device.name}:{iface.name}' # пример
iface.save()
# Вариант 2: массовый UPDATE без change log (быстро, но без аудита):
# interfaces_qs.update(description=...) # одно значение для всех
# Или bulk_update для разных значений по объектам:
# to_update = []
# for iface in interfaces_qs:
# iface.description = f'{iface.device.name}:{iface.name}'
# to_update.append(iface)
# Interface.objects.bulk_update(to_update, ['description'])
else:
count = interfaces_qs.count()
self.log_success(f'Будет обновлено интерфейсов: {count}')
# vchassis = VirtualChassis.objects.all()
# for vc in vchassis:
# interfaces = Interface.objects.filter(device=vc)
# for interface in interfaces:
# interface.name = f'{vc.name}-{interface.name}'
# interface.save()