Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
ARIA-105 Integrate parser and orchestrator models
  • Loading branch information
tliron committed Mar 21, 2017
1 parent 95177d0 commit 9841ca4ae8df4353a75250ce57adfaaacec3aa88
Show file tree
Hide file tree
Showing 107 changed files with 7,517 additions and 8,834 deletions.
@@ -14,8 +14,8 @@
# limitations under the License.

"""
Aria Version module:
* version: Aria Package version
ARIA Version module:
* version: ARIA Package version
"""

version = '0.1.0' # pylint: disable=C0103
@@ -14,7 +14,7 @@
# limitations under the License.

"""
Aria top level package
ARIA top level package
"""

import sys
@@ -27,6 +27,7 @@
utils,
parser,
storage,
modeling,
orchestrator,
cli
)
@@ -69,48 +70,9 @@ def application_model_storage(api, api_kwargs=None, initiator=None, initiator_kw
"""
Initiate model storage
"""
models_to_register = [
storage.modeling.model.Parameter,

storage.modeling.model.MappingTemplate,
storage.modeling.model.SubstitutionTemplate,
storage.modeling.model.ServiceTemplate,
storage.modeling.model.NodeTemplate,
storage.modeling.model.GroupTemplate,
storage.modeling.model.InterfaceTemplate,
storage.modeling.model.OperationTemplate,
storage.modeling.model.ArtifactTemplate,
storage.modeling.model.PolicyTemplate,
storage.modeling.model.GroupPolicyTemplate,
storage.modeling.model.GroupPolicyTriggerTemplate,
storage.modeling.model.RequirementTemplate,
storage.modeling.model.CapabilityTemplate,

storage.modeling.model.Mapping,
storage.modeling.model.Substitution,
storage.modeling.model.ServiceInstance,
storage.modeling.model.Node,
storage.modeling.model.Group,
storage.modeling.model.Interface,
storage.modeling.model.Operation,
storage.modeling.model.Capability,
storage.modeling.model.Artifact,
storage.modeling.model.Policy,
storage.modeling.model.GroupPolicy,
storage.modeling.model.GroupPolicyTrigger,
storage.modeling.model.Relationship,

storage.modeling.model.Execution,
storage.modeling.model.ServiceInstanceUpdate,
storage.modeling.model.ServiceInstanceUpdateStep,
storage.modeling.model.ServiceInstanceModification,
storage.modeling.model.Plugin,
storage.modeling.model.Task,
storage.modeling.model.Log
]
return storage.ModelStorage(api_cls=api,
api_kwargs=api_kwargs,
items=models_to_register,
items=modeling.models.models_to_register,
initiator=initiator,
initiator_kwargs=initiator_kwargs or {})

@@ -91,7 +91,7 @@ def add_parse_parser(parse):
'consumer',
nargs='?',
default='validate',
help='"validate" (default), "presentation", "model", "types", "instance", or consumer '
help='"validate" (default), "presentation", "template", "types", "instance", or consumer '
'class name (full class path or short name)')
parse.add_argument(
'--loader-source',
@@ -137,10 +137,11 @@ def add_workflow_parser(workflow):
'-w', '--workflow',
default='install',
help='The workflow name')
workflow.add_argument(
'-i', '--service-instance-id',
required=False,
help='A unique ID for the service instance')
workflow.add_flag_argument(
'dry',
default=True,
help_true='dry run',
help_false='wet run')


@sub_parser_decorator(
@@ -36,13 +36,12 @@
ConsumerChain,
Read,
Validate,
Model,
ServiceTemplate,
Types,
Inputs,
Instance
ServiceInstance
)
from ..parser.loading import LiteralLocation, UriLocation
from ..parser.modeling.storage import initialize_storage
from ..utils.application import StorageManager
from ..utils.caching import cachedmethod
from ..utils.console import (puts, Colored, indent)
@@ -51,6 +50,7 @@
from ..orchestrator import WORKFLOW_DECORATOR_RESERVED_ARGUMENTS
from ..orchestrator.runner import Runner
from ..orchestrator.workflows.builtin import BUILTIN_WORKFLOWS
from .dry import convert_to_dry

