Skip to content

Commit

Permalink
[agroal#253][agroal#209] Refactor commands in pgagroal-cli and `pga…
Browse files Browse the repository at this point in the history
…groal-admin`

Now `pgagroal-cli` has a set of "logically" grouped commands and
subcommands. For example, all the commands related to shutting down
the pooler are under the `shutdown` command, that can operate with
subcommands like `gracefully`, `immediate` or `cancel`.

In order to provide this capability, new functions have been
introduced as utilities:
- `parse_command()` accepts the command line and seek for a command,
possibly its subcommand, and an optional "value" (often the database
or server name).
- `parse_command_simple()` is a wrapper around the above
`parse_command` that shorten the function call line because it does
not require to specify the key and the value (and their defaults).
- `parse_deprecated_command()` does pretty much the same thing but
against the old command. Thanks to this, old commands can still work
and the user will be warned about their deprecation, but the interface
of `pgagroal-cli` is not broken.

All the above functions require to know the offset at which start seeking for
a command, and that depends on the number of options already parsed
via `getopt_long()`. Since the `&option_index` is valued only for long
options, I decided to use the `optind` global value, see
getopt_long(3).
This value is initialized with the "next thing" to seek on the command
line, i.e., the next index on `argv`.

In the case the command accepts an optional database name, the
database value is automatically set to '*' (all databases) in case the
database name is not found on the command line.
Therefore:
   pgagroal-cli flush idle
is equivalent to
   pgagroal-cli flush idle '*'

On the other hand, commands that require a server name get the value
automatically set to "\0" (an invalid server name) in order to "block"
other pieces of code. Moroever, if the server has not been specified,
the command is automatically set to "unknown" so that the help screen
is shown.

The `pgagroal-cli` has a set of `pgagroal_log_debug()` calls whenever
a command is "parsed", so that it is possible to quickly follow the
command line parsing.

Also, since the `pgagroal-cli` exists if no command line arguments
have been specified, the safety check aboutt `argc > 0` around the
command line parsing has been removed.

In the case the user specified an unknown command, she is warned on
stdout before printing the `usage()` help screen.

Deprecated commands are notified to the user via a warning message,
printed on stderr, that provides some hints about the correct usage of
the new command. The warning about deprecated commands is shown only
if the currently running version of the software is greater than the
version the command has been deprecated onto. In particular these
commands have been deprecated since 1.6.

This commit also introduces the command refactoring for `pgagroal-admin` in
a way similar to the work done for `pgagroal-cli`.
New commands are available:
- user <what>
with <what> being <add>, <del>, <edit>, <ls>.

Updated:
- documentation
- shell completions
- help screens
- examples

Close agroal#290 agroal#253
  • Loading branch information
fluca1978 authored and ashu3103 committed Mar 2, 2024
1 parent 5c2d23f commit fb9b909
Show file tree
Hide file tree
Showing 14 changed files with 875 additions and 457 deletions.
38 changes: 35 additions & 3 deletions contrib/shell_comp/pgagroal_comp.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,59 @@

# COMP_WORDS contains
# at index 0 the executable name (pgagroal-cli)
# at index 1 the command name (e.g., flush-all)
# at index 1 the command name (e.g., flush)
# at index 2, if required, the subcommand name (e.g., all)
pgagroal_cli_completions()
{

if [ "${#COMP_WORDS[@]}" == "2" ]; then
# main completion: the user has specified nothing at all
# or a single word, that is a command
COMPREPLY=($(compgen -W "flush-idle flush-gracefully flush-all is-alive enable disable stop gracefully status details switch-to reload reset reset-server config-get config-set" "${COMP_WORDS[1]}"))
COMPREPLY=($(compgen -W "flush is-alive enable disable shutdown status details switch-to conf clear" "${COMP_WORDS[1]}"))
else
# the user has specified something else
# subcommand required?
case ${COMP_WORDS[1]} in
flush)
COMPREPLY+=($(compgen -W "gracefully idle all" "${COMP_WORDS[2]}"))
;;
shutdown)
COMPREPLY+=($(compgen -W "gracefully immediate cancel" "${COMP_WORDS[2]}"))
;;
clear)
COMPREPLY+=($(compgen -W "server prometheus" "${COMP_WORDS[2]}"))
;;
conf)
COMPREPLY+=($(compgen -W "reload get set" "${COMP_WORDS[2]}"))
;;
esac
fi


}



pgagroal_admin_completions()
{
if [ "${#COMP_WORDS[@]}" == "2" ]; then
# main completion: the user has specified nothing at all
# or a single word, that is a command
COMPREPLY=($(compgen -W "master-key add-user update-user remove-user list-users" "${COMP_WORDS[1]}"))
COMPREPLY=($(compgen -W "master-key user" "${COMP_WORDS[1]}"))
else
# the user has specified something else
# subcommand required?
case ${COMP_WORDS[1]} in
user)
COMPREPLY+=($(compgen -W "add del edit ls" "${COMP_WORDS[2]}"))
;;
esac
fi
}




# install the completion functions
complete -F pgagroal_cli_completions pgagroal-cli
complete -F pgagroal_admin_completions pgagroal-admin
65 changes: 63 additions & 2 deletions contrib/shell_comp/pgagroal_comp.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,75 @@ function _pgagroal_cli()
{
local line
_arguments -C \
"1: :(flush-idle flush-all flush-gracefully is-alive enable disable stop gracefully status details switch-to reload reset reset-server config-get config-set)" \
"1: :(flush is-alive enable disable shutdown status details switch-to conf clear)" \
"*::arg:->args"

case $line[1] in
flush)
_pgagroal_cli_flush
;;
shutdown)
_pgagroal_cli_shutdown
;;
clear)
_pgagroal_cli_clear
;;
conf)
_pgagroal_cli_conf
;;
esac
}

function _pgagroal_cli_flush()
{
local line
_arguments -C \
"1: :(gracefully idle all)" \
"*::arg:->args"
}

function _pgagroal_cli_conf()
{
local line
_arguments -C \
"1: :(reload get set)" \
"*::arg:->args"
}

function _pgagroal_cli_shutdown()
{
local line
_arguments -C \
"1: :(gracefully immediate cancel)" \
"*::arg:->args"
}

function _pgagroal_cli_clear()
{
local line
_arguments -C \
"1: :(server prometheus)" \
"*::arg:->args"
}


function _pgagroal_admin()
{
local line
_arguments -C \
"1: :(master-key add-user update-user remove-user list-users)" \
"1: :(master-key user)" \
"*::arg:->args"

case $line[1] in
user)
_pgagroal_admin_user
;;
esac
}

function _pgagroal_admin_user()
{
_arguments -C \
"1: :(add del edit ls)" \
"*::arg:->args"
}
87 changes: 87 additions & 0 deletions doc/ADMIN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# `pgagroal-admin` user guide

`pgagroal-admin` is a command line interface to manage users known
to the `pgagroal` connection pooler.
The executable accepts a set of options, as well as a command to execute.
If no command is provided, the program will show the help screen.

The `pgagroal-admin` utility has the following synopsis:

```
pgagroal-admin [ OPTIONS ] [ COMMAND ]
```


## Options

Available options are the following ones:

```
-f, --file FILE Set the path to a user file
-U, --user USER Set the user name
-P, --password PASSWORD Set the password for the user
-g, --generate Generate a password
-l, --length Password length
-V, --version Display version information
-?, --help Display help
```

Options can be specified either in short or long form, in any position of the command line.

The `-f` option is mandatory for every operation that involves user management. If no
user file is specified, `pgagroal-admin` will silently use the default one (`pgagroal_users.conf`).

## Commands

### user
The `user` command allows the management of the users known to the connection pooler.
The command accepts the following subcommands:
- `add` to add a new user to the system;
- `del` to remove an existing user from the system;
- `edit` to change the credentials of an existing user;
- `ls` to list all known users within the system.

The command will edit the `pgagroal_users.conf` file or any file specified by means of the `-f` option flag.

Unless the command is run with the `-U` and/or `-P` flags, the execution will be interactive.

Examples:

``` shell
pgagroal-admin user add -U simon -P secret
pgagroal-admin user del -U simon

```

## master-key

The `master-key` command allows the definition of a password to protect the vault of the users,
that is the "container" for users' credentials.


## Deprecated commands

The following commands have been deprecated and will be removed
in later releases of `pgagroal`.
For each command, this is the corresponding current mapping
to the working command:

- `add-user` is now `user add`;
- `remove-user` is now `user del`;
- `update-user` is now `user edit`;
- `list-users` is now `user ls`.

Whenever you use a deprecated command, the `pgagroal-admin` will print on standard error a warning message.
If you don't want to get any warning about deprecated commands, you
can redirect the `stderr` to `/dev/null` or any other location with:

```
pgagroal-admin user-add -U luca -P strongPassword 2>/dev/null
```


## Shell completion

There is a minimal shell completion support for `pgagroal-admin`.
See the [Install pgagroal](https://github.com/pgagroal/pgagroal/blob/main/doc/tutorial/01_install.md) for more details.
Loading

0 comments on commit fb9b909

Please sign in to comment.