Misc. clap improvements, , more accurate value names, ...
This commit is contained in:
@@ -24,34 +24,30 @@ pub use show_privs::*;
|
|||||||
pub use show_user::*;
|
pub use show_user::*;
|
||||||
pub use unlock_user::*;
|
pub use unlock_user::*;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Subcommand;
|
||||||
|
|
||||||
use crate::core::protocol::{ClientToServerMessageStream, Response};
|
use crate::core::protocol::{ClientToServerMessageStream, Response};
|
||||||
|
|
||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Subcommand, Debug, Clone)]
|
||||||
|
#[command(subcommand_required = true)]
|
||||||
pub enum ClientCommand {
|
pub enum ClientCommand {
|
||||||
/// Check whether you are authorized to manage the specified databases or users.
|
/// Check whether you are authorized to manage the specified databases or users.
|
||||||
#[command()]
|
|
||||||
CheckAuth(CheckAuthArgs),
|
CheckAuth(CheckAuthArgs),
|
||||||
|
|
||||||
/// Create one or more databases
|
/// Create one or more databases
|
||||||
#[command()]
|
|
||||||
CreateDb(CreateDbArgs),
|
CreateDb(CreateDbArgs),
|
||||||
|
|
||||||
/// Delete one or more databases
|
/// Delete one or more databases
|
||||||
#[command()]
|
|
||||||
DropDb(DropDbArgs),
|
DropDb(DropDbArgs),
|
||||||
|
|
||||||
/// Print information about one or more databases
|
/// Print information about one or more databases
|
||||||
///
|
///
|
||||||
/// If no database name is provided, all databases you have access will be shown.
|
/// If no database name is provided, all databases you have access will be shown.
|
||||||
#[command()]
|
|
||||||
ShowDb(ShowDbArgs),
|
ShowDb(ShowDbArgs),
|
||||||
|
|
||||||
/// Print user privileges for one or more databases
|
/// Print user privileges for one or more databases
|
||||||
///
|
///
|
||||||
/// If no database names are provided, all databases you have access to will be shown.
|
/// If no database names are provided, all databases you have access to will be shown.
|
||||||
#[command()]
|
|
||||||
ShowPrivs(ShowPrivsArgs),
|
ShowPrivs(ShowPrivsArgs),
|
||||||
|
|
||||||
/// Change user privileges for one or more databases. See `edit-privs --help` for details.
|
/// Change user privileges for one or more databases. See `edit-privs --help` for details.
|
||||||
@@ -116,29 +112,23 @@ pub enum ClientCommand {
|
|||||||
EditPrivs(EditPrivsArgs),
|
EditPrivs(EditPrivsArgs),
|
||||||
|
|
||||||
/// Create one or more users
|
/// Create one or more users
|
||||||
#[command()]
|
|
||||||
CreateUser(CreateUserArgs),
|
CreateUser(CreateUserArgs),
|
||||||
|
|
||||||
/// Delete one or more users
|
/// Delete one or more users
|
||||||
#[command()]
|
|
||||||
DropUser(DropUserArgs),
|
DropUser(DropUserArgs),
|
||||||
|
|
||||||
/// Change the MySQL password for a user
|
/// Change the MySQL password for a user
|
||||||
#[command()]
|
|
||||||
PasswdUser(PasswdUserArgs),
|
PasswdUser(PasswdUserArgs),
|
||||||
|
|
||||||
/// Print information about one or more users
|
/// Print information about one or more users
|
||||||
///
|
///
|
||||||
/// If no username is provided, all users you have access will be shown.
|
/// If no username is provided, all users you have access will be shown.
|
||||||
#[command()]
|
|
||||||
ShowUser(ShowUserArgs),
|
ShowUser(ShowUserArgs),
|
||||||
|
|
||||||
/// Lock account for one or more users
|
/// Lock account for one or more users
|
||||||
#[command()]
|
|
||||||
LockUser(LockUserArgs),
|
LockUser(LockUserArgs),
|
||||||
|
|
||||||
/// Unlock account for one or more users
|
/// Unlock account for one or more users
|
||||||
#[command()]
|
|
||||||
UnlockUser(UnlockUserArgs),
|
UnlockUser(UnlockUserArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use tokio_stream::StreamExt;
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct CheckAuthArgs {
|
pub struct CheckAuthArgs {
|
||||||
/// The MySQL database(s) or user(s) to check authorization for
|
/// The MySQL database(s) or user(s) to check authorization for
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "NAME")]
|
||||||
name: Vec<String>,
|
name: Vec<String>,
|
||||||
|
|
||||||
/// Treat the provided names as users instead of databases
|
/// Treat the provided names as users instead of databases
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct CreateDbArgs {
|
pub struct CreateDbArgs {
|
||||||
/// The MySQL database(s) to create
|
/// The MySQL database(s) to create
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "DB_NAME")]
|
||||||
name: Vec<MySQLDatabase>,
|
name: Vec<MySQLDatabase>,
|
||||||
|
|
||||||
/// Print the information as JSON
|
/// Print the information as JSON
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct CreateUserArgs {
|
pub struct CreateUserArgs {
|
||||||
/// The MySQL user(s) to create
|
/// The MySQL user(s) to create
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "USER_NAME")]
|
||||||
username: Vec<MySQLUser>,
|
username: Vec<MySQLUser>,
|
||||||
|
|
||||||
/// Do not ask for a password, leave it unset
|
/// Do not ask for a password, leave it unset
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct DropDbArgs {
|
pub struct DropDbArgs {
|
||||||
/// The MySQL database(s) to drop
|
/// The MySQL database(s) to drop
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "DB_NAME")]
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
||||||
name: Vec<MySQLDatabase>,
|
name: Vec<MySQLDatabase>,
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct DropUserArgs {
|
pub struct DropUserArgs {
|
||||||
/// The MySQL user(s) to drop
|
/// The MySQL user(s) to drop
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "USER_NAME")]
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
||||||
username: Vec<MySQLUser>,
|
username: Vec<MySQLUser>,
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ use crate::{
|
|||||||
pub struct EditPrivsArgs {
|
pub struct EditPrivsArgs {
|
||||||
/// The MySQL database to edit privileges for
|
/// The MySQL database to edit privileges for
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
||||||
|
#[arg(value_name = "DB_NAME")]
|
||||||
pub name: Option<MySQLDatabase>,
|
pub name: Option<MySQLDatabase>,
|
||||||
|
|
||||||
#[arg(
|
#[arg(
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct LockUserArgs {
|
pub struct LockUserArgs {
|
||||||
/// The MySQL user(s) to loc
|
/// The MySQL user(s) to loc
|
||||||
#[arg(num_args = 1..)]
|
#[arg(num_args = 1.., value_name = "USER_NAME")]
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
||||||
username: Vec<MySQLUser>,
|
username: Vec<MySQLUser>,
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use crate::{
|
|||||||
pub struct PasswdUserArgs {
|
pub struct PasswdUserArgs {
|
||||||
/// The MySQL user whose password is to be changed
|
/// The MySQL user whose password is to be changed
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
||||||
|
#[arg(value_name = "USER_NAME")]
|
||||||
username: MySQLUser,
|
username: MySQLUser,
|
||||||
|
|
||||||
/// Read the new password from a file instead of prompting for it
|
/// Read the new password from a file instead of prompting for it
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct ShowDbArgs {
|
pub struct ShowDbArgs {
|
||||||
/// The MySQL database(s) to show
|
/// The MySQL database(s) to show
|
||||||
#[arg(num_args = 0..)]
|
#[arg(num_args = 0.., value_name = "DB_NAME")]
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
||||||
name: Vec<MySQLDatabase>,
|
name: Vec<MySQLDatabase>,
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct ShowPrivsArgs {
|
pub struct ShowPrivsArgs {
|
||||||
/// The MySQL database(s) to show privileges for
|
/// The MySQL database(s) to show privileges for
|
||||||
#[arg(num_args = 0..)]
|
#[arg(num_args = 0.., value_name = "DB_NAME")]
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_database_completer)))]
|
||||||
name: Vec<MySQLDatabase>,
|
name: Vec<MySQLDatabase>,
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct ShowUserArgs {
|
pub struct ShowUserArgs {
|
||||||
/// The MySQL user(s) to show
|
/// The MySQL user(s) to show
|
||||||
#[arg(num_args = 0..)]
|
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
||||||
|
#[arg(num_args = 0.., value_name = "USER_NAME")]
|
||||||
username: Vec<MySQLUser>,
|
username: Vec<MySQLUser>,
|
||||||
|
|
||||||
/// Print the information as JSON
|
/// Print the information as JSON
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ use crate::{
|
|||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
pub struct UnlockUserArgs {
|
pub struct UnlockUserArgs {
|
||||||
/// The MySQL user(s) to unlock
|
/// The MySQL user(s) to unlock
|
||||||
#[arg(num_args = 1..)]
|
|
||||||
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
#[cfg_attr(not(feature = "suid-sgid-mode"), arg(add = ArgValueCompleter::new(mysql_user_completer)))]
|
||||||
|
#[arg(num_args = 1.., value_name = "USER_NAME")]
|
||||||
username: Vec<MySQLUser>,
|
username: Vec<MySQLUser>,
|
||||||
|
|
||||||
/// Print the information as JSON
|
/// Print the information as JSON
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use clap::Parser;
|
use clap::{Parser, Subcommand};
|
||||||
use clap_complete::ArgValueCompleter;
|
use clap_complete::ArgValueCompleter;
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
use std::os::unix::net::UnixStream as StdUnixStream;
|
use std::os::unix::net::UnixStream as StdUnixStream;
|
||||||
@@ -98,7 +98,7 @@ pub struct Args {
|
|||||||
// NOTE: mysql-dbadm explicitly calls privileges "permissions".
|
// NOTE: mysql-dbadm explicitly calls privileges "permissions".
|
||||||
// This is something we're trying to move away from.
|
// This is something we're trying to move away from.
|
||||||
// See https://git.pvv.ntnu.no/Projects/muscl/issues/29
|
// See https://git.pvv.ntnu.no/Projects/muscl/issues/29
|
||||||
#[derive(Parser)]
|
#[derive(Subcommand)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// create the DATABASE(s).
|
/// create the DATABASE(s).
|
||||||
Create(CreateArgs),
|
Create(CreateArgs),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use clap::Parser;
|
use clap::{Parser, Subcommand};
|
||||||
use clap_complete::ArgValueCompleter;
|
use clap_complete::ArgValueCompleter;
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -67,7 +67,7 @@ pub struct Args {
|
|||||||
config: Option<PathBuf>,
|
config: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Subcommand)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// create the USER(s).
|
/// create the USER(s).
|
||||||
Create(CreateArgs),
|
Create(CreateArgs),
|
||||||
|
|||||||
@@ -75,9 +75,12 @@ const LONG_VERSION: &str = long_version();
|
|||||||
version,
|
version,
|
||||||
about,
|
about,
|
||||||
disable_help_subcommand = true,
|
disable_help_subcommand = true,
|
||||||
|
propagate_version = true,
|
||||||
before_long_help = ASCII_BANNER,
|
before_long_help = ASCII_BANNER,
|
||||||
after_long_help = KIND_REGARDS,
|
after_long_help = KIND_REGARDS,
|
||||||
long_version = LONG_VERSION,
|
long_version = LONG_VERSION,
|
||||||
|
// NOTE: All non-registered "subcommands" are processed before Arg::parse() is called.
|
||||||
|
subcommand_required = true,
|
||||||
)]
|
)]
|
||||||
struct Args {
|
struct Args {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
@@ -169,8 +172,8 @@ fn handle_dynamic_completion() -> anyhow::Result<Option<()>> {
|
|||||||
|
|
||||||
let command = match argv0.as_str() {
|
let command = match argv0.as_str() {
|
||||||
"muscl" => Args::command(),
|
"muscl" => Args::command(),
|
||||||
"mysql-dbadm" => mysql_dbadm::Command::command(),
|
"mysql-dbadm" => mysql_dbadm::Args::command(),
|
||||||
"mysql-useradm" => mysql_useradm::Command::command(),
|
"mysql-useradm" => mysql_useradm::Args::command(),
|
||||||
command => anyhow::bail!("Unknown executable name: `{}`", command),
|
command => anyhow::bail!("Unknown executable name: `{}`", command),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::{Parser, Subcommand};
|
||||||
use clap_verbosity_flag::{InfoLevel, Verbosity};
|
use clap_verbosity_flag::{InfoLevel, Verbosity};
|
||||||
use tracing_subscriber::prelude::*;
|
use tracing_subscriber::prelude::*;
|
||||||
|
|
||||||
@@ -26,15 +26,13 @@ pub struct ServerArgs {
|
|||||||
pub disable_landlock: bool,
|
pub disable_landlock: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Subcommand, Debug, Clone)]
|
||||||
pub enum ServerCommand {
|
pub enum ServerCommand {
|
||||||
/// Start the server and listen for incoming connections on the unix socket
|
/// Start the server and listen for incoming connections on the unix socket
|
||||||
/// specified in the configuration file.
|
/// specified in the configuration file.
|
||||||
#[command()]
|
|
||||||
Listen,
|
Listen,
|
||||||
|
|
||||||
/// Start the server using systemd socket activation.
|
/// Start the server using systemd socket activation.
|
||||||
#[command()]
|
|
||||||
SocketActivate,
|
SocketActivate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user