[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-11 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115934893
  
--- Diff: aria/cli/core/aria.py ---
@@ -40,16 +41,8 @@
 
 
 class MutuallyExclusiveOption(click.Option):
-"""Makes options mutually exclusive. The option must pass a `cls` 
argument
-with this class name and a `mutually_exclusive` argument with a list of
-argument names it is mutually exclusive with.
-
-NOTE: All mutually exclusive options must use this. It's not enough to
-use it in just one of the options.
-"""
-
 def __init__(self, *args, **kwargs):
-self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutually_exclusive = kwargs.pop('mutually_exclusive', tuple())
--- End diff --

why change this from a set to another type?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-11 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115934648
  
--- Diff: aria/cli/core/aria.py ---
@@ -325,6 +339,46 @@ def __init__(self):
 default=defaults.SERVICE_TEMPLATE_FILENAME,
 help=helptexts.SERVICE_TEMPLATE_FILENAME)
 
+self.show_full = click.option(
+'-f',
+'--full',
+'mode',
+is_flag=True,
+flag_value='full',
--- End diff --

I think I don't like this approach as much at the previous one.
It seems like it simplifies the code a bit but makes things somewhat more 
confusing to the user - specifically the fact that only the last flag of a 
given "destination" (e.g. `mode`) takes hold.

If instead you have different destinations for these flags, it'd be easier 
to inform the user of misuse (even if for some reason the mutually-exclusive 
mechanism is problematic to use, you can always just manually validate the 
parameters in the command function itself)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-11 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115935686
  
--- Diff: aria/cli/core/aria.py ---
@@ -65,15 +58,33 @@ def __init__(self, *args, **kwargs):
 super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
 
 def handle_parse_result(self, ctx, opts, args):
-if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+if (self.name in opts) and 
self.mutually_exclusive.keys().intersection(opts):
 raise click.UsageError(
 'Illegal usage: `{0}` is mutually exclusive with '
 'arguments: [{1}] ({2}).'.format(
 self.name,
 self.mutuality_string,
 self.mutuality_error_message))
-return super(MutuallyExclusiveOption, self).handle_parse_result(
-ctx, opts, args)
+return super(MutuallyExclusiveOption, 
self).handle_parse_result(ctx, opts, args)
+
+
+def mutually_exclusive_option(*param_decls, **attrs):
+"""
+Makes options mutually exclusive. The decorator must pass a a 
``mutually_exclusive`` argument
+with a list of argument names with which the option is mutually 
exclusive.
+
+NOTE: All mutually exclusive options must use this. It's not enough to 
use it in just one of the
+options.
+"""
+def decorator(func):
+if 'help' in attrs:
--- End diff --

could you please document this func a bit more?
I'm not sure what are `param_decls` and `attrs` in this case, why `help` is 
being inspected, and why the internal `__click_params__` is accessed directly 
here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-11 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115935090
  
--- Diff: aria/cli/core/aria.py ---
@@ -65,15 +58,33 @@ def __init__(self, *args, **kwargs):
 super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
 
 def handle_parse_result(self, ctx, opts, args):
-if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+if (self.name in opts) and 
self.mutually_exclusive.keys().intersection(opts):
 raise click.UsageError(
 'Illegal usage: `{0}` is mutually exclusive with '
 'arguments: [{1}] ({2}).'.format(
 self.name,
 self.mutuality_string,
 self.mutuality_error_message))
-return super(MutuallyExclusiveOption, self).handle_parse_result(
-ctx, opts, args)
+return super(MutuallyExclusiveOption, 
self).handle_parse_result(ctx, opts, args)
+
+
+def mutually_exclusive_option(*param_decls, **attrs):
+"""
+Makes options mutually exclusive. The decorator must pass a a 
``mutually_exclusive`` argument
--- End diff --

a a a a a


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-11 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115934967
  
--- Diff: aria/cli/core/aria.py ---
@@ -65,15 +58,33 @@ def __init__(self, *args, **kwargs):
 super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
 
 def handle_parse_result(self, ctx, opts, args):
-if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+if (self.name in opts) and 
self.mutually_exclusive.keys().intersection(opts):
--- End diff --

seems like `mutually_exclusive` might be a `tuple` now, so `.keys()` would 
raise an error here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-10 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115728444
  
--- Diff: aria/cli/commands/services.py ---
@@ -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
--- End diff --

i actually didnt mean the flag but only the variables etc.,
although now that i think of it it might also be better to change the flag, 
as it might be confusing i.e. users might think it will show all 
service-templates or so..?
in any case what matters to me more is the variables, the flag can still be 
`all` to the user, but the "destination" of the variable (configurable in 
`aria.py`) should be renamed.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-10 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115726284
  
--- Diff: aria/cli/table.py ---
@@ -85,7 +85,7 @@ def get_values_per_column(column, row_data):
 
 return val
 else:
-return defaults[column]
+return defaults.get(column) if defaults is not None else None
--- End diff --

should instead have a `defaults = defaults or {}` before calling the nested 
method


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-10 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r115726390
  
--- Diff: aria/cli/commands/services.py ---
@@ -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
--- End diff --

i'd rename the flag, it's both unclear and a python keyword. `show_all` or 
`all_info` might be better.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #130: ARIA-62 Apply pylint on extensions

2017-05-10 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/130

ARIA-62 Apply pylint on extensions



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-62-apply-pylint-on-extensions

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/130.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #130


commit 0af9e638b7c75eea6eac39374b7176f9dc2c645a
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-05-10T09:08:01Z

ARIA-62 Apply pylint on extensions




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115498822
  
--- Diff: tests/cli/test_service_templates.py ---
@@ -244,3 +258,13 @@ 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
+
+def test_create_archive_from_relative_path(self, monkeypatch, 
mock_object):
+
+monkeypatch.setattr(os.path, 'isfile', lambda x: True)
+monkeypatch.setattr(os.path, 'isfile', mock_object)
--- End diff --

doesnt this line override the previous one?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115498975
  
--- Diff: aria/cli/csar.py ---
@@ -22,7 +22,7 @@
 import requests
 from ruamel import yaml
 
-
+CSAR_FILE_EXTENSION = '.csar'
--- End diff --

do a quick search for `.csar`, there should be at least one more reference 
to it in modules you've touched anyway :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115499156
  
--- Diff: tests/cli/test_service_templates.py ---
@@ -131,6 +133,18 @@ def test_store_no_exception(self, monkeypatch, 
mock_object):
 assert 'Service template {name} stored'.format(
 name=mock_models.SERVICE_TEMPLATE_NAME) in 
self.logger_output_string
 
+def test_store_relative_path_single_yaml_file(self, monkeypatch, 
mock_object):
+monkeypatch.setattr(Core, 'create_service_template', mock_object)
+monkeypatch.setattr(os.path, 'isfile', lambda x: True)
+monkeypatch.setattr(service_template_utils, '_is_archive', lambda 
x: False)
+
+self.invoke('service_templates store service_template.yaml 
{name}'.format(
+name=mock_models.SERVICE_TEMPLATE_NAME))
+
+mock_object.assert_called_with(os.path.join(os.getcwd(), 
'service_template.yaml'),
--- End diff --

just curious why you've decided to use `join` and `getcwd` here rather than 
absolute path (like you did in the actual code). not that it should matter :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #125: ARIA-165 Make node name suffix UUIDs ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/125#discussion_r115431430
  
--- Diff: aria/modeling/service_template.py ---
@@ -549,9 +549,14 @@ def as_raw(self):
 ('requirement_templates', 
formatting.as_raw_list(self.requirement_templates
 
 def instantiate(self, container):
-context = ConsumptionContext.get_thread_local()
 from . import models
-name = context.modeling.generate_node_id(self.name)
+import pydevd; pydevd.settrace('localhost', suspend=False)
+if self.nodes:
+highest_name_suffix = max(self.nodes, key=lambda n: 
n.name).name.rsplit('_', 1)[1]
--- End diff --

im not sure this would work;
note that `mynode_2` will come after `mynode_11` :|


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #125: ARIA-165 Make node name suffix UUIDs ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/125#discussion_r115431168
  
--- Diff: aria/modeling/service_template.py ---
@@ -549,9 +549,14 @@ def as_raw(self):
 ('requirement_templates', 
formatting.as_raw_list(self.requirement_templates
 
 def instantiate(self, container):
-context = ConsumptionContext.get_thread_local()
 from . import models
-name = context.modeling.generate_node_id(self.name)
+import pydevd; pydevd.settrace('localhost', suspend=False)
--- End diff --

poo


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #126: ARIA-160 tests fail spordically over ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/126#discussion_r115428827
  
--- Diff: tests/orchestrator/context/test_operation.py ---
@@ -97,31 +103,31 @@ def basic_workflow(graph, **_):
 
 execute(workflow_func=basic_workflow, workflow_context=ctx, 
executor=thread_executor)
 
-assert global_test_holder['ctx_name'] == 
context.operation.NodeOperationContext.__name__
+assert test_holder['ctx_name'] == 
context.operation.NodeOperationContext.__name__
--- End diff --

TBH i'd called it `dataholder` everywhere it says simply `holder` but up to 
you


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #126: ARIA-160 tests fail spordically over ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/126#discussion_r115427438
  
--- Diff: tests/helpers.py ---
@@ -34,16 +33,17 @@ def get_service_template_uri(*args):
 
 
 class FilesystemDataHolder(object):
-_tmpfile = tempfile.NamedTemporaryFile('w')
 
 def _load(self):
-return json.load(open(self._tmpfile.name))
+return json.load(open(self._path))
 
 def _dump(self, value):
-return json.dump(value, open(self._tmpfile.name, 'w'))
+return json.dump(value, open(self._path, 'w'))
 
-def __init__(self):
-self.clear()
+def __init__(self, path, reset=False):
--- End diff --

move init to be the first method


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #126: ARIA-160 tests fail spordically over ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/126#discussion_r115428189
  
--- Diff: tests/helpers.py ---
@@ -34,16 +33,17 @@ def get_service_template_uri(*args):
 
 
 class FilesystemDataHolder(object):
-_tmpfile = tempfile.NamedTemporaryFile('w')
 
 def _load(self):
-return json.load(open(self._tmpfile.name))
+return json.load(open(self._path))
 
 def _dump(self, value):
-return json.dump(value, open(self._tmpfile.name, 'w'))
+return json.dump(value, open(self._path, 'w'))
 
-def __init__(self):
-self.clear()
+def __init__(self, path, reset=False):
+self._path = path
+if reset or not os.path.exists(self._path) or 
open(self._path).read() == '':
--- End diff --

no closing of the file?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #125: ARIA-165 Make node name suffix UUIDs ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/125#discussion_r115427157
  
--- Diff: aria/modeling/service_template.py ---
@@ -549,9 +549,13 @@ def as_raw(self):
 ('requirement_templates', 
formatting.as_raw_list(self.requirement_templates
 
 def instantiate(self, container):
-context = ConsumptionContext.get_thread_local()
 from . import models
-name = context.modeling.generate_node_id(self.name)
+if self.nodes:
+latest_node_index = self.nodes[-1].name.rsplit('_', 1)[1]
--- End diff --

is the nodes list guaranteed to be ordered?
if not then we need to find the max

either way, i'd change `latest` to `highest`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #125: ARIA-165 Make node name suffix UUIDs ...

2017-05-09 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/125#discussion_r115426507
  
--- Diff: aria/modeling/service_template.py ---
@@ -549,9 +549,13 @@ def as_raw(self):
 ('requirement_templates', 
formatting.as_raw_list(self.requirement_templates
 
 def instantiate(self, container):
-context = ConsumptionContext.get_thread_local()
 from . import models
-name = context.modeling.generate_node_id(self.name)
+if self.nodes:
+latest_node_index = self.nodes[-1].name.rsplit('_', 1)[1]
+index = int(latest_node_index) + 1
+else:
+index = 0
--- End diff --

i'd start from index=1 actually


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-08 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115325816
  
--- Diff: aria/cli/service_template_utils.py ---
@@ -53,7 +53,7 @@ def get(source, service_template_filename):
 return _get_service_template_file_from_archive(source, 
service_template_filename)
--- End diff --

What about adding a short test or two for these scenarios? :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-08 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115324345
  
--- Diff: aria/cli/csar.py ---
@@ -38,17 +38,19 @@
 }
 
 
-def write(source, entry, destination, logger):
-source = os.path.expanduser(source)
-destination = os.path.expanduser(destination)
-entry_definitions = os.path.join(source, entry)
+def write(service_template_path, destination, logger):
--- End diff --

good, i like the signature better this way


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #128: ARIA-210 Handle relative paths in CLI...

2017-05-08 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/128#discussion_r115324450
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -195,7 +195,9 @@ def create_archive(service_template_path, destination, 
logger):
 `destination` is the path of the output CSAR archive file
 """
 logger.info('Creating a CSAR archive')
-csar.write(os.path.dirname(service_template_path), 
service_template_path, destination, logger)
+if not destination.endswith('.csar'):
--- End diff --

maybe extract `.csar` suffix to a constant in csar.py? seems like its 
defined in several places now


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #123: Dry execution changes the state of no...

2017-05-07 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/123#discussion_r115145843
  
--- Diff: aria/orchestrator/workflows/executor/base.py ---
@@ -31,7 +31,14 @@ def execute(self, task):
 Execute a task
 :param task: task to execute
 """
-raise NotImplementedError
+if task.model_task.implementation:
+self._execute_empty_task(task)
+else:
+raise NotImplementedError
--- End diff --

??
so to implement this i have to override `execute` entirely?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #124: ARIA-215 Refactor plugin-related code...

2017-05-07 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/124

ARIA-215 Refactor plugin-related code into PluginManager

Refactored plugin-related code from ProcessExecutor into PluginManager.
Additionally, renamed plugin_prefix to plugin_dir in PluginManager.

You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-215-refactor-plugin-related-code

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/124.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #124






---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #120: ARIA-209 Fix CLI command help

2017-05-04 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/120

ARIA-209 Fix  CLI command help



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-209-fix-create-archive-command-help

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/120.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #120


commit 505df8d20be5c6ea699c8a5d0aad20a7388d6102
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-05-04T14:07:50Z

ARIA-209 Fix  CLI command help




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114553081
  
--- Diff: aria/cli/helptexts.py ---
@@ -47,3 +47,8 @@
 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"
--- End diff --

lets merge this with `JSON_OUTPUT`,
the latter is a good name, and simply have it as "Format the output as JSON"


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114554248
  
--- Diff: aria/cli/commands/services.py ---
@@ -177,3 +179,31 @@ def inputs(service_name, model_storage, logger):
 logger.info(inputs_string.getvalue())
 else:
 logger.info('\tNo inputs')
+
+
+@services.command(name='display',
+  short_help='Display service information')
+@aria.argument('service-name')
+@aria.options.verbose()
+@aria.options.display_json
+@aria.options.display_yaml
+@aria.options.display_graph
+@aria.pass_model_storage
+@aria.pass_logger
+def display(service_name, model_storage, json, yaml, graph, logger):
--- End diff --

nitpicking that model_storage should probably sit after `graph`, before 
`logger`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114554090
  
--- Diff: aria/cli/commands/services.py ---
@@ -177,3 +179,31 @@ def inputs(service_name, model_storage, logger):
 logger.info(inputs_string.getvalue())
 else:
 logger.info('\tNo inputs')
+
+
+@services.command(name='display',
+  short_help='Display service information')
+@aria.argument('service-name')
+@aria.options.verbose()
+@aria.options.display_json
+@aria.options.display_yaml
+@aria.options.display_graph
+@aria.pass_model_storage
+@aria.pass_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:
--- End diff --

General reminder that none of the methods below are standard for the CLI
Fine for now, but keep https://issues.apache.org/jira/browse/ARIA-183 in 
mind


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114553193
  
--- Diff: aria/cli/core/aria.py ---
@@ -325,6 +325,30 @@ def __init__(self):
 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(
--- End diff --

`yaml_output`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114555739
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -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')
+@aria.argument('service-template-name')
+@aria.options.verbose()
+@aria.options.display_json
+@aria.options.display_yaml
+@aria.options.display_types
+@aria.pass_model_storage
+@aria.pass_logger
+def display(service_template_name, model_storage, json, yaml, types, 
logger):
--- End diff --

Having both `display` and `show` is confusing :/
I agree however that it doesn't make sense to make this command into a mere 
flag of `show` as they're very different.
I'm generally ok with this as is, but Maxim wanted me to suggest `aria 
parse service/service-template` as an option as well. I'll leave it for your 
consideration :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #107: ARIA-148 CLI display commands

2017-05-03 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/107#discussion_r114553136
  
--- Diff: aria/cli/core/aria.py ---
@@ -325,6 +325,30 @@ def __init__(self):
 default=defaults.SERVICE_TEMPLATE_FILENAME,
 help=helptexts.SERVICE_TEMPLATE_FILENAME)
 
+self.display_json = click.option(
--- End diff --

merge this with the other JSON one


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #115: Aria 161 disable end2end tests on win...

2017-04-30 Thread ran-z
Github user ran-z closed the pull request at:

https://github.com/apache/incubator-ariatosca/pull/115


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #116: ARIA-161 Disable end2end tests on Win...

2017-04-30 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/116

ARIA-161 Disable end2end tests on Windows



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-161-disable-end-to-end-tests-on-windows

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/116.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #116


commit 978bd49a327824990a7a71345fcf919b9cb684bb
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-30T12:40:57Z

ARIA-161 Disable end2end tests on Windows




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #115: Aria 161 disable end2end tests on win...

2017-04-30 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/115

Aria 161 disable end2end tests on windows



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-161-disable-end2end-tests-on-windows

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/115.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #115


commit d0c5e6fa1732a1b90992a7a75721b408f8a1b575
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-30T12:15:37Z

ARIA-155 Clean models from unused fields

commit 733af31367a58773d1c4a15c7558330277aa2ff9
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-30T12:40:57Z

ARIA-161 Disabled end2end tests on Windows




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #114: ARIA-155 Clean models from unused fie...

2017-04-30 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/114

ARIA-155 Clean models from unused fields



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-155-clean-models-from-usused-fields

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/114.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #114


commit 18a50ba5b4236acbdb039e2d39cb76642fc5dcc4
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-30T12:15:37Z

ARIA-155 Clean models from unused fields




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #111: ARIA-153 Write end-to-end tests for A...

2017-04-27 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/111#discussion_r113643276
  
--- Diff: tests/end2end/test_hello_world.py ---
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import requests
+
+from .testenv import testenv  # pylint: disable=unused-import
+from .. import helpers
+
+
+def test_hello_world(testenv):
+hello_world_template_uri = helpers.get_example_uri('hello-world', 
'helloworld.yaml')
+service_name = testenv.install_service(hello_world_template_uri)
+
+try:
+_verify_deployed_service_in_storage(service_name, 
testenv.model_storage)
+_verify_webserver_running('http://localhost:9090')
+finally:
+# Even if some assertions failed, attempt to execute uninstall so 
the
+# webserver process doesn't stay up once the test is finished
+# TODO: remove force_service_delete=True
+testenv.uninstall_service(force_service_delete=True)
+
+testenv.verify_clean_storage()
--- End diff --

add verification that the server is not there at the end


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #111: ARIA-153 Write end-to-end tests for A...

2017-04-26 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/111

ARIA-153 Write end-to-end tests for ARIA

Created infrastructure for end-to-end tests,
plus a test for the hello-world example.

You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-153-end-to-end-tests

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/111.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #111


commit 7cc71bbbc3a8ffc69b1ea4a168b4985679d4e444
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-26T17:21:19Z

ARIA-153 Write end-to-end tests for ARIA

Created infrastructure for end-to-end tests,
plus a test for the hello-world example.




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #106: ARIA-145 deploying CLI config file at...

2017-04-20 Thread ran-z
GitHub user ran-z opened a pull request:

https://github.com/apache/incubator-ariatosca/pull/106

ARIA-145 deploying CLI config file at installation



You can merge this pull request into a Git repository by running:

$ git pull https://github.com/apache/incubator-ariatosca 
ARIA-145-cli-config-file-deployment

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/incubator-ariatosca/pull/106.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #106


commit f73c121a3d74c5fd08ec71de194b0646f5949e5e
Author: Ran Ziv <r...@gigaspaces.com>
Date:   2017-04-20T12:00:30Z

ARIA-145 deploying CLI config file at installation




---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #104: ARIA-138-Make-logging-more-informativ...

2017-04-20 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/104#discussion_r112417076
  
--- Diff: aria/cli/commands/executions.py ---
@@ -19,6 +19,8 @@
 from .. import table
 from .. import utils
 from ..core import aria
+from .. import logger as cli_logger
--- End diff --

move above the previous import


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #104: ARIA-138-Make-logging-more-informativ...

2017-04-20 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/104#discussion_r112417099
  
--- Diff: aria/cli/commands/logs.py ---
@@ -12,13 +12,12 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-from .. import utils
-from ..core import aria
+from ..logger import ModelLogIterator
+from ..cli import aria
--- End diff --

this line is wrong


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112176010
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -0,0 +1,216 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+
+from .. import utils
+from .. import csar
+from .. import service_template_utils
+from ..cli import aria
+from ..table import print_data
+from ..exceptions import AriaCliError
+from ..utils import handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+DESCRIPTION_LIMIT = 20
+SERVICE_TEMPLATE_COLUMNS = \
+['id', 'name', 'main_file_name', 'created_at', 'updated_at']
+
+
+@aria.group(name='service-templates')
+@aria.options.verbose()
+def service_templates():
+"""Handle service templates on the manager
+"""
+pass
+
+
+@service_templates.command(name='show',
+   short_help='Show service template information')
+@aria.argument('service-template-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_template_id, model_storage, logger):
+"""Show information for a specific service templates
+
+`SERVICE_TEMPLATE_ID` is the id of the service template to show 
information on.
+"""
+logger.info('Showing service template 
{0}...'.format(service_template_id))
+service_template = 
model_storage.service_template.get(service_template_id)
+services = [d.to_dict() for d in service_template.services]
+service_template_dict = service_template.to_dict()
+service_template_dict['#services'] = len(services)
+columns = SERVICE_TEMPLATE_COLUMNS + ['#services']
--- End diff --

decided not to - it would require listing all services for all service 
templates


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112175262
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112171918
  
--- Diff: aria/orchestrator/workflows/executor/process.py ---
@@ -148,7 +149,7 @@ def _create_arguments_dict(self, task):
 return {
 'task_id': task.id,
 'implementation': task.implementation,
-'operation_inputs': dict((k, v.value) for k, v in 
task.inputs.iteritems()),
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112157439
  
--- Diff: aria/cli/service_template_utils.py ---
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from urlparse import urlparse
+
+from . import csar
+from . import utils
+from .exceptions import AriaCliError
+from .constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ..utils import archive as archive_utils
+
+
+def get(source, 
service_template_filename=SAMPLE_SERVICE_TEMPLATE_FILENAME):
+"""Get a source and return a path to the main service template file
+
+The behavior based on then source argument content is:
+-
+- local archive:
+extract it locally and return path service template file
+- local yaml file: return the file
+- URL:
+- return it (download=False)
+- download and get service template from downloaded file 
(download=True)
+- github repo:
+- map it to a URL and return it (download=False)
+- download and get service template from downloaded file 
(download=True)
+
+Supported archive types are: csar, zip, tar, tar.gz and tar.bz2
+
+:param source: Path/URL/github repo to archive/service-template file
+:type source: str
+:param service_template_filename: Path to service template (if source 
is an archive file)
+:type service_template_filename: str
+:param download: Download service template file if source is 
URL/github repo
+:type download: bool
+:return: Path to file (if archive/service-template file passed) or url
+:rtype: str
+
+"""
+if urlparse(source).scheme:
+downloaded_file = utils.download_file(source)
+return _get_service_template_file_from_archive(
+downloaded_file, service_template_filename)
+elif os.path.isfile(source):
+if _is_archive(source):
+return _get_service_template_file_from_archive(source, 
service_template_filename)
+else:
+# Maybe check if yaml.
+return source
+elif len(source.split('/')) == 2:
+url = _map_to_github_url(source)
+downloaded_file = utils.download_file(url)
+return _get_service_template_file_from_archive(
+downloaded_file, service_template_filename)
+else:
+raise AriaCliError(
+'You must provide either a path to a local file, a remote URL '
+'or a GitHub `organization/repository[:tag/branch]`')
+
+
+def _get_service_template_file_from_archive(archive, 
service_template_filename):
+"""Extract archive to temporary location and get path to service 
template file.
+
+:param archive: Path to archive file
+:type archive: str
+:param service_template_filename: Path to service template file 
relative to archive
+:type service_template_filename: str
+:return: Absolute path to service template file
+:rtype: str
+
+"""
+if csar.is_csar_archive(archive):
+service_template_file = _extract_csar_archive(archive)
+else:
+extract_directory = archive_utils.extract_archive(archive)(archive)
+service_template_dir = os.path.join(
+extract_directory,
+os.listdir(extract_directory)[0],
+)
+service_template_file = os.path.join(service_template_dir, 
service_template_filename)
+
+if not os.path.isfile(service_template_file):
+raise AriaCliError(
+'Could not find `{0}`. Please provide the name of the main '
+'service template file by using the 
`-n/--service-template-filename` flag'
+.format(service_template_filename))
+return service_te

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112156303
  
--- Diff: aria/cli/service_template_utils.py ---
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from urlparse import urlparse
+
+from . import csar
+from . import utils
+from .exceptions import AriaCliError
+from .constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ..utils import archive as archive_utils
+
+
+def get(source, 
service_template_filename=SAMPLE_SERVICE_TEMPLATE_FILENAME):
+"""Get a source and return a path to the main service template file
+
+The behavior based on then source argument content is:
+-
+- local archive:
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-19 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112155259
  
--- Diff: aria/cli/constants.py ---
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+SAMPLE_SERVICE_TEMPLATE_FILENAME = 'service_template.yaml'
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112088783
  
--- Diff: aria/orchestrator/exceptions.py ---
@@ -46,3 +46,24 @@ class TaskAbortException(RuntimeError):
 Used internally when ctx.task.abort is called
 """
 pass
+
+
+class UndeclaredWorkflowError(AriaError):
+"""
+Raised when attempting to execute an undeclared workflow
+"""
+pass
+
+
+class ActiveExecutionsError(AriaError):
+"""
+Raised when attempting to execute a workflow on a service which 
already has an active execution
+"""
+pass
+
+
+class WorkflowImplementationNotFoundError(AriaError):
--- End diff --

this needs to be validated in the parsing stage


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112088043
  
--- Diff: aria/orchestrator/exceptions.py ---
@@ -46,3 +46,24 @@ class TaskAbortException(RuntimeError):
 Used internally when ctx.task.abort is called
 """
 pass
+
+
+class UndeclaredWorkflowError(AriaError):
+"""
+Raised when attempting to execute an undeclared workflow
+"""
+pass
+
+
+class ActiveExecutionsError(AriaError):
--- End diff --

I think they should actually stay separate


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112063820
  
--- Diff: aria/cli/commands/plugins.py ---
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import zipfile
+
+from ..table import print_data
+from ..cli import aria
+from ..exceptions import AriaCliError
+from ..utils import storage_sort_param
+
+
+PLUGIN_COLUMNS = ['id', 'package_name', 'package_version', 
'supported_platform',
+  'distribution', 'distribution_release', 'uploaded_at']
+
+
+@aria.group(name='plugins')
+@aria.options.verbose()
+def plugins():
+"""Handle plugins
+"""
+pass
+
+
+@plugins.command(name='validate',
+ short_help='Validate a plugin')
+@aria.argument('plugin-path')
+@aria.options.verbose()
+@aria.pass_logger
+def validate(plugin_path, logger):
+"""Validate a plugin
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112054206
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -0,0 +1,216 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+
+from .. import utils
+from .. import csar
+from .. import service_template_utils
+from ..cli import aria
+from ..table import print_data
+from ..exceptions import AriaCliError
+from ..utils import handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+DESCRIPTION_LIMIT = 20
+SERVICE_TEMPLATE_COLUMNS = \
+['id', 'name', 'main_file_name', 'created_at', 'updated_at']
+
+
+@aria.group(name='service-templates')
+@aria.options.verbose()
+def service_templates():
+"""Handle service templates on the manager
+"""
+pass
+
+
+@service_templates.command(name='show',
+   short_help='Show service template information')
+@aria.argument('service-template-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_template_id, model_storage, logger):
+"""Show information for a specific service templates
+
+`SERVICE_TEMPLATE_ID` is the id of the service template to show 
information on.
+"""
+logger.info('Showing service template 
{0}...'.format(service_template_id))
+service_template = 
model_storage.service_template.get(service_template_id)
+services = [d.to_dict() for d in service_template.services]
+service_template_dict = service_template.to_dict()
+service_template_dict['#services'] = len(services)
+columns = SERVICE_TEMPLATE_COLUMNS + ['#services']
+print_data(columns, service_template_dict, 'Service-template:', 
max_width=50)
+
+if service_template_dict['description'] is not None:
+logger.info('Description:')
+
logger.info('{0}\n'.format(service_template_dict['description'].encode('UTF-8') 
or ''))
+
+logger.info('Existing services:')
+logger.info('{0}\n'.format(json.dumps([d['name'] for d in services])))
+
+
+@service_templates.command(name='list',
+   short_help='List service templates')
+@aria.options.sort_by()
+@aria.options.descending
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(sort_by, descending, model_storage, logger):
+"""List all service templates
+"""
+def trim_description(service_template):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r112054136
  
--- Diff: aria/cli/table.py ---
@@ -0,0 +1,90 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111992478
  
--- Diff: aria/cli/logger.py ---
@@ -0,0 +1,113 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import copy
+import logging
+import logging.config
+
+
+HIGH_VERBOSE = 3
+MEDIUM_VERBOSE = 2
+LOW_VERBOSE = 1
+NO_VERBOSE = 0
+
+DEFAULT_LOGGER_CONFIG = {
+"version": 1,
+"formatters": {
+"file": {
+"format": "%(asctime)s [%(levelname)s] %(message)s"
+},
+"console": {
+"format": "%(message)s"
+}
+},
+"handlers": {
+"file": {
+"class": "logging.handlers.RotatingFileHandler",
+"formatter": "file",
+"maxBytes": "500",
+"backupCount": "20"
+},
+"console": {
+"class": "logging.StreamHandler",
+"stream": "ext://sys.stdout",
+"formatter": "console"
+}
+}
+}
+
+
+class Logging(object):
+
+def __init__(self, config):
+self._log_file = None
+self._verbosity_level = NO_VERBOSE
+self._all_loggers = []
+self._configure_loggers(config)
+self._lgr = logging.getLogger('aria.cli.main')
+
+@property
+def logger(self):
+return self._lgr
+
+@property
+def log_file(self):
+return self._log_file
+
+@property
+def verbosity_level(self):
+return self._verbosity_level
+
+def is_high_verbose_level(self):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111992318
  
--- Diff: aria/cli/logger.py ---
@@ -0,0 +1,113 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import copy
+import logging
+import logging.config
+
+
+HIGH_VERBOSE = 3
+MEDIUM_VERBOSE = 2
+LOW_VERBOSE = 1
+NO_VERBOSE = 0
+
+DEFAULT_LOGGER_CONFIG = {
+"version": 1,
+"formatters": {
+"file": {
+"format": "%(asctime)s [%(levelname)s] %(message)s"
+},
+"console": {
+"format": "%(message)s"
+}
+},
+"handlers": {
+"file": {
+"class": "logging.handlers.RotatingFileHandler",
+"formatter": "file",
+"maxBytes": "500",
+"backupCount": "20"
+},
+"console": {
+"class": "logging.StreamHandler",
+"stream": "ext://sys.stdout",
+"formatter": "console"
+}
+}
+}
+
+
+class Logging(object):
+
+def __init__(self, config):
+self._log_file = None
+self._verbosity_level = NO_VERBOSE
+self._all_loggers = []
+self._configure_loggers(config)
+self._lgr = logging.getLogger('aria.cli.main')
+
+@property
+def logger(self):
+return self._lgr
+
+@property
+def log_file(self):
+return self._log_file
+
+@property
+def verbosity_level(self):
+return self._verbosity_level
+
+def is_high_verbose_level(self):
+return self.verbosity_level == HIGH_VERBOSE
+
+@verbosity_level.setter
+def verbosity_level(self, level):
+self._verbosity_level = level
+if self.is_high_verbose_level():
+for logger_name in self._all_loggers:
+logging.getLogger(logger_name).setLevel(logging.DEBUG)
+
+def _configure_loggers(self, config):
+loggers_config = config.logging.loggers
+logfile = config.logging.filename
+
+logger_dict = copy.deepcopy(DEFAULT_LOGGER_CONFIG)
+if logfile:
+# set filename on file handler
+logger_dict['handlers']['file']['filename'] = logfile
+logfile_dir = os.path.dirname(logfile)
+if not os.path.exists(logfile_dir):
+os.makedirs(logfile_dir)
+self._log_file = logfile
+else:
+del logger_dict['handlers']['file']
+
+# add handlers to all loggers
+loggers = {}
+for logger_name in loggers_config:
+loggers[logger_name] = 
dict(handlers=list(logger_dict['handlers'].keys()))
+logger_dict['loggers'] = loggers
+
+# set level for all loggers
+for logger_name, logging_level in loggers_config.iteritems():
+log = logging.getLogger(logger_name)
+level = logging._levelNames[logging_level.upper()]
+log.setLevel(level)
+self._all_loggers.append(logger_name)
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111984985
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -0,0 +1,216 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+
+from .. import utils
+from .. import csar
+from .. import service_template_utils
+from ..cli import aria
+from ..table import print_data
+from ..exceptions import AriaCliError
+from ..utils import handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+DESCRIPTION_LIMIT = 20
+SERVICE_TEMPLATE_COLUMNS = \
+['id', 'name', 'main_file_name', 'created_at', 'updated_at']
+
+
+@aria.group(name='service-templates')
+@aria.options.verbose()
+def service_templates():
+"""Handle service templates on the manager
+"""
+pass
+
+
+@service_templates.command(name='show',
+   short_help='Show service template information')
+@aria.argument('service-template-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_template_id, model_storage, logger):
+"""Show information for a specific service templates
+
+`SERVICE_TEMPLATE_ID` is the id of the service template to show 
information on.
+"""
+logger.info('Showing service template 
{0}...'.format(service_template_id))
+service_template = 
model_storage.service_template.get(service_template_id)
+services = [d.to_dict() for d in service_template.services]
+service_template_dict = service_template.to_dict()
+service_template_dict['#services'] = len(services)
+columns = SERVICE_TEMPLATE_COLUMNS + ['#services']
+print_data(columns, service_template_dict, 'Service-template:', 
max_width=50)
+
+if service_template_dict['description'] is not None:
+logger.info('Description:')
+
logger.info('{0}\n'.format(service_template_dict['description'].encode('UTF-8') 
or ''))
+
+logger.info('Existing services:')
+logger.info('{0}\n'.format(json.dumps([d['name'] for d in services])))
+
+
+@service_templates.command(name='list',
+   short_help='List service templates')
+@aria.options.sort_by()
+@aria.options.descending
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(sort_by, descending, model_storage, logger):
+"""List all service templates
+"""
+def trim_description(service_template):
+if service_template['description'] is not None:
+if len(service_template['description']) >= DESCRIPTION_LIMIT:
+service_template['description'] = '{0}..'.format(
+service_template['description'][:DESCRIPTION_LIMIT - 
2])
+else:
+service_template['description'] = ''
+return service_template
+
+logger.info('Listing all service templates...')
+service_templates_list = [trim_description(b.to_dict()) for b in
+  model_storage.service_template.list(
+  sort=utils.storage_sort_param(sort_by, 
descending))]
+print_data(SERVICE_TEMPLATE_COLUMNS, service_templates_list, 'Service 
templates:')
+
+
+@service_templates.command(name='store',
+   short_help='Store a service template')
+@aria.argument('service-template-path')
+@aria.argument('service-template-name')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_resource_storage
+@aria.pass_plugin_manager
+@aria.pass_logger
+def store(service_template_path, service_template_name, model_storage, 
resource_storage,
 

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111984998
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -0,0 +1,216 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+
+from .. import utils
+from .. import csar
+from .. import service_template_utils
+from ..cli import aria
+from ..table import print_data
+from ..exceptions import AriaCliError
+from ..utils import handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+DESCRIPTION_LIMIT = 20
+SERVICE_TEMPLATE_COLUMNS = \
+['id', 'name', 'main_file_name', 'created_at', 'updated_at']
+
+
+@aria.group(name='service-templates')
+@aria.options.verbose()
+def service_templates():
+"""Handle service templates on the manager
+"""
+pass
+
+
+@service_templates.command(name='show',
+   short_help='Show service template information')
+@aria.argument('service-template-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_template_id, model_storage, logger):
+"""Show information for a specific service templates
+
+`SERVICE_TEMPLATE_ID` is the id of the service template to show 
information on.
+"""
+logger.info('Showing service template 
{0}...'.format(service_template_id))
+service_template = 
model_storage.service_template.get(service_template_id)
+services = [d.to_dict() for d in service_template.services]
+service_template_dict = service_template.to_dict()
+service_template_dict['#services'] = len(services)
+columns = SERVICE_TEMPLATE_COLUMNS + ['#services']
+print_data(columns, service_template_dict, 'Service-template:', 
max_width=50)
+
+if service_template_dict['description'] is not None:
+logger.info('Description:')
+
logger.info('{0}\n'.format(service_template_dict['description'].encode('UTF-8') 
or ''))
+
+logger.info('Existing services:')
+logger.info('{0}\n'.format(json.dumps([d['name'] for d in services])))
+
+
+@service_templates.command(name='list',
+   short_help='List service templates')
+@aria.options.sort_by()
+@aria.options.descending
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(sort_by, descending, model_storage, logger):
+"""List all service templates
+"""
+def trim_description(service_template):
+if service_template['description'] is not None:
+if len(service_template['description']) >= DESCRIPTION_LIMIT:
+service_template['description'] = '{0}..'.format(
+service_template['description'][:DESCRIPTION_LIMIT - 
2])
+else:
+service_template['description'] = ''
+return service_template
+
+logger.info('Listing all service templates...')
+service_templates_list = [trim_description(b.to_dict()) for b in
+  model_storage.service_template.list(
+  sort=utils.storage_sort_param(sort_by, 
descending))]
+print_data(SERVICE_TEMPLATE_COLUMNS, service_templates_list, 'Service 
templates:')
+
+
+@service_templates.command(name='store',
+   short_help='Store a service template')
+@aria.argument('service-template-path')
+@aria.argument('service-template-name')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_resource_storage
+@aria.pass_plugin_manager
+@aria.pass_logger
+def store(service_template_path, service_template_name, model_storage, 
resource_storage,
 

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111984557
  
--- Diff: aria/cli/commands/services.py ---
@@ -0,0 +1,180 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+from StringIO import StringIO
+
+from . import service_templates
+from ..cli import aria, helptexts
+from ..exceptions import AriaCliError
+from ..table import print_data
+from ..utils import storage_sort_param, handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+SERVICE_COLUMNS = ['id', 'name', 'service_template_name', 'created_at', 
'updated_at']
+
+
+@aria.group(name='services')
+@aria.options.verbose()
+def services():
+"""Handle services
+"""
+pass
+
+
+@services.command(name='list', short_help='List services')
+@aria.options.service_template_name()
+@aria.options.sort_by()
+@aria.options.descending
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(service_template_name,
+ sort_by,
+ descending,
+ model_storage,
+ logger):
+"""List services
+
+If `--service-template-name` is provided, list services for that 
service template.
+Otherwise, list services for all service templates.
+"""
+if service_template_name:
+logger.info('Listing services for service template {0}...'.format(
+service_template_name))
+service_template = 
model_storage.service_template.get(service_template_name)
+filters = dict(service_template=service_template)
+else:
+logger.info('Listing all service...')
+filters = {}
+
+services_list = [d.to_dict() for d in model_storage.service.list(
+sort=storage_sort_param(sort_by=sort_by, descending=descending),
+filters=filters)]
+print_data(SERVICE_COLUMNS, services_list, 'Services:')
+
+
+@services.command(name='create',
+  short_help='Create a services')
+@aria.argument('service-name', required=False)
+@aria.options.service_template_name(required=True)
+@aria.options.inputs
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_resource_storage
+@aria.pass_plugin_manager
+@aria.pass_logger
+def create(service_template_name,
+   service_name,
+   inputs,  # pylint: disable=redefined-outer-name
+   model_storage,
+   resource_storage,
+   plugin_manager,
+   logger):
+"""Create a service
+
+`SERVICE_NAME` is the name of the service you'd like to create.
+
+"""
+logger.info('Creating new service from service template {0}...'.format(
+service_template_name))
+
+try:
+core = Core(model_storage, resource_storage, plugin_manager)
+service_template = 
model_storage.service_template.get_by_name(service_template_name)
+service = core.create_service(service_template.id, inputs, 
service_name)
+except storage_exceptions.StorageError as e:
+handle_storage_exception(e, 'service', service_name)
+except AriaException as e:
+logger.info(str(e))
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111960624
  
--- Diff: aria/orchestrator/workflow_runner.py ---
@@ -0,0 +1,166 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Workflow runner
+"""
+
+import os
+import sys
+from datetime import datetime
+
+from . import exceptions
+from .context.workflow import WorkflowContext
+from .workflows.builtin import BUILTIN_WORKFLOWS, 
BUILTIN_WORKFLOWS_PATH_PREFIX
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111959254
  
--- Diff: aria/cli/cli/__init__.py ---
@@ -0,0 +1,14 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111959241
  
--- Diff: aria/cli/cli/helptexts.py ---
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+VERBOSE = \
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111955533
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111955477
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-18 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111941813
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683684
  
--- Diff: aria/cli/main.py ---
@@ -0,0 +1,59 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from aria import install_aria_extensions
+from aria.cli import commands
+from aria.cli.cli import aria
+
+
+@aria.group(name='aria')
+@aria.options.verbose()
+@aria.options.version
+def _aria():
+"""ARIA's Command Line Interface
+
+To activate bash-completion. Run: `eval "$(_ARIA_COMPLETE=source 
aria)"`
+
+ARIA's working directory resides by default in ~/.aria. To change it, 
set
+the environment variable `ARIA_WORKDIR` to something else (e.g. /tmp/).
+"""
+aria.set_cli_except_hook()
+
+
+def _register_commands():
+"""
+Register the CLI's commands.
+"""
+
+_aria.add_command(commands.service_templates.service_templates)
+_aria.add_command(commands.node_templates.node_templates)
+_aria.add_command(commands.services.services)
+_aria.add_command(commands.nodes.nodes)
+_aria.add_command(commands.workflows.workflows)
+_aria.add_command(commands.executions.executions)
+_aria.add_command(commands.plugins.plugins)
+_aria.add_command(commands.logs.logs)
+
+
+_register_commands()
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683685
  
--- Diff: aria/cli/env.py ---
@@ -0,0 +1,118 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+import pkgutil
+
+from .config import config
+from .logger import Logging
+from .. import (application_model_storage, application_resource_storage)
+from ..orchestrator.plugin import PluginManager
+from ..storage.sql_mapi import SQLAlchemyModelAPI
+from ..storage.filesystem_rapi import FileSystemResourceAPI
+
+
+ARIA_DEFAULT_WORKDIR_NAME = '.aria'
+
+
+class Environment(object):
+
+def __init__(self, workdir):
+
+self._workdir = workdir
+self._init_workdir()
+
+self._config = config.CliConfig.create_config(workdir)
+self._logging = Logging(self._config)
+
+self._model_storage_dir = os.path.join(workdir, 'models')
+self._resource_storage_dir = os.path.join(workdir, 'resources')
+self._plugins_dir = os.path.join(workdir, 'plugins')
+
+# initialized lazily
+self._model_storage = None
+self._resource_storage = None
+self._plugin_manager = None
+
+@property
+def workdir(self):
+return self._workdir
+
+@property
+def config(self):
+return self._config
+
+@property
+def logging(self):
+return self._logging
+
+@property
+def model_storage(self):
+if not self._model_storage:
+self._model_storage = self._init_sqlite_model_storage()
+return self._model_storage
+
+@property
+def resource_storage(self):
+if not self._resource_storage:
+self._resource_storage = self._init_fs_resource_storage()
+return self._resource_storage
+
+@property
+def plugin_manager(self):
+if not self._plugin_manager:
+self._plugin_manager = self._init_plugin_manager()
+return self._plugin_manager
+
+@staticmethod
+def get_version_data():
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683498
  
--- Diff: aria/cli/VERSION ---
@@ -0,0 +1,3 @@
+{
--- End diff --

removed this module, had two different VERSION modules


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683488
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
--- End diff --

its better as an option to the main command


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683338
  
--- Diff: aria/cli/commands/workflows.py ---
@@ -0,0 +1,102 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from ..table import print_data
+from ..cli import aria
+from ..exceptions import AriaCliError
+
+WORKFLOW_COLUMNS = ['name', 'service_template_name', 'service_name']
+
+
+@aria.group(name='workflows')
+def workflows():
+"""Handle service workflows
+"""
+pass
+
+
+@workflows.command(name='show',
+   short_help='Show workflow information')
+@aria.argument('workflow-name')
+@aria.options.service_name(required=True)
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(workflow_name, service_name, model_storage, logger):
+"""Show information for a specific workflow of a specific service
+
+`WORKFLOW_NAME` is the name of the workflow to get information on.
+"""
+logger.info('Retrieving workflow {0} for service {1}'.format(
+workflow_name, service_name))
+service = model_storage.service.get_by_name(service_name)
+workflow = next((wf for wf in service.workflows.values() if
+ wf.name == workflow_name), None)
+if not workflow:
+raise AriaCliError(
+'Workflow {0} not found for service {1}'.format(workflow_name, 
service_name))
+
+defaults = {
+'service_template_name': service.service_template_name,
+'service_name': service.name
+}
+print_data(WORKFLOW_COLUMNS, workflow.to_dict(), 'Workflows:', 
defaults=defaults)
+
+# print workflow inputs
+required_inputs = dict()
+optional_inputs = dict()
+for input_name, input in workflow.inputs.iteritems():
+inputs_group = optional_inputs if input.value is not None else 
required_inputs
+inputs_group[input_name] = input
+
+logger.info('Workflow Inputs:')
+logger.info('\tMandatory Inputs:')
+for input_name, input in required_inputs.iteritems():
+if input.description is not None:
+logger.info('\t\t{0}\t({1})'.format(input_name,
+input.description))
+else:
+logger.info('\t\t{0}'.format(input_name))
+
+logger.info('\tOptional Inputs:')
+for input_name, input in optional_inputs.iteritems():
+if input.description is not None:
+logger.info('\t\t{0}: \t{1}\t({2})'.format(
+input_name, input.value, input.description))
+else:
+logger.info('\t\t{0}: \t{1}'.format(input_name,
+input.value))
+logger.info('')
+
+
+@workflows.command(name='list',
+   short_help='List workflows for a service')
+@aria.options.service_name(required=True)
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(service_name, model_storage, logger):
+"""List all workflows of a specific service
+"""
+logger.info('Listing workflows for service 
{0}...'.format(service_name))
+service = model_storage.service.get_by_name(service_name)
+workflows_list = [wf.to_dict() for wf in
+  sorted(service.workflows.values(), key=lambda w: 
w.name)]
+
+defaults = {
+'service_template_name': service.service_template_name,
--- End diff --

again, since workflows are currently modeled as Operations, i'd rather keep 
the defaults - having an association proxy "service_name" for operation makes 
less sense, but it does make sense for Workflows - so when they get their own 
model object we can have it there and remove these defaults


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683302
  
--- Diff: aria/cli/commands/workflows.py ---
@@ -0,0 +1,102 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from ..table import print_data
+from ..cli import aria
+from ..exceptions import AriaCliError
+
+WORKFLOW_COLUMNS = ['name', 'service_template_name', 'service_name']
+
+
+@aria.group(name='workflows')
+def workflows():
+"""Handle service workflows
+"""
+pass
+
+
+@workflows.command(name='show',
+   short_help='Show workflow information')
+@aria.argument('workflow-name')
+@aria.options.service_name(required=True)
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(workflow_name, service_name, model_storage, logger):
+"""Show information for a specific workflow of a specific service
+
+`WORKFLOW_NAME` is the name of the workflow to get information on.
+"""
+logger.info('Retrieving workflow {0} for service {1}'.format(
+workflow_name, service_name))
+service = model_storage.service.get_by_name(service_name)
+workflow = next((wf for wf in service.workflows.values() if
+ wf.name == workflow_name), None)
+if not workflow:
+raise AriaCliError(
+'Workflow {0} not found for service {1}'.format(workflow_name, 
service_name))
+
+defaults = {
+'service_template_name': service.service_template_name,
+'service_name': service.name
+}
+print_data(WORKFLOW_COLUMNS, workflow.to_dict(), 'Workflows:', 
defaults=defaults)
+
+# print workflow inputs
+required_inputs = dict()
+optional_inputs = dict()
+for input_name, input in workflow.inputs.iteritems():
+inputs_group = optional_inputs if input.value is not None else 
required_inputs
+inputs_group[input_name] = input
+
+logger.info('Workflow Inputs:')
+logger.info('\tMandatory Inputs:')
+for input_name, input in required_inputs.iteritems():
+if input.description is not None:
+logger.info('\t\t{0}\t({1})'.format(input_name,
+input.description))
+else:
+logger.info('\t\t{0}'.format(input_name))
+
+logger.info('\tOptional Inputs:')
+for input_name, input in optional_inputs.iteritems():
+if input.description is not None:
+logger.info('\t\t{0}: \t{1}\t({2})'.format(
+input_name, input.value, input.description))
+else:
+logger.info('\t\t{0}: \t{1}'.format(input_name,
+input.value))
+logger.info('')
+
+
+@workflows.command(name='list',
+   short_help='List workflows for a service')
+@aria.options.service_name(required=True)
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(service_name, model_storage, logger):
+"""List all workflows of a specific service
+"""
+logger.info('Listing workflows for service 
{0}...'.format(service_name))
+service = model_storage.service.get_by_name(service_name)
+workflows_list = [wf.to_dict() for wf in
+  sorted(service.workflows.values(), key=lambda w: 
w.name)]
--- End diff --

since workflows are modeled as operations and dont have a unique model 
type, and operations dont have a field describing whether they're workflows or 
not, it's problematic filtering this via model storage. working with 
service.workflows is simpler so im keeping this behavior for now, even though 
its inconsistent with the other `list` operations since the user can't specify 
the column to sort by

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683215
  
--- Diff: aria/cli/commands/workflows.py ---
@@ -0,0 +1,102 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from ..table import print_data
+from ..cli import aria
+from ..exceptions import AriaCliError
+
+WORKFLOW_COLUMNS = ['name', 'service_template_name', 'service_name']
+
+
+@aria.group(name='workflows')
+def workflows():
+"""Handle service workflows
+"""
+pass
+
+
+@workflows.command(name='show',
+   short_help='Show workflow information')
+@aria.argument('workflow-name')
+@aria.options.service_name(required=True)
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(workflow_name, service_name, model_storage, logger):
+"""Show information for a specific workflow of a specific service
+
+`WORKFLOW_NAME` is the name of the workflow to get information on.
+"""
+logger.info('Retrieving workflow {0} for service {1}'.format(
+workflow_name, service_name))
+service = model_storage.service.get_by_name(service_name)
+workflow = next((wf for wf in service.workflows.values() if
--- End diff --

decided not to


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-16 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111683113
  
--- Diff: aria/orchestrator/workflow_runner.py ---
@@ -0,0 +1,166 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Workflow runner
+"""
+
+import os
+import sys
+from datetime import datetime
+
+from . import exceptions
+from .context.workflow import WorkflowContext
+from .workflows.builtin import BUILTIN_WORKFLOWS, 
BUILTIN_WORKFLOWS_PATH_PREFIX
+from .workflows.core.engine import Engine
+from .workflows.executor.process import ProcessExecutor
+from ..modeling import models
+from ..modeling import utils as modeling_utils
+from ..utils.imports import import_fullname
+
+
+DEFAULT_TASK_MAX_ATTEMPTS = 1
+DEFAULT_TASK_RETRY_INTERVAL = 1
+# TODO move this constant somewhere in the DSL parser?
+WORKFLOW_POLICY_INTERNAL_PROPERTIES = ('implementation', 'dependencies')
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #95: ARIA-92 Automatic operation task confi...

2017-04-14 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/95#discussion_r111616080
  
--- Diff: aria/modeling/service_template.py ---
@@ -2077,27 +2091,39 @@ def service_template_fk(cls):
 """For ServiceTemplate one-to-many to PluginSpecification"""
 return relationship.foreign_key('service_template', nullable=True)
 
+@declared_attr
+def plugin_fk(cls):
+"""For PluginSpecification many-to-one to Plugin"""
+return relationship.foreign_key('plugin', nullable=True)
+
 # endregion
 
+# region many_to_one relationships
+
 @declared_attr
 def service_template(cls):
 return relationship.many_to_one(cls, 'service_template')
 
+@declared_attr
+def plugin(cls): # pylint: disable=method-hidden
+return relationship.many_to_one(cls, 'plugin', 
back_populates=relationship.NO_BACK_POP)
+
+# endregion
+
 @property
 def as_raw(self):
 return collections.OrderedDict((
 ('name', self.name),
-('version', self.version)))
+('version', self.version),
+('enabled', self.enabled)))
 
 def coerce_values(self, container, report_issues):
 pass
 
 def instantiate(self, container):
-from . import models
--- End diff --

wait, so instantiate is now empty? :confused: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #95: ARIA-92 Automatic operation task confi...

2017-04-14 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/95#discussion_r111615833
  
--- Diff: aria/modeling/service_template.py ---
@@ -1864,13 +1865,21 @@ def as_raw(self):
 
 def instantiate(self, container):
 from . import models
-plugin = self.plugin_specification.find_plugin() \
-if self.plugin_specification is not None else None
+if self.plugin_specification and self.plugin_specification.enabled:
+plugin = self.plugin_specification.plugin
+implementation = self.implementation if plugin is not None 
else None
+# "plugin" would be none if a match was not found. In that 
case, a validation error
--- End diff --

im not sure i understood this comment.
i think you're trying to say that `plugin` can't be None here since the 
test for enabled has already been performed earlier?
the first line of the comment makes it sound like `plugin` can be None when 
it cant


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #95: ARIA-92 Automatic operation task confi...

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/95#discussion_r111420329
  
--- Diff: aria/modeling/service_instance.py ---
@@ -1632,9 +1673,9 @@ def interface_fk(cls):
 return relationship.foreign_key('interface', nullable=True)
 
 @declared_attr
-def plugin_specification_fk(cls):
-"""For Operation one-to-one to PluginSpecification"""
-return relationship.foreign_key('plugin_specification', 
nullable=True)
+def plugin_fk(cls):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #95: ARIA-92 Automatic operation task confi...

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/95#discussion_r111412168
  
--- Diff: aria/modeling/service_instance.py ---
@@ -529,6 +524,32 @@ def validate_capabilities(self):
 satisfied = False
 return satisfied
 
+def find_host(self):
+def _find_host(node):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111403911
  
--- Diff: tests/mock/models.py ---
@@ -168,6 +167,13 @@ def create_interface_template(service_template, 
interface_name, operation_name,
 def create_interface(service, interface_name, operation_name, 
operation_kwargs=None,
  interface_kwargs=None):
 the_type = 
service.service_template.interface_types.get_descendant('test_interface_type')
+
+if operation_kwargs and operation_kwargs.get('inputs'):
+wrapped_inputs = {}
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111403334
  
--- Diff: aria/utils/formatting.py ---
@@ -83,6 +83,49 @@ def full_type_name(value):
 return name if module == '__builtin__' else '%s.%s' % (module, name)
 
 
+def decode_list(data):
+decoded_list = []
+for item in data:
+if isinstance(item, unicode):
+item = item.encode('utf-8')
+elif isinstance(item, list):
+item = decode_list(item)
+elif isinstance(item, dict):
+item = decode_dict(item)
+decoded_list.append(item)
+return decoded_list
+
+
+def decode_dict(data):
+decoded_dict = {}
+for key, value in data.iteritems():
+if isinstance(key, unicode):
+key = key.encode('utf-8')
+if isinstance(value, unicode):
+value = value.encode('utf-8')
+elif isinstance(value, list):
+value = decode_list(value)
+elif isinstance(value, dict):
+value = decode_dict(value)
+decoded_dict[key] = value
+return decoded_dict
+
+
+def try_convert_from_str(string, target_type):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111403090
  
--- Diff: aria/orchestrator/workflows/executor/dry.py ---
@@ -0,0 +1,54 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Dry executor
+"""
+
+from datetime import datetime
+
+from .base import BaseExecutor
+from modeling.models import Parameter
+
+
+class DryExecutor(BaseExecutor):
+"""
+Executor which dry runs tasks - prints task information without 
causing any side effects
+"""
+
+def execute(self, task):
+# updating the task manually instead of calling 
self._task_started(task),
+# to avoid any side effects raising that event might cause
+with task._update():
+task.started_at = datetime.utcnow()
+task.status = task.STARTED
+
+actor_type = type(task.actor).__name__.lower()
+implementation = '{0} > '.format(task.plugin) if task.plugin else 
''
+implementation += task.implementation
+inputs = Parameter.unwrap_dict(task.inputs)
+
+task.context.logger.info(
+'Executing {actor_type} {actor_name} operation 
{interface_name} {operation_name}: '
+'{implementation} (Inputs: {inputs})'
+.format(actor_type=actor_type, actor_name=task.actor.name,
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111402765
  
--- Diff: aria/modeling/utils.py ---
@@ -13,12 +13,99 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from json import JSONEncoder
+from StringIO import StringIO
+
+from . import exceptions
 from ..parser.consumption import ConsumptionContext
 from ..parser.exceptions import InvalidValueError
 from ..parser.presentation import Value
 from ..utils.collections import OrderedDict
 from ..utils.console import puts
-from .exceptions import CannotEvaluateFunctionException
+from ..utils.type import validate_value_type
+
+
+class ModelJSONEncoder(JSONEncoder):
+def default(self, o):  # pylint: disable=method-hidden
+from .mixins import ModelMixin
+if isinstance(o, ModelMixin):
+if hasattr(o, 'value'):
+dict_to_return = o.to_dict(fields=('value',))
+return dict_to_return['value']
+else:
+return o.to_dict()
+else:
+return JSONEncoder.default(self, o)
+
+
+def create_inputs(inputs, template_inputs):
+"""
+:param inputs: key-value dict
+:param template_inputs: parameter name to parameter object dict
+:return: dict of parameter name to Parameter models
+"""
+merged_inputs = _merge_and_validate_inputs(inputs, template_inputs)
+
+from . import models
+input_models = []
+for input_name, input_val in merged_inputs.iteritems():
+parameter = models.Parameter(
+name=input_name,
+type_name=template_inputs[input_name].type_name,
+description=template_inputs[input_name].description,
+value=input_val)
+input_models.append(parameter)
+
+return dict((inp.name, inp) for inp in input_models)
+
+
+def _merge_and_validate_inputs(inputs, template_inputs):
+"""
+:param inputs: key-value dict
+:param template_inputs: parameter name to parameter object dict
+:return:
+"""
+merged_inputs = inputs.copy()
+
+missing_inputs = []
+wrong_type_inputs = {}
+for input_name, input_template in template_inputs.iteritems():
+if input_name not in inputs:
+if input_template.value is not None:
+merged_inputs[input_name] = input_template.value  # apply 
default value
+else:
+missing_inputs.append(input_name)
+else:
+# Validate input type
+try:
+validate_value_type(inputs[input_name], 
input_template.type_name)
+except ValueError:
+wrong_type_inputs[input_name] = input_template.type_name
+except RuntimeError:
+# TODO: This error shouldn't be raised (or caught), but 
right now we lack support
+# for custom data_types, which will raise this error. 
Skipping their validation.
+pass
+
+if missing_inputs:
+raise exceptions.MissingRequiredInputsException(
+'Required inputs {0} have not been specified - expected 
inputs: {1}'
+.format(missing_inputs, template_inputs.keys()))
+
+if wrong_type_inputs:
+error_message = StringIO()
+for param_name, param_type in wrong_type_inputs.iteritems():
+error_message.write('Input "{0}" must be of type {1}\n'.
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111402088
  
--- Diff: aria/core.py ---
@@ -0,0 +1,117 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from . import exceptions
+from .parser.consumption import (
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111401230
  
--- Diff: aria/cli/commands/executions.py ---
@@ -0,0 +1,170 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from .. import utils
+from ..table import print_data
+from ..cli import aria
+from ...modeling.models import Execution
+from ...orchestrator.workflow_runner import WorkflowRunner
+from ...orchestrator.workflows.executor.dry import DryExecutor
+from ...utils import formatting
+from ...utils import threading
+
+EXECUTION_COLUMNS = ['id', 'workflow_name', 'status', 'service_name',
+ 'created_at', 'error']
+
+
+@aria.group(name='executions')
+@aria.options.verbose()
+def executions():
+"""Handle workflow executions
+"""
+pass
+
+
+@executions.command(name='show',
+short_help='Show execution information')
+@aria.argument('execution-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(execution_id, model_storage, logger):
+"""Show information for a specific execution
+
+`EXECUTION_ID` is the execution to get information on.
+"""
+logger.info('Showing execution {0}'.format(execution_id))
+execution = model_storage.execution.get(execution_id)
+
+print_data(EXECUTION_COLUMNS, execution.to_dict(), 'Execution:', 
max_width=50)
+
+# print execution parameters
+logger.info('Execution Inputs:')
+if execution.inputs:
+#TODO check this section, havent tested it
+execution_inputs = [ei.to_dict() for ei in execution.inputs]
+for input_name, input_value in formatting.decode_dict(
+execution_inputs).iteritems():
+logger.info('\t{0}: \t{1}'.format(input_name, input_value))
+else:
+logger.info('\tNo inputs')
+logger.info('')
+
+
+@executions.command(name='list',
+short_help='List service executions')
+@aria.options.service_name(required=False)
+@aria.options.sort_by()
+@aria.options.descending
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def list(service_name,
+ sort_by,
+ descending,
+ model_storage,
+ logger):
+"""List executions
+
+If `SERVICE_NAME` is provided, list executions for that service.
+Otherwise, list executions for all services.
+"""
+if service_name:
+logger.info('Listing executions for service {0}...'.format(
+service_name))
+service = model_storage.service.get_by_name(service_name)
+filters = dict(service=service)
+else:
+logger.info('Listing all executions...')
+filters = {}
+
+executions_list = [e.to_dict() for e in model_storage.execution.list(
+filters=filters,
+sort=utils.storage_sort_param(sort_by, descending))]
+
+print_data(EXECUTION_COLUMNS, executions_list, 'Executions:')
+
+
+@executions.command(name='start',
+short_help='Execute a workflow')
+@aria.argument('workflow-name')
+@aria.options.service_name(required=True)
+@aria.options.inputs
+@aria.options.dry_execution
+@aria.options.task_max_attempts()
+@aria.options.task_retry_interval()
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_resource_storage
+@aria.pass_plugin_manager
+@aria.pass_logger
+def start(workflow_name,
+  service_name,
+  inputs,
+  dry,
+  task_max_attempts,
+  task_retry_interval,
+  model_storage,
+  resource_storage,
+  plugin_manager,
+  logger):
+   

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111399347
  
--- Diff: aria/cli/service_template_utils.py ---
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from urlparse import urlparse
+
+from . import csar
+from . import utils
+from .exceptions import AriaCliError
+from .constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ..utils import archive as archive_utils
+
+
+def get(source, 
service_template_filename=SAMPLE_SERVICE_TEMPLATE_FILENAME):
+"""Get a source and return a path to the main service template file
+
+The behavior based on then source argument content is:
+-
+- local archive:
+extract it locally and return path service template file
+- local yaml file: return the file
+- URL:
+- return it (download=False)
+- download and get service template from downloaded file 
(download=True)
+- github repo:
+- map it to a URL and return it (download=False)
+- download and get service template from downloaded file 
(download=True)
+
+Supported archive types are: csar, zip, tar, tar.gz and tar.bz2
+
+:param source: Path/URL/github repo to archive/service-template file
+:type source: str
+:param service_template_filename: Path to service template (if source 
is an archive file)
+:type service_template_filename: str
+:param download: Download service template file if source is 
URL/github repo
+:type download: bool
+:return: Path to file (if archive/service-template file passed) or url
+:rtype: str
+
+"""
+if urlparse(source).scheme:
+downloaded_file = utils.download_file(source)
+return _get_service_template_file_from_archive(
+downloaded_file, service_template_filename)
+elif os.path.isfile(source):
+if _is_archive(source):
+return _get_service_template_file_from_archive(source, 
service_template_filename)
+else:
+# Maybe check if yaml.
+return source
+elif len(source.split('/')) == 2:
+url = _map_to_github_url(source)
+downloaded_file = utils.download_file(url)
+return _get_service_template_file_from_archive(
+downloaded_file, service_template_filename)
+else:
+raise AriaCliError(
+'You must provide either a path to a local file, a remote URL '
+'or a GitHub `organization/repository[:tag/branch]`')
+
+
+def _get_service_template_file_from_archive(archive, 
service_template_filename):
+"""Extract archive to temporary location and get path to service 
template file.
+
+:param archive: Path to archive file
+:type archive: str
+:param service_template_filename: Path to service template file 
relative to archive
+:type service_template_filename: str
+:return: Absolute path to service template file
+:rtype: str
+
+"""
+if csar.is_csar_archive(archive):
+service_template_file = _extract_csar_archive(archive)
+else:
+extract_directory = archive_utils.extract_archive(archive)(archive)
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111399214
  
--- Diff: aria/cli/env.py ---
@@ -0,0 +1,118 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+import pkgutil
+
+from .config import config
+from .logger import Logging
+from .. import (application_model_storage, application_resource_storage)
+from ..orchestrator.plugin import PluginManager
+from ..storage.sql_mapi import SQLAlchemyModelAPI
+from ..storage.filesystem_rapi import FileSystemResourceAPI
+
+
+ARIA_DEFAULT_WORKDIR_NAME = '.aria'
+
+
+class Environment(object):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111399055
  
--- Diff: aria/cli/inputs.py ---
@@ -0,0 +1,118 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import glob
+import yaml
+
+from .env import logger
+from.exceptions import AriaCliError
+
+
+def inputs_to_dict(resources):
+"""Returns a dictionary of inputs
+
+`resources` can be:
+- A list of files.
+- A single file
+- A directory containing multiple input files
+- A key1=value1;key2=value2 pairs string.
+- A string formatted as JSON/YAML.
+- Wildcard based string (e.g. *-inputs.yaml)
+"""
+if not resources:
+return dict()
+
+parsed_dict = {}
+
+for resource in resources:
+logger.debug('Processing inputs source: {0}'.format(resource))
+# Workflow parameters always pass an empty dictionary. We ignore it
+if isinstance(resource, basestring):
+try:
+parsed_dict.update(_parse_single_input(resource))
+except AriaCliError:
+raise AriaCliError(
+"Invalid input: {0}. It must represent a dictionary. "
+"Valid values can be one of:\n "
+"- A path to a YAML file\n "
+"- A path to a directory containing YAML files\n "
+"- A single quoted wildcard based path "
+"(e.g. '*-inputs.yaml')\n "
+"- A string formatted as JSON/YAML\n "
+"- A string formatted as 
key1=value1;key2=value2".format(
+resource))
+return parsed_dict
+
+
+def _parse_single_input(resource):
+try:
+# parse resource as string representation of a dictionary
+return plain_string_to_dict(resource)
+except AriaCliError:
+input_files = glob.glob(resource)
+parsed_dict = dict()
+if os.path.isdir(resource):
+for input_file in os.listdir(resource):
+parsed_dict.update(
+_parse_yaml_path(os.path.join(resource, input_file)))
+elif input_files:
+for input_file in input_files:
+parsed_dict.update(_parse_yaml_path(input_file))
+else:
+parsed_dict.update(_parse_yaml_path(resource))
+return parsed_dict
+
+
+def _parse_yaml_path(resource):
+
+try:
+# if resource is a path - parse as a yaml file
+if os.path.isfile(resource):
+with open(resource) as f:
+content = yaml.load(f.read())
+else:
+# parse resource content as yaml
+content = yaml.load(resource)
+except yaml.error.YAMLError as e:
+raise AriaCliError("'{0}' is not a valid YAML. {1}".format(
+resource, str(e)))
+
+# Emtpy files return None
+content = content or dict()
+if not isinstance(content, dict):
+raise AriaCliError()
+
+return content
+
+
+def plain_string_to_dict(input_string):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111398929
  
--- Diff: aria/cli/colorful_event.py ---
@@ -0,0 +1,152 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111398430
  
--- Diff: aria/cli/commands/service_templates.py ---
@@ -0,0 +1,216 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import json
+
+from .. import utils
+from .. import csar
+from .. import service_template_utils
+from ..cli import aria
+from ..table import print_data
+from ..exceptions import AriaCliError
+from ..utils import handle_storage_exception
+from ...core import Core
+from ...exceptions import AriaException
+from ...storage import exceptions as storage_exceptions
+
+
+DESCRIPTION_LIMIT = 20
+SERVICE_TEMPLATE_COLUMNS = \
+['id', 'name', 'main_file_name', 'created_at', 'updated_at']
+
+
+@aria.group(name='service-templates')
+@aria.options.verbose()
+def service_templates():
+"""Handle service templates on the manager
+"""
+pass
+
+
+@service_templates.command(name='show',
+   short_help='Show service template information')
+@aria.argument('service-template-id')
+@aria.options.verbose()
+@aria.pass_model_storage
+@aria.pass_logger
+def show(service_template_id, model_storage, logger):
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111398207
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111397933
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111397740
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111397249
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
+from ...utils.exceptions import get_exception_as_string
+
+
+CLICK_CONTEXT_SETTINGS = dict(
+help_option_names=['-h', '--help'],
+token_normalize_func=lambda param: param.lower())
+
+
+class MutuallyExclusiveOption(click.Option):
+"""Makes options mutually exclusive. The option must pass a `cls` 
argument
+with this class name and a `mutually_exclusive` argument with a list of
+argument names it is mutually exclusive with.
+
+NOTE: All mutually exclusive options must use this. It's not enough to
+use it in just one of the options.
+"""
+
+def __init__(self, *args, **kwargs):
+self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
+self.mutuality_error_message = \
+kwargs.pop('mutuality_error_message',
+   helptexts.DEFAULT_MUTUALITY_MESSAGE)
+self.mutuality_string = ', '.join(self.mutually_exclusive)
+if self.mutually_exclusive:
+help = kwargs.get('help', '')
+kwargs['help'] = (
+'{0}. This argument is mutually exclusive with '
+'arguments: [{1}] ({2})'.format(
+help,
+self.mutuality_string,
+self.mutuality_error_message))
+super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
+
+def handle_parse_result(self, ctx, opts, args):
+if self.mutually_exclusive.intersection(opts) and self.name in 
opts:
+raise click.UsageError(
+'Illegal usage: `{0}` is mutually exclusive with '
+'arguments: [{1}] ({2}).'.format(
+self.name,
+self.mutuality_string,
+self.mutuality_error_message))
+return super(MutuallyExclusiveOption, self).handle_parse_result(
+ctx, opts, args)
+
+
+def _format_version_data(version_data,
+ prefix=None,
+ suffix=None,
+ infix=None):
+all_data = version_data.copy()
+all_data['prefix'] = prefix or ''
+all_data['suffix'] = suffix or ''
+all_data['infix'] = infix or ''
+output = StringIO.StringIO()
+output.write('{prefix}{version}'.format(**all_data))
+output.write('{suffix}'.format(**all_data))
+return output.getvalue()
+
+
+def show_version(ctx, param, value):
+if not value:
+return
+
+cli_version_data = env.get_version_data()
+cli_version = _format_version_data(
+cli_version_data,
+prefix='ARIA CLI ',
+infix=' ' * 5,
+suffix='')
+
+logger.info(cli_version)
+ctx.exit()
+
+
+def inputs_callback(ctx, param, value):
+"""Allow to pass any inputs we provide to a command as
+processed inputs instead of having to call `inputs_to_dict`
+inside the command.
+
+`@aria.options.inputs` already calls this callback so that
+every time you use the option it returns the inputs as a
+dictionary.
+"""
+if not value:
+return {}
+
+return inputs_to_dict(value)
+
+
+def set_verbosity_level(ctx, param, value):
+if not value:
+  

[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111396908
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
+from ..cli import helptexts
+from ..inputs import inputs_to_dict
+from ..constants import SAMPLE_SERVICE_TEMPLATE_FILENAME
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111396507
  
--- Diff: aria/cli/cli/aria.py ---
@@ -0,0 +1,458 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import difflib
+import StringIO
+import traceback
+from functools import wraps
+
+import click
+
+from ..env import env, logger
--- End diff --

:+1: 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111386153
  
--- Diff: aria/orchestrator/workflows/executor/dry.py ---
@@ -0,0 +1,54 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Dry executor
+"""
+
+from datetime import datetime
+
+from .base import BaseExecutor
+from modeling.models import Parameter
+
+
+class DryExecutor(BaseExecutor):
+"""
+Executor which dry runs tasks - prints task information without 
causing any side effects
+"""
+
+def execute(self, task):
+# updating the task manually instead of calling 
self._task_started(task),
+# to avoid any side effects raising that event might cause
+with task._update():
+task.started_at = datetime.utcnow()
+task.status = task.STARTED
+
+actor_type = type(task.actor).__name__.lower()
+implementation = '{0} > '.format(task.plugin) if task.plugin else 
''
+implementation += task.implementation
+inputs = Parameter.unwrap_dict(task.inputs)
+
+task.context.logger.info(
+'Executing {actor_type} {actor_name} operation 
{interface_name} {operation_name}: '
+'{implementation} (Inputs: {inputs})'
+.format(actor_type=actor_type, actor_name=task.actor.name,
--- End diff --

betterify interpolation


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111388512
  
--- Diff: aria/utils/formatting.py ---
@@ -83,6 +83,49 @@ def full_type_name(value):
 return name if module == '__builtin__' else '%s.%s' % (module, name)
 
 
+def decode_list(data):
+decoded_list = []
+for item in data:
+if isinstance(item, unicode):
+item = item.encode('utf-8')
+elif isinstance(item, list):
+item = decode_list(item)
+elif isinstance(item, dict):
+item = decode_dict(item)
+decoded_list.append(item)
+return decoded_list
+
+
+def decode_dict(data):
+decoded_dict = {}
+for key, value in data.iteritems():
+if isinstance(key, unicode):
+key = key.encode('utf-8')
+if isinstance(value, unicode):
+value = value.encode('utf-8')
+elif isinstance(value, list):
+value = decode_list(value)
+elif isinstance(value, dict):
+value = decode_dict(value)
+decoded_dict[key] = value
+return decoded_dict
+
+
+def try_convert_from_str(string, target_type):
--- End diff --

remove


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111375763
  
--- Diff: aria/orchestrator/workflow_runner.py ---
@@ -0,0 +1,166 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Workflow runner
+"""
+
+import os
+import sys
+from datetime import datetime
+
+from . import exceptions
+from .context.workflow import WorkflowContext
+from .workflows.builtin import BUILTIN_WORKFLOWS, 
BUILTIN_WORKFLOWS_PATH_PREFIX
+from .workflows.core.engine import Engine
+from .workflows.executor.process import ProcessExecutor
+from ..modeling import models
+from ..modeling import utils as modeling_utils
+from ..utils.imports import import_fullname
+
+
+DEFAULT_TASK_MAX_ATTEMPTS = 1
+DEFAULT_TASK_RETRY_INTERVAL = 1
--- End diff --

change this; also check in cli


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111375923
  
--- Diff: aria/orchestrator/workflow_runner.py ---
@@ -0,0 +1,166 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Workflow runner
+"""
+
+import os
+import sys
+from datetime import datetime
+
+from . import exceptions
+from .context.workflow import WorkflowContext
+from .workflows.builtin import BUILTIN_WORKFLOWS, 
BUILTIN_WORKFLOWS_PATH_PREFIX
+from .workflows.core.engine import Engine
+from .workflows.executor.process import ProcessExecutor
+from ..modeling import models
+from ..modeling import utils as modeling_utils
+from ..utils.imports import import_fullname
+
+
+DEFAULT_TASK_MAX_ATTEMPTS = 1
+DEFAULT_TASK_RETRY_INTERVAL = 1
+# TODO move this constant somewhere in the DSL parser?
+WORKFLOW_POLICY_INTERNAL_PROPERTIES = ('implementation', 'dependencies')
--- End diff --

can remove this after tal's merge


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111390478
  
--- Diff: tests/mock/models.py ---
@@ -168,6 +167,13 @@ def create_interface_template(service_template, 
interface_name, operation_name,
 def create_interface(service, interface_name, operation_name, 
operation_kwargs=None,
  interface_kwargs=None):
 the_type = 
service.service_template.interface_types.get_descendant('test_interface_type')
+
+if operation_kwargs and operation_kwargs.get('inputs'):
+wrapped_inputs = {}
--- End diff --

pythonisic


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111386272
  
--- Diff: aria/orchestrator/workflows/executor/process.py ---
@@ -148,7 +149,7 @@ def _create_arguments_dict(self, task):
 return {
 'task_id': task.id,
 'implementation': task.implementation,
-'operation_inputs': dict((k, v.value) for k, v in 
task.inputs.iteritems()),
--- End diff --

change


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111375015
  
--- Diff: aria/orchestrator/exceptions.py ---
@@ -46,3 +46,24 @@ class TaskAbortException(RuntimeError):
 Used internally when ctx.task.abort is called
 """
 pass
+
+
+class UndeclaredWorkflowError(AriaError):
+"""
+Raised when attempting to execute an undeclared workflow
+"""
+pass
+
+
+class ActiveExecutionsError(AriaError):
--- End diff --

consider merging with DependentActiveExecutionsError


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111374826
  
--- Diff: aria/orchestrator/exceptions.py ---
@@ -46,3 +46,24 @@ class TaskAbortException(RuntimeError):
 Used internally when ctx.task.abort is called
 """
 pass
+
+
+class UndeclaredWorkflowError(AriaError):
+"""
+Raised when attempting to execute an undeclared workflow
+"""
+pass
+
+
+class ActiveExecutionsError(AriaError):
+"""
+Raised when attempting to execute a workflow on a service which 
already has an active execution
+"""
+pass
+
+
+class WorkflowImplementationNotFoundError(AriaError):
--- End diff --

check if implementation can be None, that could also be an error


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


[GitHub] incubator-ariatosca pull request #97: Aria 48 aria cli

2017-04-13 Thread ran-z
Github user ran-z commented on a diff in the pull request:

https://github.com/apache/incubator-ariatosca/pull/97#discussion_r111374158
  
--- Diff: aria/modeling/utils.py ---
@@ -13,12 +13,99 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from json import JSONEncoder
+from StringIO import StringIO
+
+from . import exceptions
 from ..parser.consumption import ConsumptionContext
 from ..parser.exceptions import InvalidValueError
 from ..parser.presentation import Value
 from ..utils.collections import OrderedDict
 from ..utils.console import puts
-from .exceptions import CannotEvaluateFunctionException
+from ..utils.type import validate_value_type
+
+
+class ModelJSONEncoder(JSONEncoder):
+def default(self, o):  # pylint: disable=method-hidden
+from .mixins import ModelMixin
+if isinstance(o, ModelMixin):
+if hasattr(o, 'value'):
+dict_to_return = o.to_dict(fields=('value',))
+return dict_to_return['value']
+else:
+return o.to_dict()
+else:
+return JSONEncoder.default(self, o)
+
+
+def create_inputs(inputs, template_inputs):
+"""
+:param inputs: key-value dict
+:param template_inputs: parameter name to parameter object dict
+:return: dict of parameter name to Parameter models
+"""
+merged_inputs = _merge_and_validate_inputs(inputs, template_inputs)
+
+from . import models
+input_models = []
+for input_name, input_val in merged_inputs.iteritems():
+parameter = models.Parameter(
+name=input_name,
+type_name=template_inputs[input_name].type_name,
+description=template_inputs[input_name].description,
+value=input_val)
+input_models.append(parameter)
+
+return dict((inp.name, inp) for inp in input_models)
+
+
+def _merge_and_validate_inputs(inputs, template_inputs):
+"""
+:param inputs: key-value dict
+:param template_inputs: parameter name to parameter object dict
+:return:
+"""
+merged_inputs = inputs.copy()
+
+missing_inputs = []
+wrong_type_inputs = {}
+for input_name, input_template in template_inputs.iteritems():
+if input_name not in inputs:
+if input_template.value is not None:
+merged_inputs[input_name] = input_template.value  # apply 
default value
+else:
+missing_inputs.append(input_name)
+else:
+# Validate input type
+try:
+validate_value_type(inputs[input_name], 
input_template.type_name)
+except ValueError:
+wrong_type_inputs[input_name] = input_template.type_name
+except RuntimeError:
+# TODO: This error shouldn't be raised (or caught), but 
right now we lack support
+# for custom data_types, which will raise this error. 
Skipping their validation.
+pass
+
+if missing_inputs:
+raise exceptions.MissingRequiredInputsException(
+'Required inputs {0} have not been specified - expected 
inputs: {1}'
+.format(missing_inputs, template_inputs.keys()))
+
+if wrong_type_inputs:
+error_message = StringIO()
+for param_name, param_type in wrong_type_inputs.iteritems():
+error_message.write('Input "{0}" must be of type {1}\n'.
--- End diff --

take the dot a line below


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---


  1   2   3   >