summaryrefslogtreecommitdiffstats
path: root/pike
diff options
context:
space:
mode:
authorHuang Haibin <haibin.huang@intel.com>2018-07-10 19:22:34 +0800
committerHuang Haibin <haibin.huang@intel.com>2018-07-25 15:39:11 +0800
commit0d3e9ace323660381350a884b08ed92aa2290dbd (patch)
treef5893c82318261da9527714956870cafad85b263 /pike
parent1ef4d132b8e9bd99ac88fe4bd1a023c97ca58ad9 (diff)
Add Openstack Pike plugin framework
Add Pike framework and one function extension Add Vagrant for test Change-Id: I045ac1f1a920b509a69d7a72f8e60fb108102839 Issue-ID: MULTICLOUD-276 Signed-off-by: Huang Haibin <haibin.huang@intel.com>
Diffstat (limited to 'pike')
-rw-r--r--pike/.gitignore13
-rw-r--r--pike/README.md15
-rw-r--r--pike/assembly.xml77
-rw-r--r--pike/docker/Dockerfile29
-rwxr-xr-xpike/docker/build_image.sh31
-rwxr-xr-xpike/initialize.sh16
-rw-r--r--pike/logs/empty.txt0
-rw-r--r--pike/manage.py22
-rwxr-xr-xpike/mvn-phase-script.sh83
-rw-r--r--pike/pike/__init__.py14
-rw-r--r--pike/pike/extensions/__init__.py14
-rw-r--r--pike/pike/extensions/tests/__init__.py14
-rw-r--r--pike/pike/extensions/tests/test_epacaps.py67
-rw-r--r--pike/pike/extensions/tests/test_extensions.py45
-rw-r--r--pike/pike/extensions/urls.py26
-rw-r--r--pike/pike/extensions/views/__init__.py14
-rw-r--r--pike/pike/extensions/views/epacaps.py33
-rw-r--r--pike/pike/extensions/views/extensions.py29
-rw-r--r--pike/pike/middleware.py65
-rw-r--r--pike/pike/pub/__init__.py14
-rw-r--r--pike/pike/pub/config/__init__.py14
-rw-r--r--pike/pike/pub/config/config.py13
-rw-r--r--pike/pike/pub/config/log.yml37
-rw-r--r--pike/pike/samples/__init__.py14
-rw-r--r--pike/pike/samples/tests.py32
-rw-r--r--pike/pike/samples/urls.py19
-rw-r--r--pike/pike/samples/views.py29
-rw-r--r--pike/pike/settings.py138
-rw-r--r--pike/pike/swagger/__init__.py14
-rw-r--r--pike/pike/swagger/tests.py32
-rw-r--r--pike/pike/swagger/urls.py24
-rw-r--r--pike/pike/swagger/views.py48
-rw-r--r--pike/pike/urls.py26
-rw-r--r--pike/pike/wsgi.py21
-rw-r--r--pike/pom.xml117
-rw-r--r--pike/requirements.txt23
-rwxr-xr-xpike/run.sh18
-rwxr-xr-xpike/stop.sh18
-rw-r--r--pike/tox.ini27
-rw-r--r--pike/vagrant/Vagrantfile23
-rw-r--r--pike/vagrant/pip.conf4
-rwxr-xr-xpike/vagrant/piprepo.sh7
-rw-r--r--pike/vagrant/test/Dockerfile25
-rw-r--r--pike/vagrant/test/extsys.py145
-rw-r--r--pike/vagrant/test/test-extensions.sh6
-rw-r--r--pike/vagrant/test/test_multicloud.sh29
-rw-r--r--pike/vagrant/test/tests1
47 files changed, 1525 insertions, 0 deletions
diff --git a/pike/.gitignore b/pike/.gitignore
new file mode 100644
index 00000000..06570027
--- /dev/null
+++ b/pike/.gitignore
@@ -0,0 +1,13 @@
+.project
+.classpath
+.settings/
+.checkstyle
+target/
+logs/*.log
+*.pyc
+.tox
+.coverage
+htmlcov/
+coverage.xml
+test-reports/
+
diff --git a/pike/README.md b/pike/README.md
new file mode 100644
index 00000000..e6231224
--- /dev/null
+++ b/pike/README.md
@@ -0,0 +1,15 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+# Micro service of MultiCloud plugin for pike.
diff --git a/pike/assembly.xml b/pike/assembly.xml
new file mode 100644
index 00000000..420c6c49
--- /dev/null
+++ b/pike/assembly.xml
@@ -0,0 +1,77 @@
+<!--
+ Copyright (c) 2017-2018 Wind River Systems, Inc.
+
+ 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.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>pike</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>pike</directory>
+ <outputDirectory>/pike</outputDirectory>
+ <includes>
+ <include>**/*.py</include>
+ <include>**/*.json</include>
+ <include>**/*.xml</include>
+ <include>**/*.wsdl</include>
+ <include>**/*.xsd</include>
+ <include>**/*.bpel</include>
+ <include>**/*.yml</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>../share</directory>
+ <outputDirectory>/lib/share</outputDirectory>
+ <includes>
+ <include>**/*.py</include>
+ <include>**/*.json</include>
+ <include>**/*.xml</include>
+ <include>**/*.wsdl</include>
+ <include>**/*.xsd</include>
+ <include>**/*.bpel</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>logs</directory>
+ <outputDirectory>/logs</outputDirectory>
+ <includes>
+ <include>*.txt</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>docker</directory>
+ <outputDirectory>/docker</outputDirectory>
+ <includes>
+ <include>*.sh</include>
+ <include>Dockerfile</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>.</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>*.py</include>
+ <include>*.txt</include>
+ <include>*.sh</include>
+ <include>*.ini</include>
+ <include>*.md</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ <baseDirectory>pike</baseDirectory>
+</assembly>
diff --git a/pike/docker/Dockerfile b/pike/docker/Dockerfile
new file mode 100644
index 00000000..45e99502
--- /dev/null
+++ b/pike/docker/Dockerfile
@@ -0,0 +1,29 @@
+FROM python:2.7
+
+ARG HTTP_PROXY=${HTTP_PROXY}
+ARG HTTPS_PROXY=${HTTPS_PROXY}
+
+ENV http_proxy $HTTP_PROXY
+ENV https_proxy $HTTPS_PROXY
+
+ENV MSB_ADDR "127.0.0.1"
+ENV MSB_PORT "80"
+ENV AAI_ADDR "aai.api.simpledemo.openecomp.org"
+ENV AAI_PORT "8443"
+ENV AAI_SERVICE_URL ""
+ENV AAI_SCHEMA_VERSION "v13"
+ENV AAI_USERNAME "AAI"
+ENV AAI_PASSWORD "AAI"
+
+EXPOSE 9007
+
+WORKDIR /opt/pike
+RUN apt-get update && apt-get install -y memcached unzip
+RUN wget -O /opt/multicloud-openstack-pike.zip "https://nexus.onap.org/service/local/artifact/maven/redirect?r=snapshots&g=org.onap.multicloud.openstack&a=multicloud-openstack-pike&e=zip&v=LATEST" && \
+ unzip -q -o -B /opt/multicloud-openstack-pike.zip -d /opt/ && \
+ rm -f /opt/multicloud-openstack-pike.zip
+RUN mkdir -p /var/log/onap/multicloud/openstack/pike/
+#COPY ./ .
+RUN pip install -r requirements.txt
+
+CMD "/opt/pike/run.sh"
diff --git a/pike/docker/build_image.sh b/pike/docker/build_image.sh
new file mode 100755
index 00000000..83340be5
--- /dev/null
+++ b/pike/docker/build_image.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+DIRNAME=`dirname $0`
+DOCKER_BUILD_DIR=`cd $DIRNAME/; pwd`
+echo "DOCKER_BUILD_DIR=${DOCKER_BUILD_DIR}"
+cd ${DOCKER_BUILD_DIR}
+
+BUILD_ARGS="--no-cache"
+VERSION="1.2.0-SNAPSHOT"
+STAGING="1.2.0-STAGING"
+OS_VERSION="pike"
+IMAGE_NAME="nexus3.onap.org:10003/onap/multicloud/openstack-${OS_VERSION}"
+
+if [ $HTTP_PROXY ]; then
+ BUILD_ARGS+=" --build-arg HTTP_PROXY=${HTTP_PROXY}"
+fi
+if [ $HTTPS_PROXY ]; then
+ BUILD_ARGS+=" --build-arg HTTPS_PROXY=${HTTPS_PROXY}"
+fi
+
+function build_image {
+ docker build ${BUILD_ARGS} -t ${IMAGE_NAME}:${VERSION} -t ${IMAGE_NAME}:latest -t ${IMAGE_NAME}:${STAGING} .
+}
+
+function push_image {
+ docker push ${IMAGE_NAME}:${VERSION}
+ docker push ${IMAGE_NAME}:latest
+ docker push ${IMAGE_NAME}:${STAGING}
+}
+
+build_image
+push_image
diff --git a/pike/initialize.sh b/pike/initialize.sh
new file mode 100755
index 00000000..1d64bfca
--- /dev/null
+++ b/pike/initialize.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+pip install -r requirements.txt
diff --git a/pike/logs/empty.txt b/pike/logs/empty.txt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/pike/logs/empty.txt
diff --git a/pike/manage.py b/pike/manage.py
new file mode 100644
index 00000000..426c6b19
--- /dev/null
+++ b/pike/manage.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import os
+import sys
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pike.settings")
+
+if __name__ == "__main__":
+ from django.core.management import execute_from_command_line
+ execute_from_command_line(sys.argv)
diff --git a/pike/mvn-phase-script.sh b/pike/mvn-phase-script.sh
new file mode 100755
index 00000000..ad1d6329
--- /dev/null
+++ b/pike/mvn-phase-script.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+
+set -e
+
+echo "running script: [$0] for module [$1] at stage [$2]"
+
+export SETTINGS_FILE=${SETTINGS_FILE:-$HOME/.m2/settings.xml}
+MVN_PROJECT_MODULEID="$1"
+MVN_PHASE="$2"
+
+
+FQDN="${MVN_PROJECT_GROUPID}.${MVN_PROJECT_ARTIFACTID}"
+if [ "$MVN_PROJECT_MODULEID" == "__" ]; then
+ MVN_PROJECT_MODULEID=""
+fi
+
+if [ -z "$WORKSPACE" ]; then
+ WORKSPACE=$(pwd)
+fi
+
+# mvn phase in life cycle
+MVN_PHASE="$2"
+
+
+echo "MVN_PROJECT_MODULEID is [$MVN_PROJECT_MODULEID]"
+echo "MVN_PHASE is [$MVN_PHASE]"
+echo "MVN_PROJECT_GROUPID is [$MVN_PROJECT_GROUPID]"
+echo "MVN_PROJECT_ARTIFACTID is [$MVN_PROJECT_ARTIFACTID]"
+echo "MVN_PROJECT_VERSION is [$MVN_PROJECT_VERSION]"
+
+run_tox_test()
+{
+ set -x
+ echo $PWD
+ CURDIR=$(pwd)
+ TOXINIS=$(find . -name "tox.ini")
+ cd ..
+ for TOXINI in "${TOXINIS[@]}"; do
+ DIR=$(echo "$TOXINI" | rev | cut -f2- -d'/' | rev)
+ cd "${CURDIR}/${DIR}"
+ rm -rf ./venv-tox ./.tox
+ virtualenv ./venv-tox
+ source ./venv-tox/bin/activate
+ pip install --upgrade pip
+ pip install --upgrade tox argparse
+ pip freeze
+ cd ${CURDIR}
+ tox
+ deactivate
+ cd ..
+ rm -rf ./venv-tox ./.tox
+ done
+}
+
+
+case $MVN_PHASE in
+clean)
+ echo "==> clean phase script"
+ rm -rf ./venv-*
+ ;;
+test)
+ echo "==> test phase script"
+ run_tox_test
+ ;;
+*)
+ echo "==> unprocessed phase"
+ ;;
+esac
+
diff --git a/pike/pike/__init__.py b/pike/pike/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/extensions/__init__.py b/pike/pike/extensions/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/extensions/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/extensions/tests/__init__.py b/pike/pike/extensions/tests/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/extensions/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/extensions/tests/test_epacaps.py b/pike/pike/extensions/tests/test_epacaps.py
new file mode 100644
index 00000000..40f8d3a7
--- /dev/null
+++ b/pike/pike/extensions/tests/test_epacaps.py
@@ -0,0 +1,67 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import json
+
+import mock
+from django.test import Client
+from rest_framework import status
+import unittest
+
+from newton_base.util import VimDriverUtils
+
+MOCK_VIM_INFO = {
+ "createTime": "2017-04-01 02:22:27",
+ "domain": "Default",
+ "name": "TiS_R4",
+ "password": "admin",
+ "tenant": "admin",
+ "type": "openstack",
+ "url": "http://128.224.180.14:5000/v3",
+ "userName": "admin",
+ "vendor": "WindRiver",
+ "version": "pike",
+ "vimId": "windriver-hudson-dc_RegionOne",
+ 'cloud_owner':'windriver-hudson-dc',
+ 'cloud_region_id':'RegionOne',
+ 'cloud_extra_info':'',
+ 'cloud_epa_caps':'{"huge_page":"true","cpu_pinning":"true",\
+ "cpu_thread_policy":"true","numa_aware":"true","sriov":"true",\
+ "dpdk_vswitch":"true","rdt":"false","numa_locality_pci":"true"}',
+ 'insecure':'True',
+}
+
+
+class TestEpaCaps(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ @mock.patch.object(VimDriverUtils, 'get_vim_info')
+ def test_get_epa_caps_info(self, mock_get_vim_info):
+ mock_get_vim_info.return_value = MOCK_VIM_INFO
+ cloud_owner = "windriver-hudson-dc"
+ cloud_region_id = "RegionOne"
+ vimid = cloud_owner + "_" + cloud_region_id
+
+ response = self.client.get(
+ "/api/multicloud-pike/v0/" + vimid + "/extensions/epa-caps")
+ json_content = response.json()
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEquals(4, len(json_content.keys()))
+ self.assertEquals(cloud_owner, json_content["cloud-owner"])
+ self.assertEquals(cloud_region_id, json_content["cloud-region-id"])
+ self.assertEquals(vimid, json_content["vimid"])
+ self.assertEquals(json.loads(MOCK_VIM_INFO['cloud_epa_caps']),
+ json_content["cloud-epa-caps"])
diff --git a/pike/pike/extensions/tests/test_extensions.py b/pike/pike/extensions/tests/test_extensions.py
new file mode 100644
index 00000000..3842d4b7
--- /dev/null
+++ b/pike/pike/extensions/tests/test_extensions.py
@@ -0,0 +1,45 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+from django.test import Client
+from rest_framework import status
+import unittest
+
+
+class TestExtensions(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def test_get_extensions_info(self):
+ cloud_owner = "windriver-hudson-dc"
+ cloud_region_id = "RegionOne"
+ vimid = cloud_owner + "_" + cloud_region_id
+
+ response = self.client.get(
+ "/api/multicloud-pike/v0/" + vimid + "/extensions/")
+ json_content = response.json()
+
+ self.assertEquals(status.HTTP_200_OK, response.status_code)
+ self.assertEquals(4, len(json_content.keys()))
+
+ self.assertEquals(cloud_owner, json_content["cloud-owner"])
+ self.assertEquals(cloud_region_id, json_content["cloud-region-id"])
+ self.assertEquals(vimid, json_content["vimid"])
+
+ self.assertEquals("epa-caps", json_content["extensions"][0]["alias"])
+ self.assertEquals("Multiple network support", json_content["extensions"][0]["description"])
+ self.assertEquals("EPACapsQuery", json_content["extensions"][0]["name"])
+ self.assertEquals("http://127.0.0.1:80/api/multicloud-pike/v0/%s/extensions/epa-caps" % vimid,
+ json_content["extensions"][0]["url"])
+ self.assertEquals("", json_content["extensions"][0]["spec"])
diff --git a/pike/pike/extensions/urls.py b/pike/pike/extensions/urls.py
new file mode 100644
index 00000000..545dec98
--- /dev/null
+++ b/pike/pike/extensions/urls.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+from django.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from pike.extensions.views import extensions
+from pike.extensions.views import epacaps
+
+urlpatterns = [
+ url(r'^sions/?$', extensions.Extensions.as_view()),
+ url(r'^sions/epa-caps/?$', epacaps.EpaCaps.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/pike/pike/extensions/views/__init__.py b/pike/pike/extensions/views/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/extensions/views/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/extensions/views/epacaps.py b/pike/pike/extensions/views/epacaps.py
new file mode 100644
index 00000000..025d55df
--- /dev/null
+++ b/pike/pike/extensions/views/epacaps.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import logging
+import json
+import traceback
+
+from django.conf import settings
+
+
+from newton_base.extensions import epacaps as newton_epacaps
+
+logger = logging.getLogger(__name__)
+
+# DEBUG=True
+
+
+class EpaCaps(newton_epacaps.EpaCaps):
+
+ def __init__(self):
+ self.proxy_prefix = settings.MULTICLOUD_PREFIX
+ self._logger = logger
diff --git a/pike/pike/extensions/views/extensions.py b/pike/pike/extensions/views/extensions.py
new file mode 100644
index 00000000..2c499f36
--- /dev/null
+++ b/pike/pike/extensions/views/extensions.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import logging
+
+from django.conf import settings
+from newton_base.extensions import extensions as newton_extensions
+
+logger = logging.getLogger(__name__)
+
+# DEBUG=True
+
+class Extensions(newton_extensions.Extensions):
+
+ def __init__(self):
+ self._logger = logger
+ self.proxy_prefix = settings.MULTICLOUD_PREFIX
+
diff --git a/pike/pike/middleware.py b/pike/pike/middleware.py
new file mode 100644
index 00000000..f2618e06
--- /dev/null
+++ b/pike/pike/middleware.py
@@ -0,0 +1,65 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import uuid
+from django.conf import settings
+from onaplogging.mdcContext import MDC
+
+FORWARDED_FOR_FIELDS = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST",
+ "HTTP_X_FORWARDED_SERVER"]
+
+class LogContextMiddleware(object):
+
+ # the last IP behind multiple proxies, if no exist proxies
+ # get local host ip.
+ def _getLastIp(self, request):
+
+ ip = ""
+ try:
+ for field in FORWARDED_FOR_FIELDS:
+ if field in request.META:
+ if ',' in request.META[field]:
+ parts = request.META[field].split(',')
+ ip = parts[-1].strip().split(":")[0]
+ else:
+ ip = request.META[field].split(":")[0]
+
+ if ip == "":
+ ip = request.META.get("HTTP_HOST").split(":")[0]
+
+ except Exception:
+ pass
+
+ return ip
+
+
+ def process_request(self, request):
+ # fetch propageted Id from other component. if do not fetch id,
+ # generate one.
+ ReqeustID = request.META.get("HTTP_X_TRANSACTIONID", None)
+ if ReqeustID is None:
+ ReqeustID = str(uuid.uuid3(uuid.NAMESPACE_URL, settings.MULTIVIM_VERSION))
+ MDC.put("requestID", ReqeustID)
+ # generate the reqeust id
+ InvocationID = str(uuid.uuid4())
+ MDC.put("invocationID", InvocationID)
+ MDC.put("serviceName", settings.MULTIVIM_VERSION)
+ MDC.put("serviceIP", self._getLastIp(request))
+ return None
+
+ def process_response(self, request, response):
+
+ MDC.clear()
+ return response
+
diff --git a/pike/pike/pub/__init__.py b/pike/pike/pub/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/pub/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/pub/config/__init__.py b/pike/pike/pub/config/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/pub/config/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/pub/config/config.py b/pike/pike/pub/config/config.py
new file mode 100644
index 00000000..ae1ce9db
--- /dev/null
+++ b/pike/pike/pub/config/config.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
diff --git a/pike/pike/pub/config/log.yml b/pike/pike/pub/config/log.yml
new file mode 100644
index 00000000..73a14eef
--- /dev/null
+++ b/pike/pike/pub/config/log.yml
@@ -0,0 +1,37 @@
+version: 1
+disable_existing_loggers: False
+
+loggers:
+ pike:
+ handlers: [console_handler, file_handler]
+ level: "DEBUG"
+ propagate: False
+ newton_base:
+ handlers: [console_handler, file_handler]
+ level: "DEBUG"
+ propagate: False
+ common:
+ handlers: [console_handler, file_handler]
+ level: "DEBUG"
+ propagate: False
+handlers:
+ console_handler:
+ level: "DEBUG"
+ class: "logging.StreamHandler"
+ formatter: "mdcFormat"
+ file_handler:
+ level: "DEBUG"
+ class: "logging.handlers.RotatingFileHandler"
+ filename: "/var/log/onap/multicloud/openstack/pike/pike.log"
+ formatter: "mdcFormat"
+ maxBytes: 1024*1024*50
+ backupCount: 10
+formatters:
+ standard:
+ format: "%(asctime)s|||||%(name)s||%(thread)||%(funcName)s||%(levelname)s||%(message)s"
+ mdcFormat:
+ format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s \t"
+ mdcfmt: "{requestID} {invocationID} {serviceName} {serviceIP}"
+ datefmt: "%Y-%m-%d %H:%M:%S"
+ (): onaplogging.mdcformatter.MDCFormatter
+
diff --git a/pike/pike/samples/__init__.py b/pike/pike/samples/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/samples/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/samples/tests.py b/pike/pike/samples/tests.py
new file mode 100644
index 00000000..b294a52b
--- /dev/null
+++ b/pike/pike/samples/tests.py
@@ -0,0 +1,32 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import unittest
+import json
+from django.test import Client
+from rest_framework import status
+
+
+class SampleViewTest(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def tearDown(self):
+ pass
+
+ def test_sample(self):
+ response = self.client.get("/samples/")
+ self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
+ resp_data = response.json()
+ self.assertEqual({"status": "active"}, resp_data)
diff --git a/pike/pike/samples/urls.py b/pike/pike/samples/urls.py
new file mode 100644
index 00000000..94bd5669
--- /dev/null
+++ b/pike/pike/samples/urls.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+from django.conf.urls import url
+from pike.samples import views
+
+urlpatterns = [
+ url(r'^samples/$', views.SampleList.as_view()), ]
diff --git a/pike/pike/samples/views.py b/pike/pike/samples/views.py
new file mode 100644
index 00000000..58d1d80b
--- /dev/null
+++ b/pike/pike/samples/views.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import logging
+
+from rest_framework.views import APIView
+from rest_framework.response import Response
+
+logger = logging.getLogger(__name__)
+
+
+class SampleList(APIView):
+ """
+ List all samples.
+ """
+ def get(self, request, format=None):
+ logger.debug("get")
+ return Response({"status": "active"})
diff --git a/pike/pike/settings.py b/pike/pike/settings.py
new file mode 100644
index 00000000..39c83d47
--- /dev/null
+++ b/pike/pike/settings.py
@@ -0,0 +1,138 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import os
+import sys
+
+from logging import config
+from onaplogging import monkey
+monkey.patch_all()
+
+CACHE_EXPIRATION_TIME = 3600
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '3o-wney!99y)^h3v)0$j16l9=fdjxcb+a8g+q3tfbahcnu2b0o'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+# DEBUG = True
+
+ALLOWED_HOSTS = ['*']
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'rest_framework',
+]
+
+MIDDLEWARE_CLASSES = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'pike.middleware.LogContextMiddleware',
+]
+
+ROOT_URLCONF = 'pike.urls'
+
+WSGI_APPLICATION = 'pike.wsgi.application'
+
+REST_FRAMEWORK = {
+ 'DEFAULT_RENDERER_CLASSES': (
+ 'rest_framework.renderers.JSONRenderer',
+ ),
+
+ 'DEFAULT_PARSER_CLASSES': (
+ 'rest_framework.parsers.JSONParser',
+ 'rest_framework.parsers.MultiPartParser',
+ # 'rest_framework.parsers.FormParser',
+ # 'rest_framework.parsers.FileUploadParser',
+ )
+}
+
+TIME_ZONE = 'UTC'
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.6/howto/static-files/
+
+STATIC_URL = '/static/'
+
+CACHES = {
+ 'default': {
+ 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+ 'LOCATION': '127.0.0.1:11211',
+ }
+}
+
+# [MSB]
+MSB_SERVICE_ADDR = os.environ.get('MSB_ADDR', "127.0.0.1")
+MSB_SERVICE_PORT = os.environ.get('MSB_PORT', "80")
+
+#[Multicloud]
+MULTICLOUD_PREFIX = "http://%s:%s/api/multicloud-pike/v0" % (
+ MSB_SERVICE_ADDR, MSB_SERVICE_PORT)
+
+# [A&AI]
+AAI_ADDR = os.environ.get('AAI_ADDR', "aai.api.simpledemo.openecomp.org")
+AAI_PORT = os.environ.get('AAI_PORT', "8443")
+
+AAI_SERVICE_URL = os.environ.get('AAI_SERVICE_URL', "")
+if AAI_SERVICE_URL == "":
+ AAI_SERVICE_URL = 'https://%s:%s/aai' % (AAI_ADDR, AAI_PORT)
+
+AAI_SCHEMA_VERSION = os.environ.get('AAI_SCHEMA_VERSION', "v13")
+AAI_USERNAME = os.environ.get('AAI_USERNAME', "AAI")
+AAI_PASSWORD = os.environ.get('AAI_PASSWORD', "AAI")
+
+AAI_BASE_URL = "%s/%s" % (AAI_SERVICE_URL, AAI_SCHEMA_VERSION)
+
+MULTICLOUD_APP_ID = 'MultiCloud-Pike'
+
+# [IMAGE LOCAL PATH]
+ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+OPENSTACK_VERSION = "pike"
+MULTIVIM_VERSION = "multicloud-" + OPENSTACK_VERSION
+
+LOGGING_CONFIG = None
+# yaml configuration of logging
+LOGGING_FILE = os.path.join(BASE_DIR, 'pike/pub/config/log.yml')
+config.yamlConfig(filepath=LOGGING_FILE, watchDog=True)
+
+if 'test' in sys.argv:
+
+ #LOGGING['handlers']['pike_handler']['filename'] = 'logs/pike.log'
+
+ REST_FRAMEWORK = {}
+ import platform
+
+ if platform.system() == 'Linux':
+ TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner'
+ TEST_OUTPUT_VERBOSE = True
+ TEST_OUTPUT_DESCRIPTIONS = True
+ TEST_OUTPUT_DIR = 'test-reports'
diff --git a/pike/pike/swagger/__init__.py b/pike/pike/swagger/__init__.py
new file mode 100644
index 00000000..afa702d3
--- /dev/null
+++ b/pike/pike/swagger/__init__.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
diff --git a/pike/pike/swagger/tests.py b/pike/pike/swagger/tests.py
new file mode 100644
index 00000000..fe1b81c8
--- /dev/null
+++ b/pike/pike/swagger/tests.py
@@ -0,0 +1,32 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import unittest
+import json
+from django.test import Client
+from rest_framework import status
+
+
+class SampleViewTest(unittest.TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ def tearDown(self):
+ pass
+
+ def test_sample(self):
+ response = self.client.get("/api/multicloud-pike/v0/swagger.json")
+ self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
+# resp_data = response.json()
+# self.assertEqual({"status": "active"}, resp_data)
diff --git a/pike/pike/swagger/urls.py b/pike/pike/swagger/urls.py
new file mode 100644
index 00000000..c06f7b49
--- /dev/null
+++ b/pike/pike/swagger/urls.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+from django.conf.urls import patterns, url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from pike.swagger.views import SwaggerJsonView
+
+urlpatterns = [
+ url(r'^api/multicloud-pike/v0/swagger.json$', SwaggerJsonView.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/pike/pike/swagger/views.py b/pike/pike/swagger/views.py
new file mode 100644
index 00000000..ddf34731
--- /dev/null
+++ b/pike/pike/swagger/views.py
@@ -0,0 +1,48 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import json
+import logging
+import os
+import traceback
+
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+
+from common.exceptions import VimDriverNewtonException
+from newton_base.swagger import views as newton_json_view
+
+logger = logging.getLogger(__name__)
+
+
+class SwaggerJsonView(newton_json_view.SwaggerJsonView):
+
+ def get(self, request):
+ '''
+ reuse newton code and update the basePath
+ :param request:
+ :return:
+ '''
+
+ resp = super(SwaggerJsonView,self).get(request)
+ json_data = resp.data if resp else None
+ if json_data:
+ json_data["basePath"] = "/api/multicloud-pike/v0/"
+ json_data["info"]["title"] = "Service NBI of MultiCloud plugin for OpenStack Pike"
+ return Response(data=json_data, status=200)
+ else:
+ return Response(data={'error':'internal error'}, status=500)
+
+
diff --git a/pike/pike/urls.py b/pike/pike/urls.py
new file mode 100644
index 00000000..6ff32d91
--- /dev/null
+++ b/pike/pike/urls.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+from django.conf.urls import include, url
+
+from newton_base.openoapi import tenants
+
+urlpatterns = [
+ url(r'^', include('pike.swagger.urls')),
+ url(r'^', include('pike.samples.urls')),
+ url(r'^api/multicloud-pike/v0/(?P<vimid>[0-9a-zA-Z_-]+)/exten',
+ include('pike.extensions.urls')),
+]
+
+
diff --git a/pike/pike/wsgi.py b/pike/pike/wsgi.py
new file mode 100644
index 00000000..ebe63812
--- /dev/null
+++ b/pike/pike/wsgi.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pike.settings")
+
+application = get_wsgi_application()
diff --git a/pike/pom.xml b/pike/pom.xml
new file mode 100644
index 00000000..05869654
--- /dev/null
+++ b/pike/pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (c) 2017-2018 Wind River Systems, Inc.
+
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.oparent</groupId>
+ <artifactId>oparent</artifactId>
+ <version>1.1.0</version>
+ <relativePath>../oparent</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.onap.multicloud.openstack</groupId>
+ <artifactId>multicloud-openstack-pike</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>multicloud/openstack/pike</name>
+ <description>multicloud for openstack pike</description>
+ <properties>
+ <encoding>UTF-8</encoding>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <nexusproxy>https://nexus.onap.org</nexusproxy>
+ <sonar.sources>.</sonar.sources>
+ <sonar.junit.reportsPath>xunit-results.xml</sonar.junit.reportsPath>
+ <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath>
+ <sonar.language>py</sonar.language>
+ <sonar.pluginName>Python</sonar.pluginName>
+ <sonar.inclusions>**/*.py</sonar.inclusions>
+ <sonar.exclusions>**/venv-tox/**,**/.tox/**, **/tests/**,setup.py</sonar.exclusions>
+ </properties>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <configuration>
+ <executable>${project.basedir}/mvn-phase-script.sh</executable>
+ <environmentVariables>
+ <!-- make mvn properties as env for our script -->
+ <MVN_PROJECT_GROUPID>${project.groupId}</MVN_PROJECT_GROUPID>
+ <MVN_PROJECT_ARTIFACTID>${project.artifactId}</MVN_PROJECT_ARTIFACTID>
+ <MVN_PROJECT_VERSION>${project.version}</MVN_PROJECT_VERSION>
+ </environmentVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <id>clean phase script</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <arguments>
+ <argument>__</argument>
+ <argument>clean</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ <execution>
+ <id>test script</id>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <arguments>
+ <argument>__</argument>
+ <argument>test</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <descriptors>
+ <descriptor>assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/pike/requirements.txt b/pike/requirements.txt
new file mode 100644
index 00000000..d9e87f87
--- /dev/null
+++ b/pike/requirements.txt
@@ -0,0 +1,23 @@
+# rest framework
+Django==1.9.6
+djangorestframework==3.3.3
+
+# for call rest api
+httplib2==0.9.2
+
+# for call openstack auth and transport api
+keystoneauth1==2.18.0
+
+#python-memcached
+python-memcached
+
+#uwsgi for parallel processing
+uwsgi
+
+# for unit test
+coverage==4.2
+mock==2.0.0
+unittest_xml_reporting==1.12.0
+
+# for onap logging
+onappylog>=1.0.6
diff --git a/pike/run.sh b/pike/run.sh
new file mode 100755
index 00000000..e3df3b3c
--- /dev/null
+++ b/pike/run.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+memcached -d -m 2048 -u root -c 1024 -p 11211 -P /tmp/memcached1.pid
+export PYTHONPATH=lib/share
+uwsgi --http :9007 --module pike.wsgi --master --processes 4
diff --git a/pike/stop.sh b/pike/stop.sh
new file mode 100755
index 00000000..9e433eb4
--- /dev/null
+++ b/pike/stop.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+#ps auxww | grep 'manage.py runserver 0.0.0.0:9007' | awk '{print $2}' | xargs kill -9
+ps auxww |grep 'uwsgi --http :9007 --module pike.wsgi --master' |awk '{print $2}' |xargs kill -9
+ps auxww | grep 'memcached -d -m 2048 -u root -c 1024 -p 11211 -P /tmp/memcached1.pid' | awk '{print $2}' | xargs kill -9
diff --git a/pike/tox.ini b/pike/tox.ini
new file mode 100644
index 00000000..20a7f6cc
--- /dev/null
+++ b/pike/tox.ini
@@ -0,0 +1,27 @@
+[tox]
+envlist = py27,cov
+skipsdist = true
+
+[tox:jenkins]
+downloadcache = ~/cache/pip
+
+[flake8]
+ignore = E501,E722
+exclude = ./venv-tox,./.tox
+max-complexity = 27
+
+[testenv]
+setenv =
+ PYTHONPATH = {toxinidir}/../share
+deps = -r{toxinidir}/requirements.txt
+commands =
+ coverage run --branch manage.py test pike
+ coverage report --omit="./venv-tox/*,./.tox/*,*tests*,*__init__.py,*newton_base*,*common*" --fail-under=30
+
+[testenv:pep8]
+deps=flake8
+commands=flake8
+
+[testenv:cov]
+commands = coverage xml --omit="./venv-tox/*,./.tox/*,*tests*,*__init__.py,*newton_base*,*common*, *site-packages*"
+
diff --git a/pike/vagrant/Vagrantfile b/pike/vagrant/Vagrantfile
new file mode 100644
index 00000000..666f307b
--- /dev/null
+++ b/pike/vagrant/Vagrantfile
@@ -0,0 +1,23 @@
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+
+Vagrant.configure("2") do |config|
+
+ config.vm.box = "bento/ubuntu-16.04"
+
+ config.vm.provider :virtualbox do |vb|
+ vb.customize ["modifyvm", :id, "--memory", 9192]
+ vb.customize ["modifyvm", :id, "--cpus", 4]
+ vb.customize ["modifyvm", :id, "--nicpromisc3", "allow-all"]
+ vb.customize "post-boot",["controlvm", :id, "setlinkstate1", "on"]
+ end
+
+ config.vm.define "onap" do |config|
+ config.vm.hostname = "onap"
+ config.vm.synced_folder "../..", "/openstack"
+ config.vm.network "private_network", ip: "192.168.0.30"
+ config.vm.network :private_network, ip: "192.168.1.30"
+ config.vm.provision "shell", path: "piprepo.sh", privileged: false
+ config.vm.provision "shell", path: "test/test_multicloud.sh", privileged: false
+ end
+
+end
diff --git a/pike/vagrant/pip.conf b/pike/vagrant/pip.conf
new file mode 100644
index 00000000..73e7f4c4
--- /dev/null
+++ b/pike/vagrant/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://pypi.douban.com/simple/
+[install]
+trusted-host = pypi.douban.com
diff --git a/pike/vagrant/piprepo.sh b/pike/vagrant/piprepo.sh
new file mode 100755
index 00000000..737ad4f3
--- /dev/null
+++ b/pike/vagrant/piprepo.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -ex
+
+mkdir -p ~/.pip
+cp /vagrant/pip.conf ~/.pip/
+sudo cp /vagrant/pip.conf /etc/pip.conf
diff --git a/pike/vagrant/test/Dockerfile b/pike/vagrant/test/Dockerfile
new file mode 100644
index 00000000..00f8250c
--- /dev/null
+++ b/pike/vagrant/test/Dockerfile
@@ -0,0 +1,25 @@
+FROM python:2
+
+ENV MSB_ADDR "127.0.0.1"
+ENV MSB_PORT "80"
+ENV AAI_ADDR "aai.api.simpledemo.openecomp.org"
+ENV AAI_PORT "8443"
+ENV AAI_SCHEMA_VERSION "v13"
+ENV AAI_USERNAME "AAI"
+ENV AAI_PASSWORD "AAI"
+
+EXPOSE 9007
+
+COPY multicloud-openstack-pike.zip /opt
+RUN apt-get update && \
+ apt-get install -y vim memcached unzip && \
+ cd /opt/ && \
+ unzip -q -o -B multicloud-openstack-pike.zip && \
+ chmod +x /opt/pike/*.sh && \
+ rm -f multicloud-openstack-pike.zip && \
+ pip install -r /opt/pike/requirements.txt
+
+ADD extsys.py /opt/pike/lib/share/common/msapi/extsys.py
+
+WORKDIR /opt/pike
+CMD /bin/sh -c /opt/pike/run.sh
diff --git a/pike/vagrant/test/extsys.py b/pike/vagrant/test/extsys.py
new file mode 100644
index 00000000..78b41387
--- /dev/null
+++ b/pike/vagrant/test/extsys.py
@@ -0,0 +1,145 @@
+# Copyright (c) 2017-2018 Wind River Systems, Inc.
+#
+# 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.
+
+import json
+import logging
+import re
+
+from rest_framework import status
+from common.exceptions import VimDriverNewtonException
+from common.utils.restcall import req_by_msb,req_to_aai
+
+
+logger = logging.getLogger(__name__)
+
+tisr4 = {
+ "createTime": "2017-04-01 02:22:27",
+ "domain": "Default",
+ "name": "TiS_R4",
+ "password": "admin",
+ "tenant": "admin",
+ "type": "openstack",
+ "url": "http://192.168.1.10:5000/v3",
+ "userName": "admin",
+ "vendor": "OpenStack",
+ "version": "pike",
+ "vimId": "openstack-hudson-dc_RegionOne",
+ 'cloud_owner':'openstack-hudson-dc',
+ 'cloud_region_id':'RegionOne',
+ 'cloud_extra_info':'',
+ 'cloud_epa_caps':'{"huge_page":"true","cpu_pinning":"true",\
+ "cpu_thread_policy":"true","numa_aware":"true","sriov":"true",\
+ "dpdk_vswitch":"true","rdt":"false","numa_locality_pci":"true"}',
+ 'insecure':'True',
+}
+
+# "vimId": "6e720f68-34b3-44f0-a6a4-755929b20393"
+
+def mock_get_vim_by_id(method):
+ def wrapper(vimid):
+ return tisr4
+ return wrapper
+
+def mock_delete_vim_by_id(method):
+ def wrapper(vimid):
+ return status.HTTP_202_ACCEPTED
+ return wrapper
+
+#def get_vims():
+# retcode, content, status_code = \
+# req_by_msb("/api/aai-cloudInfrastructure/v1/cloud-infrastructure/cloud-regions", "GET")
+# if retcode != 0:
+# logger.error("Status code is %s, detail is %s.", status_code, content)
+# raise VimDriverNewtonException("Failed to query VIMs from extsys.")
+# return json.JSONDecoder().decode(content)
+
+@mock_get_vim_by_id
+def get_vim_by_id(vim_id):
+
+ cloud_owner,cloud_region_id = decode_vim_id(vim_id)
+
+ if cloud_owner and cloud_region_id:
+ retcode, content, status_code = \
+ req_to_aai("/cloud-infrastructure/cloud-regions/cloud-region/%s/%s"
+ % (cloud_owner,cloud_region_id),"GET")
+ if retcode != 0:
+ logger.error("Status code is %s, detail is %s.", status_code, content)
+ raise VimDriverNewtonException(
+ "Failed to query VIM with id (%s:%s,%s)." % (vim_id,cloud_owner,cloud_region_id),
+ status_code, content)
+ tmp_viminfo = json.JSONDecoder().decode(content)
+
+ #assume esr-system-info-id is composed by {cloud-owner} _ {cloud-region-id}
+ retcode2,content2,status_code2 = \
+ req_to_aai("/cloud-infrastructure/cloud-regions/cloud-region/%s/%s"
+ + "/esr-system-info-list/esr-system-info/%s_%s" \
+ % (cloud_owner,cloud_region_id,cloud_owner,cloud_region_id),
+ "GET")
+ if retcode2 != 0:
+ logger.error("Status code is %s, detail is %s.", status_code, content)
+ raise VimDriverNewtonException(
+ "Failed to query ESR system with id (%s:%s,%s)." % (vim_id,cloud_owner,cloud_region_id),
+ status_code, content)
+ tmp_authinfo = json.JSONDecoder().decode(content2)
+
+ #convert vim information
+
+ if tmp_viminfo:
+ viminfo = {}
+ viminfo['vimId'] = vim_id
+ viminfo['cloud_owner'] = cloud_owner
+ viminfo['cloud_region_id'] = cloud_region_id
+ viminfo['type'] = tmp_viminfo['cloud-type']
+ viminfo['name'] = tmp_viminfo['complex-name']
+ viminfo['version'] = tmp_viminfo['cloud-region-version']
+ viminfo['cloud_extra_info'] = tmp_viminfo['cloud-extra-info']
+ viminfo['cloud_epa_caps'] = tmp_viminfo['cloud-epa-caps']
+
+ if tmp_authinfo:
+ viminfo['userName'] = tmp_authinfo['user-name']
+ viminfo['password'] = tmp_authinfo['password']
+ viminfo['domain'] = tmp_authinfo['cloud-domain']
+ viminfo['url'] = tmp_authinfo['service-url']
+ viminfo['tenant'] = tmp_authinfo['default-tenant']
+ viminfo['cacert'] = tmp_authinfo['ssl-cacert']
+ viminfo['insecure'] = tmp_authinfo['ssl-insecure']
+ else:
+ return None
+
+ return viminfo
+ else:
+ return None
+ else:
+ return None
+
+@mock_delete_vim_by_id
+def delete_vim_by_id(vim_id):
+ cloud_owner, cloud_region_id = decode_vim_id(vim_id)
+ if cloud_owner and cloud_region_id:
+ retcode, content, status_code = \
+ req_to_aai("/cloud-infrastructure/cloud-regions/cloud-region/%s/%s"
+ % ( cloud_owner, cloud_region_id), "DELETE")
+ if retcode != 0:
+ logger.error("Status code is %s, detail is %s.", status_code, content)
+ raise VimDriverNewtonException(
+ "Failed to delete VIM in AAI with id (%s:%s,%s)." % (vim_id,cloud_owner,cloud_region_id),
+ status_code, content)
+ return 0
+ # return non zero if failed to decode cloud owner and region id
+ return 1
+
+def decode_vim_id(vim_id):
+ m = re.search(r'^([0-9a-zA-Z-]+)_([0-9a-zA-Z_-]+)$', vim_id)
+ cloud_owner, cloud_region_id = m.group(1), m.group(2)
+ return cloud_owner, cloud_region_id
diff --git a/pike/vagrant/test/test-extensions.sh b/pike/vagrant/test/test-extensions.sh
new file mode 100644
index 00000000..82c254a8
--- /dev/null
+++ b/pike/vagrant/test/test-extensions.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -ex
+
+MULTICLOUD_PLUGIN_ENDPOINT=http://172.16.77.40:9007/api/multicloud-pike/v0/openstack-hudson-dc_RegionOne
+curl -v -s -H "Content-Type: application/json" -X GET $MULTICLOUD_PLUGIN_ENDPOINT/extensions
+curl -v -s -H "Content-Type: application/json" -X GET $MULTICLOUD_PLUGIN_ENDPOINT/extensions/epa-caps
diff --git a/pike/vagrant/test/test_multicloud.sh b/pike/vagrant/test/test_multicloud.sh
new file mode 100644
index 00000000..efc934ce
--- /dev/null
+++ b/pike/vagrant/test/test_multicloud.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+set -ex
+
+sudo apt-get update -y
+sudo apt-get install -y docker.io maven npm virtualenv python-dev
+
+git clone http://gerrit.onap.org/r/oparent
+mkdir $HOME/.m2
+cp oparent/settings.xml $HOME/.m2
+
+git clone /openstack
+cd openstack
+mvn clean install
+cp pike/target/multicloud-openstack-pike*.zip pike/vagrant/test/multicloud-openstack-pike.zip
+
+cd pike/vagrant/test
+sudo docker build -t multicloud-pike-test:latest .
+sudo docker network create --subnet=172.16.77.0/24 onap
+sudo docker run -d -t --name pike-test --network onap --ip 172.16.77.40 -e MSB_ADDR=172.16.77.40 -e MSB_PORT=9007 multicloud-pike-test
+
+while true; do
+ sleep 10
+ curl http://172.16.77.40:9007/api/multicloud-pike/v0/swagger.json && break
+done
+
+for i in `cat tests`
+do
+ bash ./$i
+done
diff --git a/pike/vagrant/test/tests b/pike/vagrant/test/tests
new file mode 100644
index 00000000..018c7a48
--- /dev/null
+++ b/pike/vagrant/test/tests
@@ -0,0 +1 @@
+test-extensions.sh