You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/03/31 00:37:14 UTC

incubator-ariatosca git commit: Default configuration for execution plugin

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-92-plugin-in-implementation-string a6bfe803d -> 842ec0d40


Default configuration for execution plugin


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/842ec0d4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/842ec0d4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/842ec0d4

Branch: refs/heads/ARIA-92-plugin-in-implementation-string
Commit: 842ec0d4053387e44e50027b021a9a7f1d3a881b
Parents: a6bfe80
Author: Tal Liron <ta...@gmail.com>
Authored: Thu Mar 30 19:36:51 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Thu Mar 30 19:36:51 2017 -0500

----------------------------------------------------------------------
 aria/modeling/orchestration.py                  |   1 -
 aria/modeling/service_instance.py               |  12 +-
 aria/orchestrator/execution_plugin/__init__.py  | 115 +++++++++++++++++--
 .../execution_plugin/ssh/operations.py          |   2 -
 aria/orchestrator/workflows/api/task.py         |   7 +-
 aria/orchestrator/workflows/exceptions.py       |  10 +-
 .../simple_v1_0/modeling/__init__.py            |   2 +-
 .../node-cellar/node-cellar.yaml                |  10 +-
 8 files changed, 129 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/modeling/orchestration.py
----------------------------------------------------------------------
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index e7118f9..b5c735d 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -263,7 +263,6 @@ class TaskBase(ModelMixin):
     retry_interval = Column(Float, default=0)
     ignore_failure = Column(Boolean, default=False)
 
-    # Operation specific fields
     implementation = Column(String)
     configuration = Column(modeling_types.StrictDict(key_cls=basestring))
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 8852887..ecfae2c 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -391,16 +391,8 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     @property
     def ip(self):
-        # TODO: totally broken
-        if not self.host_fk:
-            return None
-        host_node = self.host
-        if 'ip' in host_node.runtime_properties:  # pylint: disable=no-member
-            return host_node.runtime_properties['ip']  # pylint: disable=no-member
-        host_node = host_node.node_template  # pylint: disable=no-member
-        host_ip_property = host_node.properties.get('ip')
-        if host_ip_property:
-            return host_ip_property.value
+        if self.host and self.host.runtime_properties:
+            return self.host.runtime_properties.get('ip')
         return None
 
     # endregion

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/orchestrator/execution_plugin/__init__.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/__init__.py b/aria/orchestrator/execution_plugin/__init__.py
index 5561ddf..aa1acc3 100644
--- a/aria/orchestrator/execution_plugin/__init__.py
+++ b/aria/orchestrator/execution_plugin/__init__.py
@@ -15,6 +15,7 @@
 
 from contextlib import contextmanager
 from ...modeling import models
+from ...utils.formatting import full_type_name
 
 
 # Populated during execution of python scripts
@@ -35,11 +36,12 @@ def python_script_scope(operation_ctx, operation_inputs):
         inputs = None
 
 
-def init_operation(operation_task):
+def configure_operation(operation_task):
     from . import operations
 
     inputs = {}
     inputs['script_path'] = operation_task.implementation
+    inputs['process'] = _get_process(operation_task.configuration.get('process'))
 
     host = None
     if operation_task.actor_type == 'node':
@@ -51,19 +53,39 @@ def init_operation(operation_task):
         elif edge == 'target':
             host = operation_task.actor.target_node.host
         else:
-            raise ValueError('"edge" configuration must be "source" or "target": {0}'.format(edge))
+            raise ValueError('"edge" configuration must be "source" or "target" for "{0}": {1}'
+                             .format(operation_task.implementation, edge))
+    ip = host.ip if host is not None else None
+    #ip = '1.2.3.4'
+    default_user = 'admin'
+    default_password = 'admin'
 
-    if host is None:
+    if ip is None:
         # Local operation
         operation_task.implementation = '{0}.{1}'.format(operations.__name__,
                                                          operations.run_script_locally.__name__)
     else:
         # Remote SSH operation via Fabric
