Skip to content

Commit 1663a31

Browse files
gys-git雪染
authored and
雪染
committed
3.2.0 release
1 parent 2e7e453 commit 1663a31

File tree

218 files changed

+5978
-839
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

218 files changed

+5978
-839
lines changed

_cmd.py

Lines changed: 378 additions & 23 deletions
Large diffs are not rendered by default.

_deploy.py

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
from ruamel.yaml.comments import CommentedMap
2929

3030
import _errno as err
31-
from tool import ConfigUtil, FileUtil, YamlLoader, OrderedDict, COMMAND_ENV
31+
import const
32+
from tool import ConfigUtil, FileUtil, YamlLoader, OrderedDict, COMMAND_ENV, aes_encrypt, aes_decrypt, \
33+
string_to_md5_32bytes
3234
from _manager import Manager
3335
from _stdio import SafeStdio
3436
from _environ import ENV_BASE_DIR
@@ -1051,13 +1053,15 @@ def __str__(self):
10511053

10521054
class DeployConfig(SafeStdio):
10531055

1054-
def __init__(self, yaml_path, yaml_loader=yaml, inner_config=None, config_parser_manager=None, stdio=None):
1056+
def __init__(self, yaml_path, yaml_loader=yaml, inner_config=None, config_parser_manager=None, config_encrypted=None, stdio=None):
10551057
self._user = None
10561058
self.unuse_lib_repository = False
10571059
self.auto_create_tenant = False
10581060
self._inner_config = inner_config
10591061
self.components = OrderedDict()
10601062
self._src_data = None
1063+
self._need_encrypt_dump = False
1064+
self._config_encrypted = config_encrypted
10611065
self.name = os.path.split(os.path.split(yaml_path)[0])[-1]
10621066
self.yaml_path = yaml_path
10631067
self.yaml_loader = yaml_loader
@@ -1072,6 +1076,8 @@ def __init__(self, yaml_path, yaml_loader=yaml, inner_config=None, config_parser
10721076
self._removed_components = set()
10731077
self._do_not_dump = False
10741078
self._mem_mode = False
1079+
self._tmp_user_password = None
1080+
self._auto_decrypt_password()
10751081

10761082
def __deepcopy__(self, memo):
10771083
deploy_config = self.__class__(self.yaml_path, self.yaml_loader, self._inner_config, self.config_parser_manager, self.stdio)
@@ -1091,6 +1097,15 @@ def enable_mem_mode(self):
10911097
def disable_mem_mode(self):
10921098
self._mem_mode = False
10931099

1100+
def set_config_unencrypted(self):
1101+
self._config_encrypted = False
1102+
1103+
def disable_encrypt_dump(self):
1104+
self._need_encrypt_dump = False
1105+
1106+
def enable_encrypt_dump(self):
1107+
self._need_encrypt_dump = True
1108+
10941109
@property
10951110
def sorted_components(self):
10961111
available_depends = list(self.components.keys())
@@ -1201,6 +1216,14 @@ def update_component_info(self, repository):
12011216
self._src_data[component] = ori_data
12021217
return False
12031218

1219+
def _update_user_password(self):
1220+
try:
1221+
for key in self._src_data:
1222+
if key == 'user':
1223+
self._src_data[key]['password'] = self.user.password
1224+
except:
1225+
self.stdio.exception()
1226+
12041227
def _load(self):
12051228
try:
12061229
with open(self.yaml_path, 'rb') as f:
@@ -1225,6 +1248,8 @@ def _load(self):
12251248
for comp in depends:
12261249
conf = self.components[comp]
12271250
for name in depends[comp]:
1251+
if depends[comp] is None:
1252+
continue
12281253
if name == comp:
12291254
continue
12301255
if name in self.components:
@@ -1234,6 +1259,39 @@ def _load(self):
12341259
if not self.user:
12351260
self.set_user_conf(UserConfig())
12361261

1262+
def _auto_decrypt_password(self):
1263+
if not self._inner_config:
1264+
return True
1265+
if self._config_encrypted is None:
1266+
if COMMAND_ENV.get(const.ENCRYPT_PASSWORD) == '1':
1267+
self._config_encrypted = True
1268+
if not bool(self._inner_config.get_global_config(const.ENCRYPT_PASSWORD)):
1269+
self.stdio.verbose("auto_decrypt_password: deploy is not encrypted")
1270+
self._config_encrypted = False
1271+
if self._config_encrypted and bool(self._inner_config.get_global_config(const.ENCRYPT_PASSWORD)):
1272+
self.change_deploy_config_password(False, False)
1273+
self._need_encrypt_dump = True
1274+
elif not self._config_encrypted and COMMAND_ENV.get(const.ENCRYPT_PASSWORD) == '1':
1275+
self._need_encrypt_dump = True
1276+
1277+
def _encrypt_password_before_dump(self):
1278+
if not self._inner_config:
1279+
return True
1280+
if self._need_encrypt_dump and COMMAND_ENV.get(const.ENCRYPT_PASSWORD) == '1' and not self._config_encrypted:
1281+
if bool(self._inner_config.get_global_config(const.ENCRYPT_PASSWORD)):
1282+
change_deploy_encrypt = False
1283+
else:
1284+
change_deploy_encrypt = True
1285+
enable_mem_mode = False
1286+
if self._mem_mode:
1287+
enable_mem_mode = True
1288+
self._mem_mode = False
1289+
self.change_deploy_config_password(True, change_deploy_encrypt)
1290+
if enable_mem_mode:
1291+
self._mem_mode = True
1292+
self._config_encrypted = True
1293+
self._update_user_password()
1294+
12371295
def scale_out(self, config_path):
12381296
ret = True
12391297
depends = {}
@@ -1361,6 +1419,7 @@ def _dump_inner_config(self):
13611419
def _dump(self):
13621420
if self._do_not_dump:
13631421
raise Exception("Cannot dump because flag DO NOT DUMP exists.")
1422+
self._encrypt_password_before_dump()
13641423
try:
13651424
with open(self.yaml_path, 'w') as f:
13661425
self._dump_inner_config()
@@ -1548,6 +1607,76 @@ def change_component_config_style(self, component_name, style):
15481607
self._src_data[component_name] = new_config['config']
15491608
return True
15501609

1610+
def get_all_password_path(self, global_config, password_paths=[], component=None, parent_key=None):
1611+
pattern = r'password'
1612+
pattern1 = r'passwd'
1613+
for key, value in global_config.items():
1614+
if parent_key:
1615+
current_key = f"{parent_key}.{key}"
1616+
else:
1617+
current_key = key
1618+
1619+
if isinstance(value, dict):
1620+
self.get_all_password_path(value, password_paths, component, current_key)
1621+
else:
1622+
value = str(value)
1623+
if isinstance(key, str) and isinstance(value, str) and (re.findall(pattern, key, re.IGNORECASE) or re.findall(pattern1, key, re.IGNORECASE)):
1624+
self.stdio.verbose(f"find pwd key: {current_key}")
1625+
password_paths.append(current_key)
1626+
if component == const.COMP_PROMETHEUS and parent_key == 'basic_auth_users':
1627+
self.stdio.verbose(f"find pwd key: {key}")
1628+
password_paths.append(current_key)
1629+
return password_paths
1630+
1631+
def update_password_in_global_config(self, global_config, path, key, enable_encrypt):
1632+
current_key = path[0]
1633+
if len(path) == 1:
1634+
if enable_encrypt:
1635+
self.stdio.verbose(f"encrypt pwd-key: {current_key}")
1636+
global_config[current_key] = aes_encrypt(str(global_config[current_key]), key)
1637+
else:
1638+
self.stdio.verbose(f"decrypt pwd-key: {current_key}")
1639+
global_config[current_key] = aes_decrypt(global_config[current_key], key)
1640+
else:
1641+
if current_key in global_config and isinstance(global_config[current_key], dict):
1642+
self.update_password_in_global_config(global_config[current_key], path[1:], key, enable_encrypt)
1643+
1644+
def change_deploy_config_password(self, enable_encrypt, change_deploy_encrypt=True, first_encrypt=False):
1645+
if COMMAND_ENV.get(const.ENCRYPT_PASSWORD) != '1' and not first_encrypt:
1646+
return True
1647+
deploy_encrypt_enable = self.inner_config.get_global_config(const.ENCRYPT_PASSWORD) or False
1648+
if enable_encrypt == deploy_encrypt_enable == self._config_encrypted:
1649+
return True
1650+
if not enable_encrypt and not self._config_encrypted:
1651+
self._need_encrypt_dump = False
1652+
else:
1653+
1654+
cluster_id = ''
1655+
for component in const.COMPS_OB:
1656+
if component in self.components.keys():
1657+
cluster_config = self.components[component]
1658+
global_config = cluster_config.get_global_conf()
1659+
cluster_id = str(global_config['cluster_id']) if 'cluster_id' in global_config else ''
1660+
key = string_to_md5_32bytes(self.name + cluster_id).encode('utf-8')
1661+
self.stdio.verbose(f"encrypt key: {key}")
1662+
if self.user.password:
1663+
if enable_encrypt:
1664+
self.user.password = aes_encrypt(str(self.user.password), key)
1665+
else:
1666+
self.user.password = aes_decrypt(self.user.password, key)
1667+
for component, cluster_config in self.components.items():
1668+
self.stdio.verbose(f"change {component} pwd encrypt.")
1669+
password_paths = []
1670+
global_config = cluster_config.get_global_conf()
1671+
self.get_all_password_path(global_config, password_paths, component)
1672+
change_global_config = deepcopy(global_config)
1673+
for password_path in password_paths:
1674+
password_path_keys = password_path.split('.')
1675+
self.update_password_in_global_config(change_global_config, password_path_keys, key, enable_encrypt)
1676+
cluster_config.update_global_conf(password_path_keys[0], change_global_config[password_path_keys[0]], save=False)
1677+
self._config_encrypted = enable_encrypt
1678+
change_deploy_encrypt and self.inner_config.update_global_config(const.ENCRYPT_PASSWORD, enable_encrypt)
1679+
15511680

15521681
class Deploy(object):
15531682

@@ -1564,6 +1693,10 @@ def __init__(self, config_dir, config_parser_manager=None, stdio=None):
15641693
self.stdio = stdio
15651694
self.config_parser_manager = config_parser_manager
15661695
self._uprade_meta = None
1696+
self._config_encrypted = True
1697+
1698+
def set_config_decrypted(self):
1699+
self._config_encrypted = False
15671700

15681701
def use_model(self, name, repository, dump=True):
15691702
self.deploy_info.components[name] = {
@@ -1616,7 +1749,8 @@ def deploy_info(self):
16161749

16171750
def _load_deploy_config(self, path):
16181751
yaml_loader = YamlLoader(stdio=self.stdio)
1619-
deploy_config = DeployConfig(path, yaml_loader=yaml_loader, config_parser_manager=self.config_parser_manager, stdio=self.stdio)
1752+
inner_config = InnerConfig(self.get_inner_config_path(self.config_dir), yaml_loader=yaml_loader)
1753+
deploy_config = DeployConfig(path, yaml_loader=yaml_loader, inner_config=inner_config, config_parser_manager=self.config_parser_manager, config_encrypted=self._config_encrypted,stdio=self.stdio)
16201754
deploy_info = self.deploy_info
16211755
for component_name in deploy_info.components:
16221756
if component_name not in deploy_config.components:
@@ -1627,7 +1761,6 @@ def _load_deploy_config(self, path):
16271761
cluster_config.version = config['version']
16281762
if 'hash' in config and config['hash']:
16291763
cluster_config.package_hash = config['hash']
1630-
deploy_config.inner_config = InnerConfig(self.get_inner_config_path(self.config_dir), yaml_loader=yaml_loader)
16311764
return deploy_config
16321765

16331766
@property

_environ.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,14 @@
5757
ENV_OBD_INSTALL_PRE = "OBD_INSTALL_PRE"
5858

5959
# obdeploy install path. default /usr/obd/
60-
ENV_OBD_INSTALL_PATH = "OBD_INSTALL_PATH"
60+
ENV_OBD_INSTALL_PATH = "OBD_INSTALL_PATH"
61+
62+
# obd web idle minite time before shutdown. default 30
63+
# if you do not want to set idle time, you can set it to "infinity"
64+
ENV_IDLE_TIME_BEFORE_SHUTDOWN_MINITES = "IDLE_TIME_BEFORE_SHUTDOWN_MINITES"
65+
66+
# obdesktop/docker mock cluster id
67+
ENV_CUSTOM_CLUSTER_ID = "CUSTOM_CLUSTER_ID"
68+
69+
# obdeploy web type
70+
ENV_OBD_WEB_TYPE = "OBD_WEB_TYPE"

_errno.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ def __init__(self, code, msg):
3131
def __str__(self):
3232
return self.msg
3333

34+
def __bool__(self):
35+
return False
36+
3437

3538
class OBDErrorCodeTemplate(object):
3639

@@ -142,6 +145,7 @@ class InitDirFailedErrorMessage(object):
142145
WC_OBSERVER_SAME_DISK = OBDErrorCodeTemplate(1012, '({ip}) clog and data use the same disk ({disk})')
143146
WC_FAIL_TO_RESTART_OR_RELOAD = OBDErrorCodeTemplate(1021, 'The components has been {action}, but encountered problems when reloading or restarting. Details:\n{detail}')
144147
WC_FAIL_TO_RESTART_OR_RELOAD_AFTER_SCALE_OUT = OBDErrorCodeTemplate(1022, 'The cluster has been scaled out, but encountered problems when reloading or restarting. Details:\n{detail}')
148+
WC_CHANGE_SYSTEM_PARAMETER_FAILED = OBDErrorCodeTemplate(1023, '({server}) failed to change system parameter: {key})')
145149

146150
# error code for observer
147151
EC_OBSERVER_NOT_ENOUGH_MEMORY = OBDErrorCodeTemplate(2000, '({ip}) not enough memory. (Free: {free}, Need: {need})')
@@ -166,6 +170,8 @@ class InitDirFailedErrorMessage(object):
166170
EC_OBSERVER_GET_MEMINFO_FAIL = OBDErrorCodeTemplate(2011, "{server}: fail to get memory info.\nPlease configure 'memory_limit' manually in configuration file")
167171
EC_OBSERVER_FAIL_TO_START_OCS = OBDErrorCodeTemplate(2012, 'Failed to start {server} obshell')
168172
EC_OBSERVER_UNKONE_SCENARIO = OBDErrorCodeTemplate(2013, 'Unknown scenario: {scenario}')
173+
EC_CPU_NOT_SUPPORT_AVX = OBDErrorCodeTemplate(2014, "{server}'s cpu not support avx")
174+
EC_OBSERVER_DISABLE_AUTOSTART = OBDErrorCodeTemplate(2015, "{server}: Failed to modify the configuration of the automatic startup. Please check whether the current user has sudo permissions")
169175

170176
WC_OBSERVER_SYS_MEM_TOO_LARGE = OBDErrorCodeTemplate(2010, '({server}): system_memory too large. system_memory should be less than {factor} * memory_limit/memory_limit_percentage.')
171177

@@ -256,6 +262,9 @@ class InitDirFailedErrorMessage(object):
256262
EC_OBDIAG_OPTIONS_FORMAT_ERROR = OBDErrorCodeTemplate(6002, 'obdiag options {option} format error, please check the value : {value}')
257263
EC_OBDIAG_FUCYION_FAILED = OBDErrorCodeTemplate(6003, 'Failed to execute obdiag function {fuction}')
258264

265+
# obshell
266+
EC_OBSHELL_GENERAL_ERROR = OBDErrorCodeTemplate(6100, 'OBSHELL: {msg}')
267+
259268
# Unexpected exceptions code
260269
EC_UNEXPECTED_EXCEPTION = OBDErrorCodeTemplate(9999, 'Unexpected exception: need to be posted on "https://ask.oceanbase.com", and we will help you resolve them.')
261270

@@ -310,6 +319,6 @@ class InitDirFailedErrorMessage(object):
310319
SUG_OCP_SERVER_EXIST_METADB_TENANT_NOT_ENOUGH = OBDErrorSuggestionTemplate('Please reduce the ocp meta tenant memory or ocp monitor tenant memory')
311320
SUG_OCP_SERVER_NOT_EXIST_METADB_TENANT_NOT_ENOUGH = OBDErrorSuggestionTemplate('Please increase the meta db memory_limit and reduce the ocp meta tenant memory or ocp monitor tenant memory')
312321
SUG_OB_SYS_USERNAME = OBDErrorSuggestionTemplate('Please delete the "ob_sys_username" parameter.')
313-
SUG_OB_SYS_PASSWORD = OBDErrorSuggestionTemplate('''Please set the "ob_sys_password" for oblogproxy by configuring the "cdcro_password" parameter in the "oceanbase" or "oceanbase-ce" component.''')
322+
SUG_OB_SYS_PASSWORD = OBDErrorSuggestionTemplate('''Please set the "ob_sys_password" for oblogproxy by configuring the "cdcro_password" parameter in the "oceanbase" or "oceanbase-ce" or "oceanbase-standalone" component.''')
314323
SUG_OBAGENT_EDIT_HTTP_BASIC_AUTH_PASSWORD = OBDErrorSuggestionTemplate('Please edit the `http_basic_auth_password`, cannot contain characters other than uppercase letters, lowercase characters, digits, special characters:~^*{{}}[]_-+', fix_eval=[FixEval(FixEval.DEL, 'http_basic_auth_password')], auto_fix=True)
315324
SUB_OBSERVER_UNKONE_SCENARIO = OBDErrorSuggestionTemplate('Please select a valid scenario from the options: {scenarios}')

0 commit comments

Comments
 (0)