Files
Netbox-Utilities/netbox_utilities/module_installation.py
T

86 lines
3.0 KiB
Python

from dcim.forms import ModuleForm
from dcim.models import ModuleBay
from django.db import IntegrityError, transaction
class BulkModuleInstallError(Exception):
pass
def build_module_form_data(device, module_bay, module_type, status, replicate_components, description=""):
return {
"device": device.pk,
"module_bay": module_bay.pk,
"module_type": module_type.pk,
"status": status,
"replicate_components": replicate_components,
"adopt_components": False,
"description": description,
}
def _format_form_errors(form):
messages = []
for field_name, errors in form.errors.items():
field = form.fields.get(field_name)
label = field.label if field else "Allgemeiner Fehler"
messages.append(f"{label}: {', '.join(str(error) for error in errors)}")
return "; ".join(messages)
def install_modules(
*,
device,
module_type,
module_bays,
status,
replicate_components=True,
description="",
permitted_modules=None,
):
module_bay_ids = {module_bay.pk for module_bay in module_bays}
if not module_bay_ids:
return []
try:
with transaction.atomic():
locked_bays = list(ModuleBay.objects.select_for_update().filter(pk__in=module_bay_ids))
if {module_bay.pk for module_bay in locked_bays} != module_bay_ids:
raise BulkModuleInstallError("Mindestens ein ausgewählter Modulschacht existiert nicht mehr.")
installed_modules = []
for module_bay in locked_bays:
if (
module_bay.device_id != device.pk
or not module_bay.enabled
or hasattr(module_bay, "installed_module")
):
raise BulkModuleInstallError(f'Der Modulschacht "{module_bay.name}" ist nicht mehr verfügbar.')
module_form = ModuleForm(
data=build_module_form_data(
device,
module_bay,
module_type,
status,
replicate_components,
description,
)
)
if not module_form.is_valid():
raise BulkModuleInstallError(
f'Fehler bei Modulschacht "{module_bay.name}": {_format_form_errors(module_form)}'
)
module = module_form.save()
if permitted_modules is not None and not permitted_modules.filter(pk=module.pk).exists():
raise BulkModuleInstallError(
f'Keine Berechtigung zum Einbau eines Moduls in Modulschacht "{module_bay.name}".'
)
installed_modules.append(module)
return installed_modules
except IntegrityError as error:
raise BulkModuleInstallError(
"Der Masseneinbau konnte wegen eines zwischenzeitlichen Datenkonflikts nicht gespeichert werden."
) from error