Skip to content

Commit bd5cd21

Browse files
committed
Add UserConfig
1 parent ed389fe commit bd5cd21

15 files changed

Lines changed: 222 additions & 279 deletions

node_cli/cli/node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
run_checks,
3838
)
3939
from node_cli.configs import DEFAULT_NODE_BASE_PORT
40-
from node_cli.configs.env import ALLOWED_ENV_TYPES
40+
from node_cli.configs.user import ALLOWED_ENV_TYPES
4141
from node_cli.utils.decorators import check_inited
4242
from node_cli.utils.helper import abort_if_false, streamed_cmd, IP_TYPE
4343
from node_cli.utils.texts import safe_load_texts

node_cli/configs/alias_address_validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ContractType(Enum):
3838
MANAGER = 'skale-manager'
3939

4040

41-
def validate_env_alias_or_address(
41+
def validate_alias_or_address(
4242
alias_or_address: str, contract_type: ContractType, endpoint: str
4343
) -> None:
4444
if is_contract_address(alias_or_address):
Lines changed: 19 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919

2020
import inspect
2121
import os
22-
from typing import Dict, List, NamedTuple
22+
from typing import Dict, NamedTuple
2323
from dataclasses import dataclass
2424
from abc import ABC
2525

2626
from dotenv.main import DotEnv
2727

2828
from node_cli.configs import SKALE_DIR, CONTAINER_CONFIG_PATH
29-
from node_cli.configs.alias_address_validation import validate_env_alias_or_address, ContractType
29+
from node_cli.configs.alias_address_validation import validate_alias_or_address, ContractType
3030
from node_cli.utils.node_type import NodeType
3131
from node_cli.utils.helper import error_exit
3232

@@ -46,7 +46,6 @@ class ValidationResult(NamedTuple):
4646
class BaseUserConfig(ABC):
4747
container_configs_stream: str
4848
endpoint: str
49-
sgx_server_url: str
5049
env_type: str
5150
filebeat_host: str
5251
disk_mountpoint: str
@@ -79,20 +78,21 @@ def validate_params(cls, params: Dict) -> ValidationResult:
7978
}
8079
missing = expected_keys - keys
8180
extra = keys - expected_keys - optional_keys
82-
print('HEREC', params, parameters.items())
8381
return ValidationResult(missing == set() and extra == set(), missing, extra)
8482

8583

8684
@dataclass
8785
class MirageUserConfig(BaseUserConfig):
8886
mirage_contracts: str
87+
sgx_server_url: str
8988
enforce_btrfs: str = ''
9089

9190

9291
@dataclass
9392
class MirageBootUserConfig(BaseUserConfig):
9493
manager_contracts: str
9594
ima_contracts: str
95+
sgx_server_url: str
9696
enforce_btrfs: str = ''
9797

9898

@@ -101,6 +101,7 @@ class SkaleUserConfig(BaseUserConfig):
101101
manager_contracts: str
102102
ima_contracts: str
103103
docker_lvmpy_stream: str
104+
sgx_server_url: str
104105
monitoring_containers: str = ''
105106
telegraf: str = ''
106107
influx_token: str = ''
@@ -120,90 +121,40 @@ class SyncUserConfig(BaseUserConfig):
120121
enforce_btrfs: str = ''
121122

122123

