diff --git a/cli/main.py b/cli/main.py index 5a1fb1e72..7e2f9c218 100755 --- a/cli/main.py +++ b/cli/main.py @@ -83,6 +83,7 @@ root.addHandler(ch) fields = 'passphrase wallet signing tls skip_keys save_file'.split() PendingConfigurationDetails = collections.namedtuple('PendingConfigurationDetails', fields) +KEYRING_PASSPHRASE_ENVVAR = 'NUCYPHER_KEYRING_PASSPHRASE' class NucypherClickConfig: @@ -120,7 +121,7 @@ class NucypherClickConfig: config_root=self.config_root, auto_initialize=False) elif self.dev: - node_configuration = configuration_class(temp=self.dev, auto_initialize=False) + node_configuration = configuration_class(temp=self.dev, auto_initialize=False, federated_only=self.federated_only) elif self.config_file: click.echo("Using configuration file {}".format(self.config_file)) node_configuration = configuration_class.from_configuration_file(filepath=self.config_file) @@ -201,8 +202,8 @@ class NucypherClickConfig: if not any((generate_wallet, generate_tls_keys, generate_encrypting_keys)): skip_all_key_generation = click.confirm("Skip all key generation (Provide custom configuration file)?") if not skip_all_key_generation: - if os.environ.get("NUCYPHER_KEYRING_PASSPHRASE"): - passphrase = os.environ.get("NUCYPHER_KEYRING_PASSPHRASE") + if os.environ.get(KEYRING_PASSPHRASE_ENVVAR): + passphrase = os.environ.get(KEYRING_PASSPHRASE_ENVVAR) else: passphrase = click.prompt("Enter a passphrase to encrypt your keyring", hide_input=True, confirmation_prompt=True) @@ -227,6 +228,11 @@ class NucypherClickConfig: click.echo("Seed contract registry does not exist at path {}. " "Use --no-registry to skip.".format(registry_source)) raise click.Abort() + + if self.config_root: # Custom installation location + self.node_configuration.config_root = self.config_root + self.node_configuration.federated_only = self.federated_only + try: pending_config = self._collect_pending_configuration_details(force=force, ursula=ursula) new_installation_path = self.node_configuration.write(passphrase=pending_config.passphrase, @@ -370,9 +376,8 @@ def configure(config, is_valid = True # Until there is a reason to believe otherwise... try: if filesystem: # Check runtime directory - is_valid = NodeConfiguration.validate(config_root=config.node_configuration.config_root, no_registry=no_registry) - if config.config_file: - is_valid = validate_configuration_file(filepath=config.node_configuration.config_file_location) + is_valid = NodeConfiguration.validate(config_root=config.node_configuration.config_root, + no_registry=no_registry) except NodeConfiguration.InvalidConfiguration: is_valid = False finally: diff --git a/nucypher/config/node.py b/nucypher/config/node.py index e69bfd129..c089a12a6 100644 --- a/nucypher/config/node.py +++ b/nucypher/config/node.py @@ -10,7 +10,7 @@ from constant_sorrow import constants from nucypher.config.constants import DEFAULT_CONFIG_ROOT, BASE_DIR from nucypher.config.keyring import NucypherKeyring -from nucypher.config.storages import NodeStorage, InMemoryNodeStorage, LocalFileBasedNodeStorage +from nucypher.config.storages import NodeStorage, InMemoryNodeStorage from nucypher.crypto.powers import CryptoPowerUp from nucypher.network.middleware import RestMiddleware @@ -29,7 +29,7 @@ class NodeConfiguration: __CONFIG_FILE_DESERIALIZER = json.loads __TEMP_CONFIGURATION_DIR_PREFIX = "nucypher-tmp-" __DEFAULT_NETWORK_MIDDLEWARE_CLASS = RestMiddleware - __DEFAULT_NODE_STORAGE = LocalFileBasedNodeStorage + __DEFAULT_NODE_STORAGE = InMemoryNodeStorage __REGISTRY_NAME = 'contract_registry.json' REGISTRY_SOURCE = os.path.join(BASE_DIR, __REGISTRY_NAME) # TODO: #461 Where will this be hosted? diff --git a/tests/cli/test_config.py b/tests/cli/test_config.py index e57f2dbab..cf766b41c 100644 --- a/tests/cli/test_config.py +++ b/tests/cli/test_config.py @@ -7,43 +7,58 @@ from click.testing import CliRunner from cli.main import cli from nucypher.config.node import NodeConfiguration +from nucypher.utilities.sandbox.constants import TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD + + +TEST_CUSTOM_INSTALLATION_PATH = '/tmp/nucypher-tmp-test-custom' @pytest.fixture(scope='function') def custom_filepath(): - custom_filepath = '/tmp/nucypher-tmp-test-custom' + custom_filepath = TEST_CUSTOM_INSTALLATION_PATH yield custom_filepath with contextlib.suppress(FileNotFoundError): - shutil.rmtree(custom_filepath) + shutil.rmtree(custom_filepath, ignore_errors=True) -@pytest.mark.skip() -def test_initialize_configuration_directory(custom_filepath): +def test_initialize_configuration_files_and_directories(custom_filepath): runner = CliRunner() # Use the system temporary storage area - result = runner.invoke(cli, ['--dev', 'configure', 'install', '--no-registry'], input='Y', catch_exceptions=False) + args = ['--dev', '--federated-only', 'configure', 'install', '--ursula', '--force'] + result = runner.invoke(cli, args, + input='{}\n{}'''.format(TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD, + TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD), + catch_exceptions=False) assert '/tmp' in result.output, "Configuration not in system temporary directory" assert NodeConfiguration._NodeConfiguration__TEMP_CONFIGURATION_DIR_PREFIX in result.output assert result.exit_code == 0 - args = ['--config-root', custom_filepath, 'configure', 'install', '--no-registry'] - result = runner.invoke(cli, args, input='Y', catch_exceptions=False) - assert '[y/N]' in result.output, "'configure init' did not prompt the user before attempting to write files" - assert '/tmp' in result.output, "Configuration not in system temporary directory" + # Use a custom local filepath + args = ['--config-root', custom_filepath, '--federated-only', 'configure', 'install', '--ursula', '--force'] + result = runner.invoke(cli, args, + input='{}\n{}'''.format(TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD, + TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD), + catch_exceptions=False) + assert TEST_CUSTOM_INSTALLATION_PATH in result.output, "Configuration not in system temporary directory" assert 'Created' in result.output assert custom_filepath in result.output + assert "'nucypher-cli ursula run'" in result.output assert result.exit_code == 0 assert os.path.isdir(custom_filepath) # Ensure that there are not pre-existing configuration files at config_root - with pytest.raises(NodeConfiguration.ConfigurationError): - _result = runner.invoke(cli, args, input='Y', catch_exceptions=False) + _result = runner.invoke(cli, args, + input='{}\n{}'''.format(TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD, + TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD), + catch_exceptions=False) + assert "There are existing configuration files" in _result.output + # Destroy / Uninstall args = ['--config-root', custom_filepath, 'configure', 'destroy'] result = runner.invoke(cli, args, input='Y', catch_exceptions=False) assert '[y/N]' in result.output - assert '/tmp' in result.output, "Configuration not in system temporary directory" + assert TEST_CUSTOM_INSTALLATION_PATH in result.output, "Configuration not in system temporary directory" assert 'Deleted' in result.output assert custom_filepath in result.output assert result.exit_code == 0 diff --git a/tests/fixtures.py b/tests/fixtures.py index c2edfb1aa..b0f20fb71 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -1,3 +1,4 @@ +import contextlib import datetime import os import re @@ -37,10 +38,11 @@ from nucypher.utilities.sandbox.ursula import make_federated_ursulas, make_decen @pytest.fixture(scope="session", autouse=True) def cleanup(): yield # we've got a lot of men and women here... - for f in os.listdir(tempfile.tempdir): - if re.search(r'nucypher-*', f): - shutil.rmtree(os.path.join(tempfile.tempdir, f), - ignore_errors=True) + with contextlib.suppress(FileNotFoundError): + for f in os.listdir(tempfile.tempdir): + if re.search(r'nucypher-*', f): + shutil.rmtree(os.path.join(tempfile.tempdir, f), + ignore_errors=True) @pytest.fixture(scope="function")