feat: add shell execution database migrations (migrations #24-28)
Add database schema for shell command execution, kubeconfig management, and approval tracking. - Migration 024: shell_commands table with tier classification - Migration 025: kubeconfig_files table for encrypted kubeconfig storage - Migration 026: command_executions table for execution audit trail - Migration 027: approval_decisions table for session-based approval tracking - Migration 028: supports_tool_calling column for AI provider capabilities Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ea170ab340
commit
ad2d1ced84
@ -287,6 +287,79 @@ pub fn run_migrations(conn: &Connection) -> anyhow::Result<()> {
|
||||
"023_add_mcp_env_config",
|
||||
"ALTER TABLE mcp_servers ADD COLUMN env_config TEXT",
|
||||
),
|
||||
(
|
||||
"024_create_shell_commands",
|
||||
"CREATE TABLE IF NOT EXISTS shell_commands (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_template TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL CHECK(tier IN (1, 2, 3)),
|
||||
description TEXT,
|
||||
category TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
INSERT INTO shell_commands (id, command_template, tier, description, category) VALUES
|
||||
('kubectl_get', 'kubectl get', 1, 'Read Kubernetes resources', 'kubectl'),
|
||||
('kubectl_describe', 'kubectl describe', 1, 'Describe Kubernetes resources', 'kubectl'),
|
||||
('kubectl_logs', 'kubectl logs', 1, 'View pod logs', 'kubectl'),
|
||||
('kubectl_apply', 'kubectl apply', 2, 'Apply configuration', 'kubectl'),
|
||||
('kubectl_delete', 'kubectl delete', 2, 'Delete resources', 'kubectl'),
|
||||
('pvecm_status', 'pvecm status', 1, 'Check Proxmox cluster status', 'proxmox'),
|
||||
('qm_status', 'qm status', 1, 'Check VM status', 'proxmox');",
|
||||
),
|
||||
(
|
||||
"025_create_kubeconfig_files",
|
||||
"CREATE TABLE IF NOT EXISTS kubeconfig_files (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
encrypted_content TEXT NOT NULL,
|
||||
context TEXT NOT NULL,
|
||||
cluster_url TEXT,
|
||||
is_active INTEGER NOT NULL DEFAULT 0,
|
||||
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_kubeconfig_active ON kubeconfig_files(is_active);",
|
||||
),
|
||||
(
|
||||
"026_create_command_executions",
|
||||
"CREATE TABLE IF NOT EXISTS command_executions (
|
||||
id TEXT PRIMARY KEY,
|
||||
issue_id TEXT,
|
||||
command TEXT NOT NULL,
|
||||
tier INTEGER NOT NULL,
|
||||
approval_status TEXT NOT NULL,
|
||||
kubeconfig_id TEXT,
|
||||
exit_code INTEGER,
|
||||
stdout TEXT,
|
||||
stderr TEXT,
|
||||
execution_time_ms INTEGER,
|
||||
executed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (kubeconfig_id) REFERENCES kubeconfig_files(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_command_executions_issue ON command_executions(issue_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_command_executions_executed ON command_executions(executed_at);",
|
||||
),
|
||||
(
|
||||
"027_create_approval_decisions",
|
||||
"CREATE TABLE IF NOT EXISTS approval_decisions (
|
||||
id TEXT PRIMARY KEY,
|
||||
command_pattern TEXT NOT NULL,
|
||||
decision TEXT NOT NULL CHECK(decision IN ('allow_once', 'allow_session', 'deny')),
|
||||
session_id TEXT,
|
||||
decided_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
expires_at TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_approval_decisions_session ON approval_decisions(session_id);",
|
||||
),
|
||||
(
|
||||
"028_add_supports_tool_calling",
|
||||
"ALTER TABLE ai_providers ADD COLUMN supports_tool_calling INTEGER DEFAULT 1;
|
||||
-- Default to true for existing providers to maintain backward compatibility",
|
||||
),
|
||||
];
|
||||
|
||||
for (name, sql) in migrations {
|
||||
@ -306,6 +379,8 @@ pub fn run_migrations(conn: &Connection) -> anyhow::Result<()> {
|
||||
|| name.ends_with("_add_created_at")
|
||||
|| name.ends_with("_add_log_content_compressed")
|
||||
|| name.ends_with("_add_image_data")
|
||||
|| name.ends_with("_add_supports_tool_calling")
|
||||
|| name.ends_with("_add_mcp_env_config")
|
||||
{
|
||||
// Use execute for ALTER TABLE (SQLite only allows one statement per command)
|
||||
// Skip error if column already exists (SQLITE_ERROR with "duplicate column name")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user