123-
CORE_REQUIRED_PARAMS: Dict[str, str] = {
124-
'CONTAINER_CONFIGS_STREAM': '',
125-
'ENDPOINT': '',
126-
'MANAGER_CONTRACTS': '',
127-
'DISK_MOUNTPOINT': '',
128-
'SGX_SERVER_URL': '',
129-
'ENV_TYPE': '',
130-
}
131-
132-
REQUIRED_PARAMS_SKALE: Dict[str, str] = {
133-
**CORE_REQUIRED_PARAMS,
134-
'IMA_CONTRACTS': '',
135-
'DOCKER_LVMPY_STREAM': '',
136-
'FILEBEAT_HOST': '',
137-
}
138-
139-
REQUIRED_PARAMS_MIRAGE_BOOT: Dict[str, str] = {
140-
**CORE_REQUIRED_PARAMS,
141-
'IMA_CONTRACTS': '',
142-
'FILEBEAT_HOST': '',
143-
}
144-
REQUIRED_PARAMS_MIRAGE: Dict[str, str] = {
145-
**CORE_REQUIRED_PARAMS,
146-
'FILEBEAT_HOST': '',
147-
}
148-
149-
REQUIRED_PARAMS_SYNC: Dict[str, str] = {
150-
**CORE_REQUIRED_PARAMS,
151-
'SCHAIN_NAME': '',
152-
'IMA_CONTRACTS': '',
153-
'DOCKER_LVMPY_STREAM': '',
154-
}
155-
156-
OPTIONAL_PARAMS: Dict[str, str] = {
157-
'MONITORING_CONTAINERS': '',
158-
'TELEGRAF': '',
159-
'INFLUX_TOKEN': '',
160-
'INFLUX_URL': '',
161-
'TG_API_KEY': '',
162-
'TG_CHAT_ID': '',
163-
'CONTAINER_CONFIGS_DIR': '',
164-
'DISABLE_DRY_RUN': '',
165-
'DEFAULT_GAS_LIMIT': '',
166-
'DEFAULT_GAS_PRICE_WEI': '',
167-
'SKIP_DOCKER_CONFIG': '',
168-
'ENFORCE_BTRFS': '',
169-
'SKIP_DOCKER_CLEANUP': '',
170-
}
171-
172-
173-
def absent_required_params(params: Dict[str, str]) -> List[str]:
174-
return [key for key in params if key not in OPTIONAL_PARAMS and not params[key]]
175-
176-
177124
def get_validated_user_config(
178125
node_type: NodeType,
179126
env_filepath: str = SKALE_DIR_ENV_FILEPATH,
180127
is_mirage_boot: bool = False,
181128
) -> BaseUserConfig:
182129
params = parse_env_file(env_filepath)
183-
UserConfigType = get_user_config_type(node_type, is_mirage_boot)
184-
_, missing_params, extra_params = UserConfigType.validate_params(params)
130+
user_config_type = get_user_config_type(node_type, is_mirage_boot)
131+
_, missing_params, extra_params = user_config_type.validate_params(params)
185132

186133
if len(missing_params) > 0:
187134
error_exit(f'Missing required parameters: {missing_params}')
188135

189136
if len(extra_params) > 0:
190137
error_exit(f'Extra parameters: {extra_params}')
191138

192-
validate_env_type(env_type=params['ENV_TYPE'])
193139
params = to_lower_keys(params)
194-
user_config = UserConfigType(**params)
140+
user_config = user_config_type(**params)
141+
validate_user_config(user_config)
195142

196-
if node_type == NodeType.MIRAGE and not is_mirage_boot:
143+
return user_config
144+
145+
146+
def validate_user_config(user_config: BaseUserConfig) -> None:
147+
validate_env_type(env_type=user_config.env_type)
148+
149+
if isinstance(user_config, MirageUserConfig):
197150
contract_alias_or_address = user_config.mirage_contracts
198151
else:
199-
contract_alias_or_address = params.get('MANAGER_CONTRACTS', '')
200152
contract_alias_or_address = user_config.manager_contracts
201-
validate_env_alias_or_address(contract_alias_or_address, ContractType.MANAGER, user_config.endpoint)
202153

203-
if 'IMA_CONTRACTS' in params:
204-
validate_env_alias_or_address(user_config.ima_contracts, ContractType.IMA, user_config.endpoint)
154+
validate_alias_or_address(contract_alias_or_address, ContractType.MANAGER, user_config.endpoint)
205155

206-
return user_config
156+
if isinstance(user_config, (SkaleUserConfig, MirageBootUserConfig)):
157+
validate_alias_or_address(user_config.ima_contracts, ContractType.IMA, user_config.endpoint)
207158

208159

209160
def to_lower_keys(params: Dict[str, str]) -> Dict[str, str]:

node_cli/core/host.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
NGINX_CONFIG_FILEPATH,
5151
)
5252
from node_cli.configs.cli_logger import LOG_DATA_PATH
53-
from node_cli.configs.env import SKALE_DIR_ENV_FILEPATH, CONFIGS_ENV_FILEPATH
53+
from node_cli.configs.user import SKALE_DIR_ENV_FILEPATH, CONFIGS_ENV_FILEPATH
5454
from node_cli.core.nftables import NFTablesManager
5555
from node_cli.utils.helper import safe_mkdir
5656

node_cli/core/node.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
TM_INIT_TIMEOUT,
4343
)
4444
from node_cli.cli import __version__
45-
from node_cli.configs.env import get_validated_user_config, SKALE_DIR_ENV_FILEPATH
45+
from node_cli.configs.user import get_validated_user_config, SKALE_DIR_ENV_FILEPATH
4646
from node_cli.configs.cli_logger import LOG_DATA_PATH as CLI_LOG_DATA_PATH
4747

