Skip to content

Commit

Permalink
Merge branch 'mk-rabbitmqadmin.conf-support'
Browse files Browse the repository at this point in the history
Initial support for TOML configuration files
and a two-layered approach to configuration.

As part of this significant refactoring the test suite
was split into multiple files with a common module
for helpers.

Closes #28.
  • Loading branch information
michaelklishin committed Nov 29, 2024
2 parents 6222a23 + 0a981b8 commit 55c25e5
Show file tree
Hide file tree
Showing 23 changed files with 1,432 additions and 831 deletions.
55 changes: 55 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ rabbitmq_http_client = { git = "https://github.com/michaelklishin/rabbitmq-http-
serde = { version = "1.0", features = ["derive", "std"] }
serde_json = "1"
tabled = "0.17"
toml = "0.8"
color-print = "0.3"
thiserror = "2"
log = "0.4.22"

[dev-dependencies]
assert_cmd = "2.0"
Expand Down
127 changes: 27 additions & 100 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,91 +14,8 @@
use std::path::PathBuf;

use super::constants::*;
use clap::{Arg, ArgAction, ArgMatches, Command};
use clap::{Arg, ArgAction, Command};
use rabbitmq_http_client::commons::{BindingDestinationType, QueueType};
use url::Url;

#[derive(Debug, Clone)]
pub struct SharedFlags {
pub scheme: String,
pub hostname: String,
pub port: u16,
pub path_prefix: Option<String>,

pub username: String,
pub password: String,

pub virtual_host: String,
}

impl SharedFlags {
pub fn from_args(general_args: &ArgMatches) -> SharedFlags {
if let Some(base_uri) = general_args.get_one::<String>("base_uri") {
let url = Url::parse(base_uri).unwrap();
SharedFlags::new_from_uri(&url, general_args)
} else {
SharedFlags::new(general_args)
}
}

pub fn new(cli_args: &ArgMatches) -> Self {
let default_hostname = DEFAULT_HOST.to_owned();
let hostname = cli_args
.get_one::<String>("host")
.unwrap_or(&default_hostname);
let port = cli_args.get_one::<u16>("port").unwrap();
let path_prefix = cli_args.get_one::<String>("path_prefix").cloned();
let username = cli_args.get_one::<String>("username").unwrap();
let password = cli_args.get_one::<String>("password").unwrap();
let default_vhost = DEFAULT_VHOST.to_owned();
let vhost = cli_args
.get_one::<String>("vhost")
.unwrap_or(&default_vhost);

Self {
scheme: "http".to_string(),
hostname: hostname.clone(),
port: (*port),
path_prefix,
username: username.clone(),
password: password.clone(),
virtual_host: vhost.clone(),
}
}

pub fn new_from_uri(url: &Url, cli_args: &ArgMatches) -> Self {
let scheme = url.scheme().to_string();
let hostname = url.host_str().unwrap_or(DEFAULT_HOST).to_string();
let port = url.port().unwrap_or(DEFAULT_HTTP_PORT);
let path_prefix = cli_args.get_one::<String>("path_prefix").cloned();
let username = cli_args.get_one::<String>("username").unwrap();
let password = cli_args.get_one::<String>("password").unwrap();
let default_vhost = DEFAULT_VHOST.to_owned();
let vhost = cli_args
.get_one::<String>("vhost")
.unwrap_or(&default_vhost);

Self {
scheme,
hostname,
port,
path_prefix,
username: username.clone(),
password: password.clone(),
virtual_host: vhost.clone(),
}
}

pub fn endpoint(&self) -> String {
match &self.path_prefix {
Some(prefix) => format!(
"{}://{}:{}{}/api",
self.scheme, self.hostname, self.port, prefix
),
None => format!("{}://{}:{}/api", self.scheme, self.hostname, self.port),
}
}
}

pub fn parser() -> Command {
let after_help: &'static str = color_print::cstr!(
Expand All @@ -116,11 +33,19 @@ pub fn parser() -> Command {
.long_about("RabbitMQ CLI that uses the HTTP API")
.after_help(after_help)
.disable_version_flag(true)
// --config-file
.arg(
Arg::new("config_file_path")
.short('c')
.long("config")
.value_parser(clap::value_parser!(PathBuf))
.default_value(DEFAULT_CONFIG_FILE_PATH),
)
// --node
// This is NOT the same as --node in case of rabbitmqctl, rabbitmq-diagnostics, etc.
// This is node section name in the configuration file. MK.
.arg(
Arg::new("node")
Arg::new("node_alias")
.short('N')
.long("node")
.required(false)
Expand All @@ -132,8 +57,6 @@ pub fn parser() -> Command {
.short('H')
.long("host")
.help("HTTP API hostname to use when connecting")
.required(false)
.default_value(DEFAULT_HOST),
)
.visible_alias("hostname")
// --port
Expand All @@ -159,34 +82,29 @@ pub fn parser() -> Command {
.arg(
Arg::new("path_prefix")
.long("path-prefix")
.required(false)
.default_value(DEFAULT_PATH_PREFIX),
.help("use if target node uses a path prefix. Defaults to '/api'")
)
// --vhost
.arg(
Arg::new("vhost")
.short('V')
.long("vhost")
.help("target virtual host")
.required(false)
.default_value(DEFAULT_VHOST),
.help("target virtual host. Defaults to '/'")
)
// --username
.arg(
Arg::new("username")
.short('u')
.long("username")
.required(false)
.default_value(DEFAULT_USERNAME),
.help("this user must have the permissions for HTTP API access, see https://www.rabbitmq.com/docs/management#permissions")
)
// --password
.arg(
Arg::new("password")
.short('p')
.long("password")
.required(false)
.default_value(DEFAULT_PASSWORD)
.requires("username"),
.requires("username")
.help("must be specified if --username is used")
)
// --insecure
.arg(
Expand All @@ -196,7 +114,14 @@ pub fn parser() -> Command {
.required(false)
.help("disables TLS peer (certificate chain) verification")
.value_parser(clap::value_parser!(bool))
.action(clap::ArgAction::SetTrue),
.action(ArgAction::SetTrue),
)
// --tls
.arg(
Arg::new("tls")
.long("use-tls")
.help("use TLS (HTTPS) for HTTP API requests ")
.value_parser(clap::value_parser!(bool))
)
// --tls-ca-cert-file
.arg(
Expand All @@ -214,7 +139,7 @@ pub fn parser() -> Command {
.help("produce less output")
.required(false)
.value_parser(clap::value_parser!(bool))
.action(clap::ArgAction::SetTrue),
.action(ArgAction::SetTrue),
)
.subcommand_required(true)
.subcommand_value_name("command")
Expand Down Expand Up @@ -703,11 +628,13 @@ fn declare_subcommands() -> [Command; 11] {
]
}

fn show_subcomands() -> [Command; 2] {
fn show_subcomands() -> [Command; 3] {
[
Command::new("overview")
.about("displays a essential information about target node and its cluster"),
Command::new("churn").about("displays object churn metrics"),
Command::new("endpoint")
.about("for troubleshooting: displays the computed HTTP API endpoint URI"),
]
}

Expand Down
Loading

0 comments on commit 55c25e5

Please sign in to comment.