You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/05/08 18:35:21 UTC
[15/15] incubator-ariatosca git commit: ARIA-148 Add CLI display
commands
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/57eeb716
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/57eeb716
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/57eeb716
Branch: refs/heads/ARIA-148-extra-cli-commands
Commit: 57eeb7162af01d5955dcc0ed443533682ed4c9d2
Parents: 0ec2370
Author: Tal Liron <ta...@gmail.com>
Authored: Thu Apr 20 17:54:47 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Mon May 8 13:34:46 2017 -0500
----------------------------------------------------------------------
aria/cli/commands/service_templates.py | 71 +++++++++++++++++++----------
aria/cli/commands/services.py | 52 ++++++++++++++++++++-
aria/cli/core/aria.py | 34 +++++++++++++-
aria/cli/helptexts.py | 8 +++-
aria/cli/table.py | 2 +-
aria/modeling/service_instance.py | 4 +-
aria/modeling/service_template.py | 2 +-
aria/modeling/types.py | 5 ++
aria/utils/collections.py | 2 +-
9 files changed, 146 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/cli/commands/service_templates.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/service_templates.py b/aria/cli/commands/service_templates.py
index 2537012..6e5b530 100644
--- a/aria/cli/commands/service_templates.py
+++ b/aria/cli/commands/service_templates.py
@@ -23,11 +23,13 @@ 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
SERVICE_TEMPLATE_COLUMNS = \
- ['id', 'name', 'description', 'main_file_name', 'created_at', 'updated_at']
+ ('id', 'name', 'description', 'main_file_name', 'created_at', 'updated_at')
@aria.group(name='service-templates')
@@ -43,32 +45,51 @@ def service_templates():
@aria.argument('service-template-name')
@aria.options.verbose()
@aria.pass_model_storage
+@aria.options.show_all
+@aria.options.show_types
+@aria.options.show_json
+@aria.options.show_yaml
@aria.pass_logger
-def show(service_template_name, model_storage, logger):
- """Show information for a specific service templates
+def show(service_template_name, model_storage, all, types, json, yaml, logger):
+ """Show information for a specific service template
`SERVICE_TEMPLATE_NAME` is the name of the service template to show information on.
"""
- logger.info('Showing service template {0}...'.format(service_template_name))
service_template = model_storage.service_template.get_by_name(service_template_name)
- service_template_dict = service_template.to_dict()
- service_template_dict['#services'] = len(service_template.services)
- column_formatters = \
- dict(description=table.trim_formatter_generator(DESCRIPTION_FIELD_LENGTH_LIMIT))
- columns = SERVICE_TEMPLATE_COLUMNS + ['#services']
- table.print_data(columns, service_template_dict, 'Service-template:',
- column_formatters=column_formatters, col_max_width=50)
-
- if service_template_dict['description'] is not None:
- logger.info('Description:')
- logger.info('{0}{1}'.format(service_template_dict['description'].encode('UTF-8') or '',
- os.linesep))
-
- if service_template.services:
- logger.info('Existing services:')
- for service in service_template.services:
- logger.info('\t{0}'.format(service.name))
+ if json or yaml:
+ all = True
+
+ if all:
+ consumption.ConsumptionContext()
+ 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()
+ elif types:
+ consumption.ConsumptionContext()
+ service_template.dump_types()
+ else:
+ logger.info('Showing service template {0}...'.format(service_template_name))
+ service_template_dict = service_template.to_dict()
+ service_template_dict['#services'] = len(service_template.services)
+ columns = SERVICE_TEMPLATE_COLUMNS + ('#services',)
+ column_formatters = \
+ dict(description=table.trim_formatter_generator(DESCRIPTION_FIELD_LENGTH_LIMIT))
+ table.print_data(columns, service_template_dict, 'Service-template:',
+ column_formatters=column_formatters, col_max_width=50)
+
+ if service_template_dict['description'] is not None:
+ logger.info('Description:')
+ logger.info('{0}{1}'.format(service_template_dict['description'].encode('UTF-8') or '',
+ os.linesep))
+
+ if service_template.services:
+ logger.info('Existing services:')
+ for service in service_template.services:
+ logger.info('\t{0}'.format(service.name))
@service_templates.command(name='list',
@@ -135,6 +156,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 +194,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)
@@ -188,11 +210,10 @@ def validate(service_template, service_template_filename,
@aria.options.verbose()
@aria.pass_logger
def create_archive(service_template_path, destination, logger):
- """Create a csar archive on the local file system
+ """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 file
+ `destination` is the path of the output CSAR archive
"""
logger.info('Creating a CSAR archive')
csar.write(os.path.dirname(service_template_path), service_template_path, destination, logger)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/cli/commands/services.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/services.py b/aria/cli/commands/services.py
index 50b530a..464c958 100644
--- a/aria/cli/commands/services.py
+++ b/aria/cli/commands/services.py
@@ -25,9 +25,12 @@ 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']
+DESCRIPTION_FIELD_LENGTH_LIMIT = 20
+SERVICE_COLUMNS = ('id', 'name', 'description', 'service_template_name' 'created_at', 'updated_at')
@aria.group(name='services')
@@ -38,6 +41,53 @@ def services():
pass
+@services.command(name='show',
+ short_help='Display service information')
+@aria.argument('service-name')
+@aria.options.verbose()
+@aria.options.show_all
+@aria.options.show_graph
+@aria.options.show_json
+@aria.options.show_yaml
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_name, model_storage, all, graph, json, yaml, logger):
+ """Show information for a specific service template
+
+ `SERVICE_NAME` is the name of the service to display information on.
+ """
+ logger.info('Showing service {0}...'.format(service_name))
+ service = model_storage.service.get_by_name(service_name)
+
+ if json or yaml:
+ all = True
+
+ if all:
+ consumption.ConsumptionContext()
+ 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()
+ elif graph:
+ consumption.ConsumptionContext()
+ service.dump_graph()
+ else:
+ logger.info('Showing service {0}...'.format(service_name))
+ service_dict = service.to_dict()
+ columns = SERVICE_COLUMNS
+ column_formatters = \
+ dict(description=table.trim_formatter_generator(DESCRIPTION_FIELD_LENGTH_LIMIT))
+ table.print_data(columns, service_dict, 'Service:',
+ column_formatters=column_formatters, col_max_width=50)
+
+ if service_dict['description'] is not None:
+ logger.info('Description:')
+ logger.info('{0}{1}'.format(service_dict['description'].encode('UTF-8') or '',
+ os.linesep))
+
+
@services.command(name='list', short_help='List services')
@aria.options.service_template_name()
@aria.options.sort_by()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/cli/core/aria.py
----------------------------------------------------------------------
diff --git a/aria/cli/core/aria.py b/aria/cli/core/aria.py
index ed6afa1..d303e16 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,36 @@ class Options(object):
default=defaults.SERVICE_TEMPLATE_FILENAME,
help=helptexts.SERVICE_TEMPLATE_FILENAME)
+ self.show_all = click.option(
+ '-a',
+ '--all',
+ is_flag=True,
+ help=helptexts.SHOW_ALL)
+
+ self.show_json = click.option(
+ '-j',
+ '--json',
+ is_flag=True,
+ help=helptexts.SHOW_JSON)
+
+ self.show_yaml = click.option(
+ '-y',
+ '--yaml',
+ is_flag=True,
+ help=helptexts.SHOW_YAML)
+
+ self.show_types = click.option(
+ '-t',
+ '--types',
+ is_flag=True,
+ help=helptexts.SHOW_TYPES)
+
+ self.show_graph = click.option(
+ '-g',
+ '--graph',
+ is_flag=True,
+ help=helptexts.SHOW_GRAPH)
+
@staticmethod
def verbose(expose_value=False):
return click.option(
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/cli/helptexts.py
----------------------------------------------------------------------
diff --git a/aria/cli/helptexts.py b/aria/cli/helptexts.py
index 8641822..f46bee0 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 '
@@ -48,3 +48,9 @@ SORT_BY = "Key for sorting the list"
DESCENDING = "Sort list in descending order [default: False]"
JSON_OUTPUT = "Output logs in a consumable JSON format"
MARK_PATTERN = "Mark a regex pattern in the logs"
+
+SHOW_ALL = "Show all information"
+SHOW_JSON = "Show in JSON format (implies --all)"
+SHOW_YAML = "Show in YAML format (implies --all)"
+SHOW_TYPES = "Show only the type hierarchies"
+SHOW_GRAPH = "Show only the node graph"
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/cli/table.py
----------------------------------------------------------------------
diff --git a/aria/cli/table.py b/aria/cli/table.py
index 408f81e..abc673e 100644
--- a/aria/cli/table.py
+++ b/aria/cli/table.py
@@ -85,7 +85,7 @@ def _generate(cols, data, column_formatters=None, defaults=None):
return val
else:
- return defaults[column]
+ return defaults.get(column) if defaults is not None else None
column_formatters = column_formatters or dict()
pretty_table = PrettyTable(list(cols))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index ad8e7ed..915f0f6 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -1011,7 +1011,7 @@ class SubstitutionBase(InstanceModelMixin):
@property
def as_raw(self):
return collections.OrderedDict((
- ('node_type_name', self.node_type_name),
+ ('node_type_name', self.node_type.name),
('mappings', formatting.as_raw_dict(self.mappings))))
def validate(self):
@@ -1119,7 +1119,7 @@ class SubstitutionMappingBase(InstanceModelMixin):
@property
def as_raw(self):
return collections.OrderedDict((
- ('name', self.name)))
+ ('name', self.name),))
def coerce_values(self, container, report_issues):
pass
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 7fab4fc..cea80c9 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -1042,7 +1042,7 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
@property
def as_raw(self):
return collections.OrderedDict((
- ('name', self.name)))
+ ('name', self.name),))
def coerce_values(self, container, report_issues):
pass
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/aria/modeling/types.py
----------------------------------------------------------------------
diff --git a/aria/modeling/types.py b/aria/modeling/types.py
index 06f171c..7460f47 100644
--- a/aria/modeling/types.py
+++ b/aria/modeling/types.py
@@ -22,6 +22,7 @@ from sqlalchemy import (
event
)
from sqlalchemy.ext import mutable
+from ruamel import yaml
from . import exceptions
@@ -206,6 +207,8 @@ class _StrictDict(object):
(_StrictDictMixin, _MutableDict),
{'_key_cls': key_cls, '_value_cls': value_cls}
)
+ yaml.representer.RoundTripRepresenter.add_representer(
+ listener_cls, yaml.representer.RoundTripRepresenter.represent_list)
self._strict_map[strict_dict_map_key] = _StrictValue(type_cls=strict_dict_cls,
listener_cls=listener_cls)
@@ -242,6 +245,8 @@ class _StrictList(object):
(_StrictListMixin, _MutableList),
{'_item_cls': item_cls}
)
+ yaml.representer.RoundTripRepresenter.add_representer(
+ listener_cls, yaml.representer.RoundTripRepresenter.represent_list)
self._strict_map[item_cls] = _StrictValue(type_cls=strict_list_cls,
listener_cls=listener_cls)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/57eeb716/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: