From d8beb7f217666d555d0a612d9f6988cf2f739bae Mon Sep 17 00:00:00 2001 From: Vidisha Date: Fri, 26 Oct 2018 18:07:28 +0300 Subject: [PATCH] Azure-plugin not sending REST calls to Azure cloud Change-Id: I2179d1a99f3fdede34c7f21069b3af2fcaf6776c Issue-ID: MULTICLOUD-385 Signed-off-by: Vidisha --- .../src/aria/aria/orchestrator/workflow_runner.py | 38 +++---- azure/aria/aria-rest-server/VERSION | 1 + azure/aria/aria-rest-server/build.py | 95 +++++++++++++++++ azure/aria/aria-rest-server/pom.xml | 114 +++++++++++++++++++++ azure/aria/aria-rest-server/setup.py | 41 ++++++++ .../src/main/python/aria-rest/LICENSE | 18 ++++ .../src/main/python/aria-rest/__init__.py | 19 ++++ .../main/python/aria-rest/aria_rest/__init__.py | 19 ++++ .../src/main/python/aria-rest/aria_rest/rest.py | 90 ++++++++++++++++ .../aria-rest/aria_rest/templates/index.html | 23 +++++ .../src/main/python/aria-rest/aria_rest/util.py | 48 +++++++++ .../src/main/python/aria-rest/rest.py | 57 +++++++++++ .../src/main/python/aria-rest/setup.py | 42 ++++++++ .../src/main/python/aria-rest/templates/index.html | 3 + azure/docker/Dockerfile | 6 +- azure/multicloud_azure/pub/aria/service.py | 42 +------- azure/multicloud_azure/pub/config/config.py | 3 + azure/multicloud_azure/pub/utils/restcall.py | 10 ++ azure/multicloud_azure/tests/test_aria_view.py | 29 ------ azure/run.sh | 1 + 20 files changed, 609 insertions(+), 90 deletions(-) create mode 100644 azure/aria/aria-rest-server/VERSION create mode 100644 azure/aria/aria-rest-server/build.py create mode 100644 azure/aria/aria-rest-server/pom.xml create mode 100644 azure/aria/aria-rest-server/setup.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py create mode 100644 azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html diff --git a/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/workflow_runner.py b/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/workflow_runner.py index 0c52e32..eb4efeb 100644 --- a/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/workflow_runner.py +++ b/azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/workflow_runner.py @@ -30,6 +30,7 @@ from ..modeling import models from ..modeling import utils as modeling_utils from ..utils.imports import import_fullname + DEFAULT_TASK_MAX_ATTEMPTS = 30 DEFAULT_TASK_RETRY_INTERVAL = 30 @@ -68,30 +69,24 @@ class WorkflowRunner(object): self._resource_storage = resource_storage # the IDs are stored rather than the models themselves, so this module could be used - # by several threads without raising errors on model objects shared between threadsF + # by several threads without raising errors on model objects shared between threads if self._is_resume: - self._service_id = service_id - # self._service_id = self.execution.service.id - # self._workflow_name = model_storage.execution.get(self._execution_id).workflow_name - self._workflow_name = workflow_name - self._validate_workflow_exists_for_service() self._execution_id = execution_id - + self._service_id = self.execution.service.id + self._workflow_name = model_storage.execution.get(self._execution_id).workflow_name else: self._service_id = service_id self._workflow_name = workflow_name self._validate_workflow_exists_for_service() self._execution_id = self._create_execution_model(inputs).id - self._create_execution_model(inputs, execution_id) - self._workflow_context = WorkflowContext( name=self.__class__.__name__, model_storage=self._model_storage, resource_storage=resource_storage, service_id=service_id, - execution_id=execution_id, + execution_id=self._execution_id, workflow_name=self._workflow_name, task_max_attempts=task_max_attempts, task_retry_interval=task_retry_interval) @@ -100,13 +95,13 @@ class WorkflowRunner(object): executor = executor or ProcessExecutor(plugin_manager=plugin_manager) # transforming the execution inputs to dict, to pass them to the workflow function - # execution_inputs_dict = dict(inp.unwrapped for inp in self.execution.inputs.itervalues()) + execution_inputs_dict = dict(inp.unwrapped for inp in self.execution.inputs.itervalues()) - # if not self._is_resume: - # workflow_fn = self._get_workflow_fn() - # self._tasks_graph = workflow_fn(ctx=self._workflow_context, **execution_inputs_dict) - # compiler = graph_compiler.GraphCompiler(self._workflow_context, executor.__class__) - # compiler.compile(self._tasks_graph) + if not self._is_resume: + workflow_fn = self._get_workflow_fn() + self._tasks_graph = workflow_fn(ctx=self._workflow_context, **execution_inputs_dict) + compiler = graph_compiler.GraphCompiler(self._workflow_context, executor.__class__) + compiler.compile(self._tasks_graph) self._engine = engine.Engine(executors={executor.__class__: executor}) @@ -116,7 +111,7 @@ class WorkflowRunner(object): @property def execution(self): - return self._model_storage.execution.get(self._execution_id) + return self._model_storage.execution.get(self.execution_id) @property def service(self): @@ -130,7 +125,7 @@ class WorkflowRunner(object): def cancel(self): self._engine.cancel_execution(ctx=self._workflow_context) - def _create_execution_model(self, inputs, execution_id): + def _create_execution_model(self, inputs): execution = models.Execution( created_at=datetime.utcnow(), service=self.service, @@ -148,7 +143,6 @@ class WorkflowRunner(object): supplied_inputs=inputs or {}) execution.inputs = modeling_utils.merge_parameter_values( inputs, workflow_inputs, model_cls=models.Input) - execution.id = execution_id # TODO: these two following calls should execute atomically self._validate_no_active_executions(execution) self._model_storage.execution.put(execution) @@ -156,17 +150,17 @@ class WorkflowRunner(object): def _validate_workflow_exists_for_service(self): if self._workflow_name not in self.service.workflows and \ - self._workflow_name not in builtin.BUILTIN_WORKFLOWS: + self._workflow_name not in builtin.BUILTIN_WORKFLOWS: raise exceptions.UndeclaredWorkflowError( 'No workflow policy {0} declared in service {1}' - .format(self._workflow_name, self.service.name)) + .format(self._workflow_name, self.service.name)) def _validate_no_active_executions(self, execution): active_executions = [e for e in self.service.executions if e.is_active()] if active_executions: raise exceptions.ActiveExecutionsError( "Can't start execution; Service {0} has an active execution with ID {1}" - .format(self.service.name, active_executions[0].id)) + .format(self.service.name, active_executions[0].id)) def _get_workflow_fn(self): if self._workflow_name in builtin.BUILTIN_WORKFLOWS: diff --git a/azure/aria/aria-rest-server/VERSION b/azure/aria/aria-rest-server/VERSION new file mode 100644 index 0000000..f755149 --- /dev/null +++ b/azure/aria/aria-rest-server/VERSION @@ -0,0 +1 @@ +1.0.0-SNAPSHOT diff --git a/azure/aria/aria-rest-server/build.py b/azure/aria/aria-rest-server/build.py new file mode 100644 index 0000000..cd2bcbf --- /dev/null +++ b/azure/aria/aria-rest-server/build.py @@ -0,0 +1,95 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + +import subprocess +import os +import sys +import glob +import xml.etree.ElementTree as etree + +# create and enter venv +def create_venv( name): + if subprocess.call("virtualenv {}".format(name), shell = True): + raise Exception("virtualenv create failed") + ret = subprocess.call(". {}/bin/activate && python {} run". \ + format(name,__file__), shell = True) + sys.exit(ret) + +def init_venv(): + subprocess.call("pip install -U pip", shell = True) + subprocess.call("pip install -U setuptools", shell = True) + subprocess.call("pip install wheel", shell = True) + subprocess.call("pip install twine", shell = True) + + +if len(sys.argv) == 1: + create_venv ("mavenvenv") +else: + init_venv() + + if os.environ['MVN_PHASE'] == 'package': + wheelname = os.environ['WHEEL_NAME'] + inputdir = os.environ['INPUT_DIR'] + outputdir = os.environ['OUTPUT_DIR'] + savedir = os.getcwd() + os.chdir(inputdir) + + if subprocess.call( [ "python", + "setup.py", + "bdist_wheel", + "-d", + outputdir + ]): + sys.stderr("wheel create failed") + sys.exit(1) + f = glob.glob(outputdir+"/*.whl")[0] + os.rename(f , outputdir+"/"+ wheelname) + + elif os.environ['MVN_PHASE'] == 'deploy': + + it = etree.iterparse(os.environ['SETTINGS_FILE']) + for _, el in it: + el.tag = el.tag.split('}', 1)[1] # strip namespace + settings = it.root + + username = settings.find('.//server[id="{}"]/username'.format( + os.environ['PYPI_SERVERID'])).text + password = settings.find('.//server[id="{}"]/password'.format( + os.environ['PYPI_SERVERID'])).text + + try: + if subprocess.call( [ "twine", + "upload", + "--username", + username, + "--password", + password, + "--repository-url", + os.environ["PYPI_SERVER_BASEURL"], + os.environ["WHEEL_PATH"] + ] ): + sys.stderr.write("pypi upload failed") + sys.exit(1) + finally: + subprocess.call("rm -rf mavenvenv", shell = True) + + sys.exit(0) + else: + sys.stderr.write("Unrecognized phase '{}'\n".format( + os.environ('MVN_PHASE'))) + sys.exit(1) diff --git a/azure/aria/aria-rest-server/pom.xml b/azure/aria/aria-rest-server/pom.xml new file mode 100644 index 0000000..6bfa5c2 --- /dev/null +++ b/azure/aria/aria-rest-server/pom.xml @@ -0,0 +1,114 @@ + + + + + 4.0.0 + pom + org.onap.multicloud.aria + ariarest + ariarest + 0.1.0-SNAPSHOT + ARIA REST API wheel build + + org.onap.multicloud.azure + multicloud-azure + 1.1.0-SNAPSHOT + + + + 2 + UTF-8 + ${project.artifactId}-${project.version}-py${python_version}-none-any.whl + ${project.basedir}/src/main/python/aria-rest + http://192.168.33.1:8081/repository/pypi-internal/ + ecomp-snapshots + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + write-python-version + + regex-property + + initialize + + python_version + -SNAPSHOT + ${project.version} + \.dev0 + false + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + package + package + exec + + python + + ${project.basedir}/build.py + + + package + ${wheel.name} + ${project.basedir}/src/main/python/aria-rest + ${project.build.directory} + + + + + deploy + deploy + exec + + python + + ${project.basedir}/build.py + + + deploy + ${project.version} + ${onap.nexus.dockerregistry.snapshot} + ${onap.nexus.dockerregistry.release} + ${onap.nexus.pypiserver.baseurl} + ${onap.nexus.pypiserver.serverid} + ${project.build.directory}/${wheel.name} + + + + + + + + + diff --git a/azure/aria/aria-rest-server/setup.py b/azure/aria/aria-rest-server/setup.py new file mode 100644 index 0000000..1f68901 --- /dev/null +++ b/azure/aria/aria-rest-server/setup.py @@ -0,0 +1,41 @@ +# org.onap.dcae +# ============LICENSE_START==================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# ============================================================================= +# Licensed 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. +# ============LICENSE_END====================================================== +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +from setuptools import setup, find_packages + +try: + with open('VERSION') as v_file: + version = v_file.read().strip() +except IOError: + print "There was a problem parsing the VERSION file." + +setup( + name='aria-rest-server', + version=version, + packages=find_packages(), + author = '', + author_email = '', + description = ('Library for ...'), + license = 'Apache 2.0', + keywords = '', + url = '', + zip_safe = True, + install_requires=[], + entry_points = {} +) diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE b/azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE new file mode 100644 index 0000000..48bef24 --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE @@ -0,0 +1,18 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py new file mode 100644 index 0000000..adb446c --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py @@ -0,0 +1,19 @@ + +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py new file mode 100644 index 0000000..adb446c --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py @@ -0,0 +1,19 @@ + +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py new file mode 100644 index 0000000..ecddff6 --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py @@ -0,0 +1,90 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + +from flask import Flask, request, jsonify +from flask_autodoc.autodoc import Autodoc +from aria import install_aria_extensions +from aria.cli.core import aria +from aria.utils import threading +from aria.orchestrator.workflow_runner import WorkflowRunner +from aria.orchestrator.workflows.executor.dry import DryExecutor +import util + +version_id = "v0" +route_base = "/api/multicloud-azure/" + version_id + "/" +app = Flask("onap-aria-rest") +auto = Autodoc(app) + +execution_state = util.SafeDict() + + +def main(): + install_aria_extensions() + app.run(host='0.0.0.0', port=5000, threaded=True) + + +# start execution +@app.route( + route_base + + "services//executions/", + methods=['POST']) +@auto.doc() +@aria.pass_model_storage +@aria.pass_resource_storage +@aria.pass_plugin_manager +@aria.pass_logger +def start_execution( + service_id, + workflow_name, + model_storage, + resource_storage, + plugin_manager, + logger): + """ + Start an execution for the specified service + """ + body = request.json or {} + executor = DryExecutor( + ) if 'executor' in body and body['executor'] == 'dry' else None + + inputs = body['inputs'] if 'inputs' in body else None + task_max_attempts = (body['task_max_attempts'] + if 'task_max_attempts' in body else 30) + task_retry_interval = (body['task_retry_interval'] + if 'task_retry_interval' in body else 30) + + runner = WorkflowRunner(model_storage, resource_storage, plugin_manager, + service_id=service_id, + workflow_name=workflow_name, + inputs=inputs, + executor=executor, + task_max_attempts=task_max_attempts, + task_retry_interval=task_retry_interval) + + service = model_storage.service.get(service_id) + tname = '{}_{}_{}'.format(service.name, workflow_name, runner.execution_id) + thread = threading.ExceptionThread(target=runner.execute, + name=tname) + thread.start() + execution_state[str(runner.execution_id)] = [runner, thread] + logger.info("execution {} started".format(runner.execution_id)) + return jsonify({"id": runner.execution_id}), 202 + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000, threaded=True) diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html new file mode 100644 index 0000000..932a6b1 --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html @@ -0,0 +1,23 @@ + + + +

