def test_get_external_ip_default_unknown_network(): unknown_domain = 'thisisnotarealdomain' # Without fleet sensor with pytest.raises(UnknownIPAddress): determine_external_ip_address(network=unknown_domain) # with fleet sensor sensor = FleetSensor(domain=unknown_domain) with pytest.raises(UnknownIPAddress): determine_external_ip_address(known_nodes=sensor, network=unknown_domain)
def test_get_external_ip_cascade_failure(mocker, mock_requests): first = mocker.patch('nucypher.utilities.networking.get_external_ip_from_known_nodes', return_value=None) second = mocker.patch('nucypher.utilities.networking.get_external_ip_from_default_teacher', return_value=None) third = mocker.patch('nucypher.utilities.networking.get_external_ip_from_centralized_source', return_value=None) sensor = FleetSensor(domain=MOCK_NETWORK) sensor.record_node(Dummy('0xdeadbeef')) sensor.record_fleet_state() with pytest.raises(UnknownIPAddress, match='External IP address detection failed'): determine_external_ip_address(network=MOCK_NETWORK, known_nodes=sensor) first.assert_called_once() second.assert_called_once() third.assert_called_once()
def perform_startup_ip_check(emitter: StdoutEmitter, ursula: Ursula, force: bool = False) -> None: """ Used on ursula startup to determine if the external IP address is consistent with the configuration's values. """ try: external_ip = determine_external_ip_address( network=ursula.domain, known_nodes=ursula.known_nodes) except UnknownIPAddress: message = 'Cannot automatically determine external IP address' emitter.message(message) return # TODO: crash, or not to crash... that is the question rest_host = ursula.rest_interface.host try: validate_worker_ip(worker_ip=rest_host) except InvalidWorkerIP: message = f'{rest_host} is not a valid or permitted worker IP address. Set the correct external IP then try again\n' \ f'automatic configuration -> nucypher ursula config ip-address\n' \ f'manual configuration -> nucypher ursula config --rest-host <IP ADDRESS>' emitter.message(message) return ip_mismatch = external_ip != rest_host if ip_mismatch and not force: error = f'\nX External IP address ({external_ip}) does not match configuration ({ursula.rest_interface.host}).\n' hint = f"Run 'nucypher ursula config ip-address' to reconfigure the IP address then try " \ f"again or use --no-ip-checkup to bypass this check (not recommended).\n" emitter.message(error, color='red') emitter.message(hint, color='yellow') raise click.Abort() else: emitter.message('✓ External IP matches configuration', 'green')
def collect_worker_ip_address(emitter: StdoutEmitter, network: str, force: bool = False) -> str: # From environment variable # TODO: remove this environment variable? ip = os.environ.get(NUCYPHER_ENVVAR_WORKER_IP_ADDRESS) if ip: message = f'Using IP address ({ip}) from {NUCYPHER_ENVVAR_WORKER_IP_ADDRESS} environment variable' emitter.message(message, verbosity=2) return ip # From node swarm try: message = f'Detecting external IP address automatically' emitter.message(message, verbosity=2) ip = determine_external_ip_address(network=network) except UnknownIPAddress: if force: raise emitter.message( 'Cannot automatically determine external IP address - input required' ) # Confirmation if not force: if not click.confirm(CONFIRM_URSULA_IPV4_ADDRESS.format(rest_host=ip)): ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP) validate_worker_ip(worker_ip=ip) return ip
def generate_config(self, emitter, config_root, force): if self.dev: raise RuntimeError( 'Persistent configurations cannot be created in development mode.' ) worker_address = self.worker_address if (not worker_address) and not self.federated_only: if not worker_address: prompt = "Select worker account" worker_address = select_client_account( emitter=emitter, prompt=prompt, provider_uri=self.provider_uri, signer_uri=self.signer_uri) rest_host = self.rest_host if not rest_host: rest_host = os.environ.get(NUCYPHER_ENVVAR_WORKER_IP_ADDRESS) if not rest_host: # TODO: Something less centralized... :-( # TODO: Ask Ursulas instead rest_host = determine_external_ip_address(emitter, force=force) return UrsulaConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root, rest_host=rest_host, rest_port=self.rest_port, db_filepath=self.db_filepath, domains=self.domains, federated_only=self.federated_only, worker_address=worker_address, registry_filepath=self.registry_filepath, provider_process=self.eth_node, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, poa=self.poa, light=self.light, availability_check=self.availability_check)
def collect_worker_ip_address(emitter: StdoutEmitter, network: str, force: bool = False) -> str: # From node swarm try: message = f'Detecting external IP address automatically' emitter.message(message, verbosity=2) ip = determine_external_ip_address(network=network) except UnknownIPAddress: if force: raise emitter.message('Cannot automatically determine external IP address - input required') ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP) # Confirmation if not force: if not click.confirm(CONFIRM_URSULA_IPV4_ADDRESS.format(rest_host=ip)): ip = click.prompt(COLLECT_URSULA_IPV4_ADDRESS, type=WORKER_IP) validate_worker_ip(worker_ip=ip) return ip