예제 #1
0
def test_environment_provider():
    """Creating and resetting the environment."""
    cluster1 = ClusterConfigImpl(host='host1',
                                 port=22,
                                 user='******',
                                 auth=AuthMethod.ASK)
    config = ClientConfig(clusters={'cluster1': cluster1})
    environment = EnvironmentImpl(config=config)

    EnvironmentProvider._state = None  # pylint: disable=protected-access
    environment_provider = EnvironmentProvider(initial_environment=environment)
    assert EnvironmentProvider._state == environment_provider.__dict__  # noqa, pylint: disable=protected-access,line-too-long
    assert environment_provider.environment is environment

    cluster2 = ClusterConfigImpl(host='host2',
                                 port=22,
                                 user='******',
                                 auth=AuthMethod.ASK)
    config2 = ClientConfig(clusters={'cluster2': cluster2})
    environment2 = EnvironmentImpl(config=config2)
    environment_provider2 = EnvironmentProvider(
        initial_environment=environment2)

    assert environment_provider2.environment is environment

    environment_provider2.environment = environment2
    assert environment_provider2.environment is environment2
    assert environment_provider.environment is environment2
    EnvironmentProvider._state = None  # pylint: disable=protected-access
예제 #2
0
def test_sanitize_cluster_config():
    cluster = ClusterConfigImpl(
        host='localhost1',
        port=1,
        user='******',
        auth=AuthMethod.ASK,
        key='key1',
        install_key=False,
        disable_sshd=True,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command1'],
            dask=['command2']),
        scratch='/scratch1')

    sanitized = sanitize_cluster_config(remote=cluster)

    # Cleared some fields.
    assert sanitized == ClusterConfigImpl(
        host='localhost1',
        port=1,
        user='******',
        auth=AuthMethod.ASK,
        key=None,
        install_key=True,
        disable_sshd=True,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command1'],
            dask=['command2']),
        scratch='/scratch1')
예제 #3
0
def test_client_config_deserialize():
    LoggerProvider().log_level = DEBUG
    input_json = {
        'clusters': {
            'cluster1': {
                'host': 'abc',
                'user': '******',
                'port': 22,
                'auth': 'ASK',
                'key': None,
                'installKey': True,
                'disableSshd': False,
                'setupActions': {
                    'jupyter': [],
                    'dask': []
                },
                'scratch': '$HOME',
                'retries': {}
            }
        },
        'logLevel': DEBUG
    }
    client_config = ClientConfig(clusters={
        'cluster1':
        ClusterConfigImpl(host='abc',
                          user='******',
                          port=22,
                          auth=AuthMethod.ASK)
    },
                                 log_level=DEBUG)

    deserialized = deserialize_client_config_from_json(input_json)
    pprint([i.__dict__ for i in deserialized.clusters.values()])
    assert deserialize_client_config_from_json(input_json) == client_config
def test_worker_deployment_script():
    config = ClusterConfigImpl(
        host='host',
        port=1234,
        user='******',
        auth=AuthMethod.ASK,
        setup_actions=SetupActionsConfigImpl(dask=['echo ABC', 'echo DEF']))
    script = get_scheduler_deployment_script(remote_port=1111,
                                             bokeh_port=2222,
                                             scratch_subdir='/scratch',
                                             log_file='/home/user/log',
                                             config=config)
    expected = (
        '#!/usr/bin/env bash\n'
        'echo ABC\n'
        'echo DEF\n'
        'export PATH="$PATH:$(python -m site --user-base)/bin"\n'
        'dask-scheduler --host 0.0.0.0 --port 1111 --bokeh --bokeh-port 2222'
        ' --no-show --local-directory /scratch'
        ' > /home/user/log 2>&1\n'
        'exit $?')
    print()
    print(repr(script))
    print(repr(expected))
    assert script == expected
def test_scheduler_deployment_script():
    config = ClusterConfigImpl(
        host='host',
        port=1234,
        user='******',
        auth=AuthMethod.ASK,
        setup_actions=SetupActionsConfigImpl(dask=['echo ABC',
                                                   'echo DEF']))
    script = get_worker_deployment_script(
        scheduler_address='tcp://localhost:1111/',
        bokeh_port=2222,
        scratch_subdir='/scratch',
        cores=12,
        memory_limit=bitmath.GiB(10),
        log_file='/home/user/log',
        config=config)
    expected = (
        '#!/usr/bin/env bash\n'
        'echo ABC\n'
        'echo DEF\n'
        'export PATH="$PATH:$(python -m site --user-base)/bin"\n'
        'dask-worker tcp://localhost:1111/ --host 0.0.0.0 --bokeh'
        ' --bokeh-port 2222 --nanny --reconnect --nprocs 1 --nthreads 12'
        ' --memory-limit 10737418240 --local-directory /scratch'
        ' > /home/user/log 2>&1\n'
        'exit $?')
    print()
    print(repr(script))
    print(repr(expected))
    assert script == expected
