bifroest/app/templates/admin_databases.html
2026-10-27 08:34:17 +01:00

58 lines
4.1 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}Datenbank-Treiber{% endblock %}
{% block content %}
<div class="stack stack-sm">
<h1>Datenbank-Treiber</h1>
<p class="text-muted">Ein Treiber ist ein DB-Dienst aus <code>services/db-mcp</code>, einer je Datenbanktyp (z. B. <code>db-mcp-postgres</code>, <code>db-mcp-oracle</code>). Er hat keine eigenen Daten: Workspace-Admins legen damit unter <em>Einstellungen → MCP-Server → Datenbanken</em> ihre Datenbanken mit Host, Nutzer und Passwort an. Hier registrieren, <em>Tools abrufen</em> und die vier Tools einmal einstufen; alle Datenbanken dieses Typs übernehmen die Einstufung.</p>
</div>
{% include "_flash.html" %}
<section class="card"><div class="card-body">
{% if drivers %}
<div class="table-wrap"><table>
<thead><tr><th>Treiber</th><th>Endpunkt</th><th>Status</th><th>Datenbanken</th></tr></thead>
<tbody>
{% for d in drivers %}
<tr>
<td><a href="/admin/mcp/{{ d.id }}">{{ d.label }}</a> <code class="text-xs">{{ d.name }}</code>{% if not d.active %} <span class="badge badge-default">inaktiv</span>{% endif %}
{% if d.server_info %}<p class="text-xs text-muted">{{ d.server_info.get('name') }} {{ d.server_info.get('version') }}</p>{% endif %}</td>
<td class="text-sm"><code>{{ d.url }}</code>{% if d.secret_hint %}<p class="text-xs text-muted">Schlüssel …{{ d.secret_hint }}</p>{% endif %}</td>
<td>{% if d.status == 'ok' %}<span class="badge badge-success">Tools abgerufen</span>{% elif d.status == 'error' %}<span class="badge badge-danger">Fehler</span><p class="text-xs text-muted">{{ d.last_error }}</p>{% else %}<span class="badge badge-default">neu</span>{% endif %}</td>
<td class="text-sm">{% for c in databases.get(d.id, []) %}<p><code>{{ c.name }}</code> · {{ workspace_names.get(c.workspace_id, c.workspace_id) }} <span class="text-xs text-muted">{{ c.config.host }}/{{ c.config.database }}</span></p>{% else %}<span class="text-muted">–</span>{% endfor %}</td>
</tr>
{% endfor %}
</tbody>
</table></div>
{% else %}<p class="text-muted">Noch kein Treiber registriert. Ohne Treiber können Workspaces keine Datenbanken anlegen.</p>{% endif %}
</div></section>
<section class="card"><div class="card-body stack stack-sm">
<h2>Treiber registrieren</h2>
{% if not vault_ready %}<div class="alert alert-warning" role="status"><div class="alert-content"><p>AIW_SECRET_KEY fehlt; Schlüssel können nicht gespeichert werden.</p></div></div>{% endif %}
<form method="post" action="/admin/databases" class="stack stack-sm">
<input type="hidden" name="_csrf" value="{{ p.csrf }}">
<div class="form-group">
<label for="label">Bezeichnung</label>
<input id="label" name="label" maxlength="200" value="{{ form.label or '' }}" placeholder="Oracle">
<p class="form-hint">So erscheint der Datenbanktyp im Formular der Workspaces.</p>
</div>
<div class="form-group">
<label for="name">Kurzname</label>
<input id="name" name="name" required maxlength="16" pattern="[a-z][a-z0-9_]*" value="{{ form.name or '' }}" placeholder="oracle">
<p class="form-hint">Intern, für Einstufung und Audit-Log (z. B. <code>oracle__query</code>). Lässt sich später nicht ändern.</p>
</div>
<div class="form-group">
<label for="url">URL des Dienstes</label>
<input id="url" name="url" required type="url" value="{{ form.url or '' }}" placeholder="https://db-mcp-oracle.intern/mcp">
<p class="form-hint">Nur https und nur Hosts aus AIW_MCP_ALLOWED_HOSTS (lokal auch http://localhost).</p>
</div>
<div class="form-group">
<label for="token">Schlüssel des Dienstes</label>
<input id="token" name="token" type="password" autocomplete="off">
<p class="form-hint">Ein Schlüssel aus <code>DBMCP_API_KEYS</code> des Dienstes. Er öffnet nur den Dienst, keine Datenbank; die Zugangsdaten der Datenbanken kommen aus den Workspaces. Verschlüsselt gespeichert.</p>
</div>
{% if error %}<p class="form-error">{{ error }}</p>{% endif %}
<div><button class="btn btn-primary" type="submit">Registrieren</button></div>
</form>
</div></section>
{% endblock %}