[] decouple DBMind configurations

Offering: openGaussDev

More detail:fix the bug

Match-id-f0436c0cf8c87c59b2597181cf413b71253cbfa5
This commit is contained in:
openGaussDev
2022-03-04 10:39:53 +08:00
committed by yanghao
parent e984d5525c
commit f02c16a949
3 changed files with 57 additions and 27 deletions

View File

@ -11,25 +11,57 @@
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
import os
import re
from configparser import ConfigParser
from configparser import NoSectionError, NoOptionError
from dbmind import constants
from dbmind.common import security
from dbmind.common.exceptions import InvalidPasswordException, ConfigSettingError
from dbmind.metadatabase.dao.dynamic_config import dynamic_config_get, dynamic_config_set
from dbmind.common.utils import write_to_terminal
from dbmind.metadatabase.dao.dynamic_config import dynamic_config_get, dynamic_config_set
DBMIND_CONF_HEADER = """\
# Copyright (c) 2022 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# Notice:
# 1. (null) explicitly represents empty or null. Meanwhile blank represents undefined.
# 2. DBMind encrypts password parameters. Hence, there is no plain-text password after initialization.
# 3. Users can only configure the plain-text password in this file before initializing
# (that is, using the --initialize option),
# and then if users want to modify the password-related information,
# users need to use the 'set' sub-command to achieve.
# 4. If users use relative path in this file, the current working directory is the directory where this file is located.
"""
NULL_TYPE = '(null)' # empty text.
ENCRYPTED_SIGNAL = 'Encrypted->'
# Used by check_config_validity().
CONFIG_OPTIONS = {
'TSDB-name': ['prometheus'],
'METADATABASE-dbtype': ['sqlite', 'opengauss', 'postgresql'],
'WORKER-type': ['local', 'dist'],
'LOG-level': ['DEBUG', 'INFO', 'WARNING', 'ERROR']
}
def check_config_validity(section, option, value, inline_comment=None):
def check_config_validity(section, option, value):
config_item = '%s-%s' % (section, option)
# exceptional cases:
if config_item == 'METADATABASE-port':
return True, None
# normal inspection process:
if 'port' in option:
valid_port = str.isdigit(value) and 0 < int(value) <= 65535
@ -38,16 +70,14 @@ def check_config_validity(section, option, value, inline_comment=None):
if 'database' in option:
if value == NULL_TYPE or value.strip() == '':
return False, 'Unspecified database name'
if 'Options:' in inline_comment:
# determine setting option whether choose from option list.
results = re.findall(r'Options: (.*)?\.', inline_comment)
if len(results) > 0:
options = list(map(str.strip, results[0].split(',')))
if value not in options:
return False, 'Invalid choice: %s' % value
options = CONFIG_OPTIONS.get(config_item)
if options and value not in options:
return False, 'Invalid choice: %s' % value
if 'dbtype' in option and value == 'opengauss':
write_to_terminal(
'WARN: default PostgresSQL connector (psycopg2-binary) does not support openGauss.\n'
'WARN: default PostgreSQL connector (psycopg2-binary) does not support openGauss.\n'
'It would help if you compiled psycopg2 with openGauss manually or '
'created a connection user after setting the GUC password_encryption_type to 1.',
color='yellow'
@ -102,7 +132,10 @@ class ConfigUpdater:
def get(self, section, option):
value = self.config.get(section, option)
default_value, inline_comment = map(str.strip, value.rsplit('#', 1))
try:
default_value, inline_comment = map(str.strip, value.rsplit('#', 1))
except ValueError:
default_value, inline_comment = value.strip(), ''
if default_value == '':
default_value = NULL_TYPE
return default_value, inline_comment
@ -132,10 +165,7 @@ class ConfigUpdater:
# output configurations
self.fp.truncate(0)
self.fp.seek(0)
with open(
file=os.path.join(constants.MISC_PATH, constants.CONFILE_HEADER_NAME)
) as header_fp:
self.fp.writelines(header_fp.readlines())
self.fp.write(DBMIND_CONF_HEADER)
self.config.write(self.fp)
self.fp.flush()
self.fp.close()
@ -163,7 +193,7 @@ def set_config_parameter(confpath, section: str, option: str, value: str):
old_value, comment = config.get(section, option)
except (NoSectionError, NoOptionError):
raise ConfigSettingError('Not found the parameter %s-%s.' % (section, option))
valid, reason = check_config_validity(section, option, value, comment)
valid, reason = check_config_validity(section, option, value)
if not valid:
raise ConfigSettingError('Incorrect value due to %s.' % reason)
# If user wants to change password, we should encrypt the plain-text password first.

View File

@ -19,7 +19,7 @@ from dbmind import constants, global_vars
from dbmind.cmd.config_utils import (
ConfigUpdater, check_config_validity,
DynamicConfig, load_sys_configs,
NULL_TYPE, ENCRYPTED_SIGNAL
NULL_TYPE, ENCRYPTED_SIGNAL, DBMIND_CONF_HEADER
)
from dbmind.cmd.edbmind import SKIP_LIST
from dbmind.common import utils, security
@ -70,7 +70,7 @@ def initialize_and_check_config(confpath, interactive=False):
for section, section_comment in config.sections(SKIP_LIST):
for option, value, inline_comment in config.items(section):
valid, invalid_reason = check_config_validity(
section, option, value, inline_comment
section, option, value
)
if not valid:
raise SetupError(
@ -151,7 +151,10 @@ def setup_directory_interactive(confpath):
utils.write_to_terminal(section_comment, color='yellow')
# Get each configuration item.
for option, values in config.items(section):
default_value, inline_comment = map(str.strip, values.rsplit('#', 1))
try:
default_value, inline_comment = map(str.strip, values.rsplit('#', 1))
except ValueError:
default_value, inline_comment = values.strip(), ''
# If not set default value, the default value is null.
if default_value.strip() == '':
default_value = NULL_TYPE
@ -170,7 +173,7 @@ def setup_directory_interactive(confpath):
input_value = default_value
valid, invalid_reason = check_config_validity(
section, option, input_value, inline_comment
section, option, input_value
)
if not valid:
utils.write_to_terminal(
@ -190,8 +193,7 @@ def setup_directory_interactive(confpath):
# output configurations
with open(file=config_dst, mode='w+') as fp:
# Add header comments (including license and notice).
with open(file=os.path.join(confpath, constants.CONFILE_HEADER_NAME)) as header_fp:
fp.writelines(header_fp.readlines())
fp.write(DBMIND_CONF_HEADER)
config.write(fp)
initialize_and_check_config(confpath, interactive=True)
@ -221,8 +223,7 @@ def setup_directory(confpath):
with open(file=os.path.join(confpath, constants.CONFILE_NAME), mode='r+') as fp:
old = fp.readlines()
# Add header comments (including license and notice).
with open(file=os.path.join(constants.MISC_PATH, constants.CONFILE_HEADER_NAME)) as header_fp:
fp.seek(0)
fp.writelines(header_fp.readlines())
fp.seek(0)
fp.write(DBMIND_CONF_HEADER)
fp.writelines(old)
utils.write_to_terminal("Configure directory '%s' has been created successfully." % confpath, color='green')

View File

@ -19,7 +19,6 @@ DBMIND_PATH = os.path.dirname(os.path.abspath(__file__))
MISC_PATH = os.path.join(DBMIND_PATH, 'misc')
CONFILE_NAME = 'dbmind.conf' # the name of configuration file
CONFILE_HEADER_NAME = 'dbmind.conf.header'
PIDFILE_NAME = 'dbmind.pid'
LOGFILE_NAME = 'dbmind.log'
METRIC_MAP_CONFIG = 'metric_map.conf'