You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
feat(cmapi): MCOL-5019: review fixes.
[fix] CEJPasswordHandler class methods to use directory for cskeys file [fix] CEJPasswordHandler.encrypt_password to return password in hex format [fix] CEJPasswordHandler key_length [fix] CEJPasswordHandler os.urandom call typo [upd] mcs cli README.md and man page [upd] mcs cli README_DEV.md [fix] mcs_cluster_tool/decorators.py to handle typer.Exit exception [add] various docstrings
This commit is contained in:
committed by
Alan Mologorsky
parent
215e4eea4d
commit
aa57a7684c
@ -18,6 +18,8 @@ $ mcs [OPTIONS] COMMAND [ARGS]...
|
||||
* `dbrm_backup`: Columnstore DBRM Backup.
|
||||
* `restore`: Restore Columnstore (and/or MariaDB) data.
|
||||
* `dbrm_restore`: Restore Columnstore DBRM data.
|
||||
* `cskeys`: Generates a random AES encryption key and init vector and writes them to disk.
|
||||
* `cspasswd`: Encrypt a Columnstore plaintext password using the encryption key in the key file.
|
||||
* `help-all`: Show help for all commands in man page style.
|
||||
* `status`: Get status information.
|
||||
* `stop`: Stop the Columnstore cluster.
|
||||
@ -162,6 +164,50 @@ $ mcs dbrm_restore [OPTIONS]
|
||||
* `-li, --list`: List backups.
|
||||
* `--help`: Show this message and exit.
|
||||
|
||||
## `mcs cskeys`
|
||||
|
||||
This utility generates a random AES encryption key and init vector
|
||||
and writes them to disk. The data is written to the file '.secrets',
|
||||
in the specified directory. The key and init vector are used by
|
||||
the utility 'cspasswd' to encrypt passwords used in Columnstore
|
||||
configuration files, as well as by Columnstore itself to decrypt the
|
||||
passwords.
|
||||
|
||||
WARNING: Re-creating the file invalidates all existing encrypted
|
||||
passwords in the configuration files.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```console
|
||||
$ mcs cskeys [OPTIONS] [DIRECTORY]
|
||||
```
|
||||
|
||||
**Arguments**:
|
||||
|
||||
* `[DIRECTORY]`: The directory where to store the file in. [default: /var/lib/columnstore]
|
||||
|
||||
**Options**:
|
||||
|
||||
* `-u, --user TEXT`: Designate the owner of the generated file. [default: mysql]
|
||||
* `--help`: Show this message and exit.
|
||||
|
||||
## `mcs cspasswd`
|
||||
|
||||
Encrypt a Columnstore plaintext password using the encryption key in
|
||||
the key file.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```console
|
||||
$ mcs cspasswd [OPTIONS]
|
||||
```
|
||||
|
||||
**Options**:
|
||||
|
||||
* `--password TEXT`: Password to encrypt/decrypt [required]
|
||||
* `--decrypt`: Decrypt an encrypted password instead.
|
||||
* `--help`: Show this message and exit.
|
||||
|
||||
## `mcs help-all`
|
||||
|
||||
Show help for all commands in man page style.
|
||||
|
@ -7,6 +7,14 @@
|
||||
```bash
|
||||
typer mcs_cluster_tool/__main__.py utils docs --name mcs --output README.md
|
||||
```
|
||||
Optionally could be generated from installed package.
|
||||
```bash
|
||||
PYTHONPATH="/usr/share/columnstore/cmapi:/usr/share/columnstore/cmapi/deps" /usr/share/columnstore/cmapi/python/bin/python3 -m typer /usr/share/columnstore/cmapi/mcs_cluster_tool/__main__.py utils docs --name mcs --output ~/README.md
|
||||
```
|
||||
- dependencies for gem build (RHEL example)
|
||||
```bash
|
||||
sudo dnf install make gcc redhat-rpm-config -y
|
||||
```
|
||||
- install `md2man` (for now it's the only one tool that make convertation without any issues)
|
||||
```bash
|
||||
sudo yum install -y ruby ruby-devel
|
||||
@ -14,6 +22,6 @@
|
||||
```
|
||||
- convert to perfect `.roff` file (`man` page)
|
||||
```bash
|
||||
md2man README.md > mcs.1
|
||||
md2man-roff README.md > mcs.1
|
||||
```
|
||||
- enjoy =)
|
@ -36,9 +36,16 @@ app.command(
|
||||
app.command(
|
||||
'dbrm_restore', rich_help_panel='Tools commands'
|
||||
)(restore_commands.dbrm_restore)
|
||||
app.command('cskeys', rich_help_panel='Tools commands')(tools_commands.cskeys)
|
||||
app.command(
|
||||
'cspasswd', rich_help_panel='Tools commands'
|
||||
'cskeys', rich_help_panel='Tools commands',
|
||||
short_help=(
|
||||
'Generates a random AES encryption key and init vector and writes '
|
||||
'them to disk.'
|
||||
)
|
||||
)(tools_commands.cskeys)
|
||||
app.command(
|
||||
'cspasswd', rich_help_panel='Tools commands',
|
||||
short_help='Encrypt a Columnstore plaintext password.'
|
||||
)(tools_commands.cspasswd)
|
||||
|
||||
|
||||
|
@ -25,11 +25,16 @@ def handle_output(func):
|
||||
except typer.BadParameter as err:
|
||||
logger.error('Bad command line parameter.')
|
||||
raise err
|
||||
except typer.Exit as err: # if some command used typer.Exit
|
||||
#TODO: think about universal protocol to return json data and
|
||||
# plain text results.
|
||||
return_code = err.exit_code
|
||||
except Exception:
|
||||
logger.error(
|
||||
'Undefined error during command execution',
|
||||
exc_info=True
|
||||
)
|
||||
typer.echo('Unknown error, check the log file.', err=True)
|
||||
|
||||
raise typer.Exit(return_code)
|
||||
return wrapper
|
||||
|
@ -27,6 +27,10 @@ $ mcs [OPTIONS] COMMAND [ARGS]...
|
||||
.IP \(bu 2
|
||||
\fB\fCdbrm_restore\fR: Restore Columnstore DBRM data.
|
||||
.IP \(bu 2
|
||||
\fB\fCcskeys\fR: Generates a random AES encryption key and init vector and writes them to disk.
|
||||
.IP \(bu 2
|
||||
\fB\fCcspasswd\fR: Encrypt a Columnstore plaintext password using the encryption key in the key file.
|
||||
.IP \(bu 2
|
||||
\fB\fChelp\-all\fR: Show help for all commands in man page style.
|
||||
.IP \(bu 2
|
||||
\fB\fCstatus\fR: Get status information.
|
||||
@ -252,6 +256,61 @@ $ mcs dbrm_restore [OPTIONS]
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-help\fR: Show this message and exit.
|
||||
.RE
|
||||
.SH \fB\fCmcs cskeys\fR
|
||||
.PP
|
||||
This utility generates a random AES encryption key and init vector
|
||||
and writes them to disk. The data is written to the file \[aq]\&.secrets\[aq],
|
||||
in the specified directory. The key and init vector are used by
|
||||
the utility \[aq]cspasswd\[aq] to encrypt passwords used in Columnstore
|
||||
configuration files, as well as by Columnstore itself to decrypt the
|
||||
passwords.
|
||||
.PP
|
||||
WARNING: Re\-creating the file invalidates all existing encrypted
|
||||
passwords in the configuration files.
|
||||
.PP
|
||||
\fBUsage\fP:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
$ mcs cskeys [OPTIONS] [DIRECTORY]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
\fBArguments\fP:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fC[DIRECTORY]\fR: The directory where to store the file in. [default: /var/lib/columnstore]
|
||||
.RE
|
||||
.PP
|
||||
\fBOptions\fP:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fC\-u, \-\-user TEXT\fR: Designate the owner of the generated file. [default: mysql]
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-help\fR: Show this message and exit.
|
||||
.RE
|
||||
.SH \fB\fCmcs cspasswd\fR
|
||||
.PP
|
||||
Encrypt a Columnstore plaintext password using the encryption key in
|
||||
the key file.
|
||||
.PP
|
||||
\fBUsage\fP:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
$ mcs cspasswd [OPTIONS]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
\fBOptions\fP:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-password TEXT\fR: Password to encrypt/decrypt [required]
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-decrypt\fR: Decrypt an encrypted password instead.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-help\fR: Show this message and exit.
|
||||
.RE
|
||||
.SH \fB\fCmcs help\-all\fR
|
||||
.PP
|
||||
Show help for all commands in man page style.
|
||||
|
@ -5,7 +5,9 @@ import typer
|
||||
from typing_extensions import Annotated
|
||||
|
||||
|
||||
from cmapi_server.constants import MCS_SECRETS_FILE_PATH
|
||||
from cmapi_server.constants import (
|
||||
MCS_DATA_PATH, MCS_SECRETS_FILENAME
|
||||
)
|
||||
from cmapi_server.exceptions import CEJError
|
||||
from cmapi_server.handlers.cej import CEJPasswordHandler
|
||||
from mcs_cluster_tool.decorators import handle_output
|
||||
@ -18,22 +20,33 @@ logger = logging.getLogger('mcs_cli')
|
||||
|
||||
@handle_output
|
||||
def cskeys(
|
||||
filepath: Annotated[
|
||||
user: Annotated[
|
||||
str,
|
||||
typer.Option(
|
||||
'-f', '--filepath',
|
||||
help='Path to the output file',
|
||||
)
|
||||
] = MCS_SECRETS_FILE_PATH,
|
||||
username: Annotated[
|
||||
str,
|
||||
typer.Option(
|
||||
'-u', '--username',
|
||||
help='Username for the key',
|
||||
'-u', '--user',
|
||||
help='Designate the owner of the generated file.',
|
||||
)
|
||||
] = 'mysql',
|
||||
directory: Annotated[
|
||||
str,
|
||||
typer.Argument(
|
||||
help='The directory where to store the file in.',
|
||||
)
|
||||
] = MCS_DATA_PATH
|
||||
):
|
||||
if CEJPasswordHandler().secretsfile_exists():
|
||||
"""
|
||||
This utility generates a random AES encryption key and init vector
|
||||
and writes them to disk. The data is written to the file '.secrets',
|
||||
in the specified directory. The key and init vector are used by
|
||||
the utility 'cspasswd' to encrypt passwords used in Columnstore
|
||||
configuration files, as well as by Columnstore itself to decrypt the
|
||||
passwords.
|
||||
|
||||
WARNING: Re-creating the file invalidates all existing encrypted
|
||||
passwords in the configuration files.
|
||||
"""
|
||||
filepath = os.path.join(directory, MCS_SECRETS_FILENAME)
|
||||
if CEJPasswordHandler().secretsfile_exists(directory=directory):
|
||||
typer.echo(
|
||||
(
|
||||
f'Secrets file "{filepath}" already exists. '
|
||||
@ -44,14 +57,18 @@ def cskeys(
|
||||
raise typer.Exit(code=1)
|
||||
elif not os.path.exists(os.path.dirname(filepath)):
|
||||
typer.echo(
|
||||
f'Directory "{os.path.dirname(filepath)}" does not exist.',
|
||||
f'Directory "{directory}" does not exist.',
|
||||
color='red'
|
||||
)
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
new_secrets_data = CEJPasswordHandler().generate_secrets_data()
|
||||
try:
|
||||
CEJPasswordHandler().save_secrets(new_secrets_data, owner=username)
|
||||
CEJPasswordHandler().save_secrets(
|
||||
new_secrets_data, owner=user, directory=directory
|
||||
)
|
||||
typer.echo(f'Permissions of "{filepath}" set to owner:read.')
|
||||
typer.echo(f'Ownership of "{filepath}" given to {user}.')
|
||||
except CEJError as cej_error:
|
||||
typer.echo(cej_error.message, color='red')
|
||||
raise typer.Exit(code=2)
|
||||
@ -71,10 +88,14 @@ def cspasswd(
|
||||
bool,
|
||||
typer.Option(
|
||||
'--decrypt',
|
||||
help='Decrypt the provided password',
|
||||
help='Decrypt an encrypted password instead.',
|
||||
)
|
||||
] = False
|
||||
):
|
||||
"""
|
||||
Encrypt a Columnstore plaintext password using the encryption key in
|
||||
the key file.
|
||||
"""
|
||||
if decrypt:
|
||||
try:
|
||||
decrypted_password = CEJPasswordHandler().decrypt_password(
|
||||
|
Reference in New Issue
Block a user