예제 #6
0
def test_client_cluster_config_validation_is_used():
    with pytest.raises(ValueError):
        ClusterConfigImpl(host='', port=22, user='******', auth=AuthMethod.ASK)
    with pytest.raises(ValueError):
        ClusterConfigImpl(host='abc',
                          port=-1,
                          user='******',
                          auth=AuthMethod.ASK)
    with pytest.raises(ValueError):
        ClusterConfigImpl(host='abc', port=22, user='', auth=AuthMethod.ASK)
    with pytest.raises(ValueError):
        ClusterConfigImpl(host='abc',
                          port=22,
                          user='******',
                          auth=AuthMethod.PUBLIC_KEY,
                          key='')
예제 #7
0
def reset_environment(user: str, auth: AuthMethod = AuthMethod.ASK):
    """Clears the environment and adds the testing cluster.

        :param user: User to connect to the cluster as,
                     and whose home dir should be cleaned.

        :param auth: Authentication method to use.

    """
    # pylint: disable=protected-access
    saved_state = EnvironmentProvider._state
    EnvironmentProvider._state = None

    os.environ['IDACT_KEY_LOCATION'] = get_test_key_location(user=user)
    os.environ['IDACT_CONFIG_PATH'] = get_test_environment_file(user=user)

    cluster = ClusterConfigImpl(host=get_testing_host(),
                                port=get_testing_port(),
                                user=user,
                                auth=auth,
                                retries=get_default_retries_heavy_load())
    cluster.retries[Retry.PORT_INFO] = set_retry(count=0)

    EnvironmentProvider(initial_environment=EnvironmentImpl(
        config=ClientConfig(clusters={TEST_CLUSTER: cluster})))
    set_log_level(DEBUG)
    try:
        yield
    finally:
        EnvironmentProvider._state = saved_state
        clear_home(user=user)
예제 #8
0
def deserialize_client_config_from_json(data: dict) -> ClientConfig:
    """Deserializes :class:`.ClientConfig` from json.

        :param data: json to deserialize.
    """
    log = get_logger(__name__)

    log.debug("Loaded config: %s", data)
    if use_defaults_in_missing_fields(data=data):
        log.debug("Filled missing fields with None: %s", data)

    clusters = {
        name: ClusterConfigImpl(host=value['host'],
                                port=value['port'],
                                user=value['user'],
                                auth=AuthMethod[value['auth']],
                                key=value['key'],
                                install_key=value['installKey'],
                                disable_sshd=value['disableSshd'],
                                setup_actions=SetupActionsConfigImpl(
                                    jupyter=value['setupActions']['jupyter'],
                                    dask=value['setupActions']['dask']),
                                scratch=value['scratch'],
                                notebook_defaults=value['notebookDefaults'],
                                retries=provide_defaults_for_retries(
                                    deserialize_retries(value['retries'])),
                                use_jupyter_lab=value['useJupyterLab'])
        for name, value in data['clusters'].items()
    }
    return ClientConfig(clusters=clusters, log_level=data['logLevel'])
예제 #9
0
def get_data_for_test():
    config = ClusterConfigImpl(host='localhost1',
                               port=1,
                               user='******',
                               auth=AuthMethod.ASK)

    uuid = 'uuid1'
    return config, uuid
예제 #10
0
def get_data_for_test():
    config = ClusterConfigImpl(host='localhost1',
                               port=1,
                               user='******',
                               auth=AuthMethod.ASK)
    access_node = NodeImpl(config=config)

    return config, access_node
def test_entry_point_disabled_sshd():
    config = ClusterConfigImpl(host='host',
                               port=123,
                               user='******',
                               auth=AuthMethod.PUBLIC_KEY,
                               disable_sshd=True)
    formatted = get_entry_point_script_contents(config=config)
    assert formatted == ("#!/usr/bin/env bash\n"
                         "trap : TERM INT; sleep infinity & wait")
예제 #12
0
def test_cluster_create():
    """Tests the construction of a cluster object from config."""
    client_cluster_config = ClusterConfigImpl(host='abc',
                                              port=22,
                                              user='******',
                                              auth=AuthMethod.ASK)
    ClusterImpl(name='cluster', config=client_cluster_config)

    assert str(client_cluster_config) == repr(client_cluster_config)
