summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vio/docker/Dockerfile4
-rw-r--r--vio/requirements.txt14
-rwxr-xr-xvio/run.sh17
-rwxr-xr-xvio/stop.sh3
-rwxr-xr-xvio/vio/event_listener/server.py7
-rw-r--r--vio/vio/pub/config/config.py4
-rw-r--r--vio/vio/settings.py4
-rw-r--r--vio/vio/swagger/urls.py7
-rw-r--r--vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py27
-rw-r--r--vio/vio/swagger/views/fakeplugin/image/views.py18
-rw-r--r--vio/vio/tests/test_proxy_identity_view.py264
-rw-r--r--vio/vio/tests/test_restcall.py66
12 files changed, 419 insertions, 16 deletions
diff --git a/vio/docker/Dockerfile b/vio/docker/Dockerfile
index 9c67741..30d7ce8 100644
--- a/vio/docker/Dockerfile
+++ b/vio/docker/Dockerfile
@@ -7,8 +7,8 @@ ENV AAI_PORT "8443"
ENV AAI_SCHEMA_VERSION "v11"
ENV AAI_USERNAME "AAI"
ENV AAI_PASSWORD "AAI"
-ENV MR_ADDR “127.0.0.1”
-ENV MR_PORT “3904”
+ENV MR_ADDR "127.0.0.1"
+ENV MR_PORT "3904"
EXPOSE 9004
diff --git a/vio/requirements.txt b/vio/requirements.txt
index 32384a9..1e2334c 100644
--- a/vio/requirements.txt
+++ b/vio/requirements.txt
@@ -13,7 +13,7 @@ django-redis-cache==0.13.1
httplib2==0.9.2
# for call openstack api
-openstacksdk==0.9.14
+openstacksdk==0.9.15
python-cinderclient==3.5.0
# for unit test
@@ -24,3 +24,15 @@ unittest_xml_reporting==1.12.0
# for onap logging
onappylog>=1.0.6
+
+# for event
+oslo_messaging
+
+# for pecan framework
+uwsgi
+pecan>=1.2.1
+oslo.concurrency>=3.21.0
+oslo.config>=4.11.0
+oslo.service>=1.25.0
+eventlet>=0.20.0
+PyYAML>=3.1.0
diff --git a/vio/run.sh b/vio/run.sh
index f3ba7a1..4b58fe5 100755
--- a/vio/run.sh
+++ b/vio/run.sh
@@ -26,11 +26,16 @@ sed -i "s/MR_PORT =.*/MR_PORT = \"${MR_PORT}\"/g" vio/pub/config/config.py
logDir="/var/log/onap/multicloud/vio"
-nohup python manage.py runserver 0.0.0.0:9004 2>&1 &
-nohup python vio/event_listener/server.py 2>&1 &
-
-while [ ! -f $logDir/vio.log ]; do
- sleep 1
-done
+if [ "$WEB_FRAMEWORK" == "pecan" ]
+then
+ python multivimbroker/scripts/api.py
+else
+ # nohup python manage.py runserver 0.0.0.0:9004 2>&1 &
+ nohup uwsgi --http :9004 --module vio.wsgi --master --processes 4 &
+ nohup python vio/event_listener/server.py 2>&1 &
+ while [ ! -f $logDir/vio.log ]; do
+ sleep 1
+ done
tail -F $logDir/vio.log
+fi
diff --git a/vio/stop.sh b/vio/stop.sh
index 718b3cb..e07394a 100755
--- a/vio/stop.sh
+++ b/vio/stop.sh
@@ -11,4 +11,5 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-ps auxww | grep 'manage.py runserver 0.0.0.0:9004' | awk '{print $2}' | xargs kill -9
+# ps auxww | grep 'manage.py runserver 0.0.0.0:9004' | awk '{print $2}' | xargs kill -9
+ps auxww |grep 'uwsgi --http :9004 --module vio.wsgi --master' |awk '{print $2}' |xargs kill -9
diff --git a/vio/vio/event_listener/server.py b/vio/vio/event_listener/server.py
index 83b9e6f..5e6dc00 100755
--- a/vio/vio/event_listener/server.py
+++ b/vio/vio/event_listener/server.py
@@ -9,8 +9,11 @@ import ConfigParser
import json
import os
import requests
-from vio.pub.config.config import MR_ADDR
-from vio.pub.config.config import MR_PORT
+import sys
+sys.path.append("..")
+from pub.config.config import MR_ADDR # noqa
+from pub.config.config import MR_PORT # noqa
+
LOG = logging.getLogger(__name__)
diff --git a/vio/vio/pub/config/config.py b/vio/vio/pub/config/config.py
index 757ba28..b6b8caa 100644
--- a/vio/vio/pub/config/config.py
+++ b/vio/vio/pub/config/config.py
@@ -29,8 +29,8 @@ AAI_USERNAME = 'AAI'
AAI_PASSWORD = 'AAI'
# [DMaaP]
-MR_ADDR = "127.0.0.1"
-MR_PORT = "3904"
+MR_ADDR = '127.0.0.1'
+MR_PORT = '3904'
# [MDC]
SERVICE_NAME = "multicloud-vio"
diff --git a/vio/vio/settings.py b/vio/vio/settings.py
index f1dad0f..68411ea 100644
--- a/vio/vio/settings.py
+++ b/vio/vio/settings.py
@@ -26,9 +26,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '3o-wney!99y)^h3v)0$j16l9=fdjxcb+a8g+q3tfbahcnu2b0o'
# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = True
+# DEBUG = True
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = ['*']
# Application definition
diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py
index 3871599..e0195fc 100644
--- a/vio/vio/swagger/urls.py
+++ b/vio/vio/swagger/urls.py
@@ -65,6 +65,8 @@ from vio.swagger.views.fakeplugin.image.views import FakeImage
from vio.swagger.views.fakeplugin.image.views import FakeImageVersion
from vio.swagger.views.fakeplugin.image.views import FakeImageDetail
from vio.swagger.views.fakeplugin.image.views import FakeImageSchema
+from vio.swagger.views.fakeplugin.image.views import FakeImageDownload
+from vio.swagger.views.fakeplugin.image.views import FakeImageUpload
from vio.swagger.views.fakeplugin.nova.views import FakeNovaServer
from vio.swagger.views.fakeplugin.nova.views import FakeNovaHypervisors
from vio.swagger.views.fakeplugin.nova.views import FakeNovaAggregate
@@ -210,6 +212,11 @@ urlpatterns = [
FakeImageDetail.as_view()),
url(r'^api/multicloud-vio/v0/vmware_fake/glance/v2/images',
FakeImage.as_view()),
+ url(r'^api/multicloud-vio/v0/vmware_fake/glance/v2/image/file/'
+ r'(?P<imageid>[0-9a-z-A-Z\-\_]+)$',
+ FakeImageDownload.as_view()),
+ url(r'^api/multicloud-vio/v0/vmware_fake/glance/v2/image/file$',
+ FakeImageUpload.as_view()),
url(r'^api/multicloud-vio/v0/vmware_fake/glance/version',
FakeImageVersion.as_view()),
url(r'^api/multicloud-vio/v0/vmware_fake/neutron$',
diff --git a/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py b/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py
index 0368f02..c23a1b2 100644
--- a/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py
+++ b/vio/vio/swagger/views/fakeplugin/fakeData/fakeResponse.py
@@ -1854,6 +1854,33 @@ def image_detail():
return data
+def upload_image(req):
+
+ data = {
+ "status": "active",
+ "name": req.get('name'),
+ "tags": [],
+ "container_format": req.get('container_format'),
+ "created_at": "2014-05-05T17:15:10Z",
+ "disk_format": req.get('disk_format'),
+ "updated_at": "2014-05-05T17:15:11Z",
+ "visibility": req.get('visibility'),
+ "self": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27",
+ "min_disk": 0,
+ "protected": "false",
+ "id": Imageid,
+ "file": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27/file",
+ "checksum": "64d7c1cd2b6f60c92c14662941cb7913",
+ "owner": "5ef70662f8b34079a6eddb8da9d75fe8",
+ "size": 13167616,
+ "min_ram": 0,
+ "schema": req.get('schema'),
+ "virtual_size": "null"
+ }
+
+ return data
+
+
def list_image():
data = {
diff --git a/vio/vio/swagger/views/fakeplugin/image/views.py b/vio/vio/swagger/views/fakeplugin/image/views.py
index 6d6e242..74d7467 100644
--- a/vio/vio/swagger/views/fakeplugin/image/views.py
+++ b/vio/vio/swagger/views/fakeplugin/image/views.py
@@ -2,11 +2,13 @@
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
+import json
from vio.swagger.views.fakeplugin.fakeData.fakeResponse import image_detail
from vio.swagger.views.fakeplugin.fakeData.fakeResponse import list_image
from vio.swagger.views.fakeplugin.fakeData.fakeResponse import image_schema
from vio.swagger.views.fakeplugin.fakeData.fakeResponse import image_version
+from vio.swagger.views.fakeplugin.fakeData.fakeResponse import upload_image
false = "false"
null = "null"
@@ -42,3 +44,19 @@ class FakeImageVersion(APIView):
data = image_version()
return Response(data=data, status=status.HTTP_200_OK)
+
+
+class FakeImageDownload(APIView):
+
+ def get(self, request, imageid):
+
+ data = image_detail()
+ return Response(data=data, status=status.HTTP_200_OK)
+
+
+class FakeImageUpload(APIView):
+
+ def post(self, request):
+ req = json.loads(request.body)
+ data = upload_image(dict(req))
+ return Response(data=data, status=status.HTTP_201_CREATED)
diff --git a/vio/vio/tests/test_proxy_identity_view.py b/vio/vio/tests/test_proxy_identity_view.py
new file mode 100644
index 0000000..a8bf9fb
--- /dev/null
+++ b/vio/vio/tests/test_proxy_identity_view.py
@@ -0,0 +1,264 @@
+# Copyright (c) 2018 VMware, 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.
+
+import mock
+import unittest
+
+from vio.pub.msapi import extsys
+from vio.swagger.views.proxyplugin.httpclient import BaseClient
+from vio.swagger.views.proxyplugin.identity import views
+
+
+class TestIdentityServer(unittest.TestCase):
+
+ def setUp(self):
+ self.view = views.IdentityServer()
+
+ @mock.patch.object(BaseClient, "buildRequest")
+ @mock.patch.object(BaseClient, "_request")
+ def test_get(self, mock_req, mock_build):
+ mock_build.return_value = ("http://onap.org", {}, None)
+ self.view.get(mock.Mock(), "openstack_regionone")
+ mock_req.assert_called_once()
+
+ @mock.patch.object(BaseClient, "send")
+ def test_patch(self, mock_send):
+ self.view.patch(mock.Mock(), "openstack_regionone", None)
+ mock_send.assert_called_once()
+
+ @mock.patch.object(BaseClient, "send")
+ def test_post(self, mock_send):
+ self.view.post(mock.Mock(), "openstack_regionone", None)
+ mock_send.assert_called_once()
+
+ @mock.patch.object(BaseClient, "send")
+ def test_delete(self, mock_send):
+ self.view.delete(mock.Mock(), "openstack_regionone", None)
+ mock_send.assert_called_once()
+
+ @mock.patch.object(BaseClient, "send")
+ def test_head(self, mock_send):
+ self.view.head(mock.Mock(), "openstack_regionone", None)
+ mock_send.assert_called_once()
+
+
+class TestTokenView(unittest.TestCase):
+
+ def setUp(self):
+ self.view = views.TokenView()
+
+ @mock.patch("requests.get")
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_get_v3(self, mock_getvim, mock_req):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v3"
+ res = mock.Mock()
+ res.status_code = 200
+ res.json.return_value = {
+ "version": {
+ "links": [{
+ "href": ""
+ }]
+ }
+ }
+ mock_req.return_value = res
+ resp = self.view.get(req, "vmware_nova")
+ self.assertEqual(resp.status_code, 200)
+
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_get_v2(self, mock_getvim):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v2.0"
+ resp = self.view.get(req, "vmware_nova")
+ self.assertEqual(resp.status_code, 405)
+
+ @mock.patch.object(BaseClient, "buildRequest")
+ @mock.patch.object(BaseClient, "_request")
+ def test_delete(self, mock_req, mock_build):
+ req = mock.Mock()
+ req.META = {
+ "HTTP_X_SUBJECT_TOKEN": "aaa"
+ }
+ mock_build.return_value = ("http://onap.org", {}, None)
+ self.view.delete(req, "openstack_regionone")
+ mock_req.assert_called_once()
+
+ @mock.patch("requests.post")
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_post_v3(self, mock_getvim, mock_post):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v3/auth/tokens"
+ req.body = "{}"
+ mock_getvim.return_value = {
+ "url": "http://onap.org/identity/v3/auth/tokens"
+ }
+ res = mock.Mock()
+ res.status_code = 200
+ res.headers = [("X-Subject-Token", "fake-token")]
+ res.json.return_value = {
+ "token": {
+ "value": "token-value",
+ "project": {
+ "id": "project-id"
+ },
+ "catalog": [{
+ "type": "volume",
+ "id": "3e4941704e9941a582b157ac7203ec1b",
+ "name": "cinder",
+ "endpoints": [{
+ "url": "http://onap.org/api/multicloud/v0/xxx",
+ "interface": "public"
+ }]
+ }]
+ }
+ }
+ mock_post.return_value = res
+ resp = self.view.post(req, "vmware_nova")
+ self.assertEqual(200, resp.status_code)
+
+ @mock.patch("requests.post")
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_post_v2(self, mock_getvim, mock_post):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v2.0/tokens"
+ req.body = """{
+ "auth": {
+ "tenantName": "tenant-name",
+ "passwordCredentials": {
+ "username": "admin",
+ "password": "pass"
+ }
+ }
+ }"""
+ mock_getvim.return_value = {
+ "url": "http://onap.org/identity/v2.0/tokens"
+ }
+ res = mock.Mock()
+ res.status_code = 200
+ res.headers = [("X-Subject-Token", "fake-token")]
+ res.json.return_value = {
+ "access": {
+ "token": {
+ "value": "token-value",
+ "tenant": {
+ "id": "tenant-id"
+ },
+ },
+ "serviceCatalog": [{
+ "type": "volume",
+ "id": "3e4941704e9941a582b157ac7203ec1b",
+ "name": "cinder",
+ "endpoints": [{
+ "adminURL": "http://onap.org/api/multicloud/v0/xxx",
+ "internalURL": "http://onap.org/api/multicloud/v0/xxx",
+ "publicURL": "http://onap.org/api/multicloud/v0/xxx"
+ }]
+ }]
+ }
+ }
+ mock_post.return_value = res
+ resp = self.view.post(req, "vmware_nova")
+ self.assertEqual(200, resp.status_code)
+
+
+class TestTokenV2View(unittest.TestCase):
+
+ def setUp(self):
+ self.view = views.TokenV2View()
+
+ @mock.patch("requests.get")
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_get_v2(self, mock_getvim, mock_get):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v2.0"
+ mock_getvim.return_value = {
+ "url": "http://onap.org/identity/v3"
+ }
+ res = mock.Mock()
+ res.status_code = 200
+ res.json.return_value = {
+ "version": {
+ "links": [{
+ "href": ""
+ }]
+ }
+ }
+ mock_get.return_value = res
+ resp = self.view.get(req, "vmware_nova")
+ self.assertEqual(resp.status_code, 200)
+
+ @mock.patch("requests.post")
+ @mock.patch.object(extsys, "get_vim_by_id")
+ def test_post(self, mock_getvim, mock_post):
+ req = mock.Mock()
+ req.get_full_path.return_value = "identity/v2.0/tokens"
+ req.body = """{
+ "auth": {
+ "tenantName": "tenant-name",
+ "passwordCredentials": {
+ "username": "admin",
+ "password": "pass"
+ }
+ }
+ }"""
+ mock_getvim.return_value = {
+ "url": "http://onap.org/identity/v2.0/tokens"
+ }
+ res = mock.Mock()
+ res.status_code = 200
+ res.headers = [("X-Subject-Token", "fake-token")]
+ res.json.return_value = {
+ "access": {
+ "token": {
+ "value": "token-value",
+ "tenant": {
+ "id": "tenant-id"
+ },
+ },
+ "serviceCatalog": [{
+ "type": "volume",
+ "id": "3e4941704e9941a582b157ac7203ec1b",
+ "name": "cinder",
+ "endpoints": [{
+ "adminURL": "http://onap.org/api/multicloud/v0/xxx",
+ "internalURL": "http://onap.org/api/multicloud/v0/xxx",
+ "publicURL": "http://onap.org/api/multicloud/v0/xxx"
+ }]
+ }]
+ }
+ }
+ mock_post.return_value = res
+ resp = self.view.post(req, "vmware_nova")
+ self.assertEqual(200, resp.status_code)
+
+
+class TestIdentityVersionLink(unittest.TestCase):
+
+ def setUp(self):
+ self.view = views.IdentityVersionLink()
+
+ @mock.patch.object(BaseClient, "buildRequest")
+ @mock.patch.object(BaseClient, "_request")
+ def test_get(self, mock_req, mock_build):
+ mock_build.return_value = ("http://onap.org", {}, None)
+ res = mock.Mock()
+ res.status_code = 200
+ res.data = {
+ "version": {
+ "links": [{
+ "href": ""
+ }]
+ }
+ }
+ mock_req.return_value = res
+ resp = self.view.get(mock.Mock(), "vmware_nova")
+ self.assertEqual(200, resp.status_code)
diff --git a/vio/vio/tests/test_restcall.py b/vio/vio/tests/test_restcall.py
new file mode 100644
index 0000000..051dddf
--- /dev/null
+++ b/vio/vio/tests/test_restcall.py
@@ -0,0 +1,66 @@
+# Copyright (c) 2017-2018 VMware, 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.
+
+import mock
+import unittest
+
+from vio.pub.utils import restcall
+
+
+class TestRestCall(unittest.TestCase):
+
+ def test_combine_url(self):
+ url = ["http://a.com/test/", "http://a.com/test/",
+ "http://a.com/test", "http://a.com/test"]
+ res = ["/resource", "resource", "/resource", "resource"]
+ expected = "http://a.com/test/resource"
+ for i in range(len(url)):
+ self.assertEqual(expected, restcall.combine_url(url[i], res[i]))
+
+ @mock.patch.object(restcall, "call_req")
+ def test_get_res_from_aai(self, mock_call):
+ res = "cloud-regions"
+ content = ""
+ expect_url = "https://aai.api.simpledemo.openecomp.org:8443/aai/v13"
+ expect_user = "AAI"
+ expect_pass = "AAI"
+ expect_headers = {
+ 'X-FromAppId': 'MultiCloud',
+ 'X-TransactionId': '9001',
+ 'content-type': 'application/json',
+ 'accept': 'application/json'
+ }
+ restcall.get_res_from_aai(res, content=content)
+ mock_call.assert_called_once_with(
+ expect_url, expect_user, expect_pass, restcall.rest_no_auth,
+ res, "GET", content, expect_headers)
+
+ @mock.patch.object(restcall, "call_req")
+ def test_req_by_msb(self, mock_call):
+ res = "multicloud"
+ method = "GET"
+ content = "no content"
+ restcall.req_by_msb(res, method, content=content)
+ expect_url = "http://127.0.0.1:10080/"
+ mock_call.assert_called_once_with(
+ expect_url, "", "", restcall.rest_no_auth, res, method,
+ content)
+
+ @mock.patch("httplib2.Http.request")
+ def test_call_req_success(self, mock_req):
+ mock_resp = {
+ "status": "200"
+ }
+ resp_content = "hello"
+ mock_req.return_value = mock_resp, resp_content
+ expect_ret = [0, resp_content, "200", mock_resp]
+ ret = restcall.call_req("http://onap.org/", "user", "pass",
+ restcall.rest_no_auth, "vim", "GET")
+ self.assertEqual(expect_ret, ret)