Not Implemented

+ diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py new file mode 100644 index 0000000..ecd46b1 --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py @@ -0,0 +1,48 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + + +import threading + + +def make_template_name(user, template_name): + return "{}.{}".format(user, template_name) + + +class SafeDict(dict): + def __init__(self, *args): + self._lockobj = threading.Lock() + dict.__init__(self, args) + + def __getitem__(self, key): + try: + self._lockobj.acquire() + val = dict.__getitem__(self, key) + except: + raise + finally: + self._lockobj.release() + + def __setitem__(self, key, value): + try: + self._lockobj.acquire() + dict.__setitem__(self, key, value) + except: + raise + finally: + self._lockobj.release() diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py new file mode 100644 index 0000000..c0858bf --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py @@ -0,0 +1,57 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + +from flask import Flask, render_template +from aria.exceptions import AriaException + +version_id = "0.1" +route_base = "/api/" + version_id + "/" +app = Flask("onap-aria-rest") + +@app.route("/") +def index(): + return render_template('index.html') + + +@app.route(route_base + "templates/", methods = ['GET']) +def list_templates(): + +@app.route(route_base + "templates/", methods = ['POST']) +def install_template( template_id ): + + # GET CSAR FROM SDC + + # DEPLOY CSAR + + # UPDATE A&AI? + + return "template {} instantiated" + +@app.route(route_base + "templates/", methods = ['DELETE']) +def delete_template( template_id ): + + # RUN UNINSTALL + + # DELETE TEMPLATE + + # UPDATE A&AI? + + return "template {} deleted" + +if __name__ == "__main__": + app.run() diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py new file mode 100644 index 0000000..86fd5a0 --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py @@ -0,0 +1,42 @@ +# +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs. All rights reserved. +# =================================================================== +# Licensed 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. +# ============LICENSE_END==================================================== +# + + +from setuptools import setup + +setup( + zip_safe=True, + name='aria-rest', + version='0.1', + author='dewayne', + author_email='dewayne@cloudify.co', + packages=[ + 'aria_rest' + ], + entry_points = { + 'console_scripts' : ['aria-rest=aria_rest.rest:main'] + }, + license='LICENSE', + description='Aria REST API for ONAP', + install_requires=[ + 'distribute', + 'Flask==0.12.2', + 'flask-autodoc==0.1.2', + 'apache-ariatosca==0.2.0' + ] +) diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html b/azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html new file mode 100644 index 0000000..6d74cfc --- /dev/null +++ b/azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html @@ -0,0 +1,3 @@ + +

