[] decouple DBMind configurations
Offering: openGaussDev More detail:fix the bug Match-id-f0436c0cf8c87c59b2597181cf413b71253cbfa5
This commit is contained in:
@ -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.
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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'
|
||||
|
||||
Reference in New Issue
Block a user