def test_get_pipeline_model_with_bucket(self, mock): mock.get(mocked_url('pipeline/find?id={}'.format(self.pipeline_id)), text=mock_pipe(self.pipeline_id, self.pipeline_name, raw_date, self.v_1)) mock.get(mocked_url('datastorage/rule/load?pipelineId={}'.format( self.pipeline_id)), text=mock_pipeline_datastorage(self.pipeline_id, raw_date)) actual = Pipeline.get(self.pipeline_id, load_storage_rules=True, load_versions=False, load_run_parameters=False) expected = build_pipeline_model( identifier=self.pipeline_id, name=self.pipeline_name, storage_rules=[ build_storage_rule(self.pipeline_id, server_date, "bucket/1"), build_storage_rule(self.pipeline_id, server_date, "bucket/2") ]) assert actual.name == expected.name assert actual.identifier == expected.identifier assert actual.description == expected.description assert actual.created_date == expected.created_date assert actual.repository == expected.repository assert actual.versions == expected.versions assert_storage_rules(actual.storage_rules, expected.storage_rules)
def test_get_pipeline_model_with_versions(self, mock): mock.get(mocked_url('pipeline/find?id={}'.format(self.pipeline_id)), text=mock_pipe(self.pipeline_id, self.pipeline_name, raw_date, self.v_1)) mock.get(mocked_url('pipeline/{}/versions'.format(self.pipeline_id)), text=mock_versions(raw_date, self.v_1, self.v_2)) actual = Pipeline.get(self.pipeline_id, load_storage_rules=False, load_versions=True, load_run_parameters=False) expected = build_pipeline_model( identifier=self.pipeline_id, name=self.pipeline_name, current_version=build_version(self.v_1, server_date), current_version_name=self.v_1, versions=[ build_version(self.v_1, server_date), build_version(self.v_2, server_date) ]) assert actual.name == expected.name assert actual.identifier == expected.identifier assert actual.storage_rules == expected.storage_rules assert actual.description == expected.description assert actual.created_date == expected.created_date assert actual.current_version_name == expected.current_version_name assert_version(actual.current_version, expected.current_version) assert actual.repository == expected.repository assert len(actual.versions) == len(expected.versions) for (actual_version, expected_version) in zip(actual.versions, expected.versions): assert_version(actual_version, expected_version)
def test_launch_pipeline(self, mock): mock.post(mocked_url('run'), text=mock_run(self.pipeline_id, docker_image=self.docker_image, identifier=self.run_id)) actual = Pipeline.launch_pipeline(self.pipeline_id, self.v_1, [build_run_parameter()], self.docker_image, None, None) expected = build_run_model(identifier=self.run_id, status="SCHEDULED", pipeline="image", pipeline_id=self.pipeline_id, parameters=[build_run_parameter()]) assert actual.identifier == expected.identifier assert actual.status == expected.status assert actual.version == expected.version assert actual.pipeline == expected.pipeline assert actual.pipeline_id == expected.pipeline_id assert actual.parent_id == expected.parent_id assert actual.start_date == expected.start_date assert actual.end_date == expected.end_date assert actual.scheduled_date == expected.scheduled_date assert actual.tasks == expected.tasks assert actual.instance == expected.instance assert_run_parameter(actual.parameters, actual.parameters)
def test_get_pipeline_model_with_run_parameters(self, mock): mock.get(mocked_url('pipeline/find?id={}'.format(self.pipeline_id)), text=mock_pipe(self.pipeline_id, self.pipeline_name, raw_date, self.v_1)) mock.get(mocked_url('pipeline/{}/parameters?version={}'.format( self.pipeline_id, self.v_1)), text=mock_run_parameters(self.instance_disk, self.instance_type)) actual = Pipeline.get(self.pipeline_id, load_storage_rules=False, load_versions=False, load_run_parameters=True) expected = build_pipeline_model( identifier=self.pipeline_id, name=self.pipeline_name, current_version=build_version(self.v_1, server_date, run_parameters=build_run_parameters( self.v_1, parameters=[ build_run_parameter( value="param", parameter_type="input") ])), current_version_name=self.v_1) assert actual.name == expected.name assert actual.identifier == expected.identifier assert actual.storage_rules == expected.storage_rules assert actual.description == expected.description assert actual.created_date == expected.created_date assert actual.current_version_name == expected.current_version_name assert_version(actual.current_version, expected.current_version) assert actual.repository == expected.repository assert actual.versions == expected.versions
def view_all_runs(status, date_from, date_to, pipeline, parent_id, find, top): runs_table = prettytable.PrettyTable() runs_table.field_names = ["RunID", "Parent RunID", "Pipeline", "Version", "Status", "Started"] runs_table.align = "r" try: statuses = [] if status is not None: if status.upper() != 'ANY': for status_value in status.split(','): statuses.append(status_value.upper()) else: statuses.append('RUNNING') pipeline_id = None pipeline_version_name = None if pipeline is not None: pipeline_name_parts = pipeline.split('@') pipeline_model = Pipeline.get(pipeline_name_parts[0]) pipeline_id = pipeline_model.identifier pipeline_version_name = pipeline_model.current_version_name if len(pipeline_name_parts) > 1: pipeline_version_name = pipeline_name_parts[1] page = DEFAULT_PAGE_INDEX page_size = DEFAULT_PAGE_SIZE if top is not None: page = 1 page_size = top run_filter = PipelineRun.list(page=page, page_size=page_size, statuses=statuses, date_from=date_utilities.parse_date_parameter(date_from), date_to=date_utilities.parse_date_parameter(date_to), pipeline_id=pipeline_id, version=pipeline_version_name, parent_id=parent_id, custom_filter=find) if run_filter.total_count == 0: click.echo('No data is available for the request') else: if run_filter.total_count > run_filter.page_size: click.echo('Showing {} results from {}:'.format(run_filter.page_size, run_filter.total_count)) for run_model in run_filter.elements: runs_table.add_row([run_model.identifier, run_model.parent_id, run_model.pipeline, run_model.version, state_utilities.color_state(run_model.status), run_model.scheduled_date]) click.echo(runs_table) click.echo() except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def stop(cls, run_id, yes): if not yes: click.confirm('Are you sure you want to stop run {}?'.format(run_id), abort=True) try: pipeline_run_model = Pipeline.stop_pipeline(run_id) pipeline_name = pipeline_run_model.pipeline if not pipeline_name: try: pipeline_model = Pipeline.get(pipeline_run_model.pipeline_id, load_versions=False, load_storage_rules=False, load_run_parameters=False) pipeline_name = pipeline_model.name except RuntimeError: pass click.echo('RunID {} of "{}@{}" stopped'.format(run_id, pipeline_name, pipeline_run_model.version)) except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def test_price(self, mock): mock.post(mocked_url("pipeline/{}/price?version={}".format( self.pipeline_id, self.pipeline_name)), text=mock_price(self.instance_disk, self.instance_type)) actual = Pipeline.get_estimated_price(self.pipeline_id, self.pipeline_name, self.instance_type, self.instance_disk) expected = build_instance_price() assert actual.instance_type == expected.instance_type assert actual.instance_disk == expected.instance_disk assert actual.price_per_hour == expected.price_per_hour assert actual.minimum_time_price == expected.minimum_time_price assert actual.maximum_time_price == expected.maximum_time_price assert actual.average_time_price == expected.average_time_price
def test_get_pipeline_model(self, mock): mock.get(mocked_url('pipeline/find?id={}'.format(self.pipeline_id)), text=mock_pipe(self.pipeline_id, self.pipeline_name, raw_date, self.v_1)) actual = Pipeline.get(self.pipeline_id, load_storage_rules=False, load_versions=False, load_run_parameters=False) expected = build_pipeline_model(identifier=self.pipeline_id, name=self.pipeline_name) assert actual.name == expected.name assert actual.identifier == expected.identifier assert actual.storage_rules == expected.storage_rules assert actual.description == expected.description assert actual.created_date == expected.created_date assert actual.repository == expected.repository assert actual.versions == expected.versions
def view_acl(cls, identifier, object_type): """ View object permissions """ try: if object_type == 'pipeline': model = Pipeline.get(identifier, load_storage_rules=False, load_run_parameters=False, load_versions=False) identifier = model.identifier elif object_type == 'folder': model = Folder.load(identifier) identifier = model.id elif object_type == 'data_storage': model = DataStorage.get(identifier) identifier = model.identifier permissions_list = User.get_permissions(identifier, object_type) if len(permissions_list) > 0: permissions_table = prettytable.PrettyTable() permissions_table.field_names = [ "SID", "Principal", "Allow", "Deny" ] permissions_table.align = "r" for permission in permissions_list: permissions_table.add_row([ permission.name, permission.principal, permission.get_allowed_permissions_description(), permission.get_denied_permissions_description() ]) click.echo(permissions_table) click.echo() else: click.echo('No user permissions are configured') except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def view_all_pipes(): pipes_table = prettytable.PrettyTable() pipes_table.field_names = ["ID", "Name", "Latest version", "Created", "Source repo"] pipes_table.align = "r" try: pipelines = list(Pipeline.list()) if len(pipelines) > 0: for pipeline_model in pipelines: pipes_table.add_row([pipeline_model.identifier, pipeline_model.name, pipeline_model.current_version_name, pipeline_model.created_date, pipeline_model.repository]) click.echo(pipes_table) else: click.echo('No pipelines are available') except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def run(cls, pipeline, config, parameters, yes, run_params, instance_disk, instance_type, docker_image, cmd_template, timeout, quiet, instance_count, cores, sync, price_type=None): # All pipeline run parameters can be specified as options, e.g. --read1 /path/to/reads.fastq # In this case - runs_params_dict will contain keys-values for each option, e.g. {'--read1': '/path/to/reads.fastq'} # So they can be addressed with run_params_dict['--read1'] # This approach is used because we do not know parameters list beforehand run_params_dict = dict([(k.strip('-'), v) for k, v in zip(run_params[::2], run_params[1::2])]) # Calculate instance_type and instance_count if only cores specified if not instance_count and cores: nodes_spec = ClusterManager.calculate_cluster_from_cores(cores, core_type=instance_type) instance_count = nodes_spec["count"] if instance_count > 1: instance_count -= 1 else: instance_count = None instance_type = nodes_spec["name"] try: if pipeline: parts = pipeline.split('@') pipeline_name = parts[0] if not quiet: click.echo('Fetching pipeline info...', nl=False) pipeline_model = Pipeline.get( pipeline_name, load_versions=False, load_storage_rules=False, load_run_parameters=len(parts) == 1, config_name=config) if not quiet: click.echo('done.', nl=True) pipeline_run_parameters = pipeline_model.current_version.run_parameters if len(parts) > 1: if not quiet: click.echo('Fetching parameters...', nl=False) pipeline_run_parameters = Pipeline.load_run_parameters(pipeline_model.identifier, parts[1], config_name=config) if not quiet: click.echo('done.', nl=True) if parameters: cls.print_pipeline_parameters_info(pipeline_model, pipeline_run_parameters) else: if not quiet: click.echo('Evaluating estimated price...', nl=False) run_price = Pipeline.get_estimated_price(pipeline_model.identifier, pipeline_run_parameters.version, instance_type, instance_disk, config_name=config, price_type=price_type) click.echo('done.', nl=True) price_table = prettytable.PrettyTable() price_table.field_names = ["key", "value"] price_table.align = "l" price_table.set_style(12) price_table.header = False price_table.add_row(['Price per hour ({}, hdd {})'.format(run_price.instance_type, run_price.instance_disk), '{} $'.format(round(run_price.price_per_hour, 2))]) if run_price.minimum_time_price is not None and run_price.minimum_time_price > 0: price_table.add_row(['Minimum price', '{} $'.format(round(run_price.minimum_time_price, 2))]) if run_price.average_time_price is not None and run_price.average_time_price > 0: price_table.add_row(['Average price', '{} $'.format(round(run_price.average_time_price, 2))]) if run_price.maximum_time_price is not None and run_price.maximum_time_price > 0: price_table.add_row(['Maximum price', '{} $'.format(round(run_price.maximum_time_price, 2))]) click.echo() click.echo(price_table) click.echo() # Checking if user provided required parameters: wrong_parameters = False for parameter in pipeline_run_parameters.parameters: if parameter.required and not run_params_dict.get(parameter.name) and parameter.value is None: if not quiet: click.echo('"{}" parameter is required'.format(parameter.name), err=True) else: click.echo(parameter.name) sys.exit(1) wrong_parameters = True elif run_params_dict.get(parameter.name) is not None: parameter.value = run_params_dict.get(parameter.name) for user_parameter in run_params_dict.keys(): custom_parameter = True for parameter in pipeline_run_parameters.parameters: if parameter.name.lower() == user_parameter.lower(): custom_parameter = False break if custom_parameter: pipeline_run_parameters.parameters.append(PipelineRunParameterModel(user_parameter, run_params_dict.get( user_parameter), None, False)) if not wrong_parameters: if not yes: click.confirm('Are you sure you want to schedule a run of {}?'.format(pipeline), abort=True) pipeline_run_model = Pipeline.launch_pipeline(pipeline_model.identifier, pipeline_run_parameters.version, pipeline_run_parameters.parameters, instance_disk, instance_type, docker_image, cmd_template, timeout, config_name=config, instance_count=instance_count, price_type=price_type) pipeline_run_id = pipeline_run_model.identifier if not quiet: click.echo('"{}@{}" pipeline run scheduled with RunId: {}' .format(pipeline_model.name, pipeline_run_parameters.version, pipeline_run_id)) if sync: click.echo('Pipeline run {} completed with status {}' .format(pipeline_run_id, cls.get_pipeline_processed_status(pipeline_run_id))) else: click.echo(pipeline_run_id) if sync: click.echo(cls.get_pipeline_processed_status(pipeline_run_id)) elif parameters: if not quiet: click.echo('You must specify pipeline for listing parameters', err=True) elif docker_image is None or instance_type is None or instance_disk is None: if not quiet: click.echo('Docker image, instance type and instance disk are required parameters ' 'if pipeline was not provided.') else: required_parameters = [] if docker_image is None: required_parameters.append('docker_image') if instance_type is None: required_parameters.append('instance_type') if instance_disk is None: required_parameters.append('instance_disk') click.echo(', '.join(required_parameters)) sys.exit(1) else: if not yes: click.confirm('Are you sure you want to schedule a run?', abort=True) pipeline_run_model = Pipeline.launch_command(instance_disk, instance_type, docker_image, cmd_template, run_params_dict, timeout, instance_count=instance_count, price_type=price_type) pipeline_run_id = pipeline_run_model.identifier if not quiet: click.echo('Pipeline run scheduled with RunId: {}'.format(pipeline_run_id)) if sync: click.echo('Pipeline run {} completed with status {}' .format(pipeline_run_id, cls.get_pipeline_processed_status(pipeline_run_id))) else: click.echo(pipeline_run_id) if sync: click.echo(cls.get_pipeline_processed_status(pipeline_run_id)) except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) if quiet: sys.exit(2) except requests.exceptions.RequestException as http_error: if not quiet: click.echo('Http error: {}'.format(str(http_error)), err=True) else: click.echo(str(http_error), err=True) sys.exit(2) except RuntimeError as runtime_error: if not quiet: click.echo('Error: {}'.format(str(runtime_error)), err=True) else: click.echo(str(runtime_error), err=True) sys.exit(2) except ValueError as value_error: if not quiet: click.echo('Error: {}'.format(str(value_error)), err=True) else: click.echo(str(value_error), err=True) sys.exit(2)
def set_acl(cls, identifier, object_type, sid, group, allow, deny, inherit): """ Set object permissions """ try: if object_type == 'pipeline': model = Pipeline.get(identifier, load_storage_rules=False, load_run_parameters=False, load_versions=False) identifier = model.identifier elif object_type == 'folder': model = Folder.load(identifier) identifier = model.id elif object_type == 'data_storage': model = DataStorage.get(identifier) identifier = model.identifier all_permissions = User.get_permissions(identifier, object_type) user_permissions = filter( lambda permission: permission.name.lower() == sid.lower() and permission.principal != group, all_permissions) user_mask = 0 if len(user_permissions) == 1: user_mask = user_permissions[0].mask if allow is None and deny is None and inherit is None: raise RuntimeError('You must specify at least one permission') permissions_masks = { 'r': { 'allow': 1, 'deny': 1 << 1, 'inherit': 0, 'group': 1 | 1 << 1 }, 'w': { 'allow': 1 << 2, 'deny': 1 << 3, 'inherit': 0, 'group': 1 << 2 | 1 << 3 }, 'x': { 'allow': 1 << 4, 'deny': 1 << 5, 'inherit': 0, 'group': 1 << 4 | 1 << 5 } } def check_permission(permission): exists_in_allow = allow is not None and permission.lower( ) in allow.lower() exists_in_deny = deny is not None and permission.lower( ) in deny.lower() exists_in_inherit = inherit is not None and permission.lower( ) in inherit.lower() if exists_in_allow + exists_in_deny + exists_in_inherit > 1: raise RuntimeError( 'You cannot set permission (\'{}\') in multiple groups' .format(permission)) check_permission('r') check_permission('w') check_permission('x') def modify_permissions_group(mask, permissions_group_mask, permission_mask): permissions_clear_mask = (1 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5) ^ permissions_group_mask return (mask & permissions_clear_mask) | permission_mask def modify_permissions(mask, permissions_group_name, permissions): if permissions is not None: for permission in permissions: if permission.lower() not in permissions_masks: raise RuntimeError( 'Unknown permission \'{}\''.format(permission)) else: permissions_group_mask = permissions_masks[ permission.lower()]['group'] permission_mask = permissions_masks[ permission.lower()][permissions_group_name] mask = modify_permissions_group( mask, permissions_group_mask, permission_mask) return mask user_mask = modify_permissions(user_mask, 'allow', allow) user_mask = modify_permissions(user_mask, 'deny', deny) user_mask = modify_permissions(user_mask, 'inherit', inherit) User.grant_permission(identifier, object_type, sid, not group, user_mask) click.echo('Permissions set') except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def view_run(run_id, node_details, parameters_details, tasks_details): try: run_model = PipelineRun.get(run_id) if not run_model.pipeline and run_model.pipeline_id is not None: pipeline_model = Pipeline.get(run_model.pipeline_id) if pipeline_model is not None: run_model.pipeline = pipeline_model.name run_model_price = PipelineRun.get_estimated_price(run_id) run_main_info_table = prettytable.PrettyTable() run_main_info_table.field_names = ["key", "value"] run_main_info_table.align = "l" run_main_info_table.set_style(12) run_main_info_table.header = False run_main_info_table.add_row(['ID:', run_model.identifier]) run_main_info_table.add_row(['Pipeline:', run_model.pipeline]) run_main_info_table.add_row(['Version:', run_model.version]) if run_model.owner is not None: run_main_info_table.add_row(['Owner:', run_model.owner]) if run_model.endpoints is not None and len(run_model.endpoints) > 0: endpoint_index = 0 for endpoint in run_model.endpoints: if endpoint_index == 0: run_main_info_table.add_row(['Endpoints:', endpoint]) else: run_main_info_table.add_row(['', endpoint]) endpoint_index = endpoint_index + 1 if not run_model.scheduled_date: run_main_info_table.add_row(['Scheduled', 'N/A']) else: run_main_info_table.add_row(['Scheduled:', run_model.scheduled_date]) if not run_model.start_date: run_main_info_table.add_row(['Started', 'N/A']) else: run_main_info_table.add_row(['Started:', run_model.start_date]) if not run_model.end_date: run_main_info_table.add_row(['Completed', 'N/A']) else: run_main_info_table.add_row(['Completed:', run_model.end_date]) run_main_info_table.add_row(['Status:', state_utilities.color_state(run_model.status)]) run_main_info_table.add_row(['ParentID:', run_model.parent_id]) if run_model_price.total_price > 0: run_main_info_table.add_row(['Estimated price:', '{} $'.format(round(run_model_price.total_price, 2))]) else: run_main_info_table.add_row(['Estimated price:', 'N/A']) click.echo(run_main_info_table) click.echo() if node_details: node_details_table = prettytable.PrettyTable() node_details_table.field_names = ["key", "value"] node_details_table.align = "l" node_details_table.set_style(12) node_details_table.header = False for key, value in run_model.instance: if key == PriceType.SPOT: node_details_table.add_row(['price-type', PriceType.SPOT if value else PriceType.ON_DEMAND]) else: node_details_table.add_row([key, value]) echo_title('Node details:') click.echo(node_details_table) click.echo() if parameters_details: echo_title('Parameters:') if len(run_model.parameters) > 0: for parameter in run_model.parameters: click.echo('{}={}'.format(parameter.name, parameter.value)) else: click.echo('No parameters are configured') click.echo() if tasks_details: echo_title('Tasks:', line=False) if len(run_model.tasks) > 0: tasks_table = prettytable.PrettyTable() tasks_table.field_names = ['Task', 'State', 'Scheduled', 'Started', 'Finished'] tasks_table.align = "r" for task in run_model.tasks: scheduled = 'N/A' started = 'N/A' finished = 'N/A' if task.created is not None: scheduled = task.created if task.started is not None: started = task.started if task.finished is not None: finished = task.finished tasks_table.add_row( [task.name, state_utilities.color_state(task.status), scheduled, started, finished]) click.echo(tasks_table) else: click.echo('No tasks are available for run') click.echo() except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except RuntimeError as runtime_error: click.echo('Error: {}'.format(str(runtime_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)
def view_pipe(pipeline, versions, parameters, storage_rules, permissions): try: pipeline_model = Pipeline.get(pipeline, storage_rules, versions, parameters) pipe_table = prettytable.PrettyTable() pipe_table.field_names = ["key", "value"] pipe_table.align = "l" pipe_table.set_style(12) pipe_table.header = False pipe_table.add_row(['ID:', pipeline_model.identifier]) pipe_table.add_row(['Name:', pipeline_model.name]) pipe_table.add_row(['Latest version:', pipeline_model.current_version_name]) pipe_table.add_row(['Created:', pipeline_model.created_date]) pipe_table.add_row(['Source repo:', pipeline_model.repository]) pipe_table.add_row(['Description:', pipeline_model.description]) click.echo(pipe_table) click.echo() if parameters and pipeline_model.current_version is not None and pipeline_model.current_version.run_parameters is not None: echo_title('Parameters:', line=False) if len(pipeline_model.current_version.run_parameters.parameters) > 0: parameters_table = prettytable.PrettyTable() parameters_table.field_names = ["Name", "Type", "Mandatory", "Default value"] parameters_table.align = "l" for parameter in pipeline_model.current_version.run_parameters.parameters: parameters_table.add_row( [parameter.name, parameter.parameter_type, parameter.required, parameter.value]) click.echo(parameters_table) click.echo() else: click.echo('No parameters are available for current version') if versions: echo_title('Versions:', line=False) if len(pipeline_model.versions) > 0: versions_table = prettytable.PrettyTable() versions_table.field_names = ["Name", "Created", "Draft"] versions_table.align = "r" for version_model in pipeline_model.versions: versions_table.add_row([version_model.name, version_model.created_date, version_model.draft]) click.echo(versions_table) click.echo() else: click.echo('No versions are configured for pipeline') if storage_rules: echo_title('Storage rules', line=False) if len(pipeline_model.storage_rules) > 0: storage_rules_table = prettytable.PrettyTable() storage_rules_table.field_names = ["File mask", "Created", "Move to STS"] storage_rules_table.align = "r" for rule in pipeline_model.storage_rules: storage_rules_table.add_row([rule.file_mask, rule.created_date, rule.move_to_sts]) click.echo(storage_rules_table) click.echo() else: click.echo('No storage rules are configured for pipeline') if permissions: permissions_list = User.get_permissions(pipeline_model.identifier, 'pipeline') echo_title('Permissions', line=False) if len(permissions_list) > 0: permissions_table = prettytable.PrettyTable() permissions_table.field_names = ["SID", "Principal", "Allow", "Deny"] permissions_table.align = "r" for permission in permissions_list: permissions_table.add_row([permission.name, permission.principal, permission.get_allowed_permissions_description(), permission.get_denied_permissions_description()]) click.echo(permissions_table) click.echo() else: click.echo('No user permissions are configured for pipeline') except ConfigNotFoundError as config_not_found_error: click.echo(str(config_not_found_error), err=True) except RuntimeError as error: click.echo(str(error), err=True) except requests.exceptions.RequestException as http_error: click.echo('Http error: {}'.format(str(http_error)), err=True) except ValueError as value_error: click.echo('Error: {}'.format(str(value_error)), err=True)