예제 #13
0
def test_third_try_succeeds_some_retries_with_config():
    failures = []
    config = ClusterConfigImpl(
        host='h',
        port=1,
        user='******',
        auth=AuthMethod.ASK,
        retries={Retry.PORT_INFO: RetryConfigImpl(count=3, seconds_between=0)})
    assert retry_with_config(
        fun=lambda: failing_task(fail_times=2, failures=failures),
        name=Retry.PORT_INFO,
        config=config) == 123
    assert failures == [0, 1]
예제 #14
0
def test_create_environment():
    """Creating the environment and adding a cluster."""
    cluster1 = ClusterConfigImpl(host='host1',
                                 port=22,
                                 user='******',
                                 auth=AuthMethod.ASK)
    config = ClientConfig(clusters={'cluster1': cluster1})
    environment = EnvironmentImpl(config=config)

    assert environment.config is config
    assert len(environment.config.clusters) == 1
    assert len(environment.clusters) == 1
    assert isinstance(environment.clusters['cluster1'], Cluster)

    cluster2 = ClusterConfigImpl(host='host2',
                                 port=22,
                                 user='******',
                                 auth=AuthMethod.ASK)
    environment.add_cluster(name='cluster2', config=cluster2)

    assert len(environment.config.clusters) == 2
    assert len(environment.clusters) == 2
    assert isinstance(environment.clusters['cluster2'], Cluster)
예제 #15
0
def get_data_for_test():
    config = ClusterConfigImpl(host='localhost1',
                               port=1,
                               user='******',
                               auth=AuthMethod.ASK)

    uuid = 'uuid1'

    deployment = GenericDeployment(node=NodeImpl(config=config),
                                   pid=111,
                                   runtime_dir='/dir1')
    serialized_deployment = deployment.serialize()

    return config, uuid, deployment, serialized_deployment
예제 #16
0
def test_client_cluster_config_create():
    config = ClusterConfigImpl(host='abc',
                               port=22,
                               user='******',
                               auth=AuthMethod.ASK)
    assert config.host == 'abc'
    assert config.port == 22
    assert config.user == 'user'
    assert config.auth == AuthMethod.ASK
    assert config.key is None
    assert config.install_key
    assert not config.disable_sshd
    assert config.setup_actions.jupyter == []
    assert config.setup_actions.dask == []
    assert config.scratch == "$HOME"
    assert config.retries == get_default_retries()
    assert config.use_jupyter_lab
예제 #17
0
def get_deployment_for_test(uuid: str, job_id: int) -> NodesImpl:
    config = ClusterConfigImpl(host='localhost1',
                               port=1,
                               user='******',
                               auth=AuthMethod.ASK)
    access_node = NodeImpl(config=config)

    nodes = [NodeImpl(config=config),
             NodeImpl(config=config)]
    deployment = NodesImpl(nodes=nodes,
                           allocation=SlurmAllocation(
                               job_id=job_id,
                               access_node=access_node,
                               nodes=nodes,
                               entry_point_script_path='a',
                               parameters=AllocationParameters()),
                           uuid=uuid)
    return deployment
예제 #18
0
def run_tunnel_test_for_bindings(user: str, bindings: List[Binding]):
    """Runs a tunneling test for a binding sequence.

        Runs a Python server in a separate thread through ssh, then creates
        a multi-hop tunnel, and finally performs a HTTP request to the local
        address.

        :param user: Test user.

        :param bindings: Sequence of tunnel bindings.

    """
    config = ClusterConfigImpl(host=get_testing_host(),
                               port=get_testing_port(),
                               user=user,
                               auth=AuthMethod.ASK)

    local_port = bindings[0].port
    server_port = bindings[-1].port

    with ExitStack() as stack:
        tunnel = build_tunnel(config=config,
                              bindings=bindings,
                              ssh_password=get_test_user_password(user))
        stack.enter_context(close_tunnel_on_exit(tunnel))

        server = start_dummy_server_thread(user=user, server_port=server_port)
        stack.enter_context(join_on_exit(server))

        assert tunnel.here == local_port
        assert tunnel.there == server_port

        def access_dummy_server():
            return requests.get(
                "http://127.0.0.1:{local_port}".format(local_port=local_port))

        request = retry(access_dummy_server,
                        retries=5 * get_testing_process_count(),
                        seconds_between_retries=2)
        assert "text/html" in request.headers['Content-type']
