add "show help" command (#505)

This commit adds a new function to handle notify and use it
in the SHOW HELP command, which displays the available options
in the admin console.

Also, adding Fabrízio as a co-author for all the help with the
protocol and the help to structure this PR.

Signed-off-by: Sebastian Webber <sebastian@swebber.me>
Co-authored-by: Fabrízio de Royes Mello <fabriziomello@gmail.com>
This commit is contained in:
Sebastian Webber
2023-07-14 02:40:04 -03:00
committed by GitHub
parent b2e6dfd9bb
commit 15b6db8e4e
2 changed files with 64 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
use crate::pool::BanReason; use crate::pool::BanReason;
use crate::stats::pool::PoolStats; use crate::stats::pool::PoolStats;
use bytes::{Buf, BufMut, BytesMut}; use bytes::{Buf, BufMut, BytesMut};
use log::{error, info, trace}; use log::{debug, error, info, trace};
use nix::sys::signal::{self, Signal}; use nix::sys::signal::{self, Signal};
use nix::unistd::Pid; use nix::unistd::Pid;
use std::collections::HashMap; use std::collections::HashMap;
@@ -84,6 +84,10 @@ where
shutdown(stream).await shutdown(stream).await
} }
"SHOW" => match query_parts[1].to_ascii_uppercase().as_str() { "SHOW" => match query_parts[1].to_ascii_uppercase().as_str() {
"HELP" => {
trace!("SHOW HELP");
show_help(stream).await
}
"BANS" => { "BANS" => {
trace!("SHOW BANS"); trace!("SHOW BANS");
show_bans(stream).await show_bans(stream).await
@@ -271,6 +275,45 @@ where
write_all_half(stream, &res).await write_all_half(stream, &res).await
} }
/// Show all available options.
async fn show_help<T>(stream: &mut T) -> Result<(), Error>
where
T: tokio::io::AsyncWrite + std::marker::Unpin,
{
let mut res = BytesMut::new();
let detail_msg = vec![
"",
"SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION",
// "SHOW PEERS|PEER_POOLS", // missing PEERS|PEER_POOLS
// "SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM|STATE", // missing FDS|SOCKETS|ACTIVE_SOCKETS|MEM|STATE
"SHOW LISTS",
// "SHOW DNS_HOSTS|DNS_ZONES", // missing DNS_HOSTS|DNS_ZONES
"SHOW STATS", // missing STATS_TOTALS|STATS_AVERAGES|TOTALS
"SET key = arg",
"RELOAD",
"PAUSE [<db>, <user>]",
"RESUME [<db>, <user>]",
// "DISABLE <db>", // missing
// "ENABLE <db>", // missing
// "RECONNECT [<db>]", missing
// "KILL <db>",
// "SUSPEND",
"SHUTDOWN",
// "WAIT_CLOSE [<db>]", // missing
];
res.put(notify("Console usage", detail_msg.join("\n\t")));
res.put(command_complete("SHOW"));
// ReadyForQuery
res.put_u8(b'Z');
res.put_i32(5);
res.put_u8(b'I');
write_all_half(stream, &res).await
}
/// Show shards and replicas. /// Show shards and replicas.
async fn show_databases<T>(stream: &mut T) -> Result<(), Error> async fn show_databases<T>(stream: &mut T) -> Result<(), Error>
where where

View File

@@ -530,6 +530,26 @@ pub fn command_complete(command: &str) -> BytesMut {
res res
} }
/// Create a notify message.
pub fn notify(message: &str, details: String) -> BytesMut {
let mut notify_cmd = BytesMut::new();
notify_cmd.put_slice("SNOTICE\0".as_bytes());
notify_cmd.put_slice("C00000\0".as_bytes());
notify_cmd.put_slice(format!("M{}\0", message).as_bytes());
notify_cmd.put_slice(format!("D{}\0", details).as_bytes());
// this extra byte says that is the end of the package
notify_cmd.put_u8(0);
let mut res = BytesMut::new();
res.put_u8(b'N');
res.put_i32(notify_cmd.len() as i32 + 4);
res.put(notify_cmd);
res
}
pub fn flush() -> BytesMut { pub fn flush() -> BytesMut {
let mut bytes = BytesMut::new(); let mut bytes = BytesMut::new();
bytes.put_u8(b'H'); bytes.put_u8(b'H');