-        inputs['use_sudo'] = _to_bool(operation_task.configuration.get('use_sudo'))
-        inputs['hide_output'] = operation_task.configuration.get('hide_output')
-        inputs['fabric_env'] = operation_task.configuration.get('fabric_env')
-        # How to set up fabric env?
-        # How to set up host address?
+        ssh = _get_ssh(operation_task.configuration.get('ssh'))
+        if 'user' not in ssh:
+            ssh['user'] = default_user
+            #raise ValueError('must configure "ssh.user" for "{0}"'
+            #                 .format(operation_task.implementation))
+        if ('password' not in ssh) and ('key' not in ssh) and ('key_filename' not in ssh):
+            ssh['password'] = default_password
+            #raise ValueError(
+            #    'must configure "ssh.password", "ssh.key", or "ssh.key_filename" for "{0}"'
+            #    .format(operation_task.implementation))
+        inputs['use_sudo'] = ssh.get('use_sudo')
+        inputs['hide_output'] = ssh.get('hide_output')
+        inputs['fabric_env'] = {}
+        inputs['fabric_env']['host_string'] = ip
+        if 'warn_only' in ssh:
+            inputs['fabric_env']['warn_only'] = ssh['warn_only']
+        inputs['fabric_env']['user'] = ssh.get('user')
+        inputs['fabric_env']['password'] = ssh.get('password')
+        inputs['fabric_env']['key'] = ssh.get('key')
+        inputs['fabric_env']['key_filename'] = ssh.get('key_filename')
         operation_task.implementation = '{0}.{1}'.format(operations.__name__,
                                                          operations.run_script_with_ssh.__name__)
 
@@ -71,7 +93,80 @@ def init_operation(operation_task):
         operation_task.inputs[k] = models.Parameter.wrap(k, v)
 
 
-def _to_bool(value):
+def _get_process(value):
+    from ..workflows.exceptions import TaskCreationException
     if value is None:
         return None
-    return unicode(value).lower() == 'true'
+    _validate_type(value, dict, 'process')
+    for k, v in value.iteritems():
+        if k == 'eval_python':
+            value[k] = _str_to_bool(v, 'process.eval_python')
+        elif k == 'cwd':
+            _validate_type(v, basestring, 'process.cwd')
+        elif k == 'command_prefix':
+            _validate_type(v, basestring, 'process.command_prefix')
+        elif k == 'args':
+            value[k] = _dict_to_list(v, 'process.args')
+        elif k == 'env':
+            _validate_type(v, dict, 'process.env')
+        else:
+            raise TaskCreationException('unsupported configuration: "process.{0}"'.format(k))
+    return value
+
+
+def _get_ssh(value):
+    from ..workflows.exceptions import TaskCreationException
+    if value is None:
+        return {}
+    _validate_type(value, dict, 'ssh')
+    for k, v in value.iteritems():
+        if k == 'use_sudo':
+            value[k] = _str_to_bool(v, 'ssh.use_sudo')
+        elif k == 'hide_output':
+            value[k] = _dict_to_list(v, 'ssh.hide_output')
+        elif k == 'warn_only':
+            value[k] = _str_to_bool(v, 'ssh.warn_only')
+        elif k == 'user':
+            _validate_type(v, basestring, 'ssh.user')
+        elif k == 'password':
+            _validate_type(v, basestring, 'ssh.password')
+        elif k == 'key':
+            _validate_type(v, basestring, 'ssh.key')
+        elif k == 'key_filename':
+            _validate_type(v, basestring, 'ssh.key_filename')
+        else:
+            raise TaskCreationException('unsupported configuration: "ssh.{0}"'.format(k))
+    return value
+
+
+def _validate_type(value, the_type, name):
+    from ..workflows.exceptions import TaskCreationException
+    if not isinstance(value, the_type):
+        raise TaskCreationException('"{0}" configuration is not a {1}' 
+                                    .format(name, full_type_name(the_type)))
+
+def _str_to_bool(value, name):
+    from ..workflows.exceptions import TaskCreationException
+    if value is None:
+        return None
+    _validate_type(value, basestring, name)
+    if value == 'true':
+        return True
+    elif value == 'false':
+        return False
+    else:
+        raise TaskCreationException('"{0}" configuration is not "true" or "false": {1}'
+                                    .format(name, repr(value)))
+
+
+def _dict_to_list(the_dict, name):
+    from ..workflows.exceptions import TaskCreationException
+    _validate_type(the_dict, dict, name)
+    value = []
+    for k in sorted(the_dict):
+        v = the_dict[k]
+        if not isinstance(v, basestring):
+            raise TaskCreationException('"{0}.{1}" configuration is not a string: {2}'
+                                        .format(name, k, repr(v)))
+        value.append(v)
+    return value

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/orchestrator/execution_plugin/ssh/operations.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/ssh/operations.py b/aria/orchestrator/execution_plugin/ssh/operations.py
index f240beb..d760ba8 100644
--- a/aria/orchestrator/execution_plugin/ssh/operations.py
+++ b/aria/orchestrator/execution_plugin/ssh/operations.py
@@ -143,8 +143,6 @@ def _fabric_env(ctx, fabric_env, warn_only):
     env = constants.FABRIC_ENV_DEFAULTS.copy()
     env.update(fabric_env or {})
     env.setdefault('warn_only', warn_only)