예제 #19
0
def test_client_config_create_empty_and_add_cluster():
    client_config = ClientConfig()
    assert client_config.clusters == {}

    cluster_cluster_config = VALID_CLIENT_CLUSTER_CONFIG
    with pytest.raises(ValueError):
        client_config.add_cluster(' Illegal Cluster Name',
                                  cluster_cluster_config)
    assert client_config.clusters == {}

    client_config.add_cluster('cluster1', cluster_cluster_config)
    assert client_config.clusters['cluster1'] is cluster_cluster_config

    with pytest.raises(ValueError):
        client_config.add_cluster(
            'cluster1',
            ClusterConfigImpl(host='another',
                              port=22,
                              user='******',
                              auth=AuthMethod.ASK))

    assert client_config.clusters['cluster1'] is cluster_cluster_config
def test_entry_point_sshd():
    config = ClusterConfigImpl(host='host',
                               port=123,
                               user='******',
                               auth=AuthMethod.PUBLIC_KEY,
                               disable_sshd=False)
    formatted = get_entry_point_script_contents(config=config)
    expected = (
        "#!/usr/bin/env bash\n"
        "SSHD_PORT=$(python -c 'import socket;"
        " s=socket.socket();"
        " s.bind((str(), 0)); print(s.getsockname()[1]);"
        " s.close()')\n"
        "mkdir -p ~/.idact/sshd_ports/alloc-$IDACT_ALLOCATION_ID\n"
        "chmod 700 ~/.idact/sshd_ports/alloc-$IDACT_ALLOCATION_ID\n"
        "touch ~/.idact/sshd_ports/alloc-$IDACT_ALLOCATION_ID/$(hostname):$SSHD_PORT\n"  # noqa, pylint: disable=line-too-long
        "export PATH=\"$PATH:/usr/sbin\"\n"
        " $(which sshd)"
        " -D "
        " -f /dev/null"
        " -oPort=$SSHD_PORT"
        " -oListenAddress=0.0.0.0"
        " -oHostKey=~/.ssh/ssh_host_rsa_key"
        " -oProtocol=2"
        " -oAllowUsers=$USER"
        " -oPermitRootLogin=no"
        " -oStrictModes=yes"
        " -oPubkeyAuthentication=yes"
        " -oAuthorizedKeysFile=.ssh/authorized_keys.idact"
        " -oPasswordAuthentication=no"
        " -oChallengeResponseAuthentication=no"
        " -oKerberosAuthentication=no"
        " -oGSSAPIAuthentication=no"
        " -oUsePAM=no"
        " -oSubsystem='sftp internal-sftp'"
        " -oX11Forwarding=yes\n"
        "exit $?")
    assert formatted == expected
예제 #21
0
def test_get_password():
    config = ClusterConfigImpl(
        host='host',
        port=1234,
        user='******',
        auth=AuthMethod.ASK)

    PasswordCache()._password = None  # pylint: disable=protected-access

    output = []

    def fake_getpass(prompt: str) -> str:
        output.append(prompt)
        return 'fakepass'

    saved_getpass = None
    try:
        saved_getpass = getpass.getpass
        getpass.getpass = fake_getpass
        assert get_password(config) == 'fakepass'
        assert output == ["Password for user@host:1234: "]
    finally:
        if saved_getpass is not None:
            getpass.getpass = saved_getpass
