From 08c0045e87ba69ff77667dad0dfbf6b69ecb6e4b Mon Sep 17 00:00:00 2001 From: Sebastian Webber Date: Thu, 13 Jul 2023 17:14:25 -0300 Subject: [PATCH] add "show help" command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Co-authored-by: Fabrízio de Royes Mello --- src/admin.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/messages.rs | 20 ++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/admin.rs b/src/admin.rs index 03b984ae..d17659e8 100644 --- a/src/admin.rs +++ b/src/admin.rs @@ -1,7 +1,7 @@ use crate::pool::BanReason; use crate::stats::pool::PoolStats; use bytes::{Buf, BufMut, BytesMut}; -use log::{error, info, trace}; +use log::{debug, error, info, trace}; use nix::sys::signal::{self, Signal}; use nix::unistd::Pid; use std::collections::HashMap; @@ -84,6 +84,10 @@ where shutdown(stream).await } "SHOW" => match query_parts[1].to_ascii_uppercase().as_str() { + "HELP" => { + trace!("SHOW HELP"); + show_help(stream).await + } "BANS" => { trace!("SHOW BANS"); show_bans(stream).await @@ -271,6 +275,45 @@ where write_all_half(stream, &res).await } +/// Show all available options. +async fn show_help(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 [, ]", + "RESUME [, ]", + // "DISABLE ", // missing + // "ENABLE ", // missing + // "RECONNECT []", missing + // "KILL ", + // "SUSPEND", + "SHUTDOWN", + // "WAIT_CLOSE []", // 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. async fn show_databases(stream: &mut T) -> Result<(), Error> where diff --git a/src/messages.rs b/src/messages.rs index eb0ea73c..8ebc00a3 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -530,6 +530,26 @@ pub fn command_complete(command: &str) -> BytesMut { 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 { let mut bytes = BytesMut::new(); bytes.put_u8(b'H');