Files
device_manager/device_manager/lifecycle.py
T

99 lines
3.3 KiB
Python

import frappe
from frappe import _
from device_manager.audit import emit_audit_event
from device_manager.identity import append_identifier, normalize_mac_address
def create_device_from_registration(registration_name: str, *, approver: str | None = None):
registration = frappe.get_doc("DM Device Registration", registration_name)
if registration.status not in ("Submitted", "Under Review"):
frappe.throw(_("Only submitted registrations can be approved."))
device = frappe.new_doc("DM Device")
device.device_label = registration.device_label
device.device_type = registration.device_type
device.primary_mac_address = normalize_mac_address(registration.primary_mac_address)
device.owner_user = registration.requested_by
device.project = registration.project
device.laboratory = registration.laboratory
device.organizational_unit = registration.organizational_unit
device.dataset_use_category = registration.dataset_use_category
device.network_segment = registration.network_segment
device.lifecycle_status = "Approved"
device.authorization_status = "Authorized" if registration.dataset_use_category == "None" else "Pending"
device.radius_username = registration.hostname or registration.primary_mac_address
device.risk_notes = registration.justification
append_identifier(device, "MAC Address", device.primary_mac_address, is_primary=True)
if registration.hostname:
append_identifier(device, "Hostname", registration.hostname)
if registration.serial_number:
append_identifier(device, "Serial Number", registration.serial_number)
device.insert(ignore_permissions=True)
registration.status = "Approved"
registration.approved_by = approver or frappe.session.user
registration.approved_device = device.name
registration.save(ignore_permissions=True)
emit_audit_event(
"Registration Approved",
"DM Device Registration",
registration.name,
device=device.name,
actor=approver,
decision="Approved",
reason=registration.approval_notes,
payload={"registration": registration.name, "device": device.name},
)
emit_audit_event(
"Device Created",
"DM Device",
device.name,
device=device.name,
actor=approver,
payload={"source_registration": registration.name},
)
return device.name
def reject_registration(registration_name: str, *, reason: str | None = None, actor: str | None = None):
registration = frappe.get_doc("DM Device Registration", registration_name)
registration.status = "Rejected"
registration.approval_notes = reason
registration.save(ignore_permissions=True)
return emit_audit_event(
"Registration Rejected",
"DM Device Registration",
registration.name,
actor=actor,
decision="Rejected",
reason=reason,
)
def transition_device(
device_name: str, lifecycle_status: str, *, reason: str | None = None, actor: str | None = None
):
device = frappe.get_doc("DM Device", device_name)
previous_status = device.lifecycle_status
device.lifecycle_status = lifecycle_status
if lifecycle_status == "Quarantined":
device.authorization_status = "Denied"
if lifecycle_status == "Retired":
device.authorization_status = "Revoked"
device.save(ignore_permissions=True)
return emit_audit_event(
"Device Lifecycle Transition",
"DM Device",
device.name,
device=device.name,
actor=actor,
decision=lifecycle_status,
reason=reason,
payload={"from": previous_status, "to": lifecycle_status},
)