예제 #22
0
def add_cluster(name: str,
                user: str,
                host: str,
                port: int = 22,
                auth: Optional[AuthMethod] = None,
                key: Union[None, str, KeyType] = None,
                install_key: bool = True,
                disable_sshd: bool = False,
                setup_actions: Optional[SetupActionsConfig] = None,
                scratch: Optional[str] = None,
                retries: Optional[Dict[Retry, RetryConfig]] = None,
                use_jupyter_lab: bool = True) -> Cluster:
    """Adds a new cluster.

        :param name:
            Cluster name to identify it by.
        :param user:
            Remote cluster user to log in and run commands as.
        :param host:
            Cluster access node hostname.
        :param port:
            SSH port to access the cluster.
            Default: 22.
        :param auth:
            Authentication method.
            Default: :attr:`.AuthMethod.ASK` (password-based).
        :param key:
            Private key path (if applicable), or key type to generate.
            Default: None
        :param install_key:
            True, if the public key should be installed on the cluster before
            use (if applicable).
            Default: True
        :param disable_sshd:
            Should be set to True, if the cluster allows ssh connection
            to compute nodes out of the box.
            Default: False
        :param setup_actions:
            Commands to run before deployment.
            Default: None
        :param setup_actions:
            Commands to run before deployment.
            Default: None
        :param scratch:
            Absolute path to a high-performance filesystem for temporary
            computation data, or an environment variable that contains it.
            Default: $HOME
        :param retries:
            Retry config by action name.
            Defaults: see :func:`.get_default_retries`.
        :param use_jupyter_lab:
            Use Jupyter Lab instead of Jupyter Notebook.
            Default: True.
       """
    log = get_logger(__name__)
    environment = EnvironmentProvider().environment
    if auth is None:
        log.info("No auth method specified, defaulting to password-based.")
        auth = AuthMethod.ASK

    if auth is AuthMethod.PUBLIC_KEY:
        if isinstance(key, KeyType):
            log.info("Generating public-private key pair.")
            key = generate_key(host=host, key_type=key)
        elif isinstance(key, str):
            key = os.path.expanduser(key)
        else:
            raise ValueError("Invalid key argument for public key"
                             " authentication.")

    config = ClusterConfigImpl(host=host,
                               port=port,
                               user=user,
                               auth=auth,
                               key=key,
                               install_key=install_key,
                               disable_sshd=disable_sshd,
                               setup_actions=setup_actions,
                               scratch=scratch,
                               retries=retries,
                               use_jupyter_lab=use_jupyter_lab)
    return environment.add_cluster(name=name, config=config)
예제 #23
0
def test_merge_cluster_configs():
    cluster_1 = ClusterConfigImpl(host='localhost1',
                                  port=1,
                                  user='******',
                                  auth=AuthMethod.ASK,
                                  key='key1',
                                  install_key=False,
                                  disable_sshd=True,
                                  setup_actions=SetupActionsConfigImpl(
                                      jupyter=['command1'],
                                      dask=['command2']),
                                  scratch='/scratch1')

    cluster_2 = ClusterConfigImpl(host='localhost2',
                                  port=2,
                                  user='******',
                                  auth=AuthMethod.PUBLIC_KEY,
                                  key='key2',
                                  install_key=True,
                                  disable_sshd=False,
                                  setup_actions=SetupActionsConfigImpl(
                                      jupyter=['command3'],
                                      dask=['command4']),
                                  scratch='/scratch2')

    merged_1_2 = merge_cluster_configs(local=cluster_1,
                                       remote=cluster_2)

    merged_2_1 = merge_cluster_configs(local=cluster_2,
                                       remote=cluster_1)

    # Kept some fields from 1 after merge, replaced rest with 2.
    assert merged_1_2 == ClusterConfigImpl(
        host='localhost2',
        port=2,
        user='******',
        auth=AuthMethod.PUBLIC_KEY,
        key='key1',
        install_key=False,
        disable_sshd=False,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command3'],
            dask=['command4']),
        scratch='/scratch2')

    # Kept some fields from 2 after merge, replaced rest with 1.
    assert merged_2_1 == ClusterConfigImpl(
        host='localhost1',
        port=1,
        user='******',
        auth=AuthMethod.ASK,
        key='key2',
        install_key=True,
        disable_sshd=True,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command1'],
            dask=['command2']),
        scratch='/scratch1')

    # No changes.
    assert cluster_1 == ClusterConfigImpl(
        host='localhost1',
        port=1,
        user='******',
        auth=AuthMethod.ASK,
        key='key1',
        install_key=False,
        disable_sshd=True,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command1'],
            dask=['command2']),
        scratch='/scratch1')

    # No changes.
    assert cluster_2 == ClusterConfigImpl(
        host='localhost2',
        port=2,
        user='******',
        auth=AuthMethod.PUBLIC_KEY,
        key='key2',
        install_key=True,
        disable_sshd=False,
        setup_actions=SetupActionsConfigImpl(
            jupyter=['command3'],
            dask=['command4']),
        scratch='/scratch2')
예제 #24
0
def get_config_for_test():
    return ClusterConfigImpl(host='localhost1',
                             port=1,
                             user='******',
                             auth=AuthMethod.ASK)
예제 #25
0
def check_able_to_pull_environment(user: str,
                                   remote_environment_upload_path: str,
                                   remote_environment_pull_path: Optional[
                                       str]):
    with ExitStack() as stack:
        stack.enter_context(disable_pytest_stdin())
        stack.enter_context(reset_environment(user))
        stack.enter_context(set_password(get_test_user_password(user)))
        stack.enter_context(remove_remote_file(
            user=user,
            path=remote_environment_upload_path))

        cluster = show_cluster(name=TEST_CLUSTER)
        cluster.config.key = None
        cluster.config.install_key = False

        assert len(show_clusters()) == 1

        fake_cluster = 'fake cluster'
        remote_environment = EnvironmentImpl(
            config=ClientConfig(
                clusters={
                    TEST_CLUSTER: ClusterConfigImpl(
                        host=get_testing_host(),
                        port=get_testing_port(),
                        user=user,
                        auth=AuthMethod.ASK,
                        key='key_remote',
                        install_key=True),
                    fake_cluster: ClusterConfigImpl(
                        host='fakehost',
                        port=2,
                        user=user,
                        auth=AuthMethod.ASK,
                        key='key_remote',
                        install_key=True)}))

        remote_environment_serialized = serialize_environment(
            environment=remote_environment)

        node = cluster.get_access_node()
        assert isinstance(node, NodeInternal)

        put_file_on_node(node=node,
                         remote_path=remote_environment_upload_path,
                         contents=remote_environment_serialized)

        pull_environment(cluster=cluster,
                         path=remote_environment_pull_path)

        assert len(show_clusters()) == 2

        # Local key was kept unchanged.
        assert show_cluster(TEST_CLUSTER).config == ClusterConfigImpl(
            host=get_testing_host(),
            port=get_testing_port(),
            user=user,
            auth=AuthMethod.ASK,
            key=None,
            install_key=False)

        # New cluster was sanitized
        assert show_cluster(fake_cluster).config == ClusterConfigImpl(
            host='fakehost',
            port=2,
            user=user,
            auth=AuthMethod.ASK,
            key=None,
            install_key=True)
예제 #26
0
def check_able_to_merge_push_environment(
        user: str, remote_environment_upload_path: str,
        remote_environment_push_path: Optional[str]):
    with ExitStack() as stack:
        stack.enter_context(disable_pytest_stdin())
        stack.enter_context(reset_environment(user))
        stack.enter_context(set_password(get_test_user_password(user)))
        stack.enter_context(
            remove_remote_file(user=user, path=remote_environment_upload_path))

        cluster = show_cluster(name=TEST_CLUSTER)
        cluster.config.key = None
        cluster.config.install_key = False
        cluster.config.retries[Retry.PORT_INFO] = \
            get_default_retries_heavy_load()[Retry.PORT_INFO]

        assert len(show_clusters()) == 1
        node = cluster.get_access_node()
        assert isinstance(node, NodeInternal)

        # Upload an environment to be merged on push.
        initial_remote_environment = EnvironmentImpl(config=ClientConfig(
            clusters={
                TEST_CLUSTER:
                ClusterConfigImpl(host=get_testing_host(),
                                  port=123,
                                  user=user,
                                  auth=AuthMethod.ASK,
                                  key='key_remote',
                                  install_key=True)
            }))

        initial_remote_environment_serialized = serialize_environment(
            environment=initial_remote_environment)

        put_file_on_node(node=node,
                         remote_path=remote_environment_upload_path,
                         contents=initial_remote_environment_serialized)

        # Modify current environment.
        fake_cluster = 'fake cluster'
        add_cluster(name=fake_cluster,
                    host='fakehost',
                    port=2,
                    user=user,
                    auth=AuthMethod.ASK,
                    key='key_local',
                    install_key=False)

        # Push with merge.
        push_environment(cluster=cluster, path=remote_environment_push_path)

        remote_environment_after_push_serialized = \
            get_file_from_node(node=node,
                               remote_path=remote_environment_upload_path)

        remote_environment_after_push = deserialize_environment(
            text=remote_environment_after_push_serialized)

        # Remote key was kept unchanged.
        remote_clusters = remote_environment_after_push.config.clusters
        assert len(remote_clusters) == 2
        assert remote_clusters[TEST_CLUSTER].__dict__ == ClusterConfigImpl(
            host=get_testing_host(),
            port=get_testing_port(),
            user=user,
            auth=AuthMethod.ASK,
            key='key_remote',
            install_key=True,
            retries=get_default_retries_heavy_load()).__dict__

        # New cluster was sanitized
        assert remote_clusters[fake_cluster].__dict__ == ClusterConfigImpl(
            host='fakehost',
            port=2,
            user=user,
            auth=AuthMethod.ASK,
            key=None,
            install_key=True).__dict__
예제 #27
0
def check_able_to_push_new_environment(
        user: str, remote_environment_expected_path: str,
        remote_environment_push_path: Optional[str]):
    with ExitStack() as stack:
        stack.enter_context(disable_pytest_stdin())
        stack.enter_context(reset_environment(user))
        stack.enter_context(set_password(get_test_user_password(user)))
        stack.enter_context(
            remove_remote_file(user=user,
                               path=remote_environment_expected_path))

        cluster = show_cluster(name=TEST_CLUSTER)
        cluster.config.key = None
        cluster.config.install_key = False
        cluster.config.retries[Retry.PORT_INFO] = \
            get_default_retries_heavy_load()[Retry.PORT_INFO]

        assert len(show_clusters()) == 1
        node = cluster.get_access_node()
        assert isinstance(node, NodeInternal)

        # Modify current environment.
        fake_cluster = 'fake cluster'
        add_cluster(name=fake_cluster,
                    host='fakehost',
                    port=2,
                    user=user,
                    auth=AuthMethod.ASK,
                    key='key_local',
                    install_key=False)

        # Target file does not exist.
        with pytest.raises(RuntimeError):
            node.run("cat {}".format(remote_environment_expected_path))

        push_environment(cluster=cluster, path=remote_environment_push_path)

        remote_environment_after_push_serialized = \
            get_file_from_node(node=node,
                               remote_path=remote_environment_expected_path)

        remote_environment_after_push = deserialize_environment(
            text=remote_environment_after_push_serialized)

        # Both clusters were sanitized.
        remote_clusters = remote_environment_after_push.config.clusters
        assert len(remote_clusters) == 2
        assert remote_clusters[TEST_CLUSTER] == ClusterConfigImpl(
            host=get_testing_host(),
            port=get_testing_port(),
            user=user,
            auth=AuthMethod.ASK,
            key=None,
            install_key=True,
            retries=get_default_retries_heavy_load())

        assert remote_clusters[fake_cluster] == ClusterConfigImpl(
            host='fakehost',
            port=2,
            user=user,
            auth=AuthMethod.ASK,
            key=None,
            install_key=True)
예제 #28
0
def test_merge_common_clusters():
    auth = AuthMethod.PUBLIC_KEY
    target_clusters = {'a': ClusterConfigImpl(host='localhost1',
                                              port=1,
                                              user='******',
                                              auth=auth),
                       'b': ClusterConfigImpl(host='localhost2',
                                              port=2,
                                              user='******',
                                              auth=auth),
                       'c': ClusterConfigImpl(host='localhost3',
                                              port=3,
                                              user='******',
                                              auth=auth)}

    remote_clusters = {'b': ClusterConfigImpl(host='localhost4',
                                              port=4,
                                              user='******',
                                              auth=auth),
                       'c': ClusterConfigImpl(host='localhost5',
                                              port=5,
                                              user='******',
                                              auth=auth),
                       'd': ClusterConfigImpl(host='localhost6',
                                              port=6,
                                              user='******',
                                              auth=auth)}

    merge_common_clusters(remote_clusters=remote_clusters,
                          target_clusters=target_clusters)

    # Merged common clusters with remote.
    assert target_clusters == {'a': ClusterConfigImpl(host='localhost1',
                                                      port=1,
                                                      user='******',
                                                      auth=auth),
                               'b': ClusterConfigImpl(host='localhost4',
                                                      port=4,
                                                      user='******',
                                                      auth=auth),
                               'c': ClusterConfigImpl(host='localhost5',
                                                      port=5,
                                                      user='******',
                                                      auth=auth)}

    # No changes.
    assert remote_clusters == {'b': ClusterConfigImpl(host='localhost4',
                                                      port=4,
                                                      user='******',
                                                      auth=auth),
                               'c': ClusterConfigImpl(host='localhost5',
                                                      port=5,
                                                      user='******',
                                                      auth=auth),
                               'd': ClusterConfigImpl(host='localhost6',
                                                      port=6,
                                                      user='******',
                                                      auth=auth)}
예제 #29
0
def test_sanitize_new_clusters():
    auth = AuthMethod.PUBLIC_KEY
    target_clusters = {'a': ClusterConfigImpl(host='localhost1',
                                              port=1,
                                              user='******',
                                              auth=auth),
                       'b': ClusterConfigImpl(host='localhost2',
                                              port=2,
                                              user='******',
                                              auth=auth),
                       'c': ClusterConfigImpl(host='localhost3',
                                              port=3,
                                              user='******',
                                              auth=auth)}

    remote_clusters = {'b': ClusterConfigImpl(host='localhost4',
                                              port=4,
                                              user='******',
                                              auth=auth),
                       'c': ClusterConfigImpl(host='localhost5',
                                              port=5,
                                              user='******',
                                              auth=auth),
                       'd': ClusterConfigImpl(host='localhost6',
                                              port=6,
                                              user='******',
                                              auth=auth)}

    sanitize_and_add_new_clusters(remote_clusters=remote_clusters,
                                  target_clusters=target_clusters)

    # Added new cluster.
    assert target_clusters == {'a': ClusterConfigImpl(host='localhost1',
                                                      port=1,
                                                      user='******',
                                                      auth=auth),
                               'b': ClusterConfigImpl(host='localhost2',
                                                      port=2,
                                                      user='******',
                                                      auth=auth),
                               'c': ClusterConfigImpl(host='localhost3',
                                                      port=3,
                                                      user='******',
                                                      auth=auth),
                               'd': ClusterConfigImpl(host='localhost6',
                                                      port=6,
                                                      user='******',
                                                      auth=auth)}

    # No changes.
    assert remote_clusters == {'b': ClusterConfigImpl(host='localhost4',
                                                      port=4,
                                                      user='******',
                                                      auth=auth),
                               'c': ClusterConfigImpl(host='localhost5',
                                                      port=5,
                                                      user='******',
                                                      auth=auth),
                               'd': ClusterConfigImpl(host='localhost6',
                                                      port=6,
                                                      user='******',
                                                      auth=auth)}
예제 #30
0
def test_merge_environments():
    auth = AuthMethod.PUBLIC_KEY
    environment_1 = EnvironmentImpl(
        config=ClientConfig(clusters={'a': ClusterConfigImpl(host='localhost1',
                                                             port=1,
                                                             user='******',
                                                             auth=auth,
                                                             key='key1'),
                                      'b': ClusterConfigImpl(host='localhost2',
                                                             port=2,
                                                             user='******',
                                                             auth=auth,
                                                             key='key1'),
                                      'c': ClusterConfigImpl(host='localhost3',
                                                             port=3,
                                                             user='******',
                                                             auth=auth)},
                            log_level=10))
    environment_2 = EnvironmentImpl(
        config=ClientConfig(clusters={'b': ClusterConfigImpl(host='localhost4',
                                                             port=4,
                                                             user='******',
                                                             auth=auth,
                                                             key='key2'),
                                      'c': ClusterConfigImpl(host='localhost5',
                                                             port=5,
                                                             user='******',
                                                             auth=auth),
                                      'd': ClusterConfigImpl(host='localhost6',
                                                             port=6,
                                                             user='******',
                                                             auth=auth,
                                                             key='key2')},
                            log_level=20))

    merged_1_2 = merge_environments(local=environment_1,
                                    remote=environment_2)

    # Kept some fields from 1 after merge, replaced rest with 2.
    # Sanitized some fields for new clusters from 2.
    assert merged_1_2 == EnvironmentImpl(
        config=ClientConfig(clusters={'a': ClusterConfigImpl(host='localhost1',
                                                             port=1,
                                                             user='******',
                                                             auth=auth,
                                                             key='key1'),
                                      'b': ClusterConfigImpl(host='localhost4',
                                                             port=4,
                                                             user='******',
                                                             auth=auth,
                                                             key='key1'),
                                      'c': ClusterConfigImpl(host='localhost5',
                                                             port=5,
                                                             user='******',
                                                             auth=auth),
                                      'd': ClusterConfigImpl(host='localhost6',
                                                             port=6,
                                                             user='******',
                                                             auth=auth,
                                                             key=None)},
                            log_level=10))

    merged_2_1 = merge_environments(local=environment_2,
                                    remote=environment_1)

    # Kept some fields from 2 after merge, replaced rest with 1.
    # Sanitized some fields for new clusters from 1.
    assert merged_2_1 == EnvironmentImpl(
        config=ClientConfig(clusters={'a': ClusterConfigImpl(host='localhost1',
                                                             port=1,
                                                             user='******',
                                                             auth=auth,
                                                             key=None),
                                      'b': ClusterConfigImpl(host='localhost2',
                                                             port=2,
                                                             user='******',
                                                             auth=auth,
                                                             key='key2'),
                                      'c': ClusterConfigImpl(host='localhost3',
                                                             port=3,
                                                             user='******',
                                                             auth=auth),
                                      'd': ClusterConfigImpl(host='localhost6',
                                                             port=6,
                                                             user='******',
                                                             auth=auth,
                                                             key='key2')},
                            log_level=20))