Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1b74a2bd1 | |||
| b715019845 | |||
| 3268274f69 | |||
| fc0a232808 | |||
| 774412d5dd | |||
| 909a7f10b9 | |||
| f7edac730a | |||
| 8f014953af | |||
| 7e8b74f3b8 | |||
| dd851d388c | |||
| 88fad0f9fa | |||
| 1e0c3b808b | |||
| 12cbfef017 | |||
| b416d9d530 | |||
| 109e644dad | |||
| 1d825546cb | |||
| d75d98d1a2 | |||
| cc72c4619d | |||
| edfa955edf | |||
| 6388522486 | |||
| e03c28e7d9 | |||
| 569a88a248 | |||
| e6df4820a6 | |||
| 070a1722d2 |
+3
-1
@@ -1 +1,3 @@
|
|||||||
/.idea
|
/.venv/
|
||||||
|
/.idea/
|
||||||
|
/.vscode/
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
TAGS = "sync:vchas_interface"
|
|
||||||
|
|
||||||
|
|
||||||
class Vchassis_checker(Script):
|
|
||||||
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
|
|
||||||
scheduling_enabled = False
|
|
||||||
name = "Переопределение интерфейсов"
|
|
||||||
description = "Переопределение интерфейсов у стекированных коммутаторов"
|
|
||||||
|
|
||||||
virtual_chassis = ObjectVar(
|
|
||||||
model=VirtualChassis,
|
|
||||||
description="Виртуальное шасси без тегов",
|
|
||||||
query_params={"tag__n": [TAGS.replace(":", "_")]},
|
|
||||||
)
|
|
||||||
|
|
||||||
def run(self, data, commit):
|
|
||||||
if Tag.objects.filter(name=TAGS).exists():
|
|
||||||
tag = Tag.objects.get(name=TAGS)
|
|
||||||
else:
|
|
||||||
self.log_warning(f"Отсутствует tag {TAGS}")
|
|
||||||
tag_data = {
|
|
||||||
"color": ColorChoices.COLOR_LIGHT_BLUE,
|
|
||||||
"name": TAGS,
|
|
||||||
"slug": TAGS.replace(":", "_"),
|
|
||||||
"description": "тег для автоматического назначения на синхронизированные интерфейсы vchassis",
|
|
||||||
}
|
|
||||||
tag = Tag(**tag_data)
|
|
||||||
if commit:
|
|
||||||
tag.full_clean()
|
|
||||||
tag.save()
|
|
||||||
self.log_success(
|
|
||||||
f"Создан тег: {TAGS}",
|
|
||||||
obj=tag,
|
|
||||||
)
|
|
||||||
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} отсутствует мастер")
|
|
||||||
device_ids = [d.pk for d in devices]
|
|
||||||
interfaces_qs = Interface.objects.filter(
|
|
||||||
device_id__in=device_ids
|
|
||||||
).select_related("device")
|
|
||||||
|
|
||||||
to_update = []
|
|
||||||
for iface in interfaces_qs:
|
|
||||||
m = self.IFACE_RE.match(iface.name)
|
|
||||||
if m:
|
|
||||||
prefix = m.group("prefix")
|
|
||||||
slot = m.group("slot")
|
|
||||||
rest = m.group("rest")
|
|
||||||
iface.name = f"{prefix}{iface.device.vc_position}/{rest}"
|
|
||||||
to_update.append(iface)
|
|
||||||
if commit:
|
|
||||||
Interface.objects.bulk_update(to_update, fields=["name"], batch_size=100)
|
|
||||||
vc.tags.add(tag)
|
|
||||||
for iface in to_update:
|
|
||||||
iface.tags.add(tag)
|
|
||||||
|
|
||||||
self.log_success(f"Обновлено интерфейсов: {len(to_update)}")
|
|
||||||
else:
|
|
||||||
self.log_success(f"Будет обновлено интерфейсов: {len(to_update)}")
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[project]
|
||||||
|
name = "netbox-scripts"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = []
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extraPaths": ["netbox/netbox"],
|
||||||
|
"typeCheckingMode": "off",
|
||||||
|
"reportMissingImports": "warning",
|
||||||
|
"reportMissingTypeStubs": "none",
|
||||||
|
"reportGeneralTypeIssues": "none",
|
||||||
|
"reportOptionalMemberAccess": "none",
|
||||||
|
"reportOptionalSubscript": "none",
|
||||||
|
"reportArgumentType": "none",
|
||||||
|
"reportAssignmentType": "none",
|
||||||
|
"reportReturnType": "none"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user