from .exceptions import (
AriaCliFormatInputsError,
@@ -157,14 +157,14 @@ def __call__(self, args_namespace, unknown_args):
dumper = None
elif consumer_class_name == 'presentation':
dumper = consumer.consumers[0]
elif consumer_class_name == 'model':
consumer.append(Model)
elif consumer_class_name == 'template':
consumer.append(ServiceTemplate)
elif consumer_class_name == 'types':
consumer.append(Model, Types)
consumer.append(ServiceTemplate, Types)
elif consumer_class_name == 'instance':
consumer.append(Model, Inputs, Instance)
consumer.append(ServiceTemplate, Inputs, ServiceInstance)
else:
consumer.append(Model, Inputs, Instance)
consumer.append(ServiceTemplate, Inputs, ServiceInstance)
consumer.append(import_fullname(consumer_class_name))

if dumper is None:
@@ -211,16 +211,17 @@ class WorkflowCommand(BaseCommand):
def __call__(self, args_namespace, unknown_args):
super(WorkflowCommand, self).__call__(args_namespace, unknown_args)

service_instance_id = args_namespace.service_instance_id or 1
context = self._parse(args_namespace.uri)
workflow_fn, inputs = self._get_workflow(context, args_namespace.workflow)
self._run(context, args_namespace.workflow, workflow_fn, inputs, service_instance_id)
self._dry = args_namespace.dry
self._run(context, args_namespace.workflow, workflow_fn, inputs)

def _parse(self, uri):
# Parse
context = ConsumptionContext()
context.presentation.location = UriLocation(uri)
consumer = ConsumerChain(context, (Read, Validate, Model, Inputs, Instance))
consumer = ConsumerChain(context, (Read, Validate, ServiceTemplate, Inputs,
ServiceInstance))
consumer.consume()

if context.validation.dump_issues():
@@ -230,43 +231,45 @@ def _parse(self, uri):

def _get_workflow(self, context, workflow_name):
if workflow_name in BUILTIN_WORKFLOWS:
workflow_fn = import_fullname('aria.orchestrator.workflows.builtin.%s' % workflow_name)
workflow_fn = import_fullname('aria.orchestrator.workflows.builtin.{0}'.format(
workflow_name))
inputs = {}
else:
workflow = context.modeling.instance.policies.get(workflow_name)
if workflow is None:
raise AttributeError('workflow policy does not exist: "{0}"'.format(workflow_name))
if workflow.type.role != 'workflow':
raise AttributeError('policy is not a workflow: "{0}"'.format(workflow_name))

try:
policy = context.modeling.instance.policies[workflow_name]
except KeyError:
raise AttributeError('workflow policy does not exist: "%s"' % workflow_name)
if context.modeling.policy_types.get_role(policy.type_name) != 'workflow':
raise AttributeError('policy is not a workflow: "%s"' % workflow_name)

try:
sys.path.append(policy.properties['implementation'].value)
sys.path.append(workflow.properties['implementation'].value)
except KeyError:
pass

workflow_fn = import_fullname(policy.properties['function'].value)
workflow_fn = import_fullname(workflow.properties['function'].value)

for k in policy.properties:
for k in workflow.properties:
if k in WORKFLOW_DECORATOR_RESERVED_ARGUMENTS:
raise AttributeError('workflow policy "%s" defines a reserved property: "%s"' %
(workflow_name, k))
raise AttributeError('workflow policy "{0}" defines a reserved property: "{1}"'
.format(workflow_name, k))

inputs = OrderedDict([
(k, v.value) for k, v in policy.properties.iteritems()
(k, v.value) for k, v in workflow.properties.iteritems()
if k not in WorkflowCommand.WORKFLOW_POLICY_INTERNAL_PROPERTIES
])

return workflow_fn, inputs

def _run(self, context, workflow_name, workflow_fn, inputs, service_instance_id):
def _run(self, context, workflow_name, workflow_fn, inputs):
# Storage
def _initialize_storage(model_storage):
initialize_storage(context, model_storage, service_instance_id)
if self._dry:
convert_to_dry(context.modeling.instance)
context.modeling.store(model_storage)

# Create runner
runner = Runner(workflow_name, workflow_fn, inputs, _initialize_storage,
service_instance_id)
lambda: context.modeling.instance.id)

