surrealpatch/src/cli/mod.rs

401 lines
8.6 KiB
Rust
Raw Normal View History

2020-06-29 15:36:01 +00:00
mod backup;
mod export;
mod import;
mod log;
mod start;
mod version;
use clap::{Arg, Command};
2020-06-29 15:36:01 +00:00
2022-01-23 12:30:59 +00:00
fn auth_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
if v.contains(":") {
return Ok(());
}
Err(String::from(
"\
Provide a valid user:pass value separated by a colon, \
or use the --auth-user and --auth-pass flags\
",
))
}
2022-01-23 12:30:59 +00:00
fn file_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
if v.len() > 0 {
return Ok(());
}
Err(String::from(
"\
Provide a valid path to a SQL file\
",
))
}
2022-01-23 12:30:59 +00:00
fn path_valid(v: &str) -> Result<(), String> {
if v == "memory" {
return Ok(());
}
if v.starts_with("file://") {
return Ok(());
}
if v.starts_with("tikv://") {
return Ok(());
}
Err(String::from(
"\
Provide a valid database path paramater\
",
))
}
2022-01-23 12:30:59 +00:00
fn conn_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
if v.starts_with("https://") {
return Ok(());
}
if v.starts_with("http://") {
return Ok(());
}
Err(String::from(
"\
Provide a valid database connection string\
",
))
}
2022-01-23 12:30:59 +00:00
fn from_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
if v.starts_with("https://") {
return Ok(());
}
if v.starts_with("http://") {
return Ok(());
}
if v.ends_with(".db") {
return Ok(());
}
Err(String::from(
"\
Provide a valid database connection string, \
or specify the path to a database file\
",
))
}
2022-01-23 12:30:59 +00:00
fn into_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
if v.starts_with("https://") {
return Ok(());
}
if v.starts_with("http://") {
return Ok(());
}
if v.ends_with(".db") {
return Ok(());
}
Err(String::from(
"\
Provide a valid database connection string, \
or specify the path to a database file\
",
))
}
2022-01-23 12:30:59 +00:00
fn key_valid(v: &str) -> Result<(), String> {
2020-06-29 15:36:01 +00:00
match v.len() {
16 => Ok(()),
24 => Ok(()),
32 => Ok(()),
_ => Err(String::from(
"\
For AES-128 encryption use a 16 bit key, \
for AES-192 encryption use a 24 bit key, \
and for AES-256 encryption use a 32 bit key\
",
)),
}
}
pub fn init() {
let setup = Command::new("SurrealDB command-line interface and server")
.disable_version_flag(true)
.arg_required_else_help(true)
2020-06-29 15:36:01 +00:00
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("verbose")
.short('v')
2020-06-29 15:36:01 +00:00
.long("verbose")
2022-01-23 12:30:59 +00:00
.takes_value(false)
.multiple_occurrences(true)
2020-06-29 15:36:01 +00:00
.help("Specify the log output verbosity"),
);
let setup = setup.subcommand(
Command::new("start")
2020-06-29 15:36:01 +00:00
.display_order(1)
.about("Start the database server")
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("path")
2020-06-29 15:36:01 +00:00
.index(1)
2022-01-23 12:30:59 +00:00
.required(false)
.validator(path_valid)
2020-06-29 15:36:01 +00:00
.default_value("memory")
.help("Database path used for storing data"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("auth")
.short('a')
2020-06-29 15:36:01 +00:00
.long("auth")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.validator(auth_valid)
.default_value("root:root")
.help("Master database authentication details"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("auth-user")
.short('u')
2020-06-29 15:36:01 +00:00
.long("auth-user")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("The master username for the database"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("auth-pass")
.short('p')
2020-06-29 15:36:01 +00:00
.long("auth-pass")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("The master password for the database"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("auth-addr")
2020-06-29 15:36:01 +00:00
.long("auth-addr")
.number_of_values(1)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
.multiple_occurrences(true)
2020-06-29 15:36:01 +00:00
.default_value("127.0.0.1/32")
.help("The allowed networks for master authentication"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("bind")
.short('b')
2020-06-29 15:36:01 +00:00
.long("bind")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("0.0.0.0:3000")
.help("The hostname or ip address to listen for connections on"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("key")
.short('k')
2020-06-29 15:36:01 +00:00
.long("key")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.validator(key_valid)
.help("Encryption key to use for on-disk encryption"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("kvs-ca")
2020-06-29 15:36:01 +00:00
.long("kvs-ca")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("Path to the CA file used when connecting to the remote KV store"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("kvs-crt")
2020-06-29 15:36:01 +00:00
.long("kvs-crt")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help(
"Path to the certificate file used when connecting to the remote KV store",
),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("kvs-key")
2020-06-29 15:36:01 +00:00
.long("kvs-key")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help(
"Path to the private key file used when connecting to the remote KV store",
),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("web-crt")
2020-06-29 15:36:01 +00:00
.long("web-crt")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("Path to the certificate file for encrypted client connections"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("web-key")
2020-06-29 15:36:01 +00:00
.long("web-key")
.takes_value(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("Path to the private key file for encrypted client connections"),
),
);
let setup = setup.subcommand(
Command::new("backup")
2020-06-29 15:36:01 +00:00
.display_order(2)
.about("Backup data to or from an existing database")
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("from")
2020-06-29 15:36:01 +00:00
.index(1)
.required(true)
.validator(from_valid)
.help("Path to the remote database or file from which to export"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("into")
2020-06-29 15:36:01 +00:00
.index(2)
.required(true)
.validator(into_valid)
.help("Path to the remote database or file into which to import"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("user")
.short('u')
2020-06-29 15:36:01 +00:00
.long("user")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication username to use when connecting"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("pass")
.short('p')
2020-06-29 15:36:01 +00:00
.long("pass")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication password to use when connecting"),
),
);
let setup = setup.subcommand(
Command::new("import")
2020-06-29 15:36:01 +00:00
.display_order(3)
.about("Import a SQL script into an existing database")
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("file")
2020-06-29 15:36:01 +00:00
.index(1)
.required(true)
.validator(file_valid)
.help("Path to the sql file to import"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("ns")
2020-06-29 15:36:01 +00:00
.long("ns")
.required(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("The namespace to import the data into"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("db")
2020-06-29 15:36:01 +00:00
.long("db")
.required(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("The database to import the data into"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("conn")
.short('c')
2020-06-29 15:36:01 +00:00
.long("conn")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.validator(conn_valid)
.default_value("https://surreal.io")
.help("Remote database server url to connect to"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("user")
.short('u')
2020-06-29 15:36:01 +00:00
.long("user")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication username to use when connecting"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("pass")
.short('p')
2020-06-29 15:36:01 +00:00
.long("pass")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication password to use when connecting"),
),
);
let setup = setup.subcommand(
Command::new("export")
2020-06-29 15:36:01 +00:00
.display_order(4)
.about("Export an existing database into a SQL script")
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("file")
2020-06-29 15:36:01 +00:00
.index(1)
.required(true)
.validator(file_valid)
.help("Path to the sql file to export"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("ns")
2020-06-29 15:36:01 +00:00
.long("ns")
.required(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("The namespace to export the data from"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("db")
2020-06-29 15:36:01 +00:00
.long("db")
.required(true)
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.help("The database to export the data from"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("conn")
.short('c')
2020-06-29 15:36:01 +00:00
.long("conn")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.validator(conn_valid)
.default_value("https://surreal.io")
.help("Remote database server url to connect to"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("user")
.short('u')
2020-06-29 15:36:01 +00:00
.long("user")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication username to use when connecting"),
)
.arg(
2022-01-23 12:30:59 +00:00
Arg::new("pass")
.short('p')
2020-06-29 15:36:01 +00:00
.long("pass")
2022-01-23 12:30:59 +00:00
.forbid_empty_values(true)
2020-06-29 15:36:01 +00:00
.default_value("root")
.help("Database authentication password to use when connecting"),
),
);
let setup = setup.subcommand(
Command::new("version")
2020-06-29 15:36:01 +00:00
.display_order(5)
.about("Output the command-line tool version information"),
);
let matches = setup.get_matches();
let verbose = matches.occurrences_of("verbose") as usize;
log::init(verbose);
let output = match matches.subcommand() {
2022-01-23 12:30:59 +00:00
Some(("start", m)) => start::init(m),
Some(("backup", m)) => backup::init(m),
Some(("import", m)) => import::init(m),
Some(("export", m)) => export::init(m),
Some(("version", m)) => version::init(m),
2020-06-29 15:36:01 +00:00
_ => Ok(()),
};
match output {
Err(e) => {
error!("{}", e);
return ();
}
Ok(_) => {}
};
}