vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / core.py
diff --git a/azure/aria/aria-extension-cloudify/src/aria/aria/core.py b/azure/aria/aria-extension-cloudify/src/aria/aria/core.py
new file mode 100644 (file)
index 0000000..e364f48
--- /dev/null
@@ -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.
+
+"""
+ARIA core module.
+"""
+
+from . import exceptions
+from .parser import consumption
+from .parser.loading.location import UriLocation
+from .orchestrator import topology
+
+
+class Core(object):
+
+    def __init__(self,
+                 model_storage,
+                 resource_storage,
+                 plugin_manager):
+        self._model_storage = model_storage
+        self._resource_storage = resource_storage
+        self._plugin_manager = plugin_manager
+
+    @property
+    def model_storage(self):
+        return self._model_storage
+
+    @property
+    def resource_storage(self):
+        return self._resource_storage
+
+    @property
+    def plugin_manager(self):
+        return self._plugin_manager
+
+    def validate_service_template(self, service_template_path):
+        self._parse_service_template(service_template_path)
+
+    def create_service_template(self, service_template_path, service_template_dir,
+                                service_template_name):
+        context = self._parse_service_template(service_template_path)
+        service_template = context.modeling.template
+        service_template.name = service_template_name
+        self.model_storage.service_template.put(service_template)
+        self.resource_storage.service_template.upload(
+            entry_id=str(service_template.id), source=service_template_dir)
+        return service_template.id
+
+    def delete_service_template(self, service_template_id):
+        service_template = self.model_storage.service_template.get(service_template_id)
+        if service_template.services:
+            raise exceptions.DependentServicesError(
+                'Can\'t delete service template `{0}` - service template has existing services'
+                .format(service_template.name))
+
+        self.model_storage.service_template.delete(service_template)
+        self.resource_storage.service_template.delete(entry_id=str(service_template.id))
+
+    def create_service(self, service_template_id, inputs, service_name=None):
+        service_template = self.model_storage.service_template.get(service_template_id)
+
+        storage_session = self.model_storage._all_api_kwargs['session']
+        # setting no autoflush for the duration of instantiation - this helps avoid dependency
+        # constraints as they're being set up
+        with storage_session.no_autoflush:
+            topology_ = topology.Topology()
+            service = topology_.instantiate(
+                service_template, inputs=inputs, plugins=self.model_storage.plugin.list())
+            topology_.coerce(service, report_issues=True)
+
+            topology_.validate(service)
+            topology_.satisfy_requirements(service)
+            topology_.coerce(service, report_issues=True)
+
+            topology_.validate_capabilities(service)
+            topology_.assign_hosts(service)
+            topology_.configure_operations(service)
+            topology_.coerce(service, report_issues=True)
+            if topology_.dump_issues():
+                raise exceptions.InstantiationError('Failed to instantiate service template `{0}`'
+                                                    .format(service_template.name))
+
+        storage_session.flush()  # flushing so service.id would auto-populate
+        service.name = service_name or '{0}_{1}'.format(service_template.name, service.id)
+        self.model_storage.service.put(service)
+        return service
+
+    def delete_service(self, service_id, force=False):
+        service = self.model_storage.service.get(service_id)
+
+        active_executions = [e for e in service.executions if e.is_active()]
+        if active_executions:
+            raise exceptions.DependentActiveExecutionsError(
+                'Can\'t delete service `{0}` - there is an active execution for this service. '
+                'Active execution ID: {1}'.format(service.name, active_executions[0].id))
+
+        if not force:
+            available_nodes = [str(n.id) for n in service.nodes.itervalues() if n.is_available()]
+            if available_nodes:
+                raise exceptions.DependentAvailableNodesError(
+                    'Can\'t delete service `{0}` - there are available nodes for this service. '
+                    'Available node IDs: {1}'.format(service.name, ', '.join(available_nodes)))
+
+        self.model_storage.service.delete(service)
+
+    @staticmethod
+    def _parse_service_template(service_template_path):
+        context = consumption.ConsumptionContext()
+        context.presentation.location = UriLocation(service_template_path)
+        # Most of the parser uses the topology package in order to manipulate the models.
+        # However, here we use the Consumer mechanism, but this should change in the future.
+        consumption.ConsumerChain(
+            context,
+            (
+                consumption.Read,
+                consumption.Validate,
+                consumption.ServiceTemplate
+            )).consume()
+        if context.validation.dump_issues():
+            raise exceptions.ParsingError('Failed to parse service template')
+        return context