Not Implemented

+ diff --git a/azure/docker/Dockerfile b/azure/docker/Dockerfile index 70924e3..e7bb479 100644 --- a/azure/docker/Dockerfile +++ b/azure/docker/Dockerfile @@ -10,7 +10,7 @@ ENV AAI_PASSWORD "AAI" ENV MR_ADDR "127.0.0.1" ENV MR_PORT "3904" -EXPOSE 9004 +EXPOSE 9008 RUN apt-get update && \ apt-get install -y unzip && \ @@ -27,6 +27,9 @@ RUN pip install . WORKDIR /tmp/aria-extension-cloudify RUN pip install . +WORKDIR /tmp/aria-rest-server/src/main/python/aria-rest +RUN pip install . + RUN pip install --force-reinstall pip==9.0.1 WORKDIR /tmp ADD docker/cloudify_azure_plugin-1.4.2-py27-none-linux_x86_64.wgn /tmp/ @@ -40,7 +43,6 @@ RUN cd /opt/ && \ rm -rf multicloud-azure.zip && \ pip install -r multicloud_azure/requirements.txt - WORKDIR /opt RUN chmod +x multicloud_azure/docker/*.sh && chmod +x multicloud_azure/*.sh ENTRYPOINT multicloud_azure/docker/docker-entrypoint.sh diff --git a/azure/multicloud_azure/pub/aria/service.py b/azure/multicloud_azure/pub/aria/service.py index 637858a..2c99611 100644 --- a/azure/multicloud_azure/pub/aria/service.py +++ b/azure/multicloud_azure/pub/aria/service.py @@ -17,13 +17,12 @@ import time import os from multicloud_azure.pub.aria import util +from multicloud_azure.pub.utils.restcall import call_aria_rest from aria.cli.core import aria from aria.cli import utils from aria.core import Core from aria.cli import service_template_utils from aria.storage import exceptions as storage_exceptions -from aria.utils import threading -from aria.orchestrator.workflow_runner import WorkflowRunner as Runner LOG = logging.getLogger(__name__) @@ -48,12 +47,10 @@ class AriaServiceImpl(object): status, template_name + time.strftime('%Y%m%d%H%M%S'), inputs) if (status[1] != 200): return status[0], status[1] - execution_id = time.strftime('%Y%m%d%H%M%S') - thread = threading.ExceptionThread(target=self.start_execution, - args=(status[2].id, execution_id, - inputs, 'install')) - thread.start() - return execution_id, 200 + status = call_aria_rest(status[2].id, 'install') + if (status[2] != "202"): + return status[1], status[2] + return json.loads(status[1])['id'], 200 @aria.pass_model_storage @aria.pass_resource_storage @@ -111,35 +108,6 @@ class AriaServiceImpl(object): logger.info("service {} created".format(service.name)) return "service {} created".format(service.name), 200, service - @aria.pass_model_storage - @aria.pass_resource_storage - @aria.pass_plugin_manager - @aria.pass_logger - def start_execution(self, service_id, execution_id, input, workflow_name, - model_storage, - resource_storage, - plugin_manager, - logger): - """ - Start an execution for the specified service - """ - input = input['sdnc_directives'] if'sdnc_directives'in input else None - runner = Runner(model_storage, resource_storage, plugin_manager, - execution_id=execution_id, - service_id=service_id, - workflow_name=workflow_name, - inputs=input) - - service = model_storage.service.get(service_id) - tname = '{}_{}_{}'.format(service.name, workflow_name, - runner.execution_id) - thread = threading.ExceptionThread(target=runner.execute, - name=tname) - thread.start() - execution_state[str(runner.execution_id)] = [runner, thread] - logger.info("execution {} started".format(runner.execution_id)) - return json.dumps({"id": runner.execution_id}), 202 - @aria.pass_model_storage @aria.pass_logger def show_execution(self, execution_id, model_storage, logger): diff --git a/azure/multicloud_azure/pub/config/config.py b/azure/multicloud_azure/pub/config/config.py index db09fd6..511f0ca 100644 --- a/azure/multicloud_azure/pub/config/config.py +++ b/azure/multicloud_azure/pub/config/config.py @@ -39,3 +39,6 @@ FORWARDED_FOR_FIELDS = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST", # [Local Config] API_SERVER_PORT = 9004 + +# [ARIA] +ARIA_SERVER_URL = 'http://127.0.0.1:5000/api/multicloud-azure/v0' diff --git a/azure/multicloud_azure/pub/utils/restcall.py b/azure/multicloud_azure/pub/utils/restcall.py index ff5ca6a..0b0ef33 100644 --- a/azure/multicloud_azure/pub/utils/restcall.py +++ b/azure/multicloud_azure/pub/utils/restcall.py @@ -23,6 +23,7 @@ from multicloud_azure.pub.config.config import AAI_SERVICE_URL from multicloud_azure.pub.config.config import AAI_USERNAME from multicloud_azure.pub.config.config import AAI_PASSWORD from multicloud_azure.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT +from multicloud_azure.pub.config.config import ARIA_SERVER_URL from multicloud_azure.pub.exceptions import VimDriverAzureException @@ -341,3 +342,12 @@ class AAIClient(object): {'value': cloud_dpdk_info.get("libversion")}) }) return ovsdpdk_capability + + +def call_aria_rest(service_id, workflow_name): + base_url = "%s" % (ARIA_SERVER_URL) + resource = ("/services/%s/executions/%s" % (service_id, workflow_name)) + headers = {} + headers['content-type'] = 'text/plain' + return call_req(base_url, "", "", rest_no_auth, resource, "POST", + headers=headers) diff --git a/azure/multicloud_azure/tests/test_aria_view.py b/azure/multicloud_azure/tests/test_aria_view.py index 69c18e7..3bbd105 100644 --- a/azure/multicloud_azure/tests/test_aria_view.py +++ b/azure/multicloud_azure/tests/test_aria_view.py @@ -136,35 +136,6 @@ class WorkoadViewTest(unittest.TestCase): plugin_manager, logger)) - @mock.patch.object(AriaServiceImpl, 'start_execution') - @aria.pass_model_storage - @aria.pass_resource_storage - @aria.pass_plugin_manager - @aria.pass_logger - def test_start_execution(self, mock_template_info, model_storage, - resource_storage, plugin_manager, logger): - class Workload: - def __init__(self, status_id, execution_id, name, input): - self.status_id = status_id - self.execution_id = execution_id - self.input = input - self.name = name - - service = Workload(1, 2, "a", "w") - mock_template_info.return_value = service - - class Request: - def __init__(self, query_params): - self.query_params = query_params - - req = Request({'k': 'v'}) - self.assertNotEqual(200, - self.fsv.start_execution(req, 123, 456, "a1", "b1", - model_storage, - resource_storage, - plugin_manager, - logger)) - def test_show_execution(self): service_op = AriaServiceImpl() self.assertNotEqual(200, diff --git a/azure/run.sh b/azure/run.sh index babf0c9..e781063 100644 --- a/azure/run.sh +++ b/azure/run.sh @@ -31,6 +31,7 @@ then python multivimbroker/scripts/api.py else # nohup python manage.py runserver 0.0.0.0:9008 2>&1 & + nohup aria-rest 2>&1 & nohup uwsgi --http :9008 --module multicloud_azure.wsgi --master --processes 4 & nohup python -m multicloud_azure.event_listener.server 2>&1 & -- 2.16.6