Skip to content

Commit

Permalink
improve audit aprovals (#5161)
Browse files Browse the repository at this point in the history
* update audit log to track aproval and cancellation of job

* approval to resource field

* audit resource as json

* refactor aproval audit logs

* moving audit logs to worker_flow

* striping u/ from auditor name

---------

Co-authored-by: Ruben Fiszel <[email protected]>
  • Loading branch information
alpetric and rubenfiszel authored Jan 30, 2025
1 parent f29ee67 commit 03ad038
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
26 changes: 20 additions & 6 deletions backend/windmill-api/src/jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1968,20 +1968,34 @@ async fn resume_suspended_job_internal(
resume_immediately_if_relevant(parent_flow_info, job_id, &mut tx).await?;
}

let approver = approver.unwrap_or_else(|| "anonymous".to_string());

let audit_author = match authed {
Some(authed) => (&authed).into(),
None => {
let approver = approver.unwrap_or_else(|| "anonymous".to_string());
AuditAuthor { email: approver.clone(), username: approver, username_override: None }
}
None => AuditAuthor {
email: approver.clone(),
username: approver.clone(),
username_override: None,
},
};
audit_log(
&mut *tx,
&audit_author,
"jobs.approved",
"jobs.suspend_resume",
ActionKind::Update,
&w_id,
Some(&serde_json::json!({"approved": approved, "job_id": job_id}).to_string()),
Some(
&serde_json::json!({
"approved": approved,
"job_id": job_id,
"details": if approved {
format!("Approved by {}", &approver)
} else {
format!("Cancelled by {}", &approver)
}
})
.to_string(),
),
None,
)
.await?;
Expand Down
31 changes: 31 additions & 0 deletions backend/windmill-worker/src/worker_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ use windmill_queue::{

type DB = sqlx::Pool<sqlx::Postgres>;

use windmill_audit::audit_ee::{audit_log, AuditAuthor};
use windmill_audit::ActionKind;
use windmill_queue::{canceled_job_to_result, push};

// #[instrument(level = "trace", skip_all)]
Expand Down Expand Up @@ -1894,6 +1896,12 @@ async fn push_next_flow_job(
))
&& suspend.continue_on_disapprove_timeout.unwrap_or(false);

let audit_author = AuditAuthor {
username: flow_job.permissioned_as.trim_start_matches("u/").to_string(),
email: flow_job.email.clone(),
username_override: None,
};

if can_be_resumed || disapproved_or_timeout_but_continue {
if disapproved_or_timeout_but_continue {
let js = if let Some(disapproved) = is_disapproved.as_ref() {
Expand All @@ -1903,7 +1911,18 @@ async fn push_next_flow_job(
};

resume_messages.push(to_raw_value(&js));
audit_log(
&mut *tx,
&audit_author,
"jobs.suspend_resume",
ActionKind::Update,
&flow_job.workspace_id,
Some(&serde_json::json!({"approved": false, "job_id": flow_job.id, "details": "Suspend timed out without approval but can continue".to_string()}).to_string()),
None,
)
.await?;
}

sqlx::query(
"UPDATE queue
SET flow_status = JSONB_SET(flow_status, ARRAY['modules', $1::TEXT, 'approvers'], $2)
Expand Down Expand Up @@ -1971,6 +1990,18 @@ async fn push_next_flow_job(

/* cancelled or we're WaitingForEvents but we don't have enough messages (timed out) */
} else {
if is_disapproved.is_none() {
audit_log(
&mut *tx,
&audit_author,
"jobs.suspend_resume",
ActionKind::Update,
&flow_job.workspace_id,
Some(&serde_json::json!({"approved": false, "job_id": flow_job.id, "details": "Suspend timed out without approval and is cancelled".to_string()}).to_string()),
None,
)
.await?;
}
tx.commit().await?;

let (logs, error_name) = if let Some(disapprover) = is_disapproved {
Expand Down

0 comments on commit 03ad038

Please sign in to comment.