summaryrefslogtreecommitdiffstats
path: root/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py
diff options
context:
space:
mode:
Diffstat (limited to 'azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py')
-rw-r--r--azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py223
1 files changed, 223 insertions, 0 deletions
diff --git a/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py b/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py
new file mode 100644
index 0000000..f86c9dd
--- /dev/null
+++ b/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/topology/topology.py
@@ -0,0 +1,223 @@
+# 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 ...parser.validation import issue
+from ...modeling import models
+from ...utils import console
+from . import (
+ template_handler,
+ instance_handler,
+ common
+)
+
+
+class Topology(issue.ReporterMixin):
+
+ _init_map = {
+ models.ServiceTemplate: models.Service,
+ models.ArtifactTemplate: models.Artifact,
+ models.CapabilityTemplate: models.Capability,
+ models.GroupTemplate: models.Group,
+ models.InterfaceTemplate: models.Interface,
+ models.NodeTemplate: models.Node,
+ models.PolicyTemplate: models.Policy,
+ models.SubstitutionTemplate: models.Substitution,
+ models.RelationshipTemplate: models.Relationship,
+ models.OperationTemplate: models.Operation,
+ models.SubstitutionTemplateMapping: models.SubstitutionMapping,
+
+ # Common
+ models.Metadata: models.Metadata,
+ models.Attribute: models.Attribute,
+ models.Property: models.Property,
+ models.Input: models.Input,
+ models.Output: models.Output,
+ models.Configuration: models.Configuration,
+ models.Argument: models.Argument,
+ models.Type: models.Type
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(Topology, self).__init__(*args, **kwargs)
+ self._model_cls_to_handler = dict(self._init_handlers(instance_handler),
+ **self._init_handlers(template_handler))
+
+ @staticmethod
+ def _init_handlers(module_):
+ """
+ Register handlers from a handler module to the models.
+
+ :param module_: the module to look for handlers
+ :returns: dict where the key is the models class, and the value is the handler class
+ associated with it from the provided module
+ """
+ handlers = {}
+ for attribute_name in dir(module_):
+ if attribute_name.startswith('_'):
+ continue
+ attribute = getattr(module_, attribute_name)
+ if isinstance(attribute, type) and issubclass(attribute, common.HandlerBase):
+ handlers[getattr(models, attribute_name)] = attribute
+ return handlers
+
+ def instantiate(self, model, **kwargs):
+ """
+ Instantiate the provided model.
+
+ :param model:
+ :param kwargs:
+ :returns:
+ """
+ if isinstance(model, dict):
+ return dict((name, self.instantiate(value, **kwargs))
+ for name, value in model.iteritems())
+ elif isinstance(model, list):
+ return list(self.instantiate(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ model_instance_cls = self._init_map[model.__class__]
+ return _handler(self, model).instantiate(model_instance_cls, **kwargs)
+
+ def validate(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.validate(model.values(), **kwargs)
+ elif isinstance(model, list):
+ return all(self.validate(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ return _handler(self, model).validate(**kwargs)
+
+ def dump(self, model, out_stream=None, title=None, **kwargs):
+ out_stream = out_stream or console.TopologyStylizer()
+
+ # if model is empty, no need to print out the section name
+ if model and title:
+ out_stream.write('{0}:'.format(title))
+
+ if isinstance(model, dict):
+ if str(out_stream):
+ with out_stream.indent():
+ return self.dump(model.values(), out_stream=out_stream, **kwargs)
+ else:
+ return self.dump(model.values(), out_stream=out_stream, **kwargs)
+
+ elif isinstance(model, list):
+ for value in model:
+ self.dump(value, out_stream=out_stream, **kwargs)
+
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ _handler(self, model).dump(out_stream=out_stream, **kwargs)
+
+ return out_stream
+
+ def dump_graph(self, service):
+ out_stream = console.TopologyStylizer()
+ for node in service.nodes.itervalues():
+ if not node.inbound_relationships:
+ self._dump_graph_node(out_stream, node)
+ return out_stream
+
+ def _dump_graph_node(self, out_stream, node, capability=None):
+ out_stream.write(out_stream.node_style(node.name))
+ if capability is not None:
+ out_stream.write('{0} ({1})'.format(out_stream.property_style(capability.name),
+ out_stream.type_style(capability.type.name)))
+ if node.outbound_relationships:
+ with out_stream.indent():
+ for relationship_model in node.outbound_relationships:
+ styled_relationship_name = out_stream.property_style(relationship_model.name)
+ if relationship_model.type is not None:
+ out_stream.write('-> {0} ({1})'.format(
+ styled_relationship_name,
+ out_stream.type_style(relationship_model.type.name)))
+ else:
+ out_stream.write('-> {0}'.format(styled_relationship_name))
+ with out_stream.indent(3):
+ self._dump_graph_node(out_stream,
+ relationship_model.target_node,
+ relationship_model.target_capability)
+
+ def coerce(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.coerce(model.values(), **kwargs)
+ elif isinstance(model, list):
+ return all(self.coerce(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ return _handler(self, model).coerce(**kwargs)
+
+ def dump_types(self, service_template, out_stream=None):
+ out_stream = out_stream or console.TopologyStylizer()
+ self.dump(service_template.node_types, out_stream, 'Node types')
+ self.dump(service_template.group_types, out_stream, 'Group types')
+ self.dump(service_template.capability_types, out_stream, 'Capability types')
+ self.dump(service_template.relationship_types, out_stream, 'Relationship types')
+ self.dump(service_template.policy_types, out_stream, 'Policy types')
+ self.dump(service_template.artifact_types, out_stream, 'Artifact types')
+ self.dump(service_template.interface_types, out_stream, 'Interface types')
+
+ return out_stream
+
+ def satisfy_requirements(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.satisfy_requirements(model.values(), **kwargs)
+ elif isinstance(model, list):
+ return all(self.satisfy_requirements(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ return _handler(self, model).satisfy_requirements(**kwargs)
+
+ def validate_capabilities(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.validate_capabilities(model.values(), **kwargs)
+ elif isinstance(model, list):
+ return all(self.validate_capabilities(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ return _handler(self, model).validate_capabilities(**kwargs)
+
+ def _find_host(self, node):
+ if node.type.role == 'host':
+ return node
+
+ def target_has_role(rel, role):
+ return (rel.target_capability is not None and
+ rel.target_capability.type.role == role)
+
+ for outbound_relationship in node.outbound_relationships:
+ if target_has_role(outbound_relationship, 'host'):
+ host = self._find_host(outbound_relationship.target_node)
+ if host is not None:
+ return host
+ for inbound_relationship in node.inbound_relationships:
+ if target_has_role(inbound_relationship, 'feature'):
+ host = self._find_host(inbound_relationship.source_node)
+ if host is not None:
+ return host
+ return None
+
+ def assign_hosts(self, service):
+ for node in service.nodes.values():
+ node.host = self._find_host(node)
+
+ def configure_operations(self, model, **kwargs):
+ if isinstance(model, dict):
+ return self.configure_operations(model.values(), **kwargs)
+ elif isinstance(model, list):
+ return all(self.configure_operations(value, **kwargs) for value in model)
+ elif model is not None:
+ _handler = self._model_cls_to_handler[model.__class__]
+ return _handler(self, model).configure_operations(**kwargs)