mirror of
https://github.com/mailscope/kumomta.git
synced 2026-10-28 01:06:14 +00:00
These are two different groups of queues, so there are two different sets of things to manage them. kcli now has `suspend(-list|cancel)?` and `suspend-ready-q(-list|cancel)?` subcommands for establishing a suspension, listing the suspensions and cancelling a suspension in the scheduled-q and ready-q namespaces respectively. The names of the ready queues can be derived from the metrics API: ```console $ curl -s 'http://localhost:8000/metrics.json' | jq . ... "ready_count": { "help": "number of messages in the ready queue", "type": "gauge", "value": { "service": { "smtp_client:source2->(in1-smtp|in2-smtp).messagingengine.com": 0.0 } } }, ... ``` From the above, `source2->(in1-smtp|in2-smtp).messagingengine.com` is the name of the underlying ready queue. We can and probably should add something to `kcli` to make that slightly easier to review and manage for the operator. refs: https://github.com/KumoCorp/kumomta/issues/51
67 lines
1.9 KiB
Rust
67 lines
1.9 KiB
Rust
use clap::Parser;
|
|
use kumo_api_types::{SuspendV1Request, SuspendV1Response};
|
|
use reqwest::Url;
|
|
use std::time::Duration;
|
|
|
|
#[derive(Debug, Parser)]
|
|
/// Administratively suspend messages in matching queues.
|
|
pub struct SuspendCommand {
|
|
/// The domain name to match.
|
|
/// If omitted, any domains will match!
|
|
#[arg(long)]
|
|
domain: Option<String>,
|
|
|
|
/// The campaign name to match.
|
|
/// If omitted, any campaigns will match!
|
|
#[arg(long)]
|
|
campaign: Option<String>,
|
|
|
|
/// The tenant name to match.
|
|
/// If omitted, any tenant will match!
|
|
#[arg(long)]
|
|
tenant: Option<String>,
|
|
|
|
/// The reason to log in the delivery logs
|
|
#[arg(long)]
|
|
reason: String,
|
|
|
|
/// Suspend all queues.
|
|
#[arg(long)]
|
|
everything: bool,
|
|
|
|
/// The duration over which matching messages will continue to suspend.
|
|
/// The default is '5m'.
|
|
#[arg(long, value_parser=humantime::parse_duration)]
|
|
duration: Option<Duration>,
|
|
}
|
|
|
|
impl SuspendCommand {
|
|
pub async fn run(&self, endpoint: &Url) -> anyhow::Result<()> {
|
|
if self.domain.is_none() && self.campaign.is_none() && self.tenant.is_none() {
|
|
if !self.everything {
|
|
anyhow::bail!(
|
|
"No domain, campaign or tenant was specified. \
|
|
Use --everything if you intend to suspend all queues"
|
|
);
|
|
}
|
|
}
|
|
|
|
let result: SuspendV1Response = crate::request_with_json_response(
|
|
reqwest::Method::POST,
|
|
endpoint.join("/api/admin/suspend/v1")?,
|
|
&SuspendV1Request {
|
|
campaign: self.campaign.clone(),
|
|
domain: self.domain.clone(),
|
|
tenant: self.tenant.clone(),
|
|
reason: self.reason.clone(),
|
|
duration: self.duration.clone(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
println!("{}", serde_json::to_string_pretty(&result)?);
|
|
|
|
Ok(())
|
|
}
|
|
}
|