use anyhow::Result;
use atlassian_cli_api::ApiClient;
use atlassian_cli_output::OutputRenderer;
use clap::{Args, Subcommand, ValueEnum};
mod alerts;
mod escalations;
mod heartbeats;
mod incidents;
mod schedules;
mod services;
mod teams;
pub mod utils;
pub use utils::OpsgenieContext;
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
pub enum Region {
#[default]
Us,
Eu,
}
impl Region {
pub fn base_url(&self) -> &'static str {
match self {
Region::Us => utils::OPSGENIE_US_API_URL,
Region::Eu => utils::OPSGENIE_EU_API_URL,
}
}
}
#[derive(Args, Debug, Clone)]
pub struct OpsgenieArgs {
#[command(subcommand)]
command: OpsgenieCommands,
}
#[derive(Subcommand, Debug, Clone)]
enum OpsgenieCommands {
#[command(subcommand)]
Alert(AlertCommands),
#[command(subcommand)]
Incident(IncidentCommands),
#[command(subcommand)]
Schedule(ScheduleCommands),
#[command(subcommand)]
Team(TeamCommands),
#[command(subcommand)]
Escalation(EscalationCommands),
#[command(subcommand)]
Service(ServiceCommands),
#[command(subcommand)]
Heartbeat(HeartbeatCommands),
}
#[derive(Subcommand, Debug, Clone)]
enum AlertCommands {
List {
#[arg(long)]
query: Option<String>,
#[arg(long, default_value_t = 25)]
limit: usize,
#[arg(long)]
status: Option<String>,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
message: String,
#[arg(long)]
alias: Option<String>,
#[arg(long)]
description: Option<String>,
#[arg(long)]
priority: Option<String>,
#[arg(long)]
source: Option<String>,
#[arg(long)]
tags: Vec<String>,
},
Close {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
Ack {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
Unack {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
Snooze {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
end_time: String,
#[arg(long)]
note: Option<String>,
},
Escalate {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
escalation_id: String,
#[arg(long)]
note: Option<String>,
},
Assign {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
owner_id: String,
#[arg(long)]
note: Option<String>,
},
AddNote {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: String,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
Recipients {
#[arg(value_name = "ID")]
identifier: String,
},
Logs {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long, default_value_t = 25)]
limit: usize,
},
Notes {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long, default_value_t = 25)]
limit: usize,
},
}
#[derive(Subcommand, Debug, Clone)]
enum IncidentCommands {
List {
#[arg(long)]
query: Option<String>,
#[arg(long, default_value_t = 25)]
limit: usize,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
message: String,
#[arg(long)]
description: Option<String>,
#[arg(long)]
priority: Option<String>,
#[arg(long)]
tags: Vec<String>,
#[arg(long)]
service_ids: Vec<String>,
},
Close {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
Resolve {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
Reopen {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: Option<String>,
},
AddResponder {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
responder_id: String,
#[arg(long, default_value = "user")]
responder_type: String,
#[arg(long)]
note: Option<String>,
},
AddNote {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
note: String,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
Timeline {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long, default_value_t = 25)]
limit: usize,
},
}
#[derive(Subcommand, Debug, Clone)]
enum ScheduleCommands {
List {
#[arg(long, default_value_t = 25)]
limit: usize,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
description: Option<String>,
#[arg(long)]
timezone: Option<String>,
#[arg(long)]
team_id: Option<String>,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
Enable {
#[arg(value_name = "ID")]
identifier: String,
},
Disable {
#[arg(value_name = "ID")]
identifier: String,
},
OnCall {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
date: Option<String>,
},
Timeline {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
interval: Option<i32>,
#[arg(long)]
interval_unit: Option<String>,
#[arg(long)]
date: Option<String>,
},
Export {
#[arg(value_name = "ID")]
identifier: String,
},
}
#[derive(Subcommand, Debug, Clone)]
enum TeamCommands {
List {
#[arg(long, default_value_t = 25)]
limit: usize,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
description: Option<String>,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
Members {
#[arg(value_name = "ID")]
identifier: String,
},
AddMember {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
user_id: String,
#[arg(long)]
role: Option<String>,
},
RemoveMember {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
user_id: String,
},
OnCall {
#[arg(value_name = "ID")]
identifier: String,
#[arg(long)]
date: Option<String>,
},
}
#[derive(Subcommand, Debug, Clone)]
enum EscalationCommands {
List {
#[arg(long, default_value_t = 25)]
limit: usize,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
description: Option<String>,
#[arg(long)]
team_id: Option<String>,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
}
#[derive(Subcommand, Debug, Clone)]
enum ServiceCommands {
List {
#[arg(long, default_value_t = 25)]
limit: usize,
},
Get {
#[arg(value_name = "ID")]
identifier: String,
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
team_id: String,
#[arg(long)]
description: Option<String>,
},
Delete {
#[arg(value_name = "ID")]
identifier: String,
},
}
#[derive(Subcommand, Debug, Clone)]
enum HeartbeatCommands {
List,
Get {
#[arg(value_name = "NAME")]
name: String,
},
Create {
#[arg(long)]
name: String,
#[arg(long)]
description: Option<String>,
#[arg(long, default_value_t = 10)]
interval: i32,
#[arg(long, default_value = "minutes")]
interval_unit: String,
#[arg(long)]
team_id: Option<String>,
},
Delete {
#[arg(value_name = "NAME")]
name: String,
},
Enable {
#[arg(value_name = "NAME")]
name: String,
},
Disable {
#[arg(value_name = "NAME")]
name: String,
},
Ping {
#[arg(value_name = "NAME")]
name: String,
},
}
pub async fn execute(
args: OpsgenieArgs,
client: ApiClient,
renderer: &OutputRenderer,
) -> Result<()> {
let ctx = OpsgenieContext { client, renderer };
match args.command {
OpsgenieCommands::Alert(cmd) => match cmd {
AlertCommands::List {
query,
limit,
status,
} => alerts::list_alerts(&ctx, query.as_deref(), limit, status.as_deref()).await,
AlertCommands::Get { identifier } => alerts::get_alert(&ctx, &identifier).await,
AlertCommands::Create {
message,
alias,
description,
priority,
source,
tags,
} => {
alerts::create_alert(&ctx, message, alias, description, priority, source, tags)
.await
}
AlertCommands::Close { identifier, note } => {
alerts::close_alert(&ctx, &identifier, note).await
}
AlertCommands::Ack { identifier, note } => {
alerts::acknowledge_alert(&ctx, &identifier, note).await
}
AlertCommands::Unack { identifier, note } => {
alerts::unacknowledge_alert(&ctx, &identifier, note).await
}
AlertCommands::Snooze {
identifier,
end_time,
note,
} => alerts::snooze_alert(&ctx, &identifier, &end_time, note).await,
AlertCommands::Escalate {
identifier,
escalation_id,
note,
} => alerts::escalate_alert(&ctx, &identifier, &escalation_id, note).await,
AlertCommands::Assign {
identifier,
owner_id,
note,
} => alerts::assign_alert(&ctx, &identifier, &owner_id, note).await,
AlertCommands::AddNote { identifier, note } => {
alerts::add_note(&ctx, &identifier, ¬e).await
}
AlertCommands::Delete { identifier } => alerts::delete_alert(&ctx, &identifier).await,
AlertCommands::Recipients { identifier } => {
alerts::list_recipients(&ctx, &identifier).await
}
AlertCommands::Logs { identifier, limit } => {
alerts::list_logs(&ctx, &identifier, limit).await
}
AlertCommands::Notes { identifier, limit } => {
alerts::list_notes(&ctx, &identifier, limit).await
}
},
OpsgenieCommands::Incident(cmd) => match cmd {
IncidentCommands::List { query, limit } => {
incidents::list_incidents(&ctx, query.as_deref(), limit).await
}
IncidentCommands::Get { identifier } => {
incidents::get_incident(&ctx, &identifier).await
}
IncidentCommands::Create {
message,
description,
priority,
tags,
service_ids,
} => {
incidents::create_incident(&ctx, message, description, priority, tags, service_ids)
.await
}
IncidentCommands::Close { identifier, note } => {
incidents::close_incident(&ctx, &identifier, note).await
}
IncidentCommands::Resolve { identifier, note } => {
incidents::resolve_incident(&ctx, &identifier, note).await
}
IncidentCommands::Reopen { identifier, note } => {
incidents::reopen_incident(&ctx, &identifier, note).await
}
IncidentCommands::AddResponder {
identifier,
responder_id,
responder_type,
note,
} => {
incidents::add_responder(&ctx, &identifier, &responder_id, &responder_type, note)
.await
}
IncidentCommands::AddNote { identifier, note } => {
incidents::add_note(&ctx, &identifier, ¬e).await
}
IncidentCommands::Delete { identifier } => {
incidents::delete_incident(&ctx, &identifier).await
}
IncidentCommands::Timeline { identifier, limit } => {
incidents::list_timeline(&ctx, &identifier, limit).await
}
},
OpsgenieCommands::Schedule(cmd) => match cmd {
ScheduleCommands::List { limit } => schedules::list_schedules(&ctx, limit).await,
ScheduleCommands::Get { identifier } => {
schedules::get_schedule(&ctx, &identifier).await
}
ScheduleCommands::Create {
name,
description,
timezone,
team_id,
} => schedules::create_schedule(&ctx, name, description, timezone, team_id).await,
ScheduleCommands::Delete { identifier } => {
schedules::delete_schedule(&ctx, &identifier).await
}
ScheduleCommands::Enable { identifier } => {
schedules::enable_schedule(&ctx, &identifier).await
}
ScheduleCommands::Disable { identifier } => {
schedules::disable_schedule(&ctx, &identifier).await
}
ScheduleCommands::OnCall { identifier, date } => {
schedules::get_on_call(&ctx, &identifier, date.as_deref()).await
}
ScheduleCommands::Timeline {
identifier,
interval,
interval_unit,
date,
} => {
schedules::get_timeline(
&ctx,
&identifier,
interval,
interval_unit.as_deref(),
date.as_deref(),
)
.await
}
ScheduleCommands::Export { identifier } => {
schedules::export_ical(&ctx, &identifier).await
}
},
OpsgenieCommands::Team(cmd) => match cmd {
TeamCommands::List { limit } => teams::list_teams(&ctx, limit).await,
TeamCommands::Get { identifier } => teams::get_team(&ctx, &identifier).await,
TeamCommands::Create { name, description } => {
teams::create_team(&ctx, name, description).await
}
TeamCommands::Delete { identifier } => teams::delete_team(&ctx, &identifier).await,
TeamCommands::Members { identifier } => teams::list_members(&ctx, &identifier).await,
TeamCommands::AddMember {
identifier,
user_id,
role,
} => teams::add_member(&ctx, &identifier, &user_id, role.as_deref()).await,
TeamCommands::RemoveMember {
identifier,
user_id,
} => teams::remove_member(&ctx, &identifier, &user_id).await,
TeamCommands::OnCall { identifier, date } => {
teams::get_on_call(&ctx, &identifier, date.as_deref()).await
}
},
OpsgenieCommands::Escalation(cmd) => match cmd {
EscalationCommands::List { limit } => escalations::list_escalations(&ctx, limit).await,
EscalationCommands::Get { identifier } => {
escalations::get_escalation(&ctx, &identifier).await
}
EscalationCommands::Create {
name,
description,
team_id,
} => escalations::create_escalation(&ctx, name, description, team_id).await,
EscalationCommands::Delete { identifier } => {
escalations::delete_escalation(&ctx, &identifier).await
}
},
OpsgenieCommands::Service(cmd) => match cmd {
ServiceCommands::List { limit } => services::list_services(&ctx, limit).await,
ServiceCommands::Get { identifier } => services::get_service(&ctx, &identifier).await,
ServiceCommands::Create {
name,
team_id,
description,
} => services::create_service(&ctx, name, team_id, description).await,
ServiceCommands::Delete { identifier } => {
services::delete_service(&ctx, &identifier).await
}
},
OpsgenieCommands::Heartbeat(cmd) => match cmd {
HeartbeatCommands::List => heartbeats::list_heartbeats(&ctx).await,
HeartbeatCommands::Get { name } => heartbeats::get_heartbeat(&ctx, &name).await,
HeartbeatCommands::Create {
name,
description,
interval,
interval_unit,
team_id,
} => {
heartbeats::create_heartbeat(
&ctx,
name,
description,
interval,
interval_unit,
team_id,
)
.await
}
HeartbeatCommands::Delete { name } => heartbeats::delete_heartbeat(&ctx, &name).await,
HeartbeatCommands::Enable { name } => heartbeats::enable_heartbeat(&ctx, &name).await,
HeartbeatCommands::Disable { name } => heartbeats::disable_heartbeat(&ctx, &name).await,
HeartbeatCommands::Ping { name } => heartbeats::ping_heartbeat(&ctx, &name).await,
},
}
}