1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

Review fixes.

This commit is contained in:
mariadb-AlanMologorsky
2025-04-04 15:51:21 +03:00
committed by Alan Mologorsky
parent aa57a7684c
commit d17fc7d9be
6 changed files with 59 additions and 15 deletions

View File

@ -351,13 +351,14 @@ class ConfigController:
# the config file or apply the changes # the config file or apply the changes
is_test = request_body.get('test', False) is_test = request_body.get('test', False)
mandatory = [request_revision, request_manager, request_timeout] mandatory = (request_revision, request_manager, request_timeout)
if None in mandatory: if None in mandatory:
raise_422_error( raise_422_error(
module_logger, func_name, 'Mandatory attribute is missing.') module_logger, func_name, 'Mandatory attribute is missing.')
request_mode = request_body.get('cluster_mode', None) request_mode = request_body.get('cluster_mode', None)
request_config = request_body.get('config', None) xml_config = request_body.get('config', None)
sm_config = request_body.get('sm_config', None)
mcs_config_filename = request_body.get( mcs_config_filename = request_body.get(
'mcs_config_filename', DEFAULT_MCS_CONF_PATH 'mcs_config_filename', DEFAULT_MCS_CONF_PATH
) )
@ -366,9 +367,12 @@ class ConfigController:
) )
secrets = request_body.get('secrets', None) secrets = request_body.get('secrets', None)
if request_mode is None and request_config is None: operation_params = (request_mode, xml_config, secrets)
# if no operation to apply, return 422
if not any(operation_params):
raise_422_error( raise_422_error(
module_logger, func_name, 'Mandatory attribute is missing.' module_logger, func_name,
'Mandatory attribute is missing.'
) )
request_headers = cherrypy.request.headers request_headers = cherrypy.request.headers
@ -394,11 +398,10 @@ class ConfigController:
request_response = {'timestamp': str(datetime.now())} request_response = {'timestamp': str(datetime.now())}
if secrets: if secrets:
#TODO: validate incoming secrets?
CEJPasswordHandler().save_secrets(secrets) CEJPasswordHandler().save_secrets(secrets)
node_config = NodeConfig() node_config = NodeConfig()
xml_config = request_body.get('config', None)
sm_config = request_body.get('sm_config', None)
if is_test: if is_test:
return request_response return request_response
if request_mode is not None: if request_mode is not None:

View File

@ -77,6 +77,25 @@ class CEJPasswordHandler():
) from None ) from None
return secrets_json return secrets_json
@classmethod
def is_password_encrypted(cls, passwd: str) -> bool:
"""Check if password is encrypted.
:param passwd: CEJ password
:type passwd: str
:return: True if password is encrypted
:rtype: bool
"""
# minimal length of encrypted password
if len(passwd) < (AES_IV_HEX_SIZE*2):
return False
try:
# Try converting the string to an integer with base 16
int(passwd, 16)
except ValueError:
return False
return True
@classmethod @classmethod
def decrypt_password( def decrypt_password(
cls, enc_data: str, directory: str = MCS_DATA_PATH cls, enc_data: str, directory: str = MCS_DATA_PATH
@ -91,7 +110,10 @@ class CEJPasswordHandler():
:rtype: str :rtype: str
""" """
secrets_file_path = os.path.join(directory, MCS_SECRETS_FILENAME) secrets_file_path = os.path.join(directory, MCS_SECRETS_FILENAME)
if not cls.secretsfile_exists(directory=directory): if (
not cls.secretsfile_exists(directory=directory) or
not cls.is_password_encrypted(enc_data)
):
logging.warning('Unencrypted CrossEngineSupport password used.') logging.warning('Unencrypted CrossEngineSupport password used.')
return enc_data return enc_data

View File

@ -47,7 +47,7 @@ def toggle_cluster_state(
switch_node_maintenance(maintainance_flag) switch_node_maintenance(maintainance_flag)
update_revision_and_manager() update_revision_and_manager()
broadcast_new_config(config) broadcast_new_config(config, distribute_secrets=True)
class ClusterHandler(): class ClusterHandler():

View File

@ -346,10 +346,10 @@ def broadcast_new_config(
# TODO: do not restart cluster when put xml config only with # TODO: do not restart cluster when put xml config only with
# distribute secrets # distribute secrets
if not CEJPasswordHandler.secretsfile_exists(): if not CEJPasswordHandler.secretsfile_exists():
secrets_dict = CEJPasswordHandler.generate_secrets_data() logging.debug('No .secrets file found so not distrinuting it.')
CEJPasswordHandler.save_secrets(secrets=secrets_dict) else:
secrets = CEJPasswordHandler.get_secrets_json() secrets = CEJPasswordHandler.get_secrets_json()
body['secrets'] = secrets body['secrets'] = secrets
# TODO: remove test mode here and replace it by mock in tests # TODO: remove test mode here and replace it by mock in tests
if test_mode: if test_mode:
@ -787,6 +787,7 @@ def get_cej_info(config_root):
:return: cej_host, cej_port, cej_username, cej_password :return: cej_host, cej_port, cej_username, cej_password
:rtype: tuple :rtype: tuple
""" """
#TODO: move this to cej.py?
cej_node = config_root.find('./CrossEngineSupport') cej_node = config_root.find('./CrossEngineSupport')
cej_host = cej_node.find('Host').text or '127.0.0.1' cej_host = cej_node.find('Host').text or '127.0.0.1'
cej_port = cej_node.find('Port').text or '3306' cej_port = cej_node.find('Port').text or '3306'
@ -802,8 +803,26 @@ def get_cej_info(config_root):
'Columnstore.xml has an empty CrossEngineSupport.Password tag' 'Columnstore.xml has an empty CrossEngineSupport.Password tag'
) )
if (
not CEJPasswordHandler.secretsfile_exists() and
CEJPasswordHandler.is_password_encrypted(cej_password)
):
logging.error(
'CrossengineSupport password seems to be encrypted '
'but no .secrets file exist. May be it\'s eventually removed.'
)
if CEJPasswordHandler.secretsfile_exists() and cej_password: if CEJPasswordHandler.secretsfile_exists() and cej_password:
cej_password = CEJPasswordHandler.decrypt_password(cej_password) if CEJPasswordHandler.is_password_encrypted(cej_password):
cej_password = CEJPasswordHandler.decrypt_password(cej_password)
else:
logging.error(
'CrossengineSupport password seems to be unencrypted but '
'.secrets file exist. May be .secrets file generated by '
'mistake or password left encrypted after using cskeys '
'utility.'
)
return cej_host, cej_port, cej_username, cej_password return cej_host, cej_port, cej_username, cej_password

View File

@ -486,7 +486,7 @@ def is_master():
"AND COMMAND LIKE 'Slave%';\"" "AND COMMAND LIKE 'Slave%';\""
) )
ret = subprocess.run(cmd, stdout=subprocess.PIPE, shell = True) ret = subprocess.run(cmd, stdout=subprocess.PIPE, shell=True)
if ret.returncode == 0: if ret.returncode == 0:
response = ret.stdout.decode("utf-8").strip() response = ret.stdout.decode("utf-8").strip()
# Primary will have no slave_threads # Primary will have no slave_threads

View File

@ -131,7 +131,7 @@ class TestTransactions(unittest.TestCase):
mcs_config_filename, mcs_config_filename,
cmapi_config_filename=cmapi_config_filename, cmapi_config_filename=cmapi_config_filename,
test_mode=True, test_mode=True,
nodes = result[2] nodes=result[2]
) )
# not specifying nodes here to exercise the # not specifying nodes here to exercise the
# nodes = None path # nodes = None path