fix: gate credential maintenance on enterprise and alert on stalled renewal

This commit is contained in:
hugocasa
2026-09-02 12:31:58 +02:00
parent 9750bbb3d8
commit b237aed906
4 changed files with 40 additions and 7 deletions
@@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT elem->'credential'\n FROM workspace_settings, jsonb_array_elements(git_sync->'repositories') AS elem\n WHERE workspace_id = $1 AND elem->>'git_repo_resource_path' = $2\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "?column?",
"type_info": "Jsonb"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
null
]
},
"hash": "55a272a0050115f90b4fd0de1350ecdbda3fe30cc50d68dc5dfd357113f412ac"
}
+1 -1
View File
@@ -1 +1 @@
7d11df2f77c8af2da18269532fe276b307dd2a54
97ccaf599b709902fdf7526db538a25e2460b869
+4 -5
View File
@@ -4229,7 +4229,7 @@ pub async fn monitor_db(
// and rotate the ones close to it. Every ~40 min: the values move over days, and
// `should_run` counts iterations in a u8.
let git_credential_maintenance_f = async {
#[cfg(feature = "private")]
#[cfg(all(feature = "enterprise", feature = "private"))]
if server_mode && iteration.is_some() && iteration.as_ref().unwrap().should_run(240) {
if let Some(db) = conn.as_sql() {
maintain_git_credentials(db).await;
@@ -4615,13 +4615,13 @@ const AUTO_PULL_POLL_SLACK_S: i64 = 30;
/// Advisory lock id ensuring only one server replica maintains git credentials at
/// a time (adjacent to GIT_AUTO_PULL_LOCK_ID).
#[cfg(feature = "private")]
#[cfg(all(feature = "enterprise", feature = "private"))]
const GIT_CREDENTIAL_LOCK_ID: i64 = 737_483_923;
/// Refresh every git-sync repository's credential status and rotate the ones near
/// expiry, so a token dies visibly (and usually not at all) rather than taking
/// sync down on its expiry date.
#[cfg(feature = "private")]
#[cfg(all(feature = "enterprise", feature = "private"))]
pub async fn maintain_git_credentials(db: &Pool<Postgres>) {
use windmill_common::ee_oss::{get_license_plan, LicensePlan};
@@ -4664,7 +4664,7 @@ pub async fn maintain_git_credentials(db: &Pool<Postgres>) {
}
}
#[cfg(feature = "private")]
#[cfg(all(feature = "enterprise", feature = "private"))]
async fn maintain_git_credentials_inner(db: &Pool<Postgres>) -> error::Result<()> {
use windmill_common::workspaces::WorkspaceGitSyncSettings;
@@ -4718,7 +4718,6 @@ async fn maintain_git_credentials_inner(db: &Pool<Postgres>) -> error::Result<()
Ok(())
}
#[cfg(feature = "private")]
#[cfg(feature = "private")]
async fn poll_git_auto_pull_inner(db: &Pool<Postgres>) -> error::Result<()> {
use windmill_common::workspaces::{AutoPullMode, WorkspaceGitSyncSettings};
@@ -187,9 +187,20 @@
}
}
const days = credentialDaysLeft
if (credential.rotatable || days === undefined || days > 30) return undefined
if (days === undefined) return undefined
const when =
days <= 0 ? 'has expired' : days === 1 ? 'expires tomorrow' : `expires in ${days} days`
if (credential.rotatable) {
// Renewal starts three weeks out, so a rotatable token this close to expiry
// means it has been failing silently and only a person can find out why.
if (days > 7) return undefined
return {
type: days <= 0 ? ('error' as const) : ('warning' as const),
title: `Repository token ${when}`,
body: 'Windmill renews this token automatically but has not managed to. Check that the instance can reach GitLab, and replace the token if sync has already stopped.'
}
}
if (days > 30) return undefined
return {
type: days <= 7 ? ('error' as const) : days <= 14 ? ('warning' as const) : ('info' as const),
title: `Repository token ${when}`,