Public dry run dryrun-00a47f2c6f21

Source commit: 00a47f2c6f213d43fcef11fdf7926320241da30d

Public tree identity: sha256:c41c788b9938cfa66d0c047c16729942bfe6ba4f884acec7d4cd482da762f81a
This commit is contained in:
Michel Paulissen 2026-07-03 21:08:32 +02:00
parent a40778221a
commit 005b47e4c0
6 changed files with 282 additions and 5 deletions

View file

@ -1481,13 +1481,27 @@ fn quota_status_report(args: QuotaStatusArgs, cwd: PathBuf) -> Result<Value> {
fn admin_status_report(args: AdminStatusArgs) -> Result<Value> {
if let Some(coordinator) = &args.scope.coordinator {
let tenant = args.scope.tenant.clone();
let user = args.scope.user.clone();
let mut session = JsonLineSession::connect(coordinator)?;
let response = session.request(json!({ "type": "ping" }))?;
let response = session.request(json!({
"type": "admin_status",
"tenant": tenant,
"actor_user": user,
}))?;
return Ok(json!({
"command": "admin status",
"coordinator": coordinator,
"tenant": tenant,
"user": user,
"suspended": response
.get("suspended")
.cloned()
.unwrap_or_else(|| json!(false)),
"response": response,
"safe_default": "read_only",
"private_website_required": false,
"coordinator_session_requests": session.requests(),
}));
}
Ok(json!({
@ -1516,24 +1530,34 @@ fn admin_suspend_tenant_report(args: AdminSuspendTenantArgs) -> Result<Value> {
.target_tenant
.unwrap_or_else(|| args.scope.tenant.clone());
if let Some(coordinator) = &args.scope.coordinator {
let actor_tenant = args.scope.tenant.clone();
let actor_user = args.scope.user.clone();
let mut session = JsonLineSession::connect(coordinator)?;
let response = session.request(json!({
"type": "suspend_tenant",
"tenant": tenant,
"tenant": actor_tenant,
"actor_user": actor_user,
"target_tenant": tenant,
}))?;
return Ok(json!({
"command": "admin suspend-tenant",
"coordinator": coordinator,
"requires_confirmation": !args.yes,
"tenant": tenant,
"actor_tenant": actor_tenant,
"actor_user": actor_user,
"suspended": response.get("type").and_then(Value::as_str) == Some("tenant_suspended"),
"private_website_required": false,
"response": response,
"coordinator_session_requests": session.requests(),
}));
}
Ok(json!({
"command": "admin suspend-tenant",
"status": "requires_private_hosted_coordinator",
"status": "requires_coordinator",
"requires_confirmation": !args.yes,
"tenant": tenant,
"private_website_required": false,
}))
}
@ -4501,6 +4525,69 @@ mod tests {
assert_eq!(revoked["node_credentials_separate_from_user_session"], true);
}
#[test]
fn admin_status_and_suspend_use_public_coordinator_api() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap().to_string();
let server = std::thread::spawn(move || {
for (expected, response) in [
(
"admin_status",
r#"{"type":"admin_status","tenant":"tenant","actor":"admin","suspended":false,"safe_default":"read_only"}"#,
),
(
"suspend_tenant",
r#"{"type":"tenant_suspended","tenant":"tenant","actor":"admin","policy":{"tenant":"tenant","name":"tenant:suspended","digest":"sha256:suspension"}}"#,
),
] {
let (mut stream, _) = listener.accept().unwrap();
let mut reader = BufReader::new(stream.try_clone().unwrap());
let mut line = String::new();
reader.read_line(&mut line).unwrap();
assert!(line.contains(&format!(r#""type":"{expected}""#)));
assert!(
line.contains(r#""tenant":"admin-tenant""#)
|| line.contains(r#""tenant":"tenant""#)
);
assert!(line.contains(r#""actor_user":"admin""#));
if expected == "suspend_tenant" {
assert!(line.contains(r#""target_tenant":"tenant""#));
}
stream.write_all(response.as_bytes()).unwrap();
stream.write_all(b"\n").unwrap();
}
});
let scope = CliScopeArgs {
coordinator: Some(addr),
tenant: "admin-tenant".to_owned(),
project: "project".to_owned(),
user: "admin".to_owned(),
json: false,
};
let status = admin_status_report(AdminStatusArgs {
scope: scope.clone(),
})
.unwrap();
let suspended = admin_suspend_tenant_report(AdminSuspendTenantArgs {
scope,
target_tenant: Some("tenant".to_owned()),
yes: true,
})
.unwrap();
server.join().unwrap();
assert_eq!(status["command"], "admin status");
assert_eq!(status["safe_default"], "read_only");
assert_eq!(status["private_website_required"], false);
assert_eq!(status["suspended"], false);
assert_eq!(suspended["command"], "admin suspend-tenant");
assert_eq!(suspended["tenant"], "tenant");
assert_eq!(suspended["actor_tenant"], "admin-tenant");
assert_eq!(suspended["suspended"], true);
assert_eq!(suspended["private_website_required"], false);
}
#[test]
fn human_report_is_text_not_json() {
let report = json!({