99 lines
3.3 KiB
Python
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},
|
|
)
|