-    if 'host_string' not in env:
-        env['host_string'] = ctx.task.runs_on.ip
     # validations
     if not env.get('host_string'):
         ctx.task.abort('`host_string` not supplied and ip cannot be deduced automatically')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/orchestrator/workflows/api/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/api/task.py b/aria/orchestrator/workflows/api/task.py
index 902f1be..150863d 100644
--- a/aria/orchestrator/workflows/api/task.py
+++ b/aria/orchestrator/workflows/api/task.py
@@ -89,6 +89,11 @@ class OperationTask(BaseTask):
                 'Could not find operation "{0}" on interface "{1}" for {2} "{3}"'
                 .format(operation_name, interface_name, actor_type, actor.name))
 
+        if operation.implementation is None:
+            raise exceptions.OperationNotFoundException(
+                'Empty operation "{0}" on interface "{1}" for {2} "{3}"'
+                .format(operation_name, interface_name, actor_type, actor.name))
+
         self.name = OperationTask.NAME_FORMAT.format(type=actor_type,
                                                      name=actor.name,
                                                      interface=interface_name,
@@ -127,7 +132,7 @@ class OperationTask(BaseTask):
                             actor_type, actor.name))
         else:
             # Default plugin (execution)
-            execution_plugin.init_operation(self)
+            execution_plugin.configure_operation(self)
 
     @classmethod
     def for_node(cls,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/aria/orchestrator/workflows/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/exceptions.py b/aria/orchestrator/workflows/exceptions.py
index 4fb8dd7..0ca263f 100644
--- a/aria/orchestrator/workflows/exceptions.py
+++ b/aria/orchestrator/workflows/exceptions.py
@@ -70,13 +70,19 @@ class TaskException(exceptions.AriaError):
     """
 
 
-class OperationNotFoundException(TaskException):
+class TaskCreationException(TaskException):
+    """
+    Could not create the task.
+    """
+
+
+class OperationNotFoundException(TaskCreationException):
     """
     Could not find an operation on the node or relationship.
     """
 
 
-class PluginNotFoundException(TaskException):
+class PluginNotFoundException(TaskCreationException):
     """
     Could not find a plugin matching the plugin specification.
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 45c26eb..a54c57c 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -693,5 +693,5 @@ def set_nested(the_dict, keys, value):
         the_dict[key] = value
     else:
         if key not in the_dict:
-            the_dict[key] = StrictDict(key_class=basestring, value_class=basestring)
+            the_dict[key] = StrictDict(key_class=basestring)
         set_nested(the_dict[key], keys, value)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/842ec0d4/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index 3cffc0b..65fbf92 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -160,11 +160,15 @@ topology_template:
                 Configure:
                   target_changed:
                     implementation:
-                      primary: mongodb/host_changed.sh
+                      primary: changed.sh
                       dependencies:
-                        - runs_on > target
+                        - edge > target
+                        #- { concat: [ process.args.1 >, mongodb ] }
+                        - process.args.1 > mongodb
+                        - process.args.2 > host
                         - ssh.user > admin
-                        - ssh.password > 12345
+                        - ssh.password > 1234
+                        - ssh.use_sudo > true
 
     nginx:
       type: nginx.Nginx