palladium_cli/commands/
cluster.rs1use clap::{Args, Subcommand};
2use schemars::JsonSchema;
3use serde::Serialize;
4
5use crate::client::{ControlPlaneClient, Endpoint};
6use crate::output;
7use crate::CliResult;
8
9#[derive(Subcommand, Debug, Serialize, JsonSchema)]
10#[serde(rename_all = "kebab-case")]
11pub enum ClusterCommand {
12 Status(ClusterStatusArgs),
14 Members(ClusterMembersArgs),
16 Join(ClusterJoinArgs),
18 Leave(ClusterLeaveArgs),
20 GossipStatus(ClusterGossipStatusArgs),
22 SetMeta(ClusterSetMetaArgs),
24}
25
26#[derive(Args, Debug, Serialize, JsonSchema)]
27#[serde(rename_all = "kebab-case")]
28pub struct ClusterStatusArgs {
29 #[arg(long)]
31 pub json: bool,
32}
33
34#[derive(Args, Debug, Serialize, JsonSchema)]
35#[serde(rename_all = "kebab-case")]
36pub struct ClusterMembersArgs {
37 #[arg(long)]
39 pub json: bool,
40}
41
42#[derive(Args, Debug, Serialize, JsonSchema)]
43#[serde(rename_all = "kebab-case")]
44pub struct ClusterJoinArgs {
45 #[arg(long)]
47 pub seed: Vec<String>,
48}
49
50#[derive(Args, Debug, Serialize, JsonSchema)]
51#[serde(rename_all = "kebab-case")]
52pub struct ClusterLeaveArgs {
53 #[arg(long)]
55 pub json: bool,
56}
57
58#[derive(Args, Debug, Serialize, JsonSchema)]
59#[serde(rename_all = "kebab-case")]
60pub struct ClusterGossipStatusArgs {
61 #[arg(long)]
63 pub json: bool,
64}
65
66#[derive(Args, Debug, Serialize, JsonSchema)]
67#[serde(rename_all = "kebab-case")]
68pub struct ClusterSetMetaArgs {
69 #[arg(long)]
71 pub key: String,
72 #[arg(long)]
74 pub value: String,
75 #[arg(long)]
77 pub json: bool,
78}
79
80pub fn run(cmd: ClusterCommand, endpoint: &Endpoint) -> CliResult {
81 match cmd {
82 ClusterCommand::Status(args) => run_status(&args, endpoint),
83 ClusterCommand::Members(args) => run_members(&args, endpoint),
84 ClusterCommand::Join(args) => run_join(&args, endpoint),
85 ClusterCommand::Leave(args) => run_leave(&args, endpoint),
86 ClusterCommand::GossipStatus(args) => run_gossip_status(&args, endpoint),
87 ClusterCommand::SetMeta(args) => run_set_meta(&args, endpoint),
88 }
89}
90
91fn run_status(args: &ClusterStatusArgs, endpoint: &Endpoint) -> CliResult {
92 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
93 let result = client.call("cluster.status", serde_json::Value::Null)?;
94 if args.json {
95 println!("{}", serde_json::to_string_pretty(&result)?);
96 } else {
97 print!("{}", output::format_cluster_status(&result));
98 }
99 Ok(())
100}
101
102fn run_members(args: &ClusterMembersArgs, endpoint: &Endpoint) -> CliResult {
103 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
104 let result = client.call("cluster.members", serde_json::Value::Null)?;
105 if args.json {
106 println!("{}", serde_json::to_string_pretty(&result)?);
107 } else {
108 let members = result.as_array().cloned().unwrap_or_default();
109 print!("{}", output::format_cluster_members(&members));
110 }
111 Ok(())
112}
113
114fn run_join(args: &ClusterJoinArgs, endpoint: &Endpoint) -> CliResult {
115 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
116 let params = serde_json::json!({
117 "seed_nodes": args.seed,
118 });
119 let result = client.call("cluster.join", params)?;
120 println!("{}", serde_json::to_string_pretty(&result)?);
121 Ok(())
122}
123
124fn run_leave(args: &ClusterLeaveArgs, endpoint: &Endpoint) -> CliResult {
125 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
126 let result = client.call("cluster.leave", serde_json::Value::Null)?;
127 if args.json {
128 println!("{}", serde_json::to_string_pretty(&result)?);
129 } else {
130 println!("Left cluster.");
131 }
132 Ok(())
133}
134
135fn run_gossip_status(_args: &ClusterGossipStatusArgs, endpoint: &Endpoint) -> CliResult {
136 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
137 let result = client.call("cluster.gossip.status", serde_json::Value::Null)?;
138 println!("{}", serde_json::to_string_pretty(&result)?);
139 Ok(())
140}
141
142fn run_set_meta(args: &ClusterSetMetaArgs, endpoint: &Endpoint) -> CliResult {
143 let mut client = ControlPlaneClient::connect_endpoint(endpoint)?;
144 let result = client.call(
145 "cluster.member.set-meta",
146 serde_json::json!({"key": args.key, "value": args.value}),
147 )?;
148 if args.json {
149 println!("{}", serde_json::to_string_pretty(&result)?);
150 } else {
151 println!("Member metadata updated.");
152 }
153 Ok(())
154}