This page contains the complete version history of Staging & Cisco Tools. Each entry documents new features, changes, bug fixes and security updates.
Versioning follows Semantic Versioning 2.0.0. The change format is based on Keep a Changelog.
Current size of the self-written source code (PHP, JavaScript, CSS) – excluding external dependencies in the vendor/ directory.
As of: 15.06.2026 12:25 · Last code change: 15.06.2026
Jump straight to the entry: v2.32.0
These changes are merged on the default branch but not yet part of an official release.
Modul-Zugänge auf Antrag. Außer dem Konfigurator sind alle Module pro Benutzer jetzt standardmäßig gesperrt; der Zugang wird über ein Antragssystem geregelt – Benutzer beantragen ihn direkt an der gesperrten Kachel, Admins und Superadmins geben frei oder lehnen ab, optional mit modulweiser Selbstfreigabe. Dazu: eine öffentliche Info- & Kontaktseite sowie Startseiten-Hinweise mit optionalem Ablaufdatum.
contact.php): Ansprechpartner mit Erreichbarkeits-Ampel (grün/gelb/rot) und Support-Kanäle als Schnellzugriff-Kacheln (z. B. Webex-Space; „Bug melden“ und „Feature vorschlagen“ öffnen direkt das Feedback-Formular). Pflege im Backend unter System → Kontaktseite, inklusive Sortierung und Ausblenden einzelner Einträge; Neuinstallationen erhalten die nötigen Tabellen direkt über den Setup-Wizard, Bestandsinstallationen über die Migration „Kontakt-/Infoseite".Zwei-Faktor-Authentifizierung mit Cisco Duo. Die Anmeldung am Admin-Backend kann jetzt mit Cisco Duo abgesichert werden: Nach dem korrekten Passwort bestätigt der Benutzer die Anmeldung per Duo (Push, Passcode oder Sicherheitsschlüssel). Die Durchsetzung ist stufenweise ausrollbar – von einer Pilot-Gruppe bis zur Pflicht für alle Benutzer – und vollständig im Admin-Backend konfigurierbar.
E-Mail-Versand über SMTP. System-Mails (Passwort-Reset, Registrierung, Warenkorb-Reports) können jetzt über einen SMTP-Server versendet werden statt über den lokalen Mailserver – komplett im Admin-Backend konfigurierbar, inklusive Testmail-Funktion mit aussagekräftiger Fehlerdiagnose. Dazu: Live-Port-Übersicht und Ein-Klick-Verbindung für Konsolenserver.
VLAN-IDs nachträglich änderbar – mit Sync in alle Richtungen. Schritt 3 bleibt die zentrale VLAN-Sicht, gibt Änderungen jetzt aber auch zurück: Wer dort eine VLAN-ID ändert, zieht automatisch alle Verweise im gesamten Konfigurator mit – von den Port-Gruppen über SVIs bis zu ACL-Zuweisungen. Dazu ein prägnanterer Einfach/Experte-Umschalter.
10,20,40-50.Feinschliff im Feedback-Dialog. Zwei kleine Verbesserungen an den Dialogen „Bug melden" und „Feature vorschlagen": Nach dem Absenden ist klarer, dass nichts mehr verworfen wird, und vorbelegte Felder sind auf einen Blick als nicht änderbar erkennbar.
Port-Gruppen umbenennen. Im Konfigurator (Schritt 2 – Interfaces) lassen sich Port-Gruppen jetzt direkt in der Liste umbenennen – Stift-Symbol anklicken, neuen Namen eintippen, mit Enter bestätigen.
description-Zeilen).„Picture" – Bilder im Feedback. Beim Bug melden oder Feature vorschlagen lassen sich jetzt Screenshots und Bilder anhängen – einfach ins Eingabefeld ziehen, mit Strg+V einfügen oder über den Bild-Button auswählen. Die Bilder erscheinen direkt in der Beschreibung und, sofern gewünscht, auch auf der öffentlichen Status-Seite des Vorgangs. Im Backend lassen sich Anhänge ansehen, entfernen und pro Vorgang auf „nur intern" stellen.
„Modus" – ein Einfach- und ein Experten-Modus im Konfigurator. Der Wizard ist über die Zeit sehr umfangreich geworden. Mit einem Umschalter direkt unter der Schrittleiste lässt sich nun zwischen Einfach (nur die wichtigsten Einstellungen für eine Standard-Konfiguration) und Experte (alle Optionen) wechseln. Es bleibt ein einziger Wizard – im Einfach-Modus werden die erweiterten Bereiche lediglich ausgeblendet, ihre Werte bleiben erhalten. Die gewählte Ansicht wird im Browser gemerkt.
„Recovery" – Passwort-Wiederherstellung ohne E-Mail. Der klassische „Passwort vergessen“-Link setzt einen funktionierenden Mailversand voraus. Damit ausgesperrte Benutzer auch ohne E-Mail wieder Zugang erhalten, gibt es jetzt zusätzliche Wege: selbst erzeugte Recovery-Codes, eine Authenticator-App (TOTP) sowie einen sofort wirksamen, admin-gestützten Reset im Backend.
„Activation" – die Konto-Aktivierung ist jetzt frei wählbar. Nach einer Registrierung lässt sich im Backend festlegen, wie ein neues Benutzerkonto aktiv wird: klassisch per Bestätigungs-E-Mail, sofort nach Abschluss der Registrierung oder erst nach Freigabe durch einen Superadmin. So funktioniert die Selbstregistrierung auch dann zuverlässig, wenn der E-Mail-Versand gerade nicht zur Verfügung steht. Jede Registrierung kann zusätzlich als Webhook an Slack, Teams, Webex & Co. gemeldet werden – inklusive Direkt-Link zur Freigabe.
„Setup" – ein geführter Einrichtungs-Assistent für den Browser. Die Erstinbetriebnahme läuft jetzt vollständig über einen mehrstufigen Assistenten: Systemvoraussetzungen prüfen, Datenbank verbinden und testen, das erste Administrator-Konto anlegen, die Grundeinstellungen festlegen und die Installation abschließen – Schritt für Schritt, mit Fortschrittsanzeige und ohne manuelles Hantieren an Konfigurationen. Bis die Einrichtung abgeschlossen ist, bleibt die Anwendung gesperrt und verweist freundlich auf den Assistenten.
„CVE" – Cisco-Schwachstellen-Check als neues Modul. Eine öffentliche Prüfseite vergleicht ausgewählte oder manuell eingegebene Geräte und Software-Versionen gegen die offizielle Cisco-Schwachstellen-Datenbank, zeigt Severity, CVSS, gefixte Versionen und Workaround-Verfügbarkeit pro Treffer an und gibt konkrete Handlungsempfehlungen. Tippfehler in der Software-Version werden bereits beim Eintippen über eine Autovervollständigung mit den von Cisco gepflegten Releases abgefangen.
apiconsole.cisco.com, testen die Verbindung mit einem Klick, sehen den Status pro Teil-API getrennt und können den Antwort-Cache selektiv leeren. Eine Status-Kachel zeigt Token-Gültigkeit, Cache-Statistik und die letzten Anfragen.„Translated" – projektweite DE/EN-Internationalisierung. Die komplette UI-Hülle (PHP-Templates und JS-Bundles) ist jetzt DE/EN-zweisprachig, alle nutzersichtbaren API-Fehlermeldungen liefern lokalisierten Text passend zum aktiven Cookie, und die zuvor eigenständige SDA-i18n-Runtime ist in das projektweite t()/te()-System konsolidiert – ein Sprach-Switcher schaltet jetzt Konfigurator, CLI-Editor, SSH-Terminal, Feedback-Flows und den SDA-Wizard gemeinsam um.
app_lang-Cookie und wirkt projektweit.admin/includes/i18n/*.php (eine Datei pro Modul: common, btn, js, api, sda, wizard, inbox, customers, …). Modul-Dicts liefern ['de' => …, 'en' => …] und werden automatisch eingelesen.admin/includes/i18n.php: t($key, $params), te() (HTML-escaped), Platzhalter :name, Locale-Auflösung GET → Cookie → Session → Default.js/i18n.js (window.i18n.t/te) liest das vom Server injizierte window.__I18N-Mapping und unterstützt dieselben Platzhalter.tests/i18n.smoke.php: prüft pro Dict-File, dass jeder Key in beiden Sprachen vorhanden ist.admin/api/* – Kern-Projekt-Endpoints, Template-Schema-Validierung, Feedback-/CLI-Snippet-/Firmware-Upload-APIs, das gesamte vault/* (29 Dateien, json_fail()-Helper) sowie die Plain-Text-Antworten der download/*- und export/*-Endpoints – liefern lokalisierten Text.admin/includes/sda/i18n.php mit eigenem sda_lang-Cookie und sda_t()/sda_te()) ist entfernt; SDA-Keys leben jetzt unter dem sda.*-Prefix im projektweiten Dictionary, der Sprach-Switcher umfasst auch den Wizard.i18n.t('...') auf.new Function()-Bundles im Test-Sandbox die i18n.t/te-Aufrufe nicht mehr abbrechen.$_COOKIE['sda_lang'] aus der Locale-Auflösung in locale() – die SDA-Konsolidierung hat den Cookie auf app_lang vereinheitlicht.admin/includes/sda/i18n.php samt Funktionen sda_t/sda_te/sda_locale/sda_set_locale/sda_locale_labels und dem internen _sda_dict().tests/sda-i18n.smoke.php: das Verhalten ist nun vollständig durch tests/i18n.smoke.php abgedeckt.„Locked" – Modulsteuerung und harter Wartungsmodus. Einzelne Module (Konfigurator, CLI-Editor, Live-SSH-Terminal, SDA-Wizard) lassen sich jetzt gezielt sperren – mit eigenem Hinweistext, Superadmin-Bypass und voller Audit-/Postfach-/Webhook-Spur. Der Wartungsmodus wirkt erstmals serverseitig hart und wird ebenfalls als System-Webhook ausgespielt.
module.access_changed und maintenance.changed (Klasse system, nur über das Superadmin-Webhook-Modal in der neuen Gruppe System abonnierbar).SDA-Phase 6: High-Level-Design-Vorschau mit SVG-Diagrammen. Neue read-only Seite admin/sda/preview.php bündelt das komplette Design (Eckdaten, Annahmen/Risiken, Standorte, Fabric/Transits, Adressplan, VNs, Segmentierung, Services, Validierung) als druckfreundliches HTML mit serverseitig gerenderten, deterministischen SVG-Diagrammen. Basis für den Export/Public-Preview in Phase 7. Auth-gated – kein öffentlicher Zugriff in dieser Phase.
admin/includes/sda/diagram.php (pure, DB-frei, deterministisch): Topologie (Fabrics + Transit-Bus), Fabric-Detail (Rollen-Tiers inkl. Border+CP/Intermediate, SKU ×Anzahl), Standort-Hierarchie (Area→Building→Floor mit Σ-Aggregaten), VN↔IP-Pool (bipartit). XSS-sicheres SVG-Escaping.admin/sda/preview.php: alle Sektionen + die vier Diagramme + Validierungs-Zusammenfassung (Regel-Engine). „HLD-Vorschau"-Button im Wizard-Header und Spalte in der SDA-Liste.preview.*/diagram.* (DE+EN, Parität gewahrt, EN umlautfrei).admin/css/admin.css (@media print, break-inside-Schutz für Diagramme).tests/sda-wizard.smoke.js um Preview-/Verlinkungs-/i18n-Checks erweitert. Gesamte Smoke-Suite grün.„Feld-Erläuterung"-Kachel für alle 9 Wizard-Steps. Die in Step 2 eingeführte Hilfebox ist jetzt ein wiederverwendbarer Helper (sda_help_box()) und wird als eigene Kachel unten in jedem Tab gerendert – zwischen den Eingabefeldern und der globalen Footer-Navigation. Jeder Step (Eckdaten, Standorte, Fabric & Transits, Rollen & Hardware, Adressplan, Virtual Networks, Segmentierung, Services & Identity, Validierung & Migration) hat eine eigene, fachlich passende Erläuterung mit korrekten Umlauten. i18n DE/EN-Parität 246/246.
sda_help_box($titleKey, $bulletKeys) in admin/sda/wizard.php: einheitliche Card (gleicher Stil wie SSH-/SDA-Hinweisboxen), Bullets via sda_t() (roh, da Inline-HTML wie <strong>/<em>/<code>), Titel escaped.Tab-Design + Step-2-UX. Bei 9 Steps brachen die Bootstrap-nav-tabs mehrzeilig um und „stapelten" sich optisch. Umstellung auf nav-pills (rundum abgerundete Button-Pills in einem umrandeten Flex-Container) – sauberer Umbruch, aktiver Step klar markiert, Content-Block jetzt rundum umrandet. Step 2 „Standorte" bekommt eine Feld-Hinweisbox (Name/Typ/EP/AP/SW erklärt) und gehärtete Zahlenfelder (Client-Guard + serverseitige Integer-Validierung).
nav nav-pills im umrandeten bg-body-tertiary-Container mit flex-wrap gap-2; Step-Nummer als rounded-pill-Badge. Content-Block von border-top-0 rounded-bottom auf border rounded umgestellt (alle Ecken abgerundet, da Pills nicht mit dem Block verbunden sind).type=number step=1 inputmode=numeric + Client-Guard (js/sda/wizard.js strippt Nicht-Ziffern, paste-sicher). Serverseitig (admin/api/sda/sites.php): Nicht-Integer → HTTP 422 „Nur ganze Zahlen erlaubt", Negativwerte werden auf 0 geklemmt.Zwei SDA-Wizard-Bugfixes. (1) Umlaut-Darstellung: die deutschen UI-Strings nutzten durchgängig ASCII-Transliterationen (fuer/Loeschen/Zurueck …) statt echter Umlaute – jetzt korrekt UTF-8 (für/Löschen/Zurück). Der englische i18n-Block bleibt nachweislich unverändert. (2) Tab-Sprung: jede Add-/Delete-Aktion löste window.location.reload() aus, wodurch der Wizard immer auf Schritt 1 zurücksprang. Der aktive Tab wird jetzt pro Design in sessionStorage gehalten und nach Reload (und nach dem Sprach-Switch-Redirect) wiederhergestellt.
i18n.php wurde gezielt vom Mapping ausgeschlossen; Smoketest verifiziert nun: DE hat echte Umlaute + keine Transliterationen mehr, EN enthält keine Umlaute, Key-Parität 197/197 unverändert.js/sda/wizard.js persistiert den aktiven Tab unter sda_wizard_tab_<designId> in sessionStorage (Event shown.bs.tab) und stellt ihn beim Laden via restoreTab() wieder her – bevor syncNav() die Prev/Next-Buttons synchronisiert. Behebt das Verhalten für ALLE reload-basierten Aktionen über alle neun Steps (Standort/Fabric/Transit/Rolle/Pool/VN/SGT/Service hinzufügen + löschen) und überlebt zusätzlich den Sprach-Switch-Redirect.Wizard-Steps 5–9 + Validierungs-Rule-Engine (SDA-Phase 5). Der SDA-Wizard ist jetzt vollstaendig: Adressplan (IP-Pools), Virtual Networks mit Pool-Mapping, Segmentierung mit klickbarer SGT-Policy-Matrix, Shared Services/Identity sowie Validierung & Migration. Eine neue Rule-Engine prueft das Design auf Vollstaendigkeit und Plausibilitaet (Fehler/Warnung/Hinweis) und macht bei verknuepftem Classic-Projekt eine Brownfield-Adressplan-Verschneidung gegen die Bestands-Configs. Zweisprachig (DE/EN) durchgaengig – das i18n-Dictionary umfasst jetzt 197 Keys je Locale.
admin/includes/sda/rules.php: sda_rules_run() mit ~25 Regeln auf dem Phase-3-Schema – Pool-Overlap (IPv4/IPv6), fehlende CP/Border/Edge, ungerade Border-Anzahl, Single-CP-Hinweis, Handoff-Pflicht bei Border, FiaB-Konsistenz, VN-ohne-Pool, Pflicht-Pooltypen, SGT-Default, Contract-Luecke, Shared-Services-Luecken (DHCP/DNS/ISE/CatC), DNA-Advantage-Reminder, Multicast-RP-Doku-Hinweis und Brownfield-Adressplan-Verschneidung (CIDR-Extraktion aus den Classic-Configs via sda_extract_ipv4_cidrs()). sda_rules_summary() liefert die Badge-Zaehler.admin/includes/sda/services.php: CRUD + Ownership-Guard fuer Shared Services. In load.php verdrahtet (services + rules).admin/api/sda/: addressplan.php (kind=pool/vn/map), segmentation.php (kind=sgt/contract, action=default loescht), services.php, validate.php (read-only, GET+POST). Alle mit Ownership-Checks und ueber das gemeinsame _boot.php abgesichert.bindEntity()-Feldbinder fuer Steps 5–8, Pool-Mapping-Toggle, zyklische Matrix-Zellen, Validierungs-Panel-Rendering. design.php kennt jetzt die Liste „migration" (sda_assumptions category=migration).SDA-Design-Kachel layout-vereinheitlicht. Die Frontend-Kachel sitzt jetzt oberhalb der Live-SSH-Terminal-Kachel und nutzt dasselbe Zwei-Spalten-Layout wie diese: Aktions-Karte links (col-lg-7), separate „Hinweis & Ablauf"-Box rechts (col-lg-5). Damit ist der Frontend-Block optisch konsistent statt einer schmalen, abweichenden Einzelkarte.
index.php): Markup von der Stelle unterhalb der SSH-Kachel nach oberhalb verschoben. Neue rechte Spalte „Hinweis & Ablauf" (HLD statt Config, Autosave/Versionierung, Backend-/Audit-Bindung, Sprachumschalter, Rollen-Verfügbarkeit) im selben card border-0 shadow-sm-Stil wie die SSH-Sicherheitsbox. Eligibility-Gate, Kachel-ID und Login-Toggle unverändert – die Phase-4-Smoketests greifen weiterhin.Frontend-Einstiegskachel fuer das SDA-Modul. Der SDA-Wizard war bisher nur ueber die Backend-Navigation auffindbar. Analog zur bestehenden „Live-SSH-Terminal"-Kachel zeigt das oeffentliche Frontend jetzt – nur nach Login, fuer alle Rollen – eine „SDA Design & HLD"-Kachel mit Kurzbeschreibung und einem Button, der auf den Backend-Wizard verlinkt. Der eigentliche Wizard bleibt unveraendert account- und audit-gebunden im Backend; die Kachel enthaelt keine sensiblen Daten.
index.php): Markup wird immer gerendert und beim Page-Load per d-none ausgeblendet, wenn nicht eingeloggt. _adminApplyUI() in js/admin.js toggelt die Sichtbarkeit live bei Login/Logout (kein Page-Reload), identisch zum Pattern der SSH-Kachel. Zugriffsgate $sdaTileEligible = alle eingeloggten Rollen (user/admin/superadmin). Button verlinkt auf admin/sda/index.php (Design-Liste), nicht direkt in den Wizard.d-none-Default, Backend-Link, und der Login-synchrone d-none-Toggle in js/admin.js.Erste UI-Stufe des SDA-Planungs-Moduls (SDA-Phase 4). Neuer Admin-Bereich SDA Design mit Design-Liste und einem vierstufigen Wizard (Eckdaten / Standorte / Fabric & Transits / Rollen & Hardware), der direkt auf dem Phase-3-Service-Layer aufsetzt. Alle Felder speichern per Autosave (debounced fetch) gegen drei CSRF-geschützte JSON-Endpoints; Listen-Items (Sites, Fabrics, Transits, Rollen, Annahmen, Risiken) werden per AJAX angelegt/gelöscht. Zweisprachig ab Tag 1 (DE/EN) über ein leichtgewichtiges Array-i18n mit Sprach-Switcher; jeder Übersetzungs-Key existiert in beiden Locales (smoketest-verifiziert).
admin/sda/index.php mit Status-/Typ-Badges, Filter (Name/Public-ID/Status) und einem Anlege-Modal inklusive Brownfield-Verknüpfung (Classic-Projekt-Dropdown, clientseitig nach Kunde gefiltert).admin/sda/wizard.php: Bootstrap-Tabs mit Prev/Next-Navigation. Step 1 Eckdaten (Name, Kunde, Beschreibung, Greenfield/Brownfield, Classic-Link) + Inline-Listen für Annahmen und Risiken; Step 2 rekursiv gerenderter Standort-Tree (Area→Building→Floor) mit Add-Root/Add-Child/Delete; Step 3 Fabric-Sites + Transits als Karten-Editoren; Step 4 Rollen-Tabelle pro Fabric mit SKU-Datalist aus dem Switch-Katalog.admin/includes/i18n.php: sda_t() / sda_te() (HTML-escaped) mit DE- und EN-Dictionary (je >120 Keys), Locale-Präzedenz GET → Cookie → Session → Default „de", Fallback fehlender EN-Key → DE → Key. Sprach-Switcher im Header von Liste und Wizard.admin/api/sda/ mit gemeinsamem _boot.php (require_auth + csrf_verify + JSON-Helper + Design-404-Guard): design.php (Stammdaten-PUT + Annahmen/Risiken-Listenops), sites.php (Site-Tree-CRUD mit Ownership-Check), fabric.php (Fabric/Transit/Rollen-CRUD via kind-Diskriminator, je mit Zugehörigkeits-Prüfung gegen das Design).js/sda/wizard.js: debounced Autosave (600 ms) mit Header-State-Anzeige (Speichere…/Gespeichert/Fehlgeschlagen), CSRF-Header aus dem Meta-Tag, Add/Delete für alle Listentypen, Prev/Next-Tab-Navigation synchron zu den Bootstrap-Tabs.tests/sda-wizard.smoke.js (55 Assertions – Datei-Inventar, DE/EN-Key-Parität, Header-Nav in beiden Branches, Tab-Struktur, API-Methoden + Ownership-Checks, wizard.js-Endpoints) und tests/sda-i18n.smoke.php (12 Assertions – Locale-Default, Key-Parität via Reflection, Auflösung, Unknown-Key-Fallback, Platzhalter, HTML-Escaping).$activePage === 'sda'.Datenbank-Foundation für das SDA-Planungs- und HLD-Modul (SDA-Phase 3). Sechs neue idempotente Migrationen unter admin/migrate/sda-*.php legen das vollständige Schema an: Designs, Site-Hierarchie, Fabric-Sites + Rollen, Transits, IP-Pools, Virtual Networks, VN-/Pool-Mapping, Border-Handoffs, SGTs, Contracts, Shared Services, Annahmen, Risiken, SVG-Diagramm-Cache und immutable HLD-Versions-Snapshots — alles in PG- und MariaDB-Varianten mit konsequenter Idempotenz. Brownfield-Bindung über nullable FKs auf beiden Seiten (sda_designs.classic_project_fk und staging_projects.sda_design_fk) plus eine Read-only-View v_brownfield_overview. Darüber liegt ein prozedurales Service-Layer-Skelett unter admin/includes/sda/ mit stabilen Signaturen für Design-, Site-, Fabric-, Address-Plan-, Segmentation-, BOM- und Brownfield-Operationen, das ab Phase 4 vom Wizard konsumiert wird.
sda_designs (Design-Header mit 12-stelliger Public-ID, Status draft/review/finalized/archived, Versions-Bump), sda_sites (selbstreferenzieller Tree Global → Area → Building → Floor), sda_fabric_sites (Fabric-Definition pro Standort, Typ collocated/dedicated/fiab), sda_transits (sd-access/ip-based/sdwan) und sda_roles (Rollenbelegung CP/Border/Edge/Extended/Policy-Extended/FiaB mit device_sku + device_count).sda_ip_pools (8 Pool-Typen Underlay/Loopback/P2P/LAN-Auto/Border-Handoff/Overlay/AP-Mgmt/Guest), sda_virtual_networks (VNs mit Anycast-GW, L2-Handoff, Multicast-Mode), sda_vn_pool_map (n:m), sda_handoffs (eBGP-AS-Plausibilität via CHECK 1..4294967295).sda_sgts (0..65535, UNIQUE (design_fk, tag_value) + UNIQUE (design_fk, name)) und sda_contracts (n:m mit action allow/deny/log, UNIQUE über die SGT-Paar-Achse für saubere UPSERT-Semantik).sda_services (8 Service-Typen DHCP/DNS/NTP/ISE/CatC/RADIUS/TACACS/other mit Reachability shared/border/fusion), sda_assumptions (5 Kategorien) und sda_risks (4 Severities low/medium/high/critical) für die HLD-Kapitel Annahmen und Risiken.sda_diagrams (SVG-Cache mit 8 erlaubten Diagrammtypen site-tree/fabric/multi-site/vn-pool/policy-matrix/ha-cluster/services/migration-gantt) und sda_hld_versions (immutable Snapshots mit SHA-256-Hash, UNIQUE (design_fk, version_num), JSONB-Metadata).staging_projects.sda_design_fk + Index. Read-only-View v_brownfield_overview joint Classic-Projekt und SDA-Design (LEFT JOIN, NULL-Spalten bei Greenfield).design.php (CRUD + Public-ID-Generator A-Z/2-9 ohne 0/O/1/I, Versions-Bump, Status-Wechsel), sites.php (Tree-Aufbau, Reorder), fabrics.php (Fabric/Rollen/Handoffs/Transits), addressplan.php (Pools/VNs/Mapping + pure-PHP-CIDR-Overlap-Detektor für IPv4 + IPv6), segmentation.php (SGTs/Contracts/Matrix mit UPSERT-Semantik), bom.php (Stub mit Chassis-Aggregation aus sda_roles; volle Implementierung in Phase 7), brownfield.php (Hin-/Rück-Link mit Transaktion). Single-Include-Point admin/includes/sda/load.php.admin/migrations.php für alle sechs SDA-Migrationen (sortiert im bestehenden Block, mit Phase-3-Marker in der Beschreibung).Cross-Domain-Compatibility-Matrix für den Hardware-Katalog (SDA-Phase 2). Elf neue Helper-Funktionen verbinden die fünf Catalog-Domänen (Switches / NMs / Linecards / Supervisoren / Optiken / Netzteile) zu einem konsistenten Lookup-Geflecht. Jedes Detail-Modal im öffentlichen Geräte-Katalog zeigt jetzt die passenden Cross-Domain-Treffer: Switches listen kompatible Optiken (gruppiert nach Familie) plus kompatible Netzteile; NMs/Linecards/Supervisoren listen die für ihre Port-Typen verbaubaren Optiken; Optiken und Netzteile bieten einen Reverse-Lookup „Verbaubar in …" mit Switches/NMs/Linecards/SUPs pro Cat9k-Serie. Damit ist die Foundation gelegt, auf der Phase 3+ (SDA-Datenmodell, Wizard, BOM-Aggregation) ohne weitere Datenarbeit aufsetzen kann.
js/catalog/helpers.js — findOptic(sku), findPsu(sku), platformPortTypes(m) + platformPortTypesExtended(m) (sammeln direkt vs. inkl. NM/LC/SUP), opticsCompatibleWithSwitch/Nm/Lc/Sup, psusCompatibleWith sowie die Reverse-Lookups opticPlatformsFor und psuPlatformsFor. Single Source of Truth für die Public-Detail-Modals heute und die spätere SDA-BOM-Aggregation (Phase 7).platformPortTypes(m) markiert stapelfähige Switches mit einem Pseudo-Port-Typ stack, sodass STACK-T1-*/STACK-T4-*-Kabel mit compatibility.ports: ['stack'] automatisch in den passenden Switch-Serien (C9300/L bzw. C9300X) erscheinen — ohne die Series-Filter zu umgehen.stack-Pseudo-Port automatisch in den richtigen Switch-Serien.tests/optics-compat.smoke.js: 34 Cross-Domain-Assertions — Existenz aller elf Helper, Coverage (jeder Glas-/Stack-Port-fähige Switch/NM/Linecard hat ≥1 kompatible Optik, jeder Switch hat ≥1 kompatible PSU), Stack-Cable-Special-Cases (StackWise-480 nur C9300/L, StackWise-1T nur C9300X), Symmetry-Spot-Check (Onboard-Reverse ⊂ Forward) und Sanity-Checks gegen die portlosen C9600/C9610-Supervisoren.PWR-C1-*-P-Einträgen — die Smoketest-Coverage hätte sie bei sonst gleicher PSU-Architektur als „kein Netzteil"-Lücke gemeldet. C9350-Hochlast-Modelle wie C9350-48HX sind jetzt auch auf PWR-C1-1900WAC-P abgebildet.compatOpticsBlock, compatPsusBlock, reversePlatformsBlock, reverseSwitchesBlock) plus sieben Aufruf-Pattern-Checks in den jeweiligen render*Detail-Funktionen.Vorbereitung des Hardware-Katalogs für das künftige SDA-Planungs- und HLD-Tool. js/switches-data.js ist in fünf themenscharfe Dateien unter js/catalog/ zerlegt (Chassis, NMs, Supervisoren, Linecards, Helper) – Verhalten und Globals bleiben identisch. Darauf aufbauend kommen zwei neue Domänen: ein Optik-Katalog mit 86 Cisco-OEM-SKUs (1G SFP, 10G/25G SFP+/SFP28, 40G/100G QSFP+/QSFP28, Multirate, DAC/AOC, Breakout-Kabel sowie StackWise-480/1T-Kabel) und ein AC-PSU-Katalog mit 17 SKUs über alle Catalyst-9000-Serien hinweg. Der öffentliche Geräte-Katalog (device-catalog.php) bekommt zwei neue Tabs „Optiken" und „Netzteile" mit Familien-/Serien-Filter und vollständigem Detail-Modal inklusive kompatibler Port-Typen und Cat9k-Serien. Damit ist die Datenbasis gelegt, um in den nächsten SDA-Phasen verbindliche Bill-of-Materials direkt aus dem Design zu erzeugen.
js/catalog/optics.js mit 86 Cisco-OEM-Transceiver-SKUs. Datenfelder pro Eintrag: sku, family, speed, mediaType (fiber/copper/dac/aoc/stack-cable), reach+reachM, wavelength, connector, fiber, dom, temp (COM/EXT/IND), breakout sowie compatibility.ports/compatibility.series. Abdeckung: 1G (8), 10G (20), 10/25G Multirate (2), 25G (13), 40G (19), 100G (17), Stack-Kabel (7). 400G-Optiken bewusst ausgelassen — werden bei realem SDA-Bedarf später ergänzt.js/catalog/psus.js mit 17 SKUs über alle Catalyst-9000-Serien — C9200/L (3), C9300/L/X (4), C9400 modular (3), C9500 (3), C9600 (2), C9610 (2). Datenfelder: watts, type (AC), formFactor (fixed/modular), platinum (80 Plus), poeCapable, airflow (standard/reverse) sowie compatibility.series. DC/HVDC-Varianten und höhere C9500X-Klassen werden bei realem Bedarf später ergänzt.device-catalog.php. Tab „Optiken" filtert nach Optik-Familie (SFP/SFP+/SFP28/QSFP+/QSFP28/StackWise-480/StackWise-1T), Tab „Netzteile" nach Cat9k-Serie. Detail-Modal zeigt Speed, Reichweite, Connector, Faser-/Kabeltyp, Wellenlänge, DOM, Temperaturbereich, Breakout-Annotation, kompatible Port-Typen und kompatible Switch-Serien (Optik) bzw. Watt, Formfaktor, Airflow, Platinum, PoE-Eignung und kompatible Serien (PSU). Single Source of Truth für die spätere SDA-BOM-Aggregation.js/switches-data.js ist byte-genau in fünf Domain-Dateien zerlegt — js/catalog/switches.js (SWITCH_CATALOG), js/catalog/nms.js (NM_CATALOG), js/catalog/supervisors.js (SUP/C9600_SUP/C9610_SUP_CATALOG), js/catalog/linecards.js (LC/C9600_LC/C9610_LC_CATALOG) und js/catalog/helpers.js (sämtliche Lookups, Linecard-Speed-Modi, License- und VRF-Helper). Verhalten ist identisch — Globals bleiben im selben Namensraum. index.php und device-catalog.php laden jetzt sieben statt einem <script>-Tag.tests/optics-catalog.smoke.js (48 Assertions: Pflichtfelder, SKU-Eindeutigkeit, Speed-Klassen-Abdeckung, Breakout-Konsistenz, Stack-Kabel-Compat, SKU-Anker) und tests/psu-catalog.smoke.js (39 Assertions: AC-only, Watt-Plausibilität, Serien-Coverage über alle Cat9k-Serien, Formfaktor-Konsistenz für modulare vs. fixed Chassis-Klassen).tests/vrf-pass.smoke.js und tests/routed-ports.smoke.js konkatenieren die fünf Catalog-Dateien in derselben Reihenfolge wie der Browser zu einem virtuellen SWITCHES_SRC — funktional identisch zur früheren Single-File-Quelle. tests/device-catalog.smoke.js prüft jetzt sieben <script src=…>-Patterns (statt einem) sowie sechs Tab-Anker und die neuen Render-/Detail-Funktionen.CSV- und Excel-Export für alle Admin-Listen-Seiten. Über einen neuen "Export"-Dropdown-Button rechtsbündig zwischen Filter-Form und Tabelle lädt der Admin den aktuellen Listen-Stand als UTF-8-CSV (RFC-4180, mit BOM für Excel-Codierungs-Heuristik) oder als echtes XLSX (PhpSpreadsheet, mit Bold-Header, eingefrorener Top-Zeile, Auto-Filter und Auto-Sizing) herunter. 13 Endpoints decken Projekte, Audit-Logs (Security/SSH/SSH-Vault/Error), Stammdaten (Kunden/Benutzer/Firmware/CLI-Snippets/Webhooks) und Feedback (Bugs/Features/Inbox) ab — die Filter der jeweiligen Listen-Seite werden 1:1 auf den Export übertragen, sodass der Empfänger genau den gefilterten Ausschnitt bekommt. CSV-Injection-Schutz (OWASP-Liste maskiert =/+/-/@/TAB/CR-Prefixe mit Apostroph) und ein konsequenter Ausschluss sensibler Spalten (Passwort-Hashes, MFA-Secrets, API-Tokens, Webhook-HMAC-Secrets) sind in der Foundation verbaut. Begleitend ist im Frontend der Geräte-Katalog als öffentliche Seite verfügbar, der CSRF-Enforcement-Mode wurde nach mehrtägigem sauberem Audit-Log auf hard gestellt und der frühere Backend-Geräte-Katalog entfernt.
admin/includes/export-helpers.php mit export_csv_stream() (UTF-8-BOM, RFC-4180-Quoting, CRLF-Zeilenende) und export_xlsx_stream() (PhpSpreadsheet 5.7.0, Bold-Header, Freeze-Panes A2, Auto-Filter über alle Spalten, Auto-Sizing). Gemeinsamer Helper export_cell_escape() schützt vor CSV-Injection per OWASP-Liste (=/+/-/@/TAB/CR-Prefix erhält ein führendes Apostroph; int/float-Typen werden korrekt ohne Maskierung durchgereicht). export_sanitize_filename() liefert path-traversal-sichere Dateinamen.admin/api/export/projects.php mit den 9 Listen-Spalten (Projekt-ID, Auftrag, Kunde, Projektname, Stager, Geräte, Status, Erstellt, Aktualisiert). Filter q/status/from/to und der User-Rollen-Scope (project_users-EXISTS) sind identisch zur List-Seite.admin_id-Filter) und Error-Audit (14 Spalten inkl. Stack-Trace). Alle filtern via gleicher GET-Parameter wie die List-Seite.password_hash/mfa_secret/api_token), Firmware-Images (mit Customer-Aggregation per STRING_AGG/GROUP_CONCAT), CLI-Snippets (mit Body) und Webhook-Subscriptions (ohne hmac_secret, Events-JSON als Klartext).bug_assignee/bug_watcher), Feature-Requests (User-Scope per feature_assignee/feature_watcher, mit Sort-Switch) und persönliches Postfach (immer auf admin_fk = $myId gescoped, kein Cross-User-Zugriff).security_audit_log, error_audit_log, admin_inbox, firmware_images, webhook_subscription), liefern statt eines Crashs einen leeren Export mit Hinweis-Zeile.device-catalog.php spiegelt die bisher Backend-only Lese-Übersicht ins Frontend. Vier Tabs (Switches / Netzwerkmodule / Linecards / Supervisoren) mit Filter, Series-Pillen, Stat-Karten und einem geteilten Detail-Modal inklusive VRF-Lite-Skala (aus js/switches-data.js). Aufgerufen wird die Seite über den Info-Dropdown – eine neue Trennlinie nach „Release Notes" leitet den Referenz-Block ein, in dem Geräte-Katalog vor der Lizenz-Featurematrix steht.hard: CSRF_ENFORCEMENT_MODE in admin/config.php auf hard umgestellt. Verstöße werden ab sofort sofort mit HTTP 403 abgewiesen statt nur protokolliert. Voraussetzung war ein über mehrere Tage sauberes Security-Audit-Log ohne Soft-Fail-Einträge — alle Frontend- und Backend-Aufrufer sind auf den einheitlichen CSRF-Guard migriert.composer.json um phpoffice/phpspreadsheet ^5.7 erweitert. Bringt transitiv markbaker/matrix + markbaker/complex (Matrix-/Komplex-Mathematik in Formeln), maennchen/zipstream-php (XLSX-Zip-Streaming), composer/pcre + psr/simple-cache mit. .gitignore ist um die drei neuen Top-Level-Vendor-Verzeichnisse erweitert, konsistent zum bisherigen Pattern.border-start border-4 border-cisco-blue) plus Inline-h6-Header im card-body. Daneben wirkte sie eingerückt. Position jetzt direkt unter der SVI-Kachel (globale Routing-Basis bleibt im Sichtfeld), Card-Pattern an Loopback/VRF angeglichen (card border-0 shadow-sm mit eigenem card-header und card-body p-3).$pdo->prepare(...) ohne vorherigen $pdo = get_db()-Aufruf — Folge war ein Fatal Error, und mit display_errors=off in Production lieferte PHP eine weiße Seite statt einen Download. Inzwischen fängt ein Regression-Guard in der Smoke-Suite den gleichen Fehler in zukünftigen Endpoints ab.admin/switch-catalog.php wurde gelöscht und der zugehörige Navigations-Eintrag in admin/includes/header.php entfernt. Die Daten waren nie geheim und stehen jetzt unter device-catalog.php ohne Login zur Verfügung — single source of truth für die Public-Seite, kein paralleles Backend-Pendant mehr.Virtual Routing & Forwarding (VRF Lite) als durchgängiges Feature. Der Wizard kann jetzt Mandanten-VRFs anlegen, an SVIs / Loopbacks / Routed Ports binden und in OSPF, OSPFv3, EIGRP-Named-Mode und BGP referenzieren. Hardware-Skala kommt direkt aus dem Switch-Katalog (4 User-VRFs auf C9200, 1 auf C9200L/CX, 256 auf C9300/X/350/9400/9500 access-class, 1024 auf C9500H/X und C9600) – Werte sind aus den Cisco IOS-XE 17.x Config-Guides verifiziert. Beim ersten VRF-Anlage fragt der Wizard nach einem License-Upgrade auf Network Advantage; im Backend zeigt sowohl das Geräte-Katalog-Detail-Modal als auch die Schritt-2-Specs-Kachel die VRF-Skala des gewählten Modells. Customer-Templates erhalten einen neuen step4.vrfs[]-Block (Schema-Version 10) mit Locked- und Preset-Modus.
[A-Za-z0-9][A-Za-z0-9._-]*, reservierte Namen „default" und „Mgmt-vrf" sind gesperrt), Route-Distinguisher (Live-Validation analog zu den IP-Feldern in Schritt 1), Address-Family-Toggles IPv4/IPv6 und Import-/Export-Route-Target-Listen pro AF. Mgmt-vrf wird als read-only System-VRF (Lock-Icon, nicht editierbar/löschbar) automatisch geseedet, weil er auf Catalyst 9000 nativ existiert.vrf forwarding NAME emittiert. Stale-Werte werden im Dropdown als „(nicht definiert)" markiert und beim Submit von validateVrfBinding abgewiesen. SVI- und Loopback-Tabellen blenden eine VRF-Spalte ein, sobald mindestens ein Eintrag gebunden ist.vrf definition NAME-Bloecke direkt nach den globalen Routing-Toggles, alphabetisch sortiert, mit Description, RD und je nach AF-Flag address-family ipv4|ipv6 + Export-/Import-Route-Targets. Cisco-kritische Reihenfolge auf den Interfaces: vrf forwarding NAME steht VOR ip address, sonst löscht IOS-XE die Adresse beim Apply. Statische Routen emittieren ip route vrf NAME bzw. ipv6 route vrf NAME. OSPF/OSPFv3-Prozesse hängen vrf NAME an die Prozess-Zeile an. EIGRP-Named-Mode setzt den vrf-Token zwischen unicast und autonomous-system; im Classic-Mode wird ein Warn-Comment emittiert (Cisco unterstützt VRF nicht in Classic-EIGRP). BGP gewinnt einen dedizierten VRF-Pfad mit address-family ipv4|ipv6 vrf NAME-Blöcken.VRF_LIMITS_BY_SERIES + VRF_LIMITS_BY_SKU mit den verifizierten Cisco-Werten (4 / 1 / 256 / 1024 je nach Modell). Helper modelVrfMax, modelVrfCapable, stackVrfMax (Stack-Minimum gemischter Konfigurationen). Der Wizard ersetzt den hartcodierten Soft-Limit 32 durch dieses dynamische Hard-Limit; der Add-Button wird beim Erreichen disabled, der Banner-Text nennt das Modell-spezifische Limit.switches-data.js-Helper._ensureSystemVrfs, damit Mgmt-vrf konsistent bleibt.vrf erweitert: ADVANTAGE_FEATURES in switches-data.js listet jetzt zusätzlich vrf. Der Registry-Eintrag in license-gate.js stellt den Cleanup-Hook für Downgrade-Konflikte (alle User-VRFs entfernen, Bindings auf Interfaces/Static-Routes/Protokolle zurücksetzen, Tabellen + CLI re-rendern).admin/api/template.php akzeptiert nun Schemata v2 bis v10. Pre-v10-Templates ohne step4.vrfs[] bleiben kompatibel; Templates mit gesetztem VRF-Block erzwingen v10._captureStep4() hatte den neuen vrfs-Slot zunächst nicht in den Wizard-Snapshot übernommen, sodass VRF-Konfigurationen beim Save (manuell und Auto-Save) verloren gegangen wären. Restore las den Slot bereits korrekt; jetzt ist die Symmetrie hergestellt.ue/oe/ae); alle user-sichtbaren Strings sind jetzt konsistent UTF-8 (z. B. „VRF hinzufügen", „… kann nicht gelöscht werden", „Modell-Limit erreicht").Durchgehend bessere Workflows zwischen den Wizard-Schritten und ein neues, einheitliches Bestätigungs-Modal-Design. Routing-Protokoll-Aktivierungen synchronisieren sich jetzt in beide Richtungen zwischen Routed-Ports (Schritt 2) und Routing (Schritt 4), die Schritt-Indikatoren in der Wizard-Navigation sind klickbar und zeigen invalide Eingaben farblich an, und sämtliche Bestätigungs-Dialoge wurden von Browser-Prompts auf ein gebrandetes Bootstrap-Modal umgestellt – mit Variant-Farbgebung, semantischen Button-Labels und Konflikt-Listen bei Kaskaden-Aktionen.
Layer-3-Routed-Ports auf physischen Switch-Ports. Bisher waren Layer-3-Interfaces nur als SVIs (Schritt 4) abbildbar; der L3-Pass macht beliebige Downlink- oder Uplink-Ports im Schritt 2 routbar. „Routed"-Modus existierte rudimentaer (Mode-Toggle + ip address), wurde aber im L3-Pass zur Cisco-IOS-XE-konformen Vollvariante ausgebaut: IPv6-Adresse + Prefix-Laenge, MTU (Jumbo-Frames), DHCP-Helper-Liste, Per-Interface OSPF/OSPFv3/EIGRP-Bindung, visuelle Markierung im Frontpanel (Aquamarin-Stroke + L3-Badge analog Po-Label), automatische Filterung der L2-only-Subkommandos (`switchport`, `spanning-tree`, `port-security`, `ip dhcp snooping trust`, `ip arp inspection trust`) im CLI-Builder. Das License-Gate erweitert sein EIGRP-Cleanup um die per-Routed-Port-Bindings, sodass beim Downgrade auf Network Essentials keine Zombie-Konfiguration zurueckbleibt. Pflichtfeld- und Optional-Badges sind im Schritt-2-Akkordion durchgehend konsistent.
modelL3Capable() in switches-data.js mit Default true (alle aktuellen Catalyst-9k unterstuetzen Routed Ports nativ). defaultGroupConfig um sieben Routed-Felder erweitert (ipv6Address, ipv6PrefixLen, mtu, ipHelperAddresses, perItfOspfArea, perItfOspfv3Area, perItfEigrpIpv6). _portGroupEnsureRoutedDefaults backfillt Pre-L3-Drafts mit Type-Coercion (NaN/Strings/falsche-Range-Werte werden defensiv normalisiert); Restore-Hook in project-edit.js::_applyStep2State.onRoutedPortInputValidate dispatcht ueber data-routed-validate an die Wizard-Validatoren aus validation.js. STP- und Sicherheit-Akkordion-Tabs werden im Routed-Modus komplett ausgeblendet (vorher: nur Banner/Badge). Tab „Layer 2" -> „Modus" (Downlink + Uplink). Optional/Pflichtfeld-Badges im gesamten Akkordion auf Projekt-Konvention angeglichen.drawRoutedPortLabels() markiert Ports einer Routed-Gruppe mit Aquamarin-Stroke (dashed) am Port-Frame und einem hellen „L3"-Label im Stecker-Slot — Pattern analog zu Port-Channel-Brackets (Po1/Po2). Hover-Tooltip erweitert um „Routed Port (10.0.0.1 255.255.255.0)".no switchport -> ip address -> ipv6 address -> ip helper-address (pro Eintrag) -> mtu. L2-only-Subkommandos (ip dhcp snooping trust, ip arp inspection trust) werden im Routed-Modus rigoros unterdrueckt — IOS lehnt sie nach no switchport ohnehin ab. QoS-Trust bleibt unconditional (DSCP-Trust ist L3-relevant).ip ospf <pid> area <X>, OSPFv3 Area (IPv6) emittiert ipv6 ospf <pid> area <X>, EIGRP IPv6 (Switch) emittiert ipv6 eigrp <AS>. UI-Gates: Felder disabled, solange der jeweilige globale Process im Schritt 4 nicht aktiv ist (analog Loopback-Editor in LO-2b).255.255.255.0) als auch CIDR-Praefix (/24) — analog Wizard-Schritt 1. State-Wert bleibt Dotted-Decimal (Cisco-CLI-Konvention); CIDR-Eingabe wird ueber cidrToMask() konvertiert.grp.config.perItfEigrpIpv6 = false auf allen Port-Gruppen, analog zur SVI- und Loopback-Schleife aus LO-6. Conflict-Detail nimmt aktive Routed Ports im IPv6-AF-Detail mit auf („N SVIs, M Loopbacks, K Routed Ports"). Defensive typeof ifState-Guards fuer Login-/Admin-Seiten ohne Interfaces-Bundle.refreshRoutingCLI() triggert jetzt zusaetzlich refreshIfaceCLI(), damit per-Interface-OSPF/EIGRP-Bindungs-Zeilen auf Routed Ports sofort erscheinen, wenn der User im Schritt 4 ein globales Protokoll aktiviert.(optional) -> Optional-Badge, 6× neue Optional-Badges an bisher unmarkierten Routed-Feldern, 2× Pflichtfeld-Badge an Access VLAN und Native VLAN, 1× Optional-Badge an Allowed-VLANs.cisco-switch-config/tests/routed-ports.smoke.js deckt 221 Cases ab — L3-1 State + Validatoren (53), L3-2 UI + Helper (38+8+20), L3-3 Visualisierung (17), L3-4 CLI-Hardening (25), L3-5 Per-Interface-Bindung (26+1 Live-Sync), L3-6 License-Gate (8 in ipv6-pass.smoke.js), L3-7 End-to-End-Pass-Done-Marker (21). Bestehende Suites unveraendert: JS-Smoke 288/288, TV-Smoke 216/216, PHP-Smoke 42/42.Live-Validierung erreicht jetzt auch die Step-1-Felder im Customer-Template-Editor. Nach TV-1..TV-7 (SVI-Card, Loopback-Card, Helper-Listen, BGP-Networks-Textareas, IPv6-Sub-Modal) schliesst TV-8 die letzte Luecke: Management IP, Subnetzmaske und Default Gateway aus dem Schritt-1-Tab bekommen denselben Haken/X-Indikator direkt am Inputfeld. Schema- und Daten-Format unveraendert.
$step1Fields definierten IP-Felder bekommen einen optionalen vierten Parameter validate (ipv4 oder mask). Beim Rendern werden diese Felder statt eines einfachen input-Elements als input-group mit .validation-icon und invalid-feedback-Div ausgegeben. data-tpl-value-wrap-Attribut am Wrapper sorgt dafuer, dass handleModeChange beim Wechsel auf Offen das ganze input-group versteckt, nicht nur den inneren Input._tplSetFieldValidity(valEl, ..., null)), damit kein stehengebliebenes is-invalid-Highlight aus einem frueheren Modus uebrig bleibt._tplOnIpValidate fuer Step-1-Felder mit data-tpl-validate-Attribut sofort getriggert, sodass vorbelegte Werte gleich gruen markiert sind.tests/template-validation.smoke.js – PHP-Source-Marker (Validate-Spalte in $step1Fields, input-group + Icon + Feedback im Render-Block) und JS-Source-Marker (Restore-Validate + Mode-Change-Reset). Pass-Done-Block um TV-8-Marker erweitert. Total jetzt 216 Cases gruen.Live-IP-Validierung im Customer-Template-Editor. Admins bekamen bisher erst beim Save Rueckmeldung, wenn eine IP-Adresse, Subnetzmaske oder ein IPv6-Prefix im falschen Format eingetragen war (Server-Validation in admin/api/template.php). Im Wizard zeigt Schritt 1 schon lange einen Haken oder ein rotes Kreuz direkt am Inputfeld – der TV-Pass spiegelt diese Live-Validierung jetzt im Editor: SVI-Card (IP, Subnetzmaske, DHCP-Helper, DHCPv6-Relay), Loopback-Card (IPv4, IPv6-Prefix), beide BGP-Networks-Textareas (kompakte Status-Zeile darunter) und das IPv6-Adressen-Sub-Modal. Schlanke editor-eigene Validatoren (~150 LoC) spiegeln die Wizard-Regex 1:1, ohne dass js/validation.js ins Admin-Bundle gezogen wird; Drift-Schutz haengt an einer eigenen Smoke-Suite tests/template-validation.smoke.js.
admin/js/template-editor.js – _tplValidateIPv4 (Range-Check), _tplValidateSubnetMask (Contiguous-1-Bits + CIDR-Aequivalent), _tplValidateIPv6 (grobe Plausi), _tplValidateIPv6Prefix (<addr>/<len>), _tplValidateIPv4List/_tplValidateIPv6List (komma-/whitespace-getrennt). Plus generischer UI-Helper _tplSetFieldValidity (analog setFieldState aus validation.js: is-valid/is-invalid + bi-check-lg/bi-x-lg/bi-dash-Icon + Klartext-Fehler in invalid-feedback).input-group input-group-sm has-validation mit Icon-Span (rechts) und Inline-Fehlertext eingerahmt. Beim Tippen zeigt der Editor sofort Haken bei gueltigen Werten bzw. rotes X plus Klartext bei Format-Fehlern. Generischer _tplOnIpValidate-Handler liest den Validator-Typ aus data-tpl-validate und dispatcht; Event-Delegation greift fuer alle Live-Felder dieses Passes.A.B.C.D) und IPv6-Prefix (CIDR-Form) im Loopback-Card-Editor analog zu TV-2 – inklusive Initial-Validate-Trigger fuer vorbelegte Werte aus dem Edit-Restore-Pfad._tplValidateBgpNetworksV4/V6 akzeptieren pro Zeile <ip> <mask>, <ip>/<cidr> bzw. <prefix>/<len>; leere Zeilen werden ignoriert. Wird vom input-Listener bei Edits und vom Restore-Loader nach dem Page-Load gepflegt.slaac/dhcpv6 (kein Adress-Wert noetig) wird der Validity-Status auf neutral zurueckgesetzt; in den Modi mit Pflichtwert (manual, eui64, link-local) wird einmal validiert, damit Edit-Restore vorbelegte Werte sofort gruen markiert.cisco-switch-config/tests/template-validation.smoke.js deckt 204 Cases ab – TV-1-Pure-Logic-Tests (74), TV-2..TV-4-HTML-Marker + Mini-Sandbox-Dispatch-Tests (58), TV-5-Multi-Line-Validatoren + Renderer (40), TV-6-Modal-Hardening (12), TV-7-End-to-End-Pass-Done-Marker (20). Bestehende Suites unveraendert: JS-Smoke 280/280, PHP-Smoke 42/42.Loopback-Interfaces im Wizard, Template-Editor und CLI. Der Routing-Wizard kann jetzt vordefinierte interface Loopback<N> anlegen – inklusive optionaler IPv4 (Cisco-Konvention 1.1.1.1/32 als Router-ID + iBGP-Update-Source), IPv6-Prefix, OSPFv3-Area und EIGRP-IPv6-Toggle. BGP-Neighbors bekommen pro Eintrag ein Update-Source-Select, das alle existierenden Loopbacks listet und im CLI als neighbor <ip> update-source Loopback<N> emittiert wird. Der „Router-ID aus Loopback ableiten"-Helper schreibt die /32-Adresse direkt in OSPF, OSPFv3, EIGRP oder BGP. Customer-Templates tragen das neue Feld step4.loopbacks[] (Schema v9), das beim Apply locked/preset-Loopbacks ins routingState.loopbacks ausrollt; das License-Gate räumt per-Loopback EIGRPv6-Bindings beim Downgrade mit ab. Persistierung ist im Auto-Save, im Edit-Mode-Restore und im Template-Apply-Pfad geschlossen. Parallel zieht der Customer-Template-Editor beim IPv6-Routing-Bundle aus 2.11.0 nach (I-14): alle Top-Level-Felder (ipv6_routing, vrrpv3_global), OSPFv3, EIGRP-Named-Mode/IPv6-AF, MP-BGP-IPv6-Networks, vier Per-SVI-Spalten und ein FHRP-Family-Toggle sind jetzt direkt im UI editierbar.
routingState.loopbacks mit { id, description, ipv4Address, ipv4PrefixLen, ipv6Addresses, ipv6OspfArea, ipv6Eigrp, shutdown }. validateLoopbackId (Integer 0..2147483647, eindeutig) und validateLoopbackPrefixLen (0..32) etablieren die Range-Checks, _loopbackEnsureDefaults backfillt fehlende Felder auf Cisco-Best-Practice-Defaults (IPv4 leer = Unnumbered, /32, no shutdown)..vlan-table darunter. IPv4/IPv6-Felder haben Live-Validierung mit Haken/X-Icon direkt am Inputfeld (Pattern aus Schritt 1), Inline-Fehler für IPv6-Prefix und OSPFv3-Area, UI-Gates für die per-Loopback Routing-Protokoll-Felder (OSPFv3-Area + EIGRP-IPv6 disabled, solange der globale Process im Routing-Accordion inaktiv ist).interface Loopback<N>-Block emittiert mit description, ip address <ip> <mask> (oder no ip address bei Unnumbered), beliebig vielen ipv6 address-Modi (manual/eui-64/slaac/dhcpv6/link-local), ipv6 ospf <pid> area <X> wenn OSPFv3 aktiv ist, ipv6 eigrp <AS> wenn EIGRP-Named-Mode + IPv6-AF aktiv sind, und abschließend shutdown/no shutdown. Sortierung aufsteigend nach ID.update-source Loopback<N> per Neighbor (LO-5): Neue Spalte „Update-Source" in der BGP-Neighbor-Tabelle mit einem Inline-<select> pro Neighbor. Optionen sind alle existierenden Loopbacks (sortiert nach ID, plus „— keine —" für eBGP). Wenn der referenzierte Loopback gelöscht wurde, zeigt das Select eine stale-Option „Loopback<N> (entfernt)" und der CLI-Builder skippt die Zeile defensiv. Im CLI wird neighbor <ip> update-source Loopback<N> direkt nach remote-as emittiert – im klassischen BGP-Block und im globalen MP-BGP-Block vor den address-family-Sektionen.lo.ipv6Eigrp = false auf allen Loopbacks analog zur SVI-Schleife. Pre-LO-Drafts ohne loopbacks-Array bleiben verhalten- und format-identisch zu vorher._collectLoopbackRows validiert ID-Range + Eindeutigkeit + IPv6-CIDR-Form und ergänzt step4.loopbacks im Template-JSON. Schema-Bump auf v9 ist auto-getriggert, Pre-v9-Templates bleiben uneingeschränkt gültig.admin/api/template.php akzeptiert Schema-Versionen 2..9 und validiert step4.loopbacks[] defense-in-depth (ID-Range/Eindeutigkeit, Mode-Enum, IPv4-Pattern + Prefix-Range, IPv6-Adressen mit allen fünf Modi und prefix_len 0..128, OSPFv3-Area, EIGRP-Boolean, Description-Länge). admin/includes/template-apply-server.php spielt locked-Loopbacks beim Apply ins wizard_state.step4.loopbacks ein (snake_case → camelCase, Add-only mit tplLocked=true)._captureStep4 nimmt loopbacks in den Auto-Save-Snapshot auf, _applyStep4State spielt sie beim Edit-Mode-Restore zurück und ruft _allLoopbackEnsureDefaults + renderLoopbackTable, und template-apply.js rollt step4.loopbacks beim Wizard-Apply mit tplLocked/tplPreset-Markierung aus.cisco-switch-config/tests/ipv6-pass.smoke.js deckt jetzt 280 JS-Pure-Logic-Cases ab (+126 für den LO-Pass: State+Validatoren, Gates, CLI-Builder, Router-ID-Helper, Update-Source, License-Gate, Template-Editor-Bump, Capture/Restore + Template-Apply, End-to-End-Sanity-Marker). cisco-switch-config/tests/ipv6-pass.smoke.php deckt 42 Server-Apply-Cases ab (+20 für LO-8: Loopback-Apply Neu-Anlage/Update/preset-skip/State-Preservation, Schema-v9-Source-Check).ipv6_routing, vrrpv3_global, kompletter OSPFv3-Block (enabled/process_id/router_id/passive_default), EIGRP-Named-Mode + Process-Name + IPv6-AF + IPv6-Redistribute, BGP-IPv6-Redistribute. Schema-Bump-Logik erweitert um die neuen Trigger; Server-Validation und Server-Apply (Pfad-Map snake_case → camelCase) sowie Client-Apply ziehen mit.<prefix>/<len>. Parser trennt strikt am letzten Slash (Doppelpunkte im IPv6-Adress-Teil bleiben heil). Client-Apply pushed die Liste mit prefix_len → prefixLen Normalisierung und Duplikat-Schutz ins routingState.bgp.ipv6Networks; ipv6 unicast-routing wird auto-erzwungen.#tpl-ipv6-addr-modal verwaltet beliebig viele IPv6-Adressen pro SVI in den fünf Cisco-Modi (manual, eui-64, slaac, dhcpv6, link-local) mit modus-spezifischer Pflichtfeld-Sichtbarkeit und Plausi-Validierung. Working-Copy sitzt am data-svi-ipv6-addresses-Attribut der Zeile, Modal-Lifecycle analog zum FHRP-Modal..vlan-table-Klasse wie SVI- und Static-Routes-Tabellen (kleinere Schrift, kompaktes thead, schmaleres Padding) und liegt bündig zur Card-Body-Kante. Spaltenreihenfolge ist an die SVI-Tabelle angeglichen.IPv6 in Schritt 4 angekommen. Der Routing-Wizard kannte bisher ausschließlich IPv4 – im neuen I-Pass kommt das volle IPv6-Set dazu: per-SVI ipv6 address in fünf Modi (manual, eui-64, slaac, dhcpv6, link-local) inkl. DHCP-Relay-Zielen, statische IPv6-Routen, OSPFv3 als separater Cisco-Prozess, EIGRP-Named-Mode mit zusätzlicher IPv6-Address-Family, MP-BGP mit Auto-Switch zwischen klassischem IPv4-Output und dem Block mit zwei address-family-Sektionen sowie HSRPv2-IPv6 und VRRPv3 mit globalem fhrp version vrrp v3 (automatisch erzwungen bei IPv6-Virtual-IPs). Außerdem: License-Gate kennt die neuen IPv6-Routing-Features, Customer-Templates lockern/presetten sie über Schema v8, und der zuvor in Schritt 4 verstreute Pflichtfeld-/Optional-Hinweis ist als einheitliche Badge-Variante umgesetzt. Zusätzlich kommen ein konsolidiertes Smoke-Skript für die JS-Pure-Logic-Slices sowie ein PHP-Pendant für die Server-Apply-Pfade in cisco-switch-config/tests/ hinzu.
manual, eui-64, slaac, dhcpv6 und link-local (Cisco-Syntax ipv6 address <prefix>/<len> [eui-64], autoconfig, dhcp oder fe80::… link-local). Zusätzlich: kommagetrennte DHCPv6-Relay-Ziele (ipv6 dhcp relay destination), ein OSPFv3-Area-Feld pro SVI (ipv6 ospf <pid> area <X>) und ein eigener separater OSPFv3-Accordion-Block (ipv6 router ospf) mit Router-ID, Passive-Default und Redistribute.family-Spalte (IPv4/IPv6) und akzeptieren das CIDR-Format 2001:db8::/32. Cisco-Output wechselt automatisch zwischen ip route und ipv6 route.router eigrp <AS> und der modernen Address-Family-Form router eigrp NAME + address-family ipv4 unicast autonomous-system <AS>. Eine zweite Address-Family address-family ipv6 unicast kann nur im Named-Mode aktiviert werden; per-SVI-Toggle "EIGRP IPv6" emittiert ipv6 eigrp <AS> im Interface-Block.network <prefix>/<len>) und IPv6-Redistribute-Checkboxen. Sobald irgendeine IPv6-Aktivität vorhanden ist, wechselt der CLI-Builder vom klassischen IPv4-only-Output auf MP-BGP mit no bgp default ipv4-unicast, zwei address-family-Blöcken und per-Neighbor neighbor <ip4|ip6> activate.standby <id> ipv6 <addr>; VRRP akzeptiert IPv6-VIPs und erzwingt dabei den neuen globalen Toggle "VRRPv3 global" (fhrp version vrrp v3). HSRPv1 + IPv6 wird mit klarem Inline-Fehler abgelehnt; eine VRRP-Gruppe mit IPv6-VIP kippt den Globalen-Toggle automatisch und blockt manuelles Deaktivieren, solange IPv6-VRRP existiert.svi.ipv6Eigrp) und ruft _refreshSviIpv6ProtocolGates, damit ein offener SVI-Editor den gesperrten Toggle korrekt darstellt.step4.fields.ipv6_routing, vrrpv3_global, step4.bgp_ipv6_networks[] sowie pro SVI ipv6_addresses[], ipv6_helper_addresses[], ipv6_ospf_area und ipv6_eigrp tragen; FHRP-Gruppen erhalten ein family-Feld. Schema-Bump auf 8 ist auto-getriggert (kein manuelles Hochzählen), Pre-v8-Templates bleiben uneingeschränkt gültig. Server-Validation und Server-Apply sind defense-in-depth implementiert; Client-Apply normalisiert prefix_len → prefixLen, damit der Wizard direkt damit arbeiten kann.bg-danger, Optional-Badge in bg-secondary) ersetzt – inklusive aller in I-1 bis I-12 neu eingeführten Felder.cisco-switch-config/tests/ipv6-pass.smoke.js deckt 76 JS-Pure-Logic-Cases ab (EIGRP-Named-Mode, MP-BGP-Auto-Switch, SVI-Gates, Live-Update/Snapshot, HSRPv2-IPv6/VRRPv3, License-Conflict/Cleanup, Schema-v8-Bump). cisco-switch-config/tests/ipv6-pass.smoke.php deckt 21 Server-Apply-Cases ab (Template-Lock-Apply, Pre-v8-Preservation, Source-Range-Stichproben). Beide Skripte sind self-contained und ohne Test-Framework-Setup lauffähig.networks-/redistribute-Feld im persistierten BGP-State. Nach dem Restore in den Wizard crashte der Klick auf „Hinzufügen" still an routingState.bgp.networks.some(...), die Checkbox-Handler sprangen wegen !routingState.bgp.redistribute in den frühen Return. Defense-in-Depth via _bgpEnsureDefaults() in jedem Mutator plus expliziter Aufruf direkt nach dem JSON-Restore in _applyStep4State reparieren das.License-Awareness für Catalyst 9000. Der Wizard kennt ab sofort die beiden Cisco-Lizenztiers Network Essentials und Network Advantage und entscheidet pro Gerät, welche Routing-Features verfügbar sind. EIGRP, BGP, HSRP und StackWise Virtual sind Advantage-Only und werden bei Essentials hart gesperrt – inklusive Auto-Cleanup bei Lizenz-Downgrade. Stack-Member erben die Lizenz vom Master-Switch; ein neuer Banner im Stack-Card macht das transparent. Customer-Templates können in Schema-Version 6 ein Feld min_license tragen, und der Wizard zeigt einen Warn-Banner, wenn die Vorlage Advantage erfordert, das aktive Gerät aber nur Essentials hat. Server-seitige Validierung bei Template-Save verhindert inkonsistente JSON-Stände.
js/license-gate.js): EIGRP- und BGP-Toggles im Routing-Accordion bekommen ein Network Advantage-Lock-Badge und werden komplett gesperrt. HSRP im FHRP-Modal ist greyed-out mit Hinweis, dass VRRP im Essentials-Tier verfügbar bleibt. StackWise-Virtual-Toggle ist disabled mit Lock-Tooltip; ein Banner im SVL-Card-Body erklärt die Voraussetzung.min_license mit Werten essentials oder advantage führen. Der Customer-Template-Editor bekommt eine Btn-Group Minimum License-Level in der Metadaten-Spalte; der Wert wird beim Speichern serialisiert und bumpt die Schema-Version auf 6, wenn Advantage gewählt ist.min_license=advantage verlangt, das aktive Gerät aber Network Essentials hat. Der Banner schlägt vor, License-Level oben anzupassen oder eine andere Vorlage zu wählen, da sonst Advantage-Features (EIGRP, BGP, HSRP, StackWise Virtual) verworfen werden.admin/api/template.php: erlaubt Schema-Versionen 2..6, prüft min_license als Enum (essentials oder advantage) und erzwingt, dass min_license nur in Schema 6 stehen darf. Konsistenzfehler liefern HTTP 422 mit aussagekräftiger Fehlermeldung.defaultLicense-Wert. Hilfsfunktionen defaultLicenseForModel(), licenseAtLeast() und featureRequiresLicense() stehen global zur Verfügung, damit andere Module (z. B. CLI-Renderer) Lizenz-aware sind, ohne den Wizard-State direkt zu kennen.Großer ACL-Release. Der Konfigurator-Wizard bekommt einen neuen Schritt 6 „Access Control Lists" mit vollständigem Editor: ACLs anlegen, Regeln pflegen, Anwendungen an Interfaces oder VTY-Lines binden – alles mit Cisco-konformer Live-CLI-Vorschau. Unterstützt werden Named und Numbered ACLs (letztere mit Deprecated-Hinweis), IPv4 und IPv6 als getrennte Adress-Familien sowie Service-Namen wie eq ssh, eq https oder eq domain statt nackter Portnummern. Drag & Drop sortiert ACLs und Regeln (Touch-fähig auf Tablets); Pfeil-Buttons bleiben als Tastatur-Fallback. Der Customer-Template-Editor bekommt einen passenden Tab, mit dem Administratoren ACL-Vorlagen pflegen und einzelne ACLs gegen Anwender-Änderungen sperren können – der Server erzwingt gesperrte Werte beim Laden eines Projekts. Implicit-Deny-Banner und sechs ?-Inline-Hints machen den Editor selbsterklärend.
ip/tcp/udp/icmp), Quelle und Ziel als any/host/network mit Prefix, Quell-/Ziel-Port (eq, neq, lt, gt, range), optionalem log-Flag und Pro-Regel-Bemerkung. Wildcard-Masken werden automatisch aus CIDR-Eingaben generiert (/24 → 0.0.0.255).last+10 als Sequenznummer, und beim Reorder werden alle Regeln auf 10/20/30/… renumeriert. Macht spätere Einschübe zwischen bestehende Regeln (in Cisco selbst 15 permit …) jederzeit möglich, ohne dass die Sequenz manuell gepflegt werden muss.access-class IN) binden. Der Target-Picker zieht echte Cisco-Interface-Namen aus den im Wizard konfigurierten Interfaces (Schritt 2) und SVIs (Schritt 4); Eindeutigkeitsprüfung verhindert zwei ACLs der gleichen Familie in derselben Richtung am selben Ziel.access-list 100 permit … pro Regel. Der Wizard zeigt einen Deprecated-Hinweis und empfiehlt Named ACLs für moderne Netze; Numbered bleibt verfügbar für Legacy-Kompatibilität.2001:db8::/32) statt Wildcard-Masken. Apply-Statements emittieren Cisco-konform ipv6 traffic-filter und ipv6 access-class; eine IPv4 und eine IPv6 ACL dürfen am selben Interface in derselben Richtung koexistieren.ssh, https, domain, ntp, tftp usw. eingegeben werden – die Auflösung erfolgt automatisch. Der generierte Cisco-CLI-Output zeigt symbolisch (eq ssh) wenn ein Mapping existiert, sonst numerisch. range bleibt zwingend numerisch.deny ip any any-Default-Verhalten, und unter jeder ACL-Karte erscheint eine graue Pseudo-Zeile → deny ip any any (impliziter Deny). Im generierten Cisco-CLI-Block steht ein Kommentar mit dem gleichen Hinweis.step6-Sektion mit ACL-Definitionen und Anwendungen tragen. Bestehende Vorlagen ohne step6 bleiben uneingeschränkt nutzbar.Migrations-Versions-Tracking. Das frueher implizite "irgendwann mal alles durchgeklickt" wird zur expliziten, nachvollziehbaren Liste: fuer jedes Migrations-Skript zeigt das neue Dashboard, ob es schon gelaufen ist, von wem, wann und wie oft. Eine Header-Pill macht ausstehende oder fehlgeschlagene Migrationen sichtbar, eine kanonische Beschreibungs-Liste dokumentiert pro Skript Sinn und Zweck, und das Setup-Skript spiegelt die Tracking-Eintraege automatisch fuer Frischinstallationen – das Dashboard zeigt direkt nach einer Neuinstallation keine faelschlichen Ausstehend-Markierungen. Ein neuer woechentlicher Cron raeumt verwaiste Eintraege auf, die durch umbenannte oder entfernte Skripte entstehen.
--dry-run testbar, gibt einen JSON-Report aus und meldet Fehler ueber das Postfach an alle Superadmins – konsistent mit den bestehenden Purge-Crons fuer SSH, Postfach und Admin-Sessions.Großes Postfach-Release. Das in 2.6.x eingeführte Inbox-System wird systematisch über die ganze Anwendung ausgerollt: über 20 neue Ereignis-Typen aus sechs Bereichen (Vault & Recovery, Bug-Reports & Feature-Requests, Kollaboration, Kontingente und Auto-Limits, System & Wartung, Onboarding) landen jetzt direkt im persönlichen Postfach des betroffenen Benutzers – ohne dass jemand aktiv Audit-Logs oder Cron-Reports prüfen muss. Die bisherige Dedup-Logik sorgt dabei dafür, dass wiederholte Trigger eine bereits offene Postfach-Zeile aktualisieren statt sie zu duplizieren – das Postfach bleibt auch bei aktiven Phasen ruhig und übersichtlich. Neu ist außerdem eine automatische Versions-Bump-Erkennung: nach einem Update sieht jeder Benutzer beim ersten Login einen Hinweis auf die neue Version mit Verweis auf die Release-Notes. Administrative Aufräumaktion: alle Migrations-Skripte sind in ein eigenes Unterverzeichnis konsolidiert und konsistent benannt.
Patch-Release im Anschluss an 2.6.0. Pass E schließt die letzte Lücke des Template-Lock-Konzepts: Step 2 (STP-Modus + MST-Region) wird jetzt sowohl im wizard_state erfasst als auch serverseitig erzwungen – damit ist das Lock-Konzept End-to-End wasserdicht. Zusätzlich wird ein in Phase 4 vergessener Whitelist-Eintrag in der Template-Apply-Pipeline ergänzt: Vorlagen mit stp_mode = mst wirken nun korrekt im Konfigurator (vorher silent verworfen).
admin/includes/template-apply-server.php aktualisiert – die "Step 2 wird nicht erfasst"-Limitation ist mit Pass E hinfällig.js/template-apply.js: Die Auswahl ist nicht mehr auf PVST-Varianten begrenzt; MSTP wird jetzt vollständig akzeptiert.admin/customer-template-editor.php) bot seit Phase 4 stp_mode = mst als Wert an, aber die Apply-Logik _applyStpGlobalField() in js/template-apply.js verwarf mst silent (Whitelist nur pvst/rapid-pvst). Effekt: Vorlagen mit stp_mode = mst wirkten nicht – das Dropdown blieb auf rapid-pvst, die MST-Region-Karte erschien nicht, der CLI-Output zeigte den falschen Modus. Bei mode: locked besonders verwirrend, weil "locked" Sicherheit suggerierte. Whitelist um mst ergänzt; bei MSTP wird zusätzlich renderStpMstCard(true) gerufen, damit die Region-Karte sofort eingeblendet ist._captureStep2() in js/project-edit.js erfasst jetzt ifState.stpGlobal (Modus + MST-Region inkl. user-spezifischer Instances). Server-seitiges Re-Apply in admin/includes/template-apply-server.php erzwingt für Templates mit mode: locked die drei Felder stp_mode, mst_region_name, mst_revision – analog zu Pass A für Step 1/3/4/5. MST-Instances bleiben bewusst außen vor (zu projektspezifisch, analog zu User-VLANs in Step 3).onStpGlobalModeChange() und onStpMstRegionChange() (js/interfaces.js) blockieren direkte JS-Aufrufe (Browser-Console etc.), wenn das jeweilige UI-Element durch disabled/readOnly als locked markiert ist. Defense-in-Depth analog zu den security.js-Guards aus Pass B._applyStep2State() in js/project-edit.js stellt beim Edit-Aufruf den persistierten stpGlobal-State wieder her, synchronisiert das Dropdown #stp-global-mode und blendet die MST-Karte ein, wenn der Modus mst ist. Defensive Defaults greifen bei Snapshots, die vor 2.6.1 angelegt wurden.Webhooks werden für eingeloggte Benutzer geöffnet (Pass D). Persönliche Webhook-Subscriptions feuern nur bei Aktionen, die der Eigentümer selbst ausgelöst hat (Owner-Scoping); System-Subscriptions des Superadmins bleiben erhalten und sehen weiterhin alle Events. Sicherheits-Events (login.lockout, csrf.violation) bleiben Superadmin-only. Defense-in-Depth durch SSRF-Härtung (DNS-Resolve + IP-Blocklist gegen Loopback, Private, Link-Local, Cloud-Metadata, CGNAT; HTTPS-only via CURLOPT_PROTOCOLS; DNS-Pinning über CURLOPT_RESOLVE), Per-User-Quotas (Subscriptions, Test-Events/Stunde, Lieferungen/Stunde) und ein bewusst zu setzendes Feature-Flag webhook_user_scope_enabled – default aus, damit der Superadmin die Härtung erst in Staging verifizieren kann. Audit-Detail (Payload, Antwort-Body) bleibt Superadmin vorbehalten.
admin/profile-webhooks.php). Eingeloggte User können eigene Empfänger anlegen (Slack, Microsoft Teams, Cisco Webex, Mattermost, Discord, generic JSON), Test-Events auslösen und Subscriptions aktivieren / deaktivieren. Im Modal sind nur user-bound Events (project.*, device.config_saved, firmware.uploaded, bug.*, feature.requested, vault.unlock_failed, template.activated, webhook.test) auswählbar.webhook_subscription.owner_admin_fk (FK admins.id, ON DELETE CASCADE). NULL = System-Subscription, INT = persönliche Subscription. Migration admin/migrate/webhooks.php mit Self-healing-ALTER für Bestand; setup.php legt die Spalte direkt beim Neuanlegen an.admin/webhook-deliveries.php) und in der Subscription-Liste (admin/webhooks.php): „System" (blau) vs. <username> (grau, mit Person-Icon) macht System- und User-Webhooks auf einen Blick unterscheidbar.webhook_dispatch($event, $data, ?int $triggeringAdminId = null): neuer optionaler Parameter. System-Subscriptions feuern wie bisher; User-Subscriptions feuern nur bei Match auf den triggernden User. Alle 7 user-bound Aufrufstellen wurden umgestellt (save.php, bugreport.php, featurerequest.php, firmware-upload-finalize.php, template.php 2x, bug-detail.php); System-Aufrufstellen (login-ratelimit.php, functions.php CSRF) bleiben unverändert.webhook_send_test() protokolliert Test-Versuche jetzt in webhook_delivery (state=delivered/failed). Damit erscheinen sie im Audit und werden für die Per-User-Test-Quota gezählt.admin/api/webhooks.php öffnet sich für Nicht-Superadmins, wenn das Feature-Flag aktiv ist; Owner-Filter bei GET / get / update / delete / toggle / test, Quota-Checks bei create / test, Sicherheits-Events bleiben verboten.webhook_send_test() direkt webhook_deliver_now() ohne Audit-Eintrag – damit waren Test-Versuche im Audit-Log unsichtbar. Jetzt wird der Versuch korrekt protokolliert.webhook_url_safety_check(): HTTPS-only, IP-Literale werden gegen die Blocklist (Loopback 127.0.0.0/8 + ::1, Private 10/8 / 172.16/12 / 192.168/16, Link-Local 169.254/16 inkl. 169.254.169.254, CGNAT 100.64/10, IPv6 fe80::/10, etc.) geprüft, Hostnames per gethostbynamel() aufgelöst – ALLE A-Records müssen Public sein, sonst Reject. Optionale Domain-Allowlist via security_settings.webhook_allowed_domains.CURLOPT_PROTOCOLS + CURLOPT_REDIR_PROTOCOLS = HTTPS, CURLOPT_FOLLOWLOCATION bleibt false (Redirects auf interne Hosts ausgeschlossen), CURLOPT_RESOLVE pinnt den Host auf die im Safety-Check ermittelte IP – Schutz gegen DNS-Rebinding-Angriffe.WEBHOOK_EVENT_CLASS markiert login.lockout und csrf.violation als system-only. Der Backend-CRUD-Endpunkt lehnt entsprechende Events für User-Subscriptions mit HTTP 403 ab; der Dispatcher schickt sie ohnehin nur an System-Subscriptions.security_settings: webhook_user_max_subscriptions (Default 5), webhook_user_test_per_hour (Default 10), webhook_user_deliveries_per_hour (Default 100). Der Dispatcher droppt User-Lieferungen still, wenn das Stunden-Limit erreicht ist; Test-Versand antwortet mit HTTP 429.owner_admin_fk beim Anlegen ausschließlich aus der Session, niemals aus dem Request-Body. Existence-Oracle-Schutz: fremde Subscription-IDs liefern 404 statt 403, damit kein Status-Code-Leak möglich ist.webhook_user_scope_enabled (Default aus): Solange nicht durch den Superadmin gesetzt, ist profile-webhooks.php nicht aufrufbar (HTTP 403) und der Profil-Dropdown-Eintrag ausgeblendet. Erlaubt einen kontrollierten Roll-out (z. B. erst in Staging).Härtungs-Release im Anschluss an 2.4.0. Das Template-Lock-Konzept wurde wasserdicht gemacht (Defense-in-Depth, Pass A + B): clientseitige UI-Locks, Handler-Guards gegen direkte JS-Aufrufe und ein serverseitiges Re-Apply in admin/api/save.php, das jeden auf locked gesetzten Vorlagen-Wert beim Speichern erzwingt – auch bei DOM-Manipulation, deaktiviertem JavaScript oder direkten API-Aufrufen mit manipuliertem Body. Sub-Sektionen wie VTP, SVI, Subnetzmasken-CIDR und alle 27 Step-5-Sicherheits-Felder schließen dabei vorher offene Bypass-Pfade. Zusätzlich kommt korrekte Cisco-Hardware-Modellierung für die Linecards C9600-LC-24C (24× 40G default / max. 12× 100G) und C9400-LC-12QC (12× 40G default / max. 4× 100G oder 25G auf Port 9–12) – inklusive klickbarem Speed-Mode-Toggle pro Port-Gruppe direkt im Switch-Panel-SVG.
C9600-LC-24C und C9400-LC-12QC: jeder toggleable Top-Port bekommt im Switch-Panel ein klickbares Speed-Tab (40G grau, 100G orange, 25G grün). Beim Wechsel auf 100G/25G wird der gepaarte Bottom-Port automatisch mit rotem Diagonal-X markiert und ist nicht mehr selektierbar. Die Render-Pipeline reichert die Port-Group um portOverrides (Map top → {prefix, num, modeId}) und disabledPorts (Set) an; Cisco-konforme Interface-Namen (Hu1/3/0/25 etc.) werden direkt in Tooltips angezeigt.speedModes unterstützt; listet betroffene Slots inkl. SKU und Modus-Zusammenfassung („12 Top-Ports 40G/100G").interface HundredGigabitEthernet…/enable-Block vor den eigentlichen Port-Konfigurationen emittiert – Cisco-konforme Reihenfolge.lock_overrides in der Save-Response), erhält der Anwender pro betroffenem Gerät einen Warning-Toast mit den zurückgesetzten Feld-Labels (12 s).wizard_state-Snapshots ohne portModes werden beim Restore auf den bestandskompatiblen 100G-Modus migriert, neue Geräte starten korrekt im 40G-Default.switches-data.js ergänzt: lcSpeedToggleablePortsFor(), lcDefaultSpeedModeId(), lcFindSpeedMode(), lcSisterPortFor(), lcInitialPortModes(lc, forceMode?), lcHasSpeedModes().lock_overrides-Map (deviceId → string[]) für die Frontend-Toasts beim Server-Re-Apply.oninput/onchange-Handler bleiben unverändert in Funktion und Reihenfolge – die neuen Lock-Guards greifen am Anfang jedes Handlers, ohne die bestehende Logik zu berühren.buildChassisPanelSVG(rawModel, effectiveModel) referenzierte fälschlich die nicht definierte Variable model beim Auflösen der Per-Port-Overrides → ReferenceError, der gesamte Chassis-Render brach ab und das Switch-Panel blieb leer (sichtbar bei C9606R + C9600-LC-24C). Auf den korrekt benannten effectiveModel-Parameter umgestellt mit defensivem Array-Check._loadCustomers() hörte nur auf DOMContentLoaded. Jetzt zusätzlich auf das admin-state-changed-Event in session.js registriert.admin/api/save.php lädt vor dem INSERT pro Gerät die aktive Vorlage und überschreibt im wizard_state alle Felder, die im Template auf mode: locked stehen, mit dem Template-Wert. Schützt gegen DOM-Manipulation, deaktiviertes JavaScript und direkte API-Aufrufe mit manipuliertem Body. Best-effort, nie blockierend – Fehler beim Template-Load werden geschluckt.sec-*-IDs in der HTML-Struktur; 4 Button-Groups (HTTP/HTTPS-Server, AAA-Login-Default, SNMP-Version) bekommen Wrapper-IDs und werden via disabled-Attribut auf allen inneren Buttons gesperrt.js/security.js: neuer _secLocked(stateKey)-Helper liest window._secLockedFields (Set über secState-Pfade); jeder der 13 on*-Handler lehnt direkte programmmatische Aufrufe (z. B. über Browser-Console) auf gesperrte Felder ab. AAA-/SNMP-Master-Toggle stellt zusätzlich den Checkbox-Wert wieder her, damit ein toggled UI sofort zurückspringt.editSvi() und deleteSvi() haben einen tplLocked-Guard erhalten; in der SVI-Tabelle erscheint statt der Edit-/Delete-Buttons ein Schloss-Icon, damit gelockte SVIs nicht über die UI-Buttons umgegangen werden können.Großes Sicherheits- und Integrations-Release. Neu: Outbound-Webhooks für Slack, Microsoft Teams, Cisco Webex, Mattermost, Discord und generic JSON, mit zentraler Backend-Verwaltung, Audit-Log, Retry-Cron und human-lesbaren Markdown-Nachrichten. Sicherheitsschicht massiv erweitert: einheitlicher CSRF-Guard mit Soft/Hard-Mode + generischer Security-Audit-Log, Login-Rate-Limiting (Brute-Force-Schutz pro Username und IP-Bucket), Backend-Verwaltung aller Security-Einstellungen mit Tag-Input für Trusted Proxies. UX-Politur im Konfigurator: Wizard-Autosave mit Restore-Banner, Zoom + Pan im Frontpanel-SVG, visuelle Markierung von Vorlagen-Locked/Preset-Feldern, zentrale Toast-API als Ersatz für native alert()-Aufrufe.
project.created, device.config_saved, firmware.uploaded, bug.created, bug.status_changed, feature.requested, login.lockout, csrf.violation, template.activated.webexteams://im?space=…), reine UUID oder die Base64-API-Form und konvertiert beim Speichern automatisch. Markdown-formatierte Nachrichten direkt im Webex-Raum.admin/cron/webhook-retry.php (analog zu ssh-purge.php): verarbeitet pending-Lieferungen mit Backoff (1 min / 5 min / 30 min / 6 h / 24 h) und räumt erledigte Einträge älter als 30 Tage auf.snake_case-Schlüssel in deutsche Labels und Status-Werte (z. B. in_progress → In Bearbeitung, active → Aktiviert). Display-Name des Admins wird als „Max Mustermann (admin)" angezeigt. Geräte-Listen, Bytes-Größen, SHA-256 und ISO-Timestamps werden kompakt formatiert. Generic-Empfänger erhalten weiter den unveränderten JSON-Envelope.TRUSTED_PROXIES-Liste sind nun live anpassbar (Hybrid-Strategie: DB überschreibt config.php-Defaults). Tag-Input für Trusted-Proxy-IPs mit clickbaren Pills und IP-Validierung.localStorage gespeichert (TTL 24 h). Beim nächsten Aufruf erscheint ein Wiederherstellen-Banner mit Datum, Modell und Schritt. Status-Pille im Step-Progress zeigt „Entwurf gespeichert vor X s". Multi-Tab-Sync via storage-Event. Cleanup nach erfolgreichem Backend-Save.js/toast.js): Stack rechts unten, max 5 sichtbar, Pause-on-hover, Dedup über id, Light/Dark-Mode, mobile-responsive, aria-live-Support. Vier Level: success / info / warning / error.alert(...)-Aufrufe in 8 JS-Dateien auf Toast.error/warning/info migriert. Browser-blockierende Modals weg.setup.php richtet bei Neuinstallationen automatisch das Security-Schema (security_audit_log, login_lockout, security_settings) und das Webhook-Schema (webhook_subscription, webhook_delivery) mit ein – die einzelnen Migrations-Skripte bleiben für bestehende Installationen erhalten.<form>-Element wurde aus dem .modal-content in das .modal-body verschoben (Bootstrap-Standard-Pattern, form="…"-Attribut auf dem Footer-Button).#step-0) und blendet Footer/Vorschau-Button ein – analog zu startProject().renderSwitchPanel()-Inject nicht mehr sichtbar, weil sie im überschriebenen Container lag. Toolbar in eigenen .switch-panel-host-Wrapper außerhalb von #switch-panel verschoben.<kbd>-Tags mit echtem Tasten-Look (Border + inset Box-Shadow).sessionState-Feldnamen im Wizard-Autosave-Snapshot korrigiert (project statt projectName, currentDevice statt deviceIndex; projectId und customerFk ergänzt).csrf_verify() in admin/includes/functions.php wurde method-aware (überspringt GET/HEAD/OPTIONS) und um Soft/Hard-Mode erweitert. Im Soft-Mode landen Verstöße im Security-Audit, ohne Funktionen zu brechen – zur Übergangsphase. Im Hard-Mode werden sie mit HTTP 403 abgewiesen.admin/js/csrf.js patcht fetch() und XMLHttpRequest global, sodass same-origin POST/PUT/PATCH/DELETE-Requests automatisch den X-CSRF-Token-Header bekommen – keine manuelle Migration der Frontend-Aufrufe nötig.TRUSTED_PROXIES-Liste schützt vor IP-Spoofing über X-Forwarded-For. Sicherer Default: leer = Header nie vertrauen.CSRF_ENFORCEMENT_MODE mit 24h-Statistiken (Soft- vs. Hard-Fails).Großer Ausbau des Inline-CLI-Editors: Autosave mit Restore-Banner, Tipps-Sidebar, Login direkt im Editor, neue Toolbar-Buttons (Verlauf, Suchen, Kommentar, Lint-Navigation, Snippets), Cisco-Autovervollständigung, verwaltete CLI-Snippets mit Backend-Editor, Backend-Badges (SVL/Stack/CLI-Editor), Save-Modal-Politur (Pflichtfelder, Kunden-Dropdown, Auto-Pick) sowie zwei neue Workflows: Konfiguration aus einem bestehenden Projekt heraus hinzufügen und vorhandene Freeform-Configs per schlankem Confirm-Dialog aktualisieren.
lg automatisch unter den Editor.index.php. Editor-Inhalt und Autosave-Slot bleiben beim Login/Logout erhalten – kein Reload. Login-Modal wurde in admin/_login_modal.php extrahiert (eine gemeinsame Quelle für index.php und editor.php).conf t → configure terminal, sh run → show running-config, no shut → no shutdown, int g/t/v/p, swi mo a/t, …) plus Wort-Match auf alle Block-Opener und Keyword-Phrases der Cisco-Sprache. Auto-Trigger nur am Zeilen-Anfang; Strg+Leertaste erzwingt das Panel auch in der Mitte.admin/cli-snippets.php). Backend-Editor mit dem gleichen dunklen CodeMirror wie das Frontend; Pflichtfeld- und Optional-Badges. Snippets erscheinen im Editor sowohl im Autocomplete (höchste Priorität) als auch über das Puzzle-Icon der Toolbar (Snippet-Picker mit Suche und Kategorie-Gruppierung). Platzhalter {{hostname}}, {{customer}}, {{project_id}}, {{user}}, {{date}} werden beim Einfügen aus dem Editor-Kontext ersetzt; unbekannte Tokens bleiben als Lückentext.project-detail.php. Der Editor öffnet mit ?add_to=PROJECT_ID, zeigt einen grünen Hinweisbanner mit Projektname und Kunde, sperrt die Projekt-ID im Save-Dialog und ersetzt das volle Save-Modal durch einen schlanken Bestätigungs-Dialog – User klickt nur „Speichern". Server vergibt device_number = max + 1 und zieht total_devices automatisch hoch.project-detail.php öffnet die existierende Freeform-Config. Editor zeigt einen blauen Hinweisbanner („Bearbeitung der Konfiguration …") mit „Zurück zum Projekt"-Link; Speichern-Button öffnet ein Update-Confirm-Modal mit Vorschau aller Werte und der erkannten Hostname-Zeile aus dem CLI.projects.php (Status-Spalte), project-detail.php (neue Spalte Typ statt Stack) und im Admin-Dashboard (Tab Projekte, neue Spalte Typ). Konsistente Farbsprache über alle Backend-Listen.partials/public-navbar.php rendert jetzt den Backend-Link mit identischem Verhalten wie auf index.php – sichtbar nur für eingeloggte Admins/Superadmins, öffnet admin/ in neuem Tab. Damit profitieren auch editor.php, guide.php, releases.php und roadmap.php.guide.php (Aufruf, Features, Tastatur-Shortcuts-Tabelle, Toolbar-Buttons, Autovervollständigung, Snippets & Platzhalter, Speichern). Zwei neue Tabellen-Sektionen CLI-Editor und CLI-Snippets in admin/help.php mit Berechtigungsmatrix (User / Admin / Superadmin).save.php sie verlangt hat). Felder Device-Nummer und Total Devices entfallen – der Server vergibt sie per Auto-Pick (max + 1). Echte Umlaute statt ae/oe/ue.project-detail.php: passt zu drei möglichen Badge-Typen pro Gerät.editor.php: alle Inline-onclick-Attribute durch addEventListener ersetzt. Login/Logout-Buttons funktionieren jetzt unter der strengen script-src 'self'-Policy.admin.js.preselectCustomer('')-Fallback klappte das Dropdown wieder zu, der Re-Fetch beim Modal-Open klaute den Fokus. Alle drei Fälle behoben.Vollständige Spanning-Tree-Unterstützung im Konfigurator: globaler Modus (PVST+/Rapid PVST+/MSTP), Port-Cost und Port-Priority pro Interface, Root-Rolle und Bridge-Priority pro VLAN sowie eine eigene MST-Region- und Instance-Konfiguration. Cross-Cutting STP-Konsistenzprüfungen im Review-Schritt.
rapid-pvst (Default), pvst und mst. Der gewählte Modus wird immer explizit als spanning-tree mode … vor die Interface-Blöcke geschrieben, damit die erzeugte Config unabhängig vom IOS-/IOS-XE-Default deterministisch bleibt.128 (Default) markiert). Leere Werte erzeugen keine CLI-Zeile – IOS-XE berechnet dann selbst aus der Speed.mode === mst. Region-Name (bis 32 Zeichen) + Revision (0–65 535), Instance-CRUD-Tabelle mit ID, VLAN-Range (10,20-30-Syntax), Priority-Dropdown und Root-Rolle. Live-Validator flaggt ID-Duplikate und VLAN-Overlap zwischen Instances als Fehler.spanning-tree mst configuration-Block mit name, revision, instance <id> vlan <range> und exit. Pro-Instance Priority und Root-Rolle (spanning-tree mst <id> priority|root …) außerhalb des Blocks auf Global-Ebene.stp_mode) sowie MST-Region-Name und Revision (mst_region_name, mst_revision) als Preset/Locked/Open-Felder im Template-Editor. Port-Profile-Templates tragen zusätzlich Port-Cost und Port-Priority.guide.php) mit Modus-Wahl, MST-Region/Instance-Erklärung und Priority-Konventionen; Schritt 3 dokumentiert jetzt auch die VLAN-STP-Felder.Globale Variablen im Konfigurator: Platzhalter wie {{hostname}} oder {{mgmt_ip}} lassen sich in Banner-Texten, Port-/Uplink-, SVI- und BGP-Neighbor-Beschreibungen verwenden und werden beim CLI-Build aufgelöst. Projektweite User-Variablen mit Validierung, Persistenz und JSON-Import/Export, Autocomplete beim Tippen von {{, klickbare Chip-Leisten unter jedem unterstützten Feld sowie eine Warnung im Review-Schritt bei ungelösten Platzhaltern.
{{hostname}}, {{mgmt_ip}}, {{mgmt_vlan}}, {{gateway}} und {{date}} werden beim Build aus dem aktuellen Wizard-State gezogen. Die Rohwerte in den Feldern bleiben erhalten – wird der Hostname später geändert, ziehen alle Verwendungen automatisch nach.{{port_id}} in Port-/Uplink-Beschreibungen, {{vlan_id}} in SVI-Beschreibungen und {{neighbor_ip}} in BGP-Neighbor-Beschreibungen.[a-z_][a-z0-9_]*, Duplikate und Kollisionen mit System-Variablen werden inline markiert. Werte sind Teil des Projekt-States und werden beim Speichern persistiert.{{ öffnet sich unter dem Feld eine Auswahlliste mit passenden System- und User-Variablen (Teilname filtert, z. B. {{host). Navigation per Arrow/Enter/Tab/Escape, Übernahme auch per Klick.globals.json heruntergeladen und projektübergreifend wieder eingespielt werden. Der Import validiert jeden Eintrag (Namensregeln, System-Var-Kollisionen, Duplikate) und fragt vor dem Ersetzen der aktuellen Liste nach.{{name}}-Tokens vorkommen – inklusive Liste der betroffenen Namen.guide.php mit Syntax, System-Var-Tabelle, drei Einfüge-Wegen, Feldliste und Import/Export-Workflow. Kontext-Hinweise in Banner-, SVI- und BGP-Neighbor-Eingabemasken verlinken direkt dorthin.description im CLI landet.Force-Wrap-Migration: Der Superadmin kann alle noch an einen stillgelegten Recovery-Key gebundenen Vaults in einem Durchlauf auf einen aktiven Recovery-Key umwrappen – ohne auf die betroffenen User zu warten. Entsiegelung und Neu-Versiegelung laufen ausschließlich im Browser.
recovery_wrapped_privkey-Blob mit dem Quell-Privkey, versiegelt den Vault-Privkey frisch gegen den Ziel-Pubkey und speichert das neue Blob pro User atomar zurück.vault_force_wrap_preview() / vault_force_wrap_save() plus die beiden Endpoints admin/api/vault/recovery-key/force-wrap-preview.php (Liste der betroffenen Vaults inkl. Quell-Blobs) und force-wrap-save.php (schreibt den neuen Wrap pro User, optimistic lock auf die bestehende Quell-Bindung). Audit pro Erfolg: action=rotate, target=user_id, Detail recovery-wrap force-migrate from=A to=B.scrub() überschrieben.Prävention und Aufräumen rund um stillgelegte Recovery-Keys: Warnung beim Stilllegen, wenn noch Vaults gebunden sind; proaktiver User-Alert, sobald ein Vault an einen nicht mehr aktuellen Recovery-Key gebunden ist; neuer Superadmin-Vorgang „Als verloren markieren“ räumt tote Recovery-Wraps auf, wenn die private Schlüsseldatei dauerhaft weg ist.
recovery.key_id !== recovery.active_key_id, erscheint in der Credential-Vault-Kachel ein gelber Hinweis-Alert mit Handlungsaufforderung (Passphrase rotieren oder Recovery-Wrap aktualisieren). Ergänzt den bestehenden V6c-Button und macht die Lage für Nicht-Eingeweihte verständlich.admin/api/vault/recovery-key/mark-lost.php und Button im Vault-Recovery-UI für stillgelegte Keys mit gebundenen Vaults. Setzt bei allen betroffenen Admins recovery_wrapped_privkey und recovery_key_fk auf NULL (atomar per Transaktion) und protokolliert jeden Fall als eigenständiges Audit-Event (Aktion delete mit target=User, Detail recovery-wrap lost-key=…). Die eigentlichen Credentials im Vault bleiben unberührt, weil sie am Passphrase-Wrap hängen, nicht am Recovery-Wrap.Pflege-Patch rund um die Recovery-Schlüssel: Stillgelegte Keys ohne gebundenen Vault lassen sich jetzt endgültig löschen, die Übersicht bekommt einen Aktive / Stillgelegte / Alle-Filter, und der Stilllegen-Dialog erklärt die Lösch-Voraussetzungen transparent.
admin_vault_key mehr auf diesen Key wrappt. Neuer Superadmin-Endpunkt admin/api/vault/recovery-key/delete.php mit zwei Wachen (retired_at IS NOT NULL & admin_count == 0); Verstöße liefern 404/409 mit klarer reason (not-retired, vaults-bound, not-found). Der Vorgang wird unter Aktion delete im Vault-Audit-Log festgehalten.localStorage gemerkt, sodass sich der Superadmin nicht bei jedem Seitenaufruf neu auf seinen bevorzugten Blick umstellen muss.Passphrase-Recovery für den Credential-Vault: Benutzer, die ihre Vault-Passphrase vergessen, können mit Hilfe eines Superadmin-gestützten Escrow-Verfahrens wieder Zugriff auf ihre gespeicherten Credentials erhalten. Der private Recovery-Schlüssel bleibt offline beim Superadmin, alle kryptografischen Schritte laufen im Browser, und der Vault wird beim Abmelden jetzt automatisch gesperrt.
crypto_box_seal) abgelegt. Bestehende Vaults ohne Wrap können den Wrap per Recovery-Wrap hinzufügen nachziehen, ohne die Passphrase zu ändern.recovery-request, recovery-grant, recovery-complete dokumentieren den gesamten Ablauf (inkl. fehlgeschlagener Einlöse-Versuche). Rate-Limits begrenzen Anfragen (3/24 h), Grants (10/24 h) und Einlöse-Versuche (10/15 min).vault_recovery_request (Request-Lebenszyklus pending → granted → completed/expired/cancelled) samt Token-Hash, versiegeltem Vault-Privkey, Wrap-Nonce und KDF-Salt. Migration via admin/migrate/vault-v6.php; Frisch-Installationen legen alles automatisch über setup.php an.localStorage weitergelebt, bis das 15-min-Idle-Timeout ablief – auch nach einem expliziten Abmelden. Jetzt räumt der Logout-Flow (Backend-Abmelden, Frontend-AJAX-Logout) den Vault-State sofort weg; zusätzlich sperrt der API-Wrapper den Vault, sobald ein Server-Aufruf mit HTTP 401 antwortet. Relevant vor allem für geteilte Rechner.Credential-Vault: Gespeicherte SSH-Credentials lassen sich im Live-SSH-Terminal direkt auswählen, nach einer manuellen Verbindung auf Wunsch in den Vault übernehmen und mit anderen Benutzern teilen. Verschlüsselung und Entschlüsselung erfolgen browser-seitig, sodass Zugangsdaten die Webanwendung niemals im Klartext erreichen.
ssh_vault_audit protokolliert die Aktionen setup, unlock/unlock-failed, rotate, reset, create, update, delete, use, share, revoke. Superadmins sehen das komplette Log, Benutzer sehen ihre eigenen Events.Major-Release: Live-SSH-Terminal im Browser. Admins und Superadmins öffnen eine Kachel auf der Startseite, wählen Host/Port/User und eine von drei Authentifizierungsarten (Passwort, Keyboard-Interactive, SSH-Key-Upload inkl. PPKv2) und erhalten ein vollwertiges Terminal-Fenster im neuen Tab. Credentials verlassen den Browser ausschließlich per WSS und werden nicht an die Webanwendung weitergereicht.
PPKv2-Format mit optionaler Passphrase. Credentials gehen direkt per WSS an den Broker und werden nicht von der Webanwendung gesehen.ssh-rsa, dh-group14-sha1 verfügbar); pro Installation überschreibbar.Switch-Katalog für Catalyst 9200/9200L/9200CX überarbeitet: C9200L als stackbar korrigiert (StackWise-80), modulare C9200 mit NM-Steckplatz wie C9300/C9350 modelliert, PoE-Budgets an aktuelles Cisco-Datenblatt angepasst, neue SKUs (PB, PXG, PL, 4G-Uplink-Varianten) aufgenommen und Catalyst 9200CX Compact Series (fanless) komplett aufgenommen.
C9200CX-12T-2X2G, C9200CX-12P-2X2G, C9200CX-8P-2X2G, C9200CX-8UXG-2X, C9200CX-8PT-2G) mit Frontpanel-Rendering, PoE-Budgets bis 240 W und fixen Uplinks aufgenommen. Eigene Serie C9200CX inklusive Dropdown-Gruppe und Serie-Farbcode; nicht stapelbar, kein NM-Steckplatz.C9200-24PB, C9200-48PB (Full PoE+ mit Enhanced VRF), C9200-24PXG, C9200-48PXG (mGig-PoE+) sowie 4G-Uplink-Varianten, Partial-PoE (C9200L-48PL-4G/-4X), Data-Only-L-Varianten (C9200L-24T-4G/-4X, -48T-4G/-4X) und mGig-L-Varianten (C9200L-24PXG-4X, C9200L-48PXG-4X).C9200-NM-4G, C9200-NM-4X, C9200-NM-2Q, C9200-NM-2Y aufgenommen; modulare C9200 bieten jetzt eine Auswahl-UI für den Network-Module-Slot analog zu C9300/C9350 (Default: C9200-NM-4X).C9200-24T/P, -48T/P, -PB, -PXG) werden jetzt mit NM-Steckplatz statt fester 4× 1G SFP-Uplinks modelliert – damit lässt sich das bestückte Network-Module (1G SFP, 10G SFP+, 40G QSFP+, 25G SFP28) pro Switch konfigurieren.applySelectedModel(sku) umgestellt, der Serien- und Modell-Dropdown synchron setzt. Bestehende gespeicherte Projekte bleiben unverändert kompatibel (keine Datenmigration nötig, nur SKU wird persistiert).C9200L-STACK-KIT (StackWise-80, 80 Gbps Ring) bis zu 8 Member stapelbar – der Katalog markierte die L-Serie bisher fälschlich als nicht stapelbar. Alle C9200L-Einträge liefern nun stackable: true, stack: StackWise-80.C9200-24P / C9200L-24P-4X: 370 W, C9200-48P / C9200L-48P-4X: 740 W).Projekt-Bearbeitung: Bestehende Projekte lassen sich jetzt direkt aus dem Admin-Backend heraus im Konfigurator öffnen, im Wizard editieren und als Update zurückspeichern. Dazu persistenter Wizard-State pro Gerät, Update-Modal mit Projekt-Metadaten, robuster Edit-Init gegen unerwartete Restore-Fehler sowie Aktualisierungs-Zeitstempel und Stack-/SVL-Badges in der Projektübersicht.
project-detail.php öffnet den Konfigurator mit ?edit=<project_id>. Der Wizard wird mit allen gespeicherten Daten aus Schritt 1–5 vorbelegt, Step 0 (Landing) wird übersprungen.State v1 signalisiert die aktive Wizard-State-Version.wizard_state-Spalte in device_configs) persistiert und beim nächsten Edit vollständig restauriert.mode=update an das Backend.update mit Permission-Check (Admin immer, User nur bei project_users-Zuordnung), Orphan-Cleanup für umbenannte Dateien (inkl. per-Chassis-SVL-Dateien) und explizitem UPDATE staging_projects.updated_at, damit der Zeitstempel den letzten Edit widerspiegelt.admin/api/load-project.php liefert Projekt-Metadaten und Device-Configs inkl. wizard_state und stack_metadata mit Berechtigungsprüfung.wizard_state (TEXT NULL) auf device_configs, idempotent per setup.php und Migrations-Endpoint admin/migrate/wizard-state.php angelegt. save.php besitzt ein Self-Heal-Fallback, das die Spalte bei Bedarf automatisch nachzieht._applyStep2State ist in ein eigenes try/catch gekapselt, der goToStep(1)-Aufruf läuft immer – die Seite bleibt nie leer.wizard_state): Der Hostname wird aus device_configs.hostname als Fallback vorbelegt, und ein Info-Banner erklärt, dass die restlichen Felder manuell zu ergänzen sind.Vollständige StackWise Virtual-Unterstützung für C9500, C9600 und C9400 (SUP-1XL+): zweistufiger Bootstrap + Fusion, horizontale Zwei-Chassis-Frontansicht, Multi-File-Download mit getrennten Chassis-Configs und tiefe Admin-Backend-Integration mit SVL-Badge und per-Chassis Downloads.
<details>-Akkordeon. Nur eine Gruppe gleichzeitig offen, Open-State bleibt bei Port-Toggle erhalten. Reservierte Ports sind für Port-Gruppen gesperrt und farblich markiert.switch N provision, stackwise-virtual domain, SVL-Link- und DAD-Interfaces), Phase 2 Reload-Anleitung als Kommentar, Phase 3 Post-SVL Unified Config. SVL-Abschnitt erscheint in Schritt 2 und Schritt 6 in der CLI-Vorschau.SVL · Domain N · 2× SKU, gelb) mit Tooltip-Details. Info-Banner unter der CLI-Vorschau weist auf die Zwei-Chassis-Struktur hin. Per-Chassis-Dateien (C1/C2-Buttons) stehen direkt zum Download bereit.stack_metadata-Spalte gespeichert (keine DB-Migration nötig). Per-Chassis-Konfigurationen werden als separate .txt-Dateien im Projektverzeichnis abgelegt und über den bestehenden Download-Endpoint mit neuem chassis-Parameter ausgeliefert.stack-String und erkannten SVL nicht. Jetzt korrekt auf StackWise Virtual gesetzt.enabled + size). SVL-Metadaten mit type:'svl' + domainId wurden still verworfen und kamen nie in der DB an. Validation erweitert um beide Formen.s5-c-1 in der CLI ausgegeben statt als korrekte Cisco-Interface-Namen wie HundredGigE1/5/0/1. _resolvePortNames() nutzt jetzt Longest-Prefix-Match.refreshIfaceCLI() wird jetzt auch in onModelChange() aufgerufen.Port-Channel-Markierung im Frontpanel-SVG umgestellt: Statt einer Klammer über alle Member bekommt jetzt jeder Member-Port individuell ein Po<N>-Overlay direkt auf seinem Stecker-Slot.
Po<N>-Text-Overlay zentriert auf dem dunklen Stecker-Slot. Die Port-Nummer bleibt am unteren Rand sichtbar, sodass sowohl die logische LAG-Zuordnung als auch die physische Port-Nummer klar erkennbar sind. Font-Size skaliert automatisch mit der Label-Länge (Po1–Po9 = 6 pt, Po10–Po99 = 5,6 pt, Po100+ = 4,8 pt), damit auch hohe Po-Nummern in die Port-Breite passen.Port-Channels (LACP) sind jetzt auch für Downlink-Gruppen verfügbar – mit gemeinsamer UI-Card, scope-spezifischen Best-Practice-Defaults, vollständiger Cisco-CLI für Access- und Trunk-LAGs, einem neuen Validator mit neun Regeln sowie Po-Badges in der Gruppen-Liste und sichtbaren Klammern über den Member-Ports im Frontpanel.
active (symmetrisch zum Core), Downlinks mit passive (Server-LAG mit LACP-Initiator auf der Serverseite).spanning-tree portfast edge trunk ausgegeben. PoE bleibt bewusst auf den Member-Interfaces, weil Cisco PoE pro Port und nicht per LAG konfiguriert.on-Modus und Scope-abhängige LACP-Empfehlung.Po<N> mit LACP-Mode als Tooltip, und das Frontpanel-SVG zeichnet eine dünne Klammer über die Member-Ports mit der Port-Channel-Nummer direkt darüber.ifState.uplinkChannel wurde zu einer scope-agnostischen Map ifState.portChannels[groupId]. Jede Port-Gruppe kann damit ihren eigenen Port-Channel haben, und das bestehende Uplink-Verhalten bleibt unverändert – nur die Datenstruktur dahinter ist einheitlich.Schritt-übergreifende Zustandskonsistenz: Ports lassen sich im Gruppen-Bearbeitungsmodus jetzt sauber hinzufügen und entfernen, und VLANs aus SVIs in Schritt 4 werden automatisch in den VLAN-Katalog von Schritt 3 übernommen.
svi<N>.Der StackWise-Konfigurator warnt jetzt live vor Best-Practice-Verletzungen und Cisco-Inkompatibilitäten in Mixed-Stacks. Dazu einige kleine Darstellungsfixes.
release_render()-Sanitizer ergänzt fehlende Schluss-Tags automatisch. Ein einzelner vergessener Tag kann damit nicht mehr die komplette Seite zerschießen. Zusätzlich wurde das 1.3.3-Summary auf Plain-Text umformuliert, nachdem ein unausbalanciertes <code> die Darstellung gebrochen hatte.pb-3 ergänzt.h-100, wodurch sie bei zwei gestapelten Karten in der linken Spalte die zweite Card (Zugeordnete Benutzer) aus dem Row-Container drückte und den Footer überlappte.Gespeicherte Projekte behalten jetzt den StackWise-Zustand als strukturierte Metadaten, sichtbar im Admin-Backend. Release Notes unterstützen zudem eine minimale Inline-Markup-Allowlist für Inline-Code, Betonung und Hervorhebung.
4× C9300-48P bzw. 4× Mixed mit Tooltip, der die komplette Member-Aufstellung (Rolle, Priority, SKU) und den stack-mac-persistent-Status zeigt.stack_metadata, JSON) in der DB abgelegt – Technologie, Größe, Member-Liste, Basis-SKU. Mixed-Stacks werden anhand unterschiedlicher Member-SKUs erkannt.<code>, <strong> und <em> in Summary- und Bullet-Texten. HTML-Entities wie <sku> werden korrekt durchgereicht. XSS-Schutz bleibt vollständig erhalten – alle anderen Tags und Attribute werden weiterhin escaped.admin/migrate/stack-metadata.php für Superadmins (idempotent), um die stack_metadata-Spalte proaktiv anzulegen.stack_metadata-Spalte beim ersten Projekt-Save automatisch nachzieht. Bestehende Deployments müssen setup.php nicht mehr manuell aufrufen, bevor Stacks gespeichert werden können.Kundenvorlagen können jetzt StackWise-Defaults vorgeben, und die Step-6-Konfigurationsübersicht hebt aktive Stacks mit einer eigenen Übersichts-Card hervor.
Kleinere Verbesserungen an Bedienung und Dark Mode sowie automatische Übernahme der in Schritt 2 referenzierten VLANs in den VLAN-Katalog von Schritt 3.
StackWise-Unterstützung im Konfigurator: stapelbare Catalyst-Modelle lassen sich jetzt als physischer Stack mit 2–8 Membern, vertikaler Frontansicht und Cisco-Best-Practice-CLI konfigurieren.
switch N provision <sku>, switch N priority und stack-mac persistent timer 0 nach Cisco Best Practice. Renumber-Kommandos werden bewusst nur als Kommentar ausgegeben.GigabitEthernet1/0/1, GigabitEthernet2/0/1, …) – Port-Gruppen, Ranges und LACP funktionieren stack-weit ohne Zusatzschritte.Superadmins können das Feedback-Menü und die Einreichung neuer Bug-Reports / Feature Requests nun einzeln deaktivieren. Zusätzlich Feinschliff am Backend-Dashboard und ein vollständiger inhaltlicher Abgleich der Anleitung mit dem Konfigurator.
Visueller Feinschliff: aufgeräumte Navbars im Konfigurator und auf den öffentlichen Sub-Pages, schlankerer Wizard-Stepper und ein gemeinsames Navbar-Partial als zentrale Quelle der Wahrheit.
Feinschliff des Feedback-Releases: Roadmap-Verlinkung an allen relevanten Stellen, kombinierter Feedback-FAB auch im Admin-Backend und überarbeitetes Dashboard mit KPI-Gruppen und Tab-Navigation.
Neues Feature-Request-System inklusive öffentlicher Roadmap, Upvote-Mechanismus und kombiniertem Feedback-Menü im Frontend – adaptiert aus dem bestehenden Bug-Report-Workflow.
Erste öffentliche Version des Cisco Switch Config Generators mit vollständigem Konfigurations-Workflow, Admin-Backend und zentraler Versionierung.
The version number consists of three numbers separated by dots: MAJOR.MINOR.PATCH.
1.5.0-beta.1 or 1.5.0-rc.2.