cellstate/entity/
deployment.rs

1//! `cellstate deployment` — Manage deployments.
2//!
3//! Subcommands: create, list, get, activate, rollout, rollback.
4
5use anyhow::Result;
6use clap::{Arg, ArgMatches, Command};
7
8use super::client::ApiClient;
9use super::output::OutputConfig;
10
11const BASE: &str = "/api/v1/deployments";
12
13pub fn build_command() -> Command {
14    Command::new("deployment")
15        .about("Manage deployments")
16        .subcommand_required(true)
17        .subcommand(
18            Command::new("create")
19                .about("Create a new deployment")
20                .arg(Arg::new("name").required(true).help("Deployment name"))
21                .arg(
22                    Arg::new("version")
23                        .long("version")
24                        .help("Deployment version"),
25                )
26                .arg(
27                    Arg::new("description")
28                        .long("description")
29                        .short('d')
30                        .help("Description"),
31                ),
32        )
33        .subcommand(
34            Command::new("list")
35                .about("List deployments")
36                .arg(
37                    Arg::new("limit")
38                        .long("limit")
39                        .default_value("20")
40                        .help("Max results"),
41                )
42                .arg(
43                    Arg::new("offset")
44                        .long("offset")
45                        .default_value("0")
46                        .help("Offset"),
47                ),
48        )
49        .subcommand(
50            Command::new("get")
51                .about("Get deployment details")
52                .arg(Arg::new("id").required(true).help("Deployment ID")),
53        )
54        .subcommand(
55            Command::new("activate")
56                .about("Activate a deployment")
57                .arg(Arg::new("id").required(true).help("Deployment ID")),
58        )
59        .subcommand(
60            Command::new("rollout")
61                .about("Roll out a deployment")
62                .arg(Arg::new("id").required(true).help("Deployment ID")),
63        )
64        .subcommand(Command::new("rollback").about("Roll back to the previous deployment"))
65}
66
67pub async fn dispatch(
68    matches: &ArgMatches,
69    client: &ApiClient,
70    output: &OutputConfig,
71    _session: &crate::session::CliSession,
72) -> Result<()> {
73    match matches.subcommand() {
74        Some(("create", sub)) => {
75            let name = sub.get_one::<String>("name").unwrap().clone();
76            let body = serde_json::json!({
77                "name": name,
78                "version": sub.get_one::<String>("version"),
79                "description": sub.get_one::<String>("description"),
80            });
81            let resp: serde_json::Value = client.post_raw(BASE, &body).await?;
82            output.print_value(&resp);
83        }
84        Some(("list", sub)) => {
85            let limit: i64 = sub.get_one::<String>("limit").unwrap().parse()?;
86            let offset: i64 = sub.get_one::<String>("offset").unwrap().parse()?;
87            let path = format!("{BASE}?limit={limit}&offset={offset}");
88            let resp: serde_json::Value = client.get_raw(&path).await?;
89            output.print_value(&resp);
90        }
91        Some(("get", sub)) => {
92            let id = sub.get_one::<String>("id").unwrap();
93            let resp: serde_json::Value = client.get_raw(&format!("{BASE}/{id}")).await?;
94            output.print_value(&resp);
95        }
96        Some(("activate", sub)) => {
97            let id = sub.get_one::<String>("id").unwrap();
98            let resp: serde_json::Value = client
99                .post_no_body_raw(&format!("{BASE}/{id}/activate"))
100                .await?;
101            output.print_value(&resp);
102        }
103        Some(("rollout", sub)) => {
104            let id = sub.get_one::<String>("id").unwrap();
105            let resp: serde_json::Value = client
106                .post_no_body_raw(&format!("{BASE}/{id}/rollout"))
107                .await?;
108            output.print_value(&resp);
109        }
110        Some(("rollback", _sub)) => {
111            let resp: serde_json::Value =
112                client.post_no_body_raw(&format!("{BASE}/rollback")).await?;
113            output.print_value(&resp);
114        }
115        _ => unreachable!("subcommand_required(true) prevents this"),
116    }
117    Ok(())
118}