4848
from node_cli.core.host import is_node_inited, save_env_params, get_flask_secret_key
@@ -173,7 +173,7 @@ def restore(backup_path, env_filepath, node_type: NodeType, no_snapshot=False, c
173173
restored_ok = restore_op(env, backup_path, node_type=node_type, config_only=config_only)
174174
if not restored_ok:
175175
error_exit('Restore operation failed', exit_code=CLIExitCodes.OPERATION_EXECUTION_ERROR)
176-
time.sleep(RESTORE_SLEEP_TIMEOUT)
176+
# time.sleep(RESTORE_SLEEP_TIMEOUT)
177177
logger.info('Generating resource allocation file ...')
178178
update_resource_allocation(env['ENV_TYPE'])
179179
print('Node is restored from backup')

node_cli/core/resources.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
import psutil
2626

27-
from node_cli.configs.env import get_validated_user_config
27+
from node_cli.configs.user import get_validated_user_config
2828
from node_cli.utils.docker_utils import ensure_volume
2929
from node_cli.utils.schain_types import SchainTypes
3030
from node_cli.utils.helper import write_json, read_json, run_cmd, safe_load_yml

node_cli/core/schains.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
SCHAIN_NODE_DATA_PATH,
1616
SCHAINS_MNT_DIR_SINGLE_CHAIN,
1717
)
18-
from node_cli.configs.env import get_validated_user_config
18+
from node_cli.configs.user import get_validated_user_config
1919

2020
from node_cli.utils.helper import get_request, error_exit, safe_load_yml
2121
from node_cli.utils.exit_codes import CLIExitCodes

node_cli/operations/base.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ def init_sync(
339339
meta_manager.update_meta(
340340
VERSION,
341341
env['CONTAINER_CONFIGS_STREAM'],
342-
env['DOCKER_LVMPY_STREAM'],
342+
None,
343343
distro.id(),
344344
distro.version(),
345345
)
@@ -449,8 +449,6 @@ def restore(env, backup_path, node_type: NodeType, config_only=False):
449449
distro.id(),
450450
distro.version(),
451451
)
452-
update_resource_allocation(env_type=env['ENV_TYPE'])
453-
454452
if not config_only:
455453
compose_up(env=env, node_type=node_type)
456454

tests/cli/node_test.py

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1919

2020
import pathlib
21-
2221
import mock
2322
from unittest.mock import MagicMock, patch
23+
2424
import requests
2525
import logging
26+
import pytest
2627

27-
from node_cli.configs import SKALE_DIR, G_CONF_HOME
28+
from node_cli.utils.node_type import NodeType
29+
30+
from node_cli.configs import INIT_ENV_FILEPATH, SKALE_DIR, G_CONF_HOME
2831
from node_cli.cli.node import (
2932
node_info,
3033
register_node,
@@ -321,14 +324,20 @@ def test_backup():
321324
assert 'Backup archive succesfully created ' in result.output
322325

323326

324-
def test_restore(mocked_g_config):
327+
@pytest.mark.parametrize("node_type,test_user_conf", [
328+
(NodeType.REGULAR, "regular_user_conf"),
329+
(NodeType.MIRAGE, "mirage_user_conf"),
330+
(NodeType.SYNC, "sync_user_conf")
331+
])
332+
def test_restore(request, node_type, test_user_conf, mocked_g_config, tmp_path):
325333
pathlib.Path(SKALE_DIR).mkdir(parents=True, exist_ok=True)
326-
result = run_command(backup_node, ['/tmp'])
334+
result = run_command(backup_node, [tmp_path])
327335
backup_path = result.output.replace('Backup archive successfully created: ', '').replace(
328336
'\n', ''
329337
)
330338

331339
with (
340+
patch('node_cli.cli.node.TYPE', node_type),
332341
patch('node_cli.core.node.restore_op', MagicMock()) as mock_restore_op,
333342
patch('subprocess.run', new=subprocess_run_mock),
334343
patch('node_cli.core.resources.get_disk_size', return_value=BIG_DISK_SIZE),
@@ -337,44 +346,20 @@ def test_restore(mocked_g_config):
337346
'node_cli.core.node.CliMetaManager.get_meta_info',
338347
return_value=CliMeta(version='2.4.0', config_stream='3.0.2'),
339348
),
340-
# patch(
341-
# 'node_cli.core.node.get_meta_info',
342-
# return_value=CliMeta(version='2.4.0', config_stream='3.0.2'),
343-
# ),
344349
patch('node_cli.operations.base.configure_nftables'),
345-
patch('node_cli.configs.env.validate_env_params'),
350+
patch('node_cli.configs.user.validate_alias_or_address'),
346351
):
347-
result = run_command(restore_node, [backup_path, './tests/test-env'])
352+
user_conf_path = request.getfixturevalue(test_user_conf).as_posix()
353+
354+
result = run_command(restore_node, [backup_path, user_conf_path])
348355
assert result.exit_code == 0
349356
assert 'Node is restored from backup\n' in result.output # noqa
357+
assert mock_restore_op.call_args[0][0].get('BACKUP_RUN') == 'True'
350358

