use std::sync::Arc; use tauri::State; use crate::commands::connection::{ensure_connection_writable, AppState}; use dbx_core::agent_kv::{ EtcdDefragResponse, EtcdLeaseListResponse, EtcdPreflightRequest, EtcdPreflightResponse, EtcdWatchPollResponse, EtcdWatchStartRequest, EtcdWatchStartResponse, KvDeleteOptions, KvDeleteResponse, KvGetOptions, KvGetResponse, KvHistoryRequest, KvHistoryResponse, KvInt64, KvListPrefixResponse, KvPutOptions, KvPutResponse, KvRangeOptions, KvRenameRequest, KvRenameResponse, KvStatusResponse, KvValue, }; use dbx_core::db::agent_driver::AgentKvMethod; #[tauri::command] pub async fn etcd_list_prefix( state: State<'_, Arc>, connection_id: String, prefix: String, limit: usize, continuation: Option, revision: Option, include_values: Option, ) -> Result { dbx_core::agent_kv::kv_list_prefix_core_with_range_options( &state, &connection_id, &prefix, limit, continuation.as_deref(), KvRangeOptions { revision, include_values }, ) .await } #[tauri::command] pub async fn etcd_supports_ttl(state: State<'_, Arc>, connection_id: String) -> Result { dbx_core::agent_kv::kv_supports_ttl_core(&state, &connection_id).await } #[tauri::command] pub async fn etcd_get( state: State<'_, Arc>, connection_id: String, key: String, key_bytes: Option, revision: Option, metadata_only: Option, ) -> Result { dbx_core::agent_kv::kv_get_core_with_options( &state, &connection_id, &key, KvGetOptions { key_bytes, revision, metadata_only }, ) .await } #[tauri::command] pub async fn etcd_put( state: State<'_, Arc>, connection_id: String, key: String, value: KvValue, lease: Option, ttl: Option, preserve_lease: Option, key_bytes: Option, expected_mod_revision: Option, expected_create_revision: Option, ) -> Result { ensure_connection_writable(&state, &connection_id, "Put").await?; dbx_core::agent_kv::kv_put_core_with_options( &state, &connection_id, &key, value, KvPutOptions { lease, ttl, preserve_lease, key_bytes, expected_mod_revision, expected_create_revision, ..KvPutOptions::default() }, ) .await } #[tauri::command] pub async fn etcd_delete( state: State<'_, Arc>, connection_id: String, key: String, key_bytes: Option, expected_mod_revision: Option, ) -> Result { ensure_connection_writable(&state, &connection_id, "Delete").await?; dbx_core::agent_kv::kv_delete_core_with_options( &state, &connection_id, &key, KvDeleteOptions { key_bytes, expected_mod_revision }, ) .await } #[tauri::command] pub async fn etcd_rename( state: State<'_, Arc>, connection_id: String, request: KvRenameRequest, ) -> Result { ensure_connection_writable(&state, &connection_id, "Rename").await?; dbx_core::agent_kv::kv_rename_core(&state, &connection_id, request).await } #[tauri::command] pub async fn etcd_history( state: State<'_, Arc>, connection_id: String, request: KvHistoryRequest, ) -> Result { dbx_core::agent_kv::kv_history_core(&state, &connection_id, request).await } #[tauri::command] pub async fn etcd_status(state: State<'_, Arc>, connection_id: String) -> Result { dbx_core::agent_kv::kv_status_core(&state, &connection_id).await } #[tauri::command] pub async fn etcd_preflight( state: State<'_, Arc>, connection_id: String, request: EtcdPreflightRequest, ) -> Result { ensure_connection_writable(&state, &connection_id, "Dangerous etcd operation").await?; dbx_core::agent_kv::etcd_preflight_core(&state, &connection_id, request).await } #[tauri::command] pub async fn etcd_compact( state: State<'_, Arc>, connection_id: String, revision: KvInt64, preflight_token: String, confirmation_text: String, ) -> Result { ensure_connection_writable(&state, &connection_id, "Compact").await?; let params = serde_json::json!({ "revision": revision.clone() }); dbx_core::agent_kv::etcd_consume_preflight_core( &state, &connection_id, "compact", ¶ms, &preflight_token, &confirmation_text, ) .await?; dbx_core::agent_kv::etcd_compact_core(&state, &connection_id, revision).await } #[tauri::command] pub async fn etcd_defrag( state: State<'_, Arc>, connection_id: String, endpoints: Vec, preflight_token: String, confirmation_text: String, ) -> Result { ensure_connection_writable(&state, &connection_id, "Defrag").await?; let params = serde_json::json!({ "endpoints": endpoints.clone() }); dbx_core::agent_kv::etcd_consume_preflight_core( &state, &connection_id, "defrag", ¶ms, &preflight_token, &confirmation_text, ) .await?; dbx_core::agent_kv::etcd_defrag_core(&state, &connection_id, endpoints).await } #[tauri::command] pub async fn etcd_watch_start( state: State<'_, Arc>, connection_id: String, request: EtcdWatchStartRequest, ) -> Result { dbx_core::agent_kv::etcd_watch_start_core(&state, &connection_id, request).await } #[tauri::command] pub async fn etcd_watch_poll( state: State<'_, Arc>, connection_id: String, watch_id: String, ) -> Result { dbx_core::agent_kv::etcd_watch_poll_core(&state, &connection_id, &watch_id).await } #[tauri::command] pub async fn etcd_watch_stop( state: State<'_, Arc>, connection_id: String, watch_id: String, ) -> Result { dbx_core::agent_kv::etcd_watch_stop_core(&state, &connection_id, &watch_id).await } #[tauri::command] pub async fn etcd_lease_list( state: State<'_, Arc>, connection_id: String, limit: Option, continuation: Option, ) -> Result { dbx_core::agent_kv::etcd_lease_list_core(&state, &connection_id, limit.unwrap_or(100), continuation.as_deref()) .await } #[tauri::command] pub async fn etcd_lease_call( state: State<'_, Arc>, connection_id: String, operation: String, params: serde_json::Value, preflight_token: Option, confirmation_text: Option, ) -> Result { let (method, write) = match operation.as_str() { "get" => (AgentKvMethod::LeaseGet, false), "grant" => (AgentKvMethod::LeaseGrant, true), "keepalive" => (AgentKvMethod::LeaseKeepalive, true), "revoke" => (AgentKvMethod::LeaseRevoke, true), _ => return Err("Unsupported etcd lease operation".to_string()), }; if write { ensure_connection_writable(&state, &connection_id, "Lease operation").await?; } if operation == "revoke" { dbx_core::agent_kv::etcd_consume_preflight_core( &state, &connection_id, "lease_revoke", ¶ms, preflight_token.as_deref().ok_or("ETCD_PREFLIGHT_REQUIRED: Request a preflight confirmation")?, confirmation_text.as_deref().ok_or("ETCD_PREFLIGHT_REQUIRED: Request a preflight confirmation")?, ) .await?; } dbx_core::agent_kv::etcd_lease_call_core(&state, &connection_id, method, params).await } #[tauri::command] pub async fn etcd_auth_call( state: State<'_, Arc>, connection_id: String, operation: String, params: serde_json::Value, preflight_token: Option, confirmation_text: Option, ) -> Result { let (method, write) = match operation.as_str() { "user_list" => (AgentKvMethod::AuthUserList, false), "user_get" => (AgentKvMethod::AuthUserGet, false), "user_add" => (AgentKvMethod::AuthUserAdd, true), "user_delete" => (AgentKvMethod::AuthUserDelete, true), "user_change_password" => (AgentKvMethod::AuthUserChangePassword, true), "user_grant_role" => (AgentKvMethod::AuthUserGrantRole, true), "user_revoke_role" => (AgentKvMethod::AuthUserRevokeRole, true), "role_list" => (AgentKvMethod::AuthRoleList, false), "role_get" => (AgentKvMethod::AuthRoleGet, false), "role_add" => (AgentKvMethod::AuthRoleAdd, true), "role_delete" => (AgentKvMethod::AuthRoleDelete, true), "role_grant_permission" => (AgentKvMethod::AuthRoleGrantPermission, true), "role_revoke_permission" => (AgentKvMethod::AuthRoleRevokePermission, true), _ => return Err("Unsupported etcd Auth operation".to_string()), }; if write { ensure_connection_writable(&state, &connection_id, "Auth operation").await?; } if let Some(action) = auth_preflight_action(&operation) { dbx_core::agent_kv::etcd_consume_preflight_core( &state, &connection_id, action, ¶ms, preflight_token.as_deref().ok_or("ETCD_PREFLIGHT_REQUIRED: Request a preflight confirmation")?, confirmation_text.as_deref().ok_or("ETCD_PREFLIGHT_REQUIRED: Request a preflight confirmation")?, ) .await?; } dbx_core::agent_kv::etcd_auth_call_core(&state, &connection_id, method, params).await } fn auth_preflight_action(operation: &str) -> Option<&'static str> { match operation { "user_add" => Some("auth_user_add"), "user_delete" => Some("auth_user_delete"), "user_change_password" => Some("auth_user_change_password"), "user_grant_role" => Some("auth_user_grant_role"), "user_revoke_role" => Some("auth_user_revoke_role"), "role_add" => Some("auth_role_add"), "role_delete" => Some("auth_role_delete"), "role_grant_permission" => Some("auth_role_grant_permission"), "role_revoke_permission" => Some("auth_role_revoke_permission"), _ => None, } }