From 77f84eccd98837db634a62318fc6f99076223adf Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Wed, 26 Nov 2025 16:13:55 +0100 Subject: [PATCH] add tags to custom instance dbs --- ...igrate_instance_ducklake_catalogs.down.sql | 15 +++++++- ..._migrate_instance_ducklake_catalogs.up.sql | 13 +++++++ backend/windmill-api/openapi.yaml | 32 ++++++++++++----- backend/windmill-api/src/settings.rs | 35 +++++++++++-------- .../CustomInstanceDbSelect.svelte | 19 +++++----- .../CustomInstanceDbWizardModal.svelte | 22 +++++++----- .../DataTableSettings.svelte | 5 +-- .../workspaceSettings/DucklakeSettings.svelte | 11 +++--- frontend/src/lib/utils.ts | 9 +++++ 9 files changed, 116 insertions(+), 45 deletions(-) diff --git a/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.down.sql b/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.down.sql index ae87d1e456..b5cbb659b1 100644 --- a/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.down.sql +++ b/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.down.sql @@ -1,4 +1,17 @@ --- Add up migration script here +UPDATE global_settings +SET value = jsonb_build_object( + 'status', ( + SELECT jsonb_object_agg( + key, + value - 'tag' + ) + FROM jsonb_each(value->'databases') + ), + 'user_pwd', value->'user_pwd' +) +WHERE name = 'custom_instance_pg_databases'; + + UPDATE global_settings SET name = 'ducklake_settings', value = jsonb_build_object( diff --git a/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.up.sql b/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.up.sql index 6458f9daaa..88f293ae78 100644 --- a/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.up.sql +++ b/backend/migrations/20251121144314_migrate_instance_ducklake_catalogs.up.sql @@ -12,3 +12,16 @@ SET name = 'custom_instance_pg_databases', 'status', value->'instance_catalog_db_status' ) WHERE name = 'ducklake_settings'; + +UPDATE global_settings +SET value = jsonb_build_object( + 'databases', ( + SELECT jsonb_object_agg( + key, + value || jsonb_build_object('tag', 'ducklake') + ) + FROM jsonb_each(value->'status') + ), + 'user_pwd', value->'user_pwd' +) +WHERE name = 'custom_instance_pg_databases'; diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index d1fe86e2f0..1212b8b652 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -831,10 +831,10 @@ paths: schema: type: boolean - /settings/get_custom_instance_pg_databases_status: + /settings/get_custom_instance_pg_databases: post: summary: Returns the set-up statuses of custom instance pg databases - operationId: getCustomInstanceDbStatus + operationId: getCustomInstanceDbs tags: - setting responses: @@ -845,7 +845,7 @@ paths: schema: type: object additionalProperties: - $ref: "#/components/schemas/CustomInstanceDbStatus" + $ref: "#/components/schemas/CustomInstanceDb" /settings/setup_custom_instance_pg_database/{name}: post: @@ -853,6 +853,15 @@ paths: operationId: setupCustomInstanceDb tags: - setting + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + tag: + $ref: "#/components/schemas/CustomInstanceDbTag" parameters: - in: path name: name @@ -866,7 +875,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/CustomInstanceDbStatus" + $ref: "#/components/schemas/CustomInstanceDb" /settings/global/{key}: get: @@ -18181,7 +18190,7 @@ components: - SKIP - FAIL - CustomInstanceDbStatusLogs: + CustomInstanceDbLogs: type: object properties: super_admin: @@ -18192,20 +18201,25 @@ components: $ref: "#/components/schemas/LoggedWizardStatus" created_database: $ref: "#/components/schemas/LoggedWizardStatus" - description: Created database status log db_connect: $ref: "#/components/schemas/LoggedWizardStatus" grant_permissions: $ref: "#/components/schemas/LoggedWizardStatus" - CustomInstanceDbStatus: + CustomInstanceDbTag: + type: string + enum: + - ducklake + - datatable + + CustomInstanceDb: type: object required: - logs - success properties: logs: - $ref: "#/components/schemas/CustomInstanceDbStatusLogs" + $ref: "#/components/schemas/CustomInstanceDbLogs" success: type: boolean description: Whether the operation completed successfully @@ -18215,6 +18229,8 @@ components: nullable: true description: Error message if the operation failed example: "Connection timeout" + tag: + $ref: "#/components/schemas/CustomInstanceDbTag" NewSqsTrigger: type: object diff --git a/backend/windmill-api/src/settings.rs b/backend/windmill-api/src/settings.rs index b5b7ab82e8..d463e9b5aa 100644 --- a/backend/windmill-api/src/settings.rs +++ b/backend/windmill-api/src/settings.rs @@ -70,8 +70,8 @@ pub fn global_service() -> Router { post(acknowledge_critical_alert), ) .route( - "/get_custom_instance_pg_databases_status", - post(get_custom_instance_pg_databases_status), + "/get_custom_instance_pg_databases", + post(get_custom_instance_pg_databases), ) .route( "/setup_custom_instance_pg_database/:name", @@ -583,15 +583,16 @@ pub async fn acknowledge_all_critical_alerts() -> error::Error { } #[derive(Deserialize, Debug, Serialize)] -struct CustomInstanceDbStatus { - logs: CustomInstanceDbStatusLogs, // (Step, Message)[] +struct CustomInstanceDb { + logs: CustomInstanceDbLogs, // (Step, Message)[] success: bool, error: Option, + tag: Option, } #[derive(Deserialize, Debug, Serialize, Default)] #[serde(default)] -struct CustomInstanceDbStatusLogs { +struct CustomInstanceDbLogs { super_admin: String, #[serde(skip_serializing_if = "String::is_empty")] database_credentials: String, @@ -605,39 +606,45 @@ struct CustomInstanceDbStatusLogs { grant_permissions: String, } -async fn get_custom_instance_pg_databases_status( +async fn get_custom_instance_pg_databases( _authed: ApiAuthed, Extension(db): Extension, -) -> JsonResult> { +) -> JsonResult> { let result = sqlx::query_scalar!( - r#"SELECT value->'status' FROM global_settings WHERE name = 'custom_instance_pg_databases'"#, + r#"SELECT value->'databases' FROM global_settings WHERE name = 'custom_instance_pg_databases'"#, ) .fetch_one(&db) .await? .ok_or_else(|| error::Error::ExecutionErr("Couldn't find custom_instance_pg_databases".to_string()))?; let result = serde_json::from_value(result).map_err(|e| { error::Error::ExecutionErr(format!( - "couldn't parse custom_instance_pg_databases.status : {}", + "couldn't parse custom_instance_pg_databases.databases : {}", e.to_string() )) })?; return Ok(Json(result)); } +#[derive(Deserialize)] +struct SetupCustomInstanceDbBody { + tag: Option, +} + async fn setup_custom_instance_pg_database( authed: ApiAuthed, Extension(db): Extension, Path(dbname): Path, -) -> JsonResult { - let mut logs = CustomInstanceDbStatusLogs::default(); + Json(body): Json, +) -> JsonResult { + let mut logs = CustomInstanceDbLogs::default(); let result = setup_custom_instance_pg_database_inner(authed, &db, &dbname, &mut logs).await; let success = result.is_ok(); let error = result.err().map(|e| e.to_string()); - let status = CustomInstanceDbStatus { logs, success, error }; + let status = CustomInstanceDb { logs, success, error, tag: body.tag }; let status_json = serde_json::to_value(&status).map_err(to_anyhow)?; // Save that the database was setup successfully sqlx::query!( - r#"UPDATE global_settings SET value = jsonb_set(value, '{status}', (COALESCE(value->'status', '{}'::jsonb) || to_jsonb($1::json))) WHERE name = 'custom_instance_pg_databases'"#, + r#"UPDATE global_settings SET value = jsonb_set(value, '{databases}', (COALESCE(value->'databases', '{}'::jsonb) || to_jsonb($1::json))) WHERE name = 'custom_instance_pg_databases'"#, json!({ dbname: status_json }) ).execute(&db).await?; @@ -648,7 +655,7 @@ async fn setup_custom_instance_pg_database_inner( authed: ApiAuthed, db: &DB, dbname: &str, - logs: &mut CustomInstanceDbStatusLogs, + logs: &mut CustomInstanceDbLogs, ) -> Result<()> { require_super_admin(db, &authed.email).await?; logs.super_admin = "OK".to_string(); diff --git a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbSelect.svelte b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbSelect.svelte index 217fbd1005..a00377f683 100644 --- a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbSelect.svelte +++ b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbSelect.svelte @@ -1,5 +1,5 @@
@@ -40,7 +42,7 @@ bind:value onCreateItem={(i) => (value = i)} placeholder="PostgreSQL database name" - items={safeSelectItems(Object.keys(customInstanceDbStatuses.current ?? {}))} + items={safeSelectItems(Object.keys(customInstanceDbs.current ?? {}))} disabled={!$isCustomInstanceDbEnabled} /> @@ -65,14 +67,15 @@
openedDbNameWizard - ? { dbname: value ?? '', status: customInstanceDbStatuses.current?.[value ?? ''] } + ? { dbname: value ?? '', status: customInstanceDbs.current?.[value ?? ''] } : undefined, (v) => !v && (openedDbNameWizard = false) } diff --git a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte index 73860a1000..da9598f20e 100644 --- a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +++ b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte @@ -1,8 +1,9 @@