You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-5496: Merge CMAPI code to engine repo.
[add] cmapi code to engine
This commit is contained in:
committed by
Alan Mologorsky
parent
77eedd1756
commit
a079a2c944
0
cmapi/mcs_cluster_tool/__init__.py
Normal file
0
cmapi/mcs_cluster_tool/__init__.py
Normal file
30
cmapi/mcs_cluster_tool/__main__.py
Normal file
30
cmapi/mcs_cluster_tool/__main__.py
Normal file
@ -0,0 +1,30 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import typer
|
||||
|
||||
from cmapi_server.logging_management import dict_config, add_logging_level
|
||||
from mcs_cluster_tool import cluster_app
|
||||
from mcs_cluster_tool.constants import MCS_CLI_LOG_CONF_PATH
|
||||
|
||||
|
||||
# don't show --install-completion and --show-completion options in help message
|
||||
app = typer.Typer(
|
||||
add_completion=False,
|
||||
help=(
|
||||
'The MCS Command Line Interface is a unified tool to manage your '
|
||||
'MCS services'
|
||||
),
|
||||
)
|
||||
app.add_typer(cluster_app.app, name="cluster")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
add_logging_level('TRACE', 5) #TODO: remove when stadalone mode added.
|
||||
dict_config(MCS_CLI_LOG_CONF_PATH)
|
||||
logger = logging.getLogger('mcs_cli')
|
||||
# add separator between cli commands logging
|
||||
logger.debug(f'{"-":-^80}')
|
||||
cl_args_line = ' '.join(sys.argv[1:])
|
||||
logger.debug(f'Called "mcs {cl_args_line}"')
|
||||
app(prog_name='mcs')
|
140
cmapi/mcs_cluster_tool/cluster_app.py
Normal file
140
cmapi/mcs_cluster_tool/cluster_app.py
Normal file
@ -0,0 +1,140 @@
|
||||
"""Cluster typer application.
|
||||
|
||||
Formally this module contains all subcommands for "mcs cluster" cli command.
|
||||
"""
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
import pyotp
|
||||
import typer
|
||||
|
||||
from cmapi_server.constants import SECRET_KEY
|
||||
from cmapi_server.handlers.cluster import ClusterHandler
|
||||
from mcs_cluster_tool.decorators import handle_output
|
||||
|
||||
|
||||
logger = logging.getLogger('mcs_cli')
|
||||
app = typer.Typer(
|
||||
help='MariaDB Columnstore cluster management command line tool.'
|
||||
)
|
||||
node_app = typer.Typer(help='Cluster nodes management.')
|
||||
app.add_typer(node_app, name='node')
|
||||
set_app = typer.Typer(help='Set cluster parameters.')
|
||||
app.add_typer(set_app, name='set')
|
||||
|
||||
|
||||
@app.command()
|
||||
@handle_output
|
||||
def status():
|
||||
"""Get status information."""
|
||||
return ClusterHandler.status(logger=logger)
|
||||
|
||||
|
||||
@app.command()
|
||||
@handle_output
|
||||
def stop():
|
||||
"""Stop the Columnstore cluster."""
|
||||
return ClusterHandler.shutdown(logger=logger)
|
||||
|
||||
|
||||
@app.command()
|
||||
@handle_output
|
||||
def start():
|
||||
"""Start the Columnstore cluster."""
|
||||
return ClusterHandler.start(logger=logger)
|
||||
|
||||
|
||||
@app.command()
|
||||
@handle_output
|
||||
def restart():
|
||||
"""Restart the Columnstore cluster."""
|
||||
stop_result = ClusterHandler.shutdown(logger=logger)
|
||||
if 'error' in stop_result:
|
||||
return stop_result
|
||||
result = ClusterHandler.start(logger=logger)
|
||||
result['stop_timestamp'] = stop_result['timestamp']
|
||||
return result
|
||||
|
||||
|
||||
@node_app.command()
|
||||
@handle_output
|
||||
def add(
|
||||
nodes: Optional[List[str]] = typer.Option(
|
||||
...,
|
||||
'--node', # command line argument name
|
||||
help=(
|
||||
'node IP, name or FQDN. '
|
||||
'Can be used multiple times to add several nodes at a time.'
|
||||
)
|
||||
)
|
||||
):
|
||||
"""Add nodes to the Columnstore cluster."""
|
||||
result = []
|
||||
for node in nodes:
|
||||
result.append(ClusterHandler.add_node(node, logger=logger))
|
||||
return result
|
||||
|
||||
|
||||
@node_app.command()
|
||||
@handle_output
|
||||
def remove(nodes: Optional[List[str]] = typer.Option(
|
||||
...,
|
||||
'--node', # command line argument name
|
||||
help=(
|
||||
'node IP, name or FQDN. '
|
||||
'Can be used multiple times to remove several nodes at a time.'
|
||||
)
|
||||
)
|
||||
):
|
||||
"""Remove nodes from the Columnstore cluster."""
|
||||
result = []
|
||||
for node in nodes:
|
||||
result.append(ClusterHandler.remove_node(node, logger=logger))
|
||||
return result
|
||||
|
||||
|
||||
@set_app.command()
|
||||
@handle_output
|
||||
def mode(cluster_mode: str = typer.Option(
|
||||
...,
|
||||
'--mode',
|
||||
help=(
|
||||
'cluster mode to set. '
|
||||
'"readonly" or "readwrite" are the only acceptable values.'
|
||||
)
|
||||
)
|
||||
):
|
||||
"""Set Columnstore cluster mode."""
|
||||
if cluster_mode not in ('readonly', 'readwrite'):
|
||||
raise typer.BadParameter(
|
||||
'"readonly" or "readwrite" are the only acceptable modes now.'
|
||||
)
|
||||
return ClusterHandler.set_mode(cluster_mode, logger=logger)
|
||||
|
||||
|
||||
@set_app.command()
|
||||
@handle_output
|
||||
def api_key(key: str = typer.Option(..., help='API key to set.')):
|
||||
"""Set API key for communication with cluster nodes via API.
|
||||
|
||||
WARNING: this command will affect API key value on all cluster nodes.
|
||||
"""
|
||||
if not key:
|
||||
raise typer.BadParameter('Empty API key not allowed.')
|
||||
|
||||
totp = pyotp.TOTP(SECRET_KEY)
|
||||
|
||||
return ClusterHandler.set_api_key(key, totp.now(), logger=logger)
|
||||
|
||||
|
||||
@set_app.command()
|
||||
@handle_output
|
||||
def log_level(level: str = typer.Option(..., help='Logging level to set.')):
|
||||
"""Set logging level on all cluster nodes for develop purposes.
|
||||
|
||||
WARNING: this could dramatically affect the number of log lines.
|
||||
"""
|
||||
if not level:
|
||||
raise typer.BadParameter('Empty log level not allowed.')
|
||||
|
||||
return ClusterHandler.set_log_level(level, logger=logger)
|
4
cmapi/mcs_cluster_tool/constants.py
Normal file
4
cmapi/mcs_cluster_tool/constants.py
Normal file
@ -0,0 +1,4 @@
|
||||
import os
|
||||
|
||||
MCS_CLI_ROOT_PATH = os.path.dirname(__file__)
|
||||
MCS_CLI_LOG_CONF_PATH = os.path.join(MCS_CLI_ROOT_PATH, 'mcs_cli_log.conf')
|
35
cmapi/mcs_cluster_tool/decorators.py
Normal file
35
cmapi/mcs_cluster_tool/decorators.py
Normal file
@ -0,0 +1,35 @@
|
||||
"""Module contains decorators for typer cli commands."""
|
||||
import json
|
||||
import logging
|
||||
from functools import wraps
|
||||
|
||||
import typer
|
||||
|
||||
from cmapi_server.exceptions import CMAPIBasicError
|
||||
|
||||
|
||||
def handle_output(func):
|
||||
"""Decorator for handling output errors and add result to log file."""
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
logger = logging.getLogger('mcs_cli')
|
||||
return_code = 1
|
||||
try:
|
||||
result = func(*args, **kwargs)
|
||||
typer.echo(json.dumps(result, indent=2))
|
||||
logger.debug(f'Command returned: {result}')
|
||||
return_code = 0
|
||||
except CMAPIBasicError as err:
|
||||
typer.echo(err.message, err=True)
|
||||
logger.error('Error while command execution', exc_info=True)
|
||||
except typer.BadParameter as err:
|
||||
logger.error('Bad command line parameter.')
|
||||
raise err
|
||||
except Exception:
|
||||
logger.error(
|
||||
'Undefined error while command execution',
|
||||
exc_info=True
|
||||
)
|
||||
typer.echo('Unknown error, check the log file.', err=True)
|
||||
raise typer.Exit(return_code)
|
||||
return wrapper
|
31
cmapi/mcs_cluster_tool/mcs_cli_log.conf
Normal file
31
cmapi/mcs_cluster_tool/mcs_cli_log.conf
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"version": 1,
|
||||
"disable_existing_loggers": true,
|
||||
"formatters": {
|
||||
"default": {
|
||||
"format": "%(asctime)s [%(levelname)s] (%(name)s) %(message)s",
|
||||
"datefmt": "%d/%b/%Y %H:%M:%S"
|
||||
}
|
||||
},
|
||||
"handlers": {
|
||||
"file": {
|
||||
"class" : "logging.handlers.RotatingFileHandler",
|
||||
"formatter": "default",
|
||||
"filename": "/var/log/mariadb/columnstore/mcs_cli.log",
|
||||
"mode": "a",
|
||||
"maxBytes": 1048576,
|
||||
"backupCount": 10
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"": {
|
||||
"level": "DEBUG",
|
||||
"handlers": ["file"]
|
||||
},
|
||||
"mcs_cli": {
|
||||
"level": "DEBUG",
|
||||
"handlers": ["file"],
|
||||
"propagate": false
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user