86 lines
3.0 KiB
Python
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
|