# Run
runner.run()
@@ -0,0 +1,88 @@
# 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 threading import RLock

from ..modeling import models
from ..orchestrator.decorators import operation
from ..utils.collections import OrderedDict
from ..utils.console import puts, Colored
from ..utils.formatting import safe_repr


_TERMINAL_LOCK = RLock()


def convert_to_dry(service):
"""
Converts all operations on the service (on workflows, node interfaces, and relationship
interfaces) to run dryly.
"""

for workflow in service.workflows:
convert_operation_to_dry(workflow)

for node in service.nodes.itervalues():
for interface in node.interfaces.itervalues():
for oper in interface.operations.itervalues():
convert_operation_to_dry(oper)
for relationship in node.outbound_relationships:
for interface in relationship.interfaces.itervalues():
for oper in interface.operations.itervalues():
convert_operation_to_dry(oper)


def convert_operation_to_dry(oper):
"""
Converts a single :class:`Operation` to run dryly.
"""

plugin = oper.plugin_specification.name \
if oper.plugin_specification is not None else None
if oper.inputs is None:
oper.inputs = OrderedDict()
oper.inputs['_implementation'] = models.Parameter(name='_implementation',
type_name='string',
value=oper.implementation)
oper.inputs['_plugin'] = models.Parameter(name='_plugin',
type_name='string',
value=plugin)
oper.implementation = '{0}.{1}'.format(__name__, 'dry_operation')
oper.plugin_specification = None


@operation
def dry_operation(ctx, _plugin, _implementation, **kwargs):
"""
The dry operation simply prints out information about the operation to the console.
"""

with _TERMINAL_LOCK:
print ctx.name
if hasattr(ctx, 'relationship'):
puts('> Relationship: {0} -> {1}'.format(
Colored.red(ctx.relationship.source_node.name),
Colored.red(ctx.relationship.target_node.name)))
else:
puts('> Node: {0}'.format(Colored.red(ctx.node.name)))
puts(' Operation: {0}'.format(Colored.green(ctx.name)))
_dump_implementation(_plugin, _implementation)


def _dump_implementation(plugin, implementation):
if plugin:
puts(' Plugin: {0}'.format(Colored.magenta(plugin, bold=True)))
if implementation:
puts(' Implementation: {0}'.format(Colored.magenta(safe_repr(implementation))))
@@ -14,8 +14,8 @@
# limitations under the License.

"""
Aria exceptions module
Every sub-package in Aria has a module with its exceptions.
ARIA exceptions module
Every sub-package in ARIA has a module with its exceptions.
aria.exceptions module conveniently collects all these exceptions for easier imports.
"""

@@ -43,4 +43,4 @@ def __init__(self, message=None, cause=None, cause_traceback=None):
if cause == e:
# Make sure it's our traceback
cause_traceback = traceback
self.cause_tb = cause_traceback
self.cause_traceback = cause_traceback
@@ -167,7 +167,7 @@ def emit(self, record):
task_fk=record.task_id,
actor=record.prefix,
level=record.levelname,
msg=record.msg,
msg=str(record.msg),
created_at=created_at,
)
self._session.add(log)
@@ -0,0 +1,48 @@
# 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 collections import namedtuple

from . import (
mixins,
types,
models,
service_template as _service_template_bases,
service_instance as _service_instance_bases,
service_changes as _service_changes_bases,
service_common as _service_common_bases,
orchestration as _orchestration_bases
)


_ModelBasesCls = namedtuple('ModelBase', 'service_template,'
'service_instance,'
'service_changes,'
'service_common,'
'orchestration')

model_bases = _ModelBasesCls(service_template=_service_template_bases,
service_instance=_service_instance_bases,
service_changes=_service_changes_bases,
service_common=_service_common_bases,
orchestration=_orchestration_bases)


__all__ = (
'mixins',
'types',
'models',
'model_bases',
)

0 comments on commit 9841ca4

Please sign in to comment.