Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-148-extra-cli-commands cd5f233db -> cf08b4bf7 (forced update)
ARIA-148 Add CLI display commands Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/cf08b4bf Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/cf08b4bf Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/cf08b4bf Branch: refs/heads/ARIA-148-extra-cli-commands Commit: cf08b4bf7ae36f3a0748741a94db87f244314719 Parents: 29bc84b Author: Tal Liron <[email protected]> Authored: Thu Apr 20 17:54:47 2017 -0500 Committer: Tal Liron <[email protected]> Committed: Thu Apr 20 18:03:33 2017 -0500 ---------------------------------------------------------------------- aria/cli/commands/service_templates.py | 45 ++++++++++++++++++++++++----- aria/cli/commands/services.py | 30 +++++++++++++++++++ aria/cli/core/aria.py | 28 ++++++++++++++++-- aria/cli/helptexts.py | 7 ++++- aria/utils/collections.py | 2 +- tests/cli/test_service_templates.py | 4 +-- 6 files changed, 103 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/aria/cli/commands/service_templates.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands/service_templates.py b/aria/cli/commands/service_templates.py index 97367c2..438e07e 100644 --- a/aria/cli/commands/service_templates.py +++ b/aria/cli/commands/service_templates.py @@ -23,6 +23,8 @@ from .. import utils from ..core import aria from ...core import Core from ...storage import exceptions as storage_exceptions +from ...parser import consumption +from ...utils import (formatting, collections, console) DESCRIPTION_FIELD_LENGTH_LIMIT = 20 @@ -45,7 +47,7 @@ def service_templates(): @aria.pass_model_storage @aria.pass_logger def show(service_template_name, model_storage, logger): - """Show information for a specific service templates + """Show information for a specific service template `SERVICE_TEMPLATE_NAME` is the name of the service template to show information on. """ @@ -135,6 +137,7 @@ def store(service_template_path, service_template_name, service_template_filenam @aria.pass_logger def delete(service_template_name, model_storage, resource_storage, plugin_manager, logger): """Delete a service template + `SERVICE_TEMPLATE_NAME` is the name of the service template to delete. """ logger.info('Deleting service template {0}...'.format(service_template_name)) @@ -172,7 +175,7 @@ def validate(service_template, service_template_filename, model_storage, resource_storage, plugin_manager, logger): """Validate a service template - `SERVICE_TEMPLATE` is the path or url of the service template or archive to validate. + `SERVICE_TEMPLATE` is the path or URL of the service template or archive to validate. """ logger.info('Validating service template: {0}'.format(service_template)) service_template_path = service_template_utils.get(service_template, service_template_filename) @@ -181,21 +184,49 @@ def validate(service_template, service_template_filename, logger.info('Service template validated successfully') +@service_templates.command(name='display', + short_help='Display service template information') [email protected]('service-template-name') [email protected]() [email protected]_json [email protected]_yaml [email protected]_types [email protected]_model_storage [email protected]_logger +def display(service_template_name, model_storage, json, yaml, types, logger): + """Display information for a specific service template + + `SERVICE_TEMPLATE_NAME` is the name of the service template to display information on. + """ + logger.info('Displaying service template {0}...'.format(service_template_name)) + service_template = model_storage.service_template.get_by_name(service_template_name) + consumption.ConsumptionContext() + if types: + service_template.dump_types() + else: + if json: + console.puts(formatting.json_dumps(collections.prune(service_template.as_raw))) + elif yaml: + console.puts(formatting.yaml_dumps(collections.prune(service_template.as_raw))) + else: + service_template.dump() + + @service_templates.command(name='create-archive', - short_help='Create a csar archive') + short_help='Create a CSAR archive') @aria.argument('service-template-path') @aria.argument('destination') @aria.options.verbose() @aria.pass_logger def create_archive(service_template_path, destination, logger): - """Create a csar archive + """Create a CSAR archive `service_template_path` is the path of the service template to create the archive from - `destination` is the path of the output csar archive + `destination` is the path of the output CSAR archive """ - logger.info('Creating a csar archive') + logger.info('Creating a CSAR archive') csar.write(os.path.dirname(service_template_path), service_template_path, destination, logger) - logger.info('Csar archive created at {0}'.format(destination)) + logger.info('CSAR archive created at {0}'.format(destination)) def print_service_template_inputs(model_storage, service_template_name, logger): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/aria/cli/commands/services.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands/services.py b/aria/cli/commands/services.py index 50b530a..91e278b 100644 --- a/aria/cli/commands/services.py +++ b/aria/cli/commands/services.py @@ -25,6 +25,8 @@ from ..core import aria from ...core import Core from ...modeling import exceptions as modeling_exceptions from ...storage import exceptions as storage_exceptions +from ...parser import consumption +from ...utils import (formatting, collections, console) SERVICE_COLUMNS = ['id', 'name', 'service_template_name', 'created_at', 'updated_at'] @@ -177,3 +179,31 @@ def inputs(service_name, model_storage, logger): logger.info(inputs_string.getvalue()) else: logger.info('\tNo inputs') + + [email protected](name='display', + short_help='Display service information') [email protected]('service-name') [email protected]() [email protected]_json [email protected]_yaml [email protected]_graph [email protected]_model_storage [email protected]_logger +def display(service_name, model_storage, json, yaml, graph, logger): + """Display information for a specific service template + + `SERVICE_NAME` is the name of the service to display information on. + """ + logger.info('Displaying service {0}...'.format(service_name)) + service = model_storage.service.get_by_name(service_name) + consumption.ConsumptionContext() + if graph: + service.dump_graph() + else: + if json: + console.puts(formatting.json_dumps(collections.prune(service.as_raw))) + elif yaml: + console.puts(formatting.yaml_dumps(collections.prune(service.as_raw))) + else: + service.dump() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/aria/cli/core/aria.py ---------------------------------------------------------------------- diff --git a/aria/cli/core/aria.py b/aria/cli/core/aria.py index ed7c490..81c682a 100644 --- a/aria/cli/core/aria.py +++ b/aria/cli/core/aria.py @@ -281,12 +281,12 @@ def argument(*args, **kwargs): class Options(object): def __init__(self): - """The options api is nicer when you use each option by calling + """The options API is nicer when you use each option by calling `@aria.options.some_option` instead of `@aria.some_option`. Note that some options are attributes and some are static methods. The reason for that is that we want to be explicit regarding how - a developer sees an option. It it can receive arguments, it's a + a developer sees an option. If it can receive arguments, it's a method - if not, it's an attribute. """ self.version = click.option( @@ -325,6 +325,30 @@ class Options(object): default=defaults.SERVICE_TEMPLATE_FILENAME, help=helptexts.SERVICE_TEMPLATE_FILENAME) + self.display_json = click.option( + '-j', + '--json', + is_flag=True, + help=helptexts.DISPLAY_JSON) + + self.display_yaml = click.option( + '-y', + '--yaml', + is_flag=True, + help=helptexts.DISPLAY_YAML) + + self.display_types = click.option( + '-t', + '--types', + is_flag=True, + help=helptexts.DISPLAY_TYPES) + + self.display_graph = click.option( + '-g', + '--graph', + is_flag=True, + help=helptexts.DISPLAY_GRAPH) + @staticmethod def verbose(expose_value=False): return click.option( http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/aria/cli/helptexts.py ---------------------------------------------------------------------- diff --git a/aria/cli/helptexts.py b/aria/cli/helptexts.py index 1a3f6c0..51524b2 100644 --- a/aria/cli/helptexts.py +++ b/aria/cli/helptexts.py @@ -29,7 +29,7 @@ EXECUTION_ID = "The unique identifier for the execution" SERVICE_TEMPLATE_PATH = "The path to the application's service template file" SERVICE_TEMPLATE_FILENAME = ( "The name of the archive's main service template file. " - "This is only relevant if uploading a (non-csar) archive") + "This is only relevant if uploading a (non-CSAR) archive") INPUTS_PARAMS_USAGE = ( '(Can be provided as wildcard based paths ' '(*.yaml, /my_inputs/, etc..) to YAML files, a JSON string or as ' @@ -47,3 +47,8 @@ IGNORE_AVAILABLE_NODES = "Delete the service even if it has available nodes" SORT_BY = "Key for sorting the list" DESCENDING = "Sort list in descending order [default: False]" JSON_OUTPUT = "Output logs in a consumable JSON format" + +DISPLAY_JSON = "Display in JSON format" +DISPLAY_YAML = "Display in YAML format" +DISPLAY_TYPES = "Display only the type hierarchies" +DISPLAY_GRAPH = "Display only the node graph" http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/aria/utils/collections.py ---------------------------------------------------------------------- diff --git a/aria/utils/collections.py b/aria/utils/collections.py index 03feabd..1e732aa 100644 --- a/aria/utils/collections.py +++ b/aria/utils/collections.py @@ -249,7 +249,7 @@ def prune(value, is_removable_function=is_removable): else: prune(v, is_removable_function) elif isinstance(value, dict): - for k, v in value.iteritems(): + for k, v in value.items(): if is_removable_function(value, k, v): del value[k] else: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cf08b4bf/tests/cli/test_service_templates.py ---------------------------------------------------------------------- diff --git a/tests/cli/test_service_templates.py b/tests/cli/test_service_templates.py index 01b3f67..dd9eedd 100644 --- a/tests/cli/test_service_templates.py +++ b/tests/cli/test_service_templates.py @@ -238,9 +238,9 @@ class TestServiceTemplatesCreateArchive(TestCliBase): monkeypatch.setattr(_Environment, 'model_storage', mock_storage) self.invoke('service_templates create_archive stubpath stubdest') - assert 'Creating a csar archive' in self.logger_output_string + assert 'Creating a CSAR archive' in self.logger_output_string def test_create_archive_successful(self, monkeypatch, mock_object): monkeypatch.setattr(csar, 'write', mock_object) self.invoke('service_templates create_archive stubpath stubdest') - assert 'Csar archive created at stubdest' in self.logger_output_string + assert 'CSAR archive created at stubdest' in self.logger_output_string