351-
assert mock_restore_op.call_args[0][0].get('BACKUP_RUN') == 'True'
352-
353-
354-
def test_restore_no_snapshot(mocked_g_config):
355-
pathlib.Path(SKALE_DIR).mkdir(parents=True, exist_ok=True)
356-
result = run_command(backup_node, ['/tmp'])
357-
backup_path = result.output.replace('Backup archive successfully created: ', '').replace(
358-
'\n', ''
359-
)
360-
361-
with (
362-
patch('node_cli.core.node.restore_op', MagicMock()) as mock_restore_op,
363-
patch('subprocess.run', new=subprocess_run_mock),
364-
patch('node_cli.core.resources.get_disk_size', return_value=BIG_DISK_SIZE),
365-
patch('node_cli.utils.decorators.is_node_inited', return_value=False),
366-
patch(
367-
'node_cli.core.node.CliMetaManager.get_meta_info',
368-
return_value=CliMeta(version='2.4.0', config_stream='3.0.2'),
369-
),
370-
patch('node_cli.operations.base.configure_nftables'),
371-
patch('node_cli.configs.env.validate_env_params'),
372-
):
373-
result = run_command(restore_node, [backup_path, './tests/test-env', '--no-snapshot'])
359+
result = run_command(restore_node, [backup_path, user_conf_path, '--no-snapshot'])
374360
assert result.exit_code == 0
375361
assert 'Node is restored from backup\n' in result.output # noqa
376-
377-
assert mock_restore_op.call_args[0][0].get('BACKUP_RUN') is None
362+
assert mock_restore_op.call_args[0][0].get('BACKUP_RUN') is None
378363

379364

380365
def test_maintenance_on():
@@ -401,13 +386,15 @@ def test_maintenance_off(mocked_g_config):
401386
)
402387

403388

404-
def test_turn_off_maintenance_on(mocked_g_config):
389+
def test_turn_off_maintenance_on(mocked_g_config, regular_user_conf):
405390
resp_mock = response_mock(requests.codes.ok, {'status': 'ok', 'payload': None})
406391
with (
407392
mock.patch('subprocess.run', new=subprocess_run_mock),
393+
mock.patch('node_cli.core.node.INIT_ENV_FILEPATH', regular_user_conf.as_posix()),
408394
mock.patch('node_cli.core.node.turn_off_op'),
409395
mock.patch('node_cli.utils.decorators.is_node_inited', return_value=True),
410-
patch('node_cli.configs.env.validate_env_params'),
396+
mock.patch('node_cli.configs.user.validate_alias_or_address'),
397+
mock.patch('node_cli.cli.node.TYPE', NodeType.REGULAR)
411398
):
412399
result = run_command_mock(
413400
'node_cli.utils.helper.requests.post',
@@ -431,21 +418,21 @@ def test_turn_off_maintenance_on(mocked_g_config):
431418
assert result.exit_code == CLIExitCodes.UNSAFE_UPDATE
432419

433420

434-
def test_turn_on_maintenance_off(mocked_g_config):
421+
def test_turn_on_maintenance_off(mocked_g_config, regular_user_conf):
435422
resp_mock = response_mock(requests.codes.ok, {'status': 'ok', 'payload': None})
436423
with (
437424
mock.patch('subprocess.run', new=subprocess_run_mock),
438425
mock.patch('node_cli.core.node.get_flask_secret_key'),
439426
mock.patch('node_cli.core.node.turn_on_op'),
440427
mock.patch('node_cli.core.node.is_base_containers_alive'),
441428
mock.patch('node_cli.utils.decorators.is_node_inited', return_value=True),
442-
patch('node_cli.configs.env.validate_env_params'),
429+
patch('node_cli.configs.user.validate_alias_or_address'),
443430
):
444431
result = run_command_mock(
445432
'node_cli.utils.helper.requests.post',
446433
resp_mock,
447434
_turn_on,
448-
['./tests/test-env', '--maintenance-off', '--sync-schains', '--yes'],
435+
[regular_user_conf.as_posix(), '--maintenance-off', '--sync-schains', '--yes'],
449436
)
450437

451438
assert result.exit_code == 0

0 commit comments

Comments
 (0)