Bereitstellungsvorlagen: archivierte Geraete/abgelaufene Medien zaehlen nicht als Nutzung

Nutzung und Loeschsperre zaehlen nur aktive Geraete und gueltige
Installationsmedien. Beim Loeschen werden Zuordnungen archivierter
Geraete und abgelaufene/widerrufene Medien mit entfernt (sonst
blockieren die Fremdschluessel). Anlass: Liebherrs
Entwicklungsprofile hingen nur noch an Altlasten vom 08./09.09.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-09 11:50:13 +02:00
1 parent 485282664a
commit ea00480df1
1 file changed
+31 -8
+31 -8
View File
@@ -755,8 +755,10 @@ def fetch_templates(organization_id: str) -> list[dict]:
w.id, w.name,
b.id, b.name, b.version,
bv.partitioning, bv.disk_encryption, bv.secure_boot_required,
(SELECT count(*) FROM assignments a WHERE a.bereitstellungsvorlage_id = bv.id),
(SELECT count(*) FROM enrollment_sessions es WHERE es.bereitstellungsvorlage_id = bv.id)
(SELECT count(*) FROM assignments a JOIN devices d ON d.id = a.device_id
WHERE a.bereitstellungsvorlage_id = bv.id AND d.archived_at IS NULL),
(SELECT count(*) FROM enrollment_sessions es
WHERE es.bereitstellungsvorlage_id = bv.id AND es.revoked_at IS NULL AND es.expires_at > now())
FROM bereitstellungsvorlagen bv
JOIN workspaces w ON w.id = bv.workspace_id
JOIN backends b ON b.id = bv.backend_id
@@ -777,8 +779,9 @@ def fetch_templates(organization_id: str) -> list[dict]:
"partitioning": row[8],
"disk_encryption": row[9],
"secure_boot_required": row[10],
# GUI-Runde 09.10.2026 (Punkt 5): Nutzung - solange Geräte oder
# Installationsmedien darauf verweisen, ist Löschen gesperrt.
# GUI-Runde 09.10.2026 (Punkt 5): Nutzung - nur aktive Geräte und
# gültige Installationsmedien; solange es die gibt, ist Löschen
# gesperrt (archivierte Geräte/abgelaufene Medien zählen nicht).
"geraete_anzahl": row[11],
"medien_anzahl": row[12],
}
@@ -6617,17 +6620,37 @@ def delete_bereitstellungsvorlage_endpoint(
with conn.cursor() as cur:
cur.execute(
"""
SELECT (SELECT count(*) FROM assignments WHERE bereitstellungsvorlage_id = %s)
+ (SELECT count(*) FROM enrollment_sessions WHERE bereitstellungsvorlage_id = %s)
SELECT (SELECT count(*) FROM assignments a JOIN devices d ON d.id = a.device_id
WHERE a.bereitstellungsvorlage_id = %(v)s AND d.archived_at IS NULL)
+ (SELECT count(*) FROM enrollment_sessions
WHERE bereitstellungsvorlage_id = %(v)s AND revoked_at IS NULL AND expires_at > now())
""",
(vorlage_id, vorlage_id),
{"v": vorlage_id},
)
(verweise,) = cur.fetchone()
if verweise:
return {
"success": False, "error": "in_benutzung",
"message": "Die Vorlage wird noch von Geräten oder Installationsmedien verwendet und kann nicht gelöscht werden.",
"message": "Die Vorlage wird noch von aktiven Geräten oder gültigen Installationsmedien verwendet und kann nicht gelöscht werden.",
}
# Altlasten mit entfernen (09.10.2026): Zuordnungen archivierter
# Geräte und abgelaufene/widerrufene Medien - sonst blockieren die
# Fremdschlüssel. Ein archiviertes Gerät, das sich neu installiert,
# bekommt bei der Installation ohnehin eine neue Zuordnung.
cur.execute(
"""
DELETE FROM assignments a USING devices d
WHERE d.id = a.device_id AND a.bereitstellungsvorlage_id = %s AND d.archived_at IS NOT NULL
""",
(vorlage_id,),
)
cur.execute(
"""
DELETE FROM enrollment_sessions
WHERE bereitstellungsvorlage_id = %s AND (revoked_at IS NOT NULL OR expires_at <= now())
""",
(vorlage_id,),
)
cur.execute(
"DELETE FROM bereitstellungsvorlagen WHERE id = %s AND organization_id = %s",
(vorlage_id, organization_id),