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
def push_environment(cluster: Cluster, path: Optional[str] = None): """Merges the environment on the cluster with the current environment. :param cluster: Cluster to push the environment to. :param path: Path to remote environment file. Default: Remote IDACT_CONFIG_PATH environment variable, or ~/.idact.conf """ log = get_logger(__name__) with stage_info(log, "Pushing the environment to cluster."): try: remote_environment = deserialize_environment_from_cluster( cluster=cluster, path=path) except RuntimeError: log.info("Remote environment is missing, current environment will" " be copied to cluster.") log.debug("Exception", exc_info=1) remote_environment = EnvironmentImpl() local_environment = EnvironmentProvider().environment merged_environment = merge_environments(local=remote_environment, remote=local_environment) serialize_environment_to_cluster(environment=merged_environment, cluster=cluster, path=path)
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)
def environment(self) -> Environment: """Returns the current environment. Tries to load it from file if there is none. """ if self._environment is None: new_environment = EnvironmentImpl() self._set_global_environment(new_environment) return self._environment
def deserialize_environment(text: str) -> Environment: """Loads the environment from string. :param text: Environment description. """ data = json.loads(text) client_config = deserialize_client_config_from_json(data) return EnvironmentImpl(config=client_config)
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)
def clear_environment(user: str): """Clears the environment, but does not add any clusters. :param user: User, whose home dir should be cleaned. """ # pylint: disable=protected-access saved_state = EnvironmentProvider._state EnvironmentProvider._state = None EnvironmentProvider(initial_environment=EnvironmentImpl()) set_log_level(logging.DEBUG) os.environ['IDACT_CONFIG_PATH'] = get_test_environment_file(user=user) try: yield finally: EnvironmentProvider._state = saved_state clear_home(user=user)
def merge_environments(local: Environment, remote: Environment) -> Environment: """Merges remote environment into local environment Replaces every entry for a given cluster, except machine-specific values, like key paths. Adds clusters present only in remote config. :param local: Local environment. :param remote: Remote environment. """ config = copy.deepcopy(local.config) merge_common_clusters(remote_clusters=remote.config.clusters, target_clusters=config.clusters) sanitize_and_add_new_clusters(remote_clusters=remote.config.clusters, target_clusters=config.clusters) return EnvironmentImpl(config=config)
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)
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__
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))