summaryrefslogtreecommitdiffstats
path: root/vio
diff options
context:
space:
mode:
Diffstat (limited to 'vio')
-rw-r--r--vio/assembly.xml8
-rw-r--r--vio/docker/Dockerfile27
-rwxr-xr-xvio/docker/build_image.sh34
-rwxr-xr-xvio/docker/docker-entrypoint.sh35
-rwxr-xr-xvio/docker/instance-config.sh29
-rwxr-xr-xvio/docker/instance-init.sh9
-rwxr-xr-xvio/docker/instance-run.sh9
-rw-r--r--vio/pom.xml10
-rwxr-xr-xvio/run.sh29
-rw-r--r--vio/version.properties13
-rw-r--r--vio/vio/pub/config/config.py20
-rw-r--r--vio/vio/pub/msapi/extsys.py37
-rw-r--r--vio/vio/pub/utils/restcall.py244
-rw-r--r--vio/vio/pub/vim/drivers/vimsdk/compute.py4
-rw-r--r--vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py8
-rw-r--r--vio/vio/swagger/urls.py10
-rw-r--r--vio/vio/swagger/views/proxyplugin/identity/views.py18
-rw-r--r--vio/vio/swagger/views/registry/__init__.py0
-rw-r--r--vio/vio/swagger/views/registry/views.py179
19 files changed, 657 insertions, 66 deletions
diff --git a/vio/assembly.xml b/vio/assembly.xml
index c59ad59..5df8abe 100644
--- a/vio/assembly.xml
+++ b/vio/assembly.xml
@@ -38,6 +38,14 @@
<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>
diff --git a/vio/docker/Dockerfile b/vio/docker/Dockerfile
new file mode 100644
index 0000000..7d2e84f
--- /dev/null
+++ b/vio/docker/Dockerfile
@@ -0,0 +1,27 @@
+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 "v11"
+ENV AAI_USERNAME "AAI"
+ENV AAI_PASSWORD "AAI"
+
+EXPOSE 9004
+
+RUN apt-get update && \
+ apt-get install -y unzip && \
+ apt-get install -y curl && \
+ apt-get install -y wget
+
+
+RUN cd /opt/ && \
+ wget -q -O multicloud-vio.zip 'https://nexus.onap.org/service/local/artifact/maven/redirect?r=snapshots&g=org.onap.multicloud.openstack.vmware&a=multicloud-vio&v=LATEST&e=zip' && \
+ unzip multicloud-vio.zip && \
+ rm -rf multicloud-vio.zip && \
+ pip install -r vio/requirements.txt
+
+
+WORKDIR /opt
+ENTRYPOINT vio/docker/docker-entrypoint.sh
diff --git a/vio/docker/build_image.sh b/vio/docker/build_image.sh
new file mode 100755
index 0000000..b1e691b
--- /dev/null
+++ b/vio/docker/build_image.sh
@@ -0,0 +1,34 @@
+#!/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"
+ORG="onap"
+VERSION="1.0.0-SNAPSHOT"
+PROJECT="multicloud"
+IMAGE="vio"
+DOCKER_REPOSITORY="nexus3.onap.org:10003"
+IMAGE_NAME="${DOCKER_REPOSITORY}/${ORG}/${PROJECT}/${IMAGE}"
+
+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 {
+ echo "Start build docker image: ${IMAGE_NAME}"
+ docker build ${BUILD_ARGS} -t ${IMAGE_NAME}:${VERSION} -t ${IMAGE_NAME}:latest .
+}
+
+function push_image {
+ echo "Start push docker image: ${IMAGE_NAME}"
+ docker push ${IMAGE_NAME}:${VERSION}
+ docker push ${IMAGE_NAME}:latest
+}
+
+build_image
+push_image
diff --git a/vio/docker/docker-entrypoint.sh b/vio/docker/docker-entrypoint.sh
new file mode 100755
index 0000000..632c558
--- /dev/null
+++ b/vio/docker/docker-entrypoint.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+
+if [ -z "$SERVICE_IP" ]; then
+ export SERVICE_IP=`hostname -i`
+fi
+echo
+echo Environment Variables:
+echo "SERVICE_IP=$SERVICE_IP"
+
+if [ -z "$MSB_ADDR" ]; then
+ echo "Missing required variable MSB_ADDR: Microservices Service Bus address <ip>:<port>"
+ exit 1
+fi
+echo "MSB_ADDR=$MSB_ADDR"
+echo
+
+
+echo
+
+# Configure service based on docker environment variables
+vio/docker/instance-config.sh
+
+
+# Perform one-time config
+if [ ! -e init.log ]; then
+
+ # microservice-specific one-time initialization
+ vio/docker/instance-init.sh
+
+ date > init.log
+fi
+
+# Start the microservice
+vio/docker/instance-run.sh
diff --git a/vio/docker/instance-config.sh b/vio/docker/instance-config.sh
new file mode 100755
index 0000000..221cac9
--- /dev/null
+++ b/vio/docker/instance-config.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# Configure MSB IP address
+MSB_IP=`echo $MSB_ADDR | cut -d: -f 1`
+MSB_PORT=`echo $MSB_ADDR | cut -d: -f 2`
+sed -i "s|MSB_SERVICE_IP.*|MSB_SERVICE_IP = '$MSB_IP'|" vio/vio/pub/config/config.py
+sed -i "s|MSB_SERVICE_PORT.*|MSB_SERVICE_PORT = '$MSB_PORT'|" vio/vio/pub/config/config.py
+sed -i "s|DB_NAME.*|DB_NAME = 'inventory'|" vio/vio/pub/config/config.py
+sed -i "s|DB_USER.*|DB_USER = 'inventory'|" vio/vio/pub/config/config.py
+sed -i "s|DB_PASSWD.*|DB_PASSWD = 'inventory'|" vio/vio/pub/config/config.py
+sed -i "s|\"ip\": \".*\"|\"ip\": \"$SERVICE_IP\"|" vio/vio/pub/config/config.py
+
+# Configure MYSQL
+if [ -z "$MYSQL_ADDR" ]; then
+ export MYSQL_IP=`hostname -i`
+ export MYSQL_PORT=3306
+ export MYSQL_ADDR=$MYSQL_IP:$MYSQL_PORT
+else
+ MYSQL_IP=`echo $MYSQL_ADDR | cut -d: -f 1`
+ MYSQL_PORT=`echo $MYSQL_ADDR | cut -d: -f 2`
+fi
+echo "MYSQL_ADDR=$MYSQL_ADDR"
+sed -i "s|DB_IP.*|DB_IP = '$MYSQL_IP'|" vio/vio/pub/config/config.py
+sed -i "s|DB_PORT.*|DB_PORT = $MYSQL_PORT|" vio/vio/pub/config/config.py
+
+cat vio/vio/pub/config/config.py
+
+sed -i "s/sip=.*/sip=$SERVICE_IP/g" vio/run.sh
+sed -i "s/sip=.*/sip=$SERVICE_IP/g" vio/stop.sh \ No newline at end of file
diff --git a/vio/docker/instance-init.sh b/vio/docker/instance-init.sh
new file mode 100755
index 0000000..f7e0e0e
--- /dev/null
+++ b/vio/docker/instance-init.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -v
+
+# Initialize DB schema
+#./bin/initDB.sh root rootpass 3306 127.0.0.1
+
+# Install python requirements
+cd /opt/vio
+./initialize.sh
+cd /opt
diff --git a/vio/docker/instance-run.sh b/vio/docker/instance-run.sh
new file mode 100755
index 0000000..d01cebb
--- /dev/null
+++ b/vio/docker/instance-run.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -v
+
+cd ./vio
+./run.sh
+
+while [ ! -f logs/runtime_vio.log ]; do
+ sleep 1
+done
+tail -F logs/runtime_vio.log
diff --git a/vio/pom.xml b/vio/pom.xml
index a3bda08..0c60fac 100644
--- a/vio/pom.xml
+++ b/vio/pom.xml
@@ -12,7 +12,9 @@
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-->
-<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">
+<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>
@@ -22,10 +24,10 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.multicloud.openstack.vmware</groupId>
<artifactId>multicloud-vio</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
- <name>multicloud/openstack/vmware</name>
- <description>multiclouddriver for vio</description>
+ <name>multicloud-opentack-vmware</name>
+ <description>multicloud vio</description>
<build>
<plugins>
<plugin>
diff --git a/vio/run.sh b/vio/run.sh
index aa2701f..9abbc85 100755
--- a/vio/run.sh
+++ b/vio/run.sh
@@ -1,14 +1,17 @@
#!/bin/bash
-# Copyright (c) 2017 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.
-
-nohup python manage.py runserver 127.0.0.1:9004 > /dev/null &
+
+sed -i "s/MSB_SERVICE_IP =.*/MSB_SERVICE_IP = \"${MSB_ADDR}\"/g" vio/pub/config/config.py
+sed -i "s/MSB_SERVICE_PORT =.*/MSB_SERVICE_PORT = \"${MSB_PORT}\"/g" vio/pub/config/config.py
+sed -i "s/AAI_ADDR =.*/AAI_ADDR = \"${AAI_ADDR}\"/g" vio/pub/config/config.py
+sed -i "s/AAI_PORT =.*/AAI_PORT = \"${AAI_PORT}\"/g" vio/pub/config/config.py
+sed -i "s/AAI_SCHEMA_VERSION =.*/AAI_SCHEMA_VERSION = \"${AAI_SCHEMA_VERSION}\"/g" vio/pub/config/config.py
+sed -i "s/AAI_USERNAME =.*/AAI_USERNAME = \"${AAI_USERNAME}\"/g" vio/pub/config/config.py
+sed -i "s/AAI_PASSWORD =.*/AAI_PASSWORD = \"${AAI_PASSWORD}\"/g" vio/pub/config/config.py
+
+nohup python manage.py runserver 0.0.0.0:9004 2>&1 &
+
+while [ ! -f logs/runtime_vio.log ]; do
+ sleep 1
+done
+
+tail -F logs/runtime_vio.log
diff --git a/vio/version.properties b/vio/version.properties
new file mode 100644
index 0000000..7f86aa1
--- /dev/null
+++ b/vio/version.properties
@@ -0,0 +1,13 @@
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+
+major=1
+minor=1
+patch=0
+
+base_version=${major}.${minor}.${patch}
+
+# Release must be completed with git revision # in Jenkins
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT
diff --git a/vio/vio/pub/config/config.py b/vio/vio/pub/config/config.py
index a31d63c..1231dd0 100644
--- a/vio/vio/pub/config/config.py
+++ b/vio/vio/pub/config/config.py
@@ -20,20 +20,28 @@ MSB_SERVICE_PORT = '10080'
ROOT_PATH = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.abspath(__file__))))
+# [A&AI]
+AAI_ADDR = "aai.api.simpledemo.openecomp.org"
+AAI_PORT = "8443"
+AAI_SERVICE_URL = 'https://%s:%s/aai' % (AAI_ADDR, AAI_PORT)
+AAI_SCHEMA_VERSION = "v11"
+AAI_USERNAME = 'AAI'
+AAI_PASSWORD = 'AAI'
+
# [REDIS]
REDIS_HOST = '127.0.0.1'
REDIS_PORT = '6379'
REDIS_PASSWD = ''
# [mysql]
-DB_IP = '127.0.0.1'
-DB_PORT = 3306
-DB_NAME = 'multivimvio'
-DB_USER = 'root'
-DB_PASSWD = 'password'
+# DB_IP = '127.0.0.1'
+# DB_PORT = 3306
+# DB_NAME = 'multivimvio'
+# DB_USER = 'root'
+# DB_PASSWD = 'password'
# [register]
-REG_TO_MSB_WHEN_START = True
+REG_TO_MSB_WHEN_START = False
REG_TO_MSB_REG_URL = "/api/microservices/v1/services"
REG_TO_MSB_REG_PARAM = {
"serviceName": "multicloud-vio",
diff --git a/vio/vio/pub/msapi/extsys.py b/vio/vio/pub/msapi/extsys.py
index 19ea80d..5584a3f 100644
--- a/vio/vio/pub/msapi/extsys.py
+++ b/vio/vio/pub/msapi/extsys.py
@@ -10,28 +10,33 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-import json
import logging
-from rest_framework import status
-from vio.pub.exceptions import VimDriverVioException
-from vio.pub.utils.restcall import req_by_msb
+from vio.pub.utils.restcall import AAIClient
logger = logging.getLogger(__name__)
-def get_vims():
- ret = req_by_msb("/openoapi/extsys/v1/vims", "GET")
- if ret[0] != 0:
- logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
- raise VimDriverVioException("Failed to query VIMs from extsys.")
- return json.JSONDecoder().decode(ret[1])
+def split_vim_to_owner_region(vim_id):
+ split_vim = vim_id.split('_')
+ cloud_owner = split_vim[0]
+ cloud_region = "".join(split_vim[1:])
+ return cloud_owner, cloud_region
def get_vim_by_id(vim_id):
- ret = req_by_msb("/openoapi/extsys/v1/vims/%s" % vim_id, "GET")
- if ret[0] != 0:
- logger.error("Status code is %s, detail is %s.", ret[2], ret[1])
- raise VimDriverVioException("Failed to query VIM with \
- id (%s) from extsys." % vim_id, status.HTTP_404_NOT_FOUND)
- return json.JSONDecoder().decode(ret[1])
+ cloud_owner, cloud_region = split_vim_to_owner_region(vim_id)
+ client = AAIClient(cloud_owner, cloud_region)
+ ret = client.get_vim(get_all=True)
+ ret['type'] = ret['cloud-type']
+ ret['version'] = ret['cloud-region-version']
+ ret['vimId'] = vim_id
+ ret['userName'] = ret['esr-system-info-list'][
+ 'esr-system-info'][0]['username']
+ ret['password'] = ret['esr-system-info-list'][
+ 'esr-system-info'][0]['password']
+ ret['tenant'] = ret['esr-system-info-list'][
+ 'esr-system-info'][0]['default-tenant']
+ ret['url'] = ret['esr-system-info-list'][
+ 'esr-system-info'][0]['service-url']
+ return ret
diff --git a/vio/vio/pub/utils/restcall.py b/vio/vio/pub/utils/restcall.py
index 590e52f..99ed9d9 100644
--- a/vio/vio/pub/utils/restcall.py
+++ b/vio/vio/pub/utils/restcall.py
@@ -16,9 +16,16 @@ import logging
import urllib2
import uuid
import httplib2
+import json
+from vio.pub.config.config import AAI_SCHEMA_VERSION
+from vio.pub.config.config import AAI_SERVICE_URL
+from vio.pub.config.config import AAI_USERNAME
+from vio.pub.config.config import AAI_PASSWORD
from vio.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
+from vio.pub.exceptions import VimDriverVioException
+
rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
HTTP_200_OK, HTTP_201_CREATED = '200', '201'
HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '204', '202'
@@ -30,16 +37,22 @@ HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '401', '400'
logger = logging.getLogger(__name__)
-def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
+def call_req(base_url, user, passwd, auth_type, resource, method, content='',
+ headers=None):
callid = str(uuid.uuid1())
- logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
- callid, base_url, user, passwd, auth_type, resource, method, content))
+# logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
+# callid, base_url, user, passwd, auth_type, resource, method, content))
ret = None
resp_status = ''
+ resp = ""
+ full_url = ""
+
try:
full_url = combine_url(base_url, resource)
- headers = {'content-type': 'application/json',
- 'accept': 'application/json'}
+ if headers is None:
+ headers = {}
+ headers['content-type'] = 'application/json'
+
if user:
headers['Authorization'] = 'Basic ' + \
('%s:%s' % (user, passwd)).encode("base64")
@@ -51,41 +64,40 @@ def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
auth_type == rest_no_auth))
http.follow_all_redirects = True
try:
+ logger.debug("request=%s" % full_url)
resp, resp_content = http.request(
- full_url, method=method.upper(),
- body=content, headers=headers)
- resp_status, resp_body = resp['status'], resp_content.decode(
- 'UTF-8')
- logger.debug("[%s][%d]status=%s,resp_body=%s)" %
- (callid, retry_times, resp_status, resp_body))
+ full_url, method=method.upper(), body=content,
+ headers=headers)
+ resp_status = resp['status']
+ resp_body = resp_content.decode('UTF-8')
+
if resp_status in status_ok_list:
- ret = [0, resp_body, resp_status]
+ ret = [0, resp_body, resp_status, resp]
else:
- ret = [1, resp_body, resp_status]
+ ret = [1, resp_body, resp_status, resp]
break
except Exception as ex:
if 'httplib.ResponseNotReady' in str(sys.exc_info()):
- logger.debug("retry_times=%d", retry_times)
logger.error(traceback.format_exc())
- ret = [1, "Unable to connect to %s" %
- full_url, resp_status]
+ ret = [1, "Unable to connect to %s" % full_url,
+ resp_status, resp]
continue
raise ex
except urllib2.URLError as err:
- ret = [2, str(err), resp_status]
+ ret = [2, str(err), resp_status, resp]
except Exception as ex:
logger.error(traceback.format_exc())
logger.error("[%s]ret=%s" % (callid, str(sys.exc_info())))
res_info = str(sys.exc_info())
if 'httplib.ResponseNotReady' in res_info:
- res_info = "The URL[%s] request failed \
- or is not responding." % full_url
- ret = [3, res_info, resp_status]
+ res_info = ("The URL[%s] request failed or is not responding." %
+ full_url)
+ ret = [3, res_info, resp_status, resp]
except:
logger.error(traceback.format_exc())
- ret = [4, str(sys.exc_info()), resp_status]
+ ret = [4, str(sys.exc_info()), resp_status, resp]
- logger.debug("[%s]ret=%s" % (callid, str(ret)))
+# logger.debug("[%s]ret=%s" % (callid, str(ret)))
return ret
@@ -105,3 +117,191 @@ def combine_url(base_url, resource):
else:
full_url = base_url + '/' + resource
return full_url
+
+
+def get_res_from_aai(resource, content=''):
+ headers = {
+ 'X-FromAppId': 'MultiCloud',
+ 'X-TransactionId': '9001',
+ 'content-type': 'application/json',
+ 'accept': 'application/json'
+ }
+ base_url = "%s/%s" % (AAI_SERVICE_URL, AAI_SCHEMA_VERSION)
+ return call_req(base_url, AAI_USERNAME, AAI_PASSWORD, rest_no_auth,
+ resource, "GET", content, headers)
+
+
+class AAIClient(object):
+ def __init__(self, cloud_owner, cloud_region):
+ self.base_url = "%s/%s" % (AAI_SERVICE_URL, AAI_SCHEMA_VERSION)
+ self.username = AAI_USERNAME
+ self.password = AAI_PASSWORD
+ self.default_headers = {
+ 'X-FromAppId': 'multicloud-openstack-vmware',
+ 'X-TransactionId': '9004',
+ 'content-type': 'application/json',
+ 'accept': 'application/json'
+ }
+ self.cloud_owner = cloud_owner
+ self.cloud_region = cloud_region
+
+ def get_vim(self, get_all=False):
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region"
+ "/%s/%s" % (self.cloud_owner, self.cloud_region))
+ if get_all:
+ resource = "%s?depth=all" % resource
+ resp = call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "GET",
+ headers=self.default_headers)
+ if resp[0] != 0:
+ raise VimDriverVioException(
+ status_code=404,
+ content="Failed to query VIM with id (%s_%s) from extsys." % (
+ self.cloud_owner, self.cloud_region))
+ return json.loads(resp[1])
+
+ def delete_vim(self):
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region"
+ "/%s/%s" % (self.cloud_owner, self.cloud_region))
+ resp = call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "DELETE",
+ headers=self.default_headers)
+ if resp[0] != 0:
+ raise VimDriverVioException(
+ status_code=400,
+ content="Failed to delete cloud %s_%s: %s." % (
+ self.cloud_owner, self.cloud_region, resp[1]))
+ return json.loads(resp[1])
+
+ def update_vim(self, content):
+ # update identity url
+ self.update_identity_url()
+ # update tenants
+ self.add_tenants(content)
+ # update flavors
+ self.add_images(content)
+ # update images
+ self.add_flavors(content)
+ # update pservers
+ self.add_pservers(content)
+
+ def update_identity_url(self):
+ vim = self.get_vim()
+ vim['identity-url'] = ("http://%s/api/multicloud/v0/%s_%s/identity/"
+ "v3" % (MSB_SERVICE_IP, self.cloud_owner,
+ self.cloud_region))
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region"
+ "/%s/%s" % (self.cloud_owner, self.cloud_region))
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(vim),
+ headers=self.default_headers)
+
+ def add_tenants(self, content):
+ for tenant in content['tenants']:
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region/"
+ "%s/%s/tenants/tenant/%s" % (
+ self.cloud_owner, self.cloud_region, tenant['id']))
+ body = {'tenant-name': tenant['name']}
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(body),
+ headers=self.default_headers)
+
+ def add_flavors(self, content):
+ for flavor in content['flavors']:
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region/"
+ "%s/%s/flavors/flavor/%s" % (
+ self.cloud_owner, self.cloud_region, flavor['id']))
+ body = {
+ 'flavor-name': flavor['name'],
+ 'flavor-vcpus': flavor['vcpus'],
+ 'flavor-ram': flavor['ram'],
+ 'flavor-disk': flavor['disk'],
+ 'flavor-ephemeral': flavor['ephemeral'],
+ 'flavor-swap': flavor['swap'],
+ 'flavor-is-public': flavor['is_public'],
+ 'flavor-selflink': flavor['links'][0]['href'],
+ 'flavor-disabled': flavor['is_disabled']
+ }
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(body),
+ headers=self.default_headers)
+
+ def add_images(self, content):
+ for image in content['images']:
+ resource = ("/cloud-infrastructure/cloud-regions/cloud-region/"
+ "%s/%s/images/image/%s" % (
+ self.cloud_owner, self.cloud_region, image['id']))
+ body = {
+ 'image-name': image['name'],
+ # 'image-architecture': image[''],
+ 'image-os-distro': image['name'].split("-")[0],
+ 'image-os-version': image['name'].split("-")[1],
+ # 'application': image[''],
+ # 'application-vendor': image[''],
+ # 'application-version': image[''],
+ # TODO replace this with image proxy endpoint
+ 'image-selflink': "",
+ }
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(body),
+ headers=self.default_headers)
+
+ def add_pservers(self, content):
+ for hypervisor in content['hypervisors']:
+ resource = ("/cloud-infrastructure/pservers/pserver/%s" % (
+ hypervisor['name']))
+ body = {
+ # 'ptnii-equip-name'
+ 'number-of-cpus': hypervisor['vcpus'],
+ 'disk-in-gigabytes': hypervisor['local_disk_size'],
+ 'ram-in-megabytes': hypervisor['memory_size'],
+ # 'equip-type'
+ # 'equip-vendor'
+ # 'equip-model'
+ # 'fqdn'
+ # 'pserver-selflink'
+ 'ipv4-oam-address': hypervisor['host_ip'],
+ # 'serial-number'
+ # 'ipaddress-v4-loopback-0'
+ # 'ipaddress-v6-loopback-0'
+ # 'ipaddress-v4-aim'
+ # 'ipaddress-v6-aim'
+ # 'ipaddress-v6-oam'
+ # 'inv-status'
+ 'pserver-id': hypervisor['id'],
+ # 'internet-topology'
+ }
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(body),
+ headers=self.default_headers)
+ # update relationship
+ resource = ("/cloud-infrastructure/pservers/pserver/%s/"
+ "relationship-list/relationship" %
+ hypervisor['name'])
+ related_link = ("%s/cloud-infrastructure/cloud-regions/"
+ "cloud-region/%s/%s" % (
+ self.base_url, self.cloud_owner,
+ self.cloud_region))
+ body = {
+ 'related-to': 'cloud-region',
+ 'related-link': related_link,
+ 'relationship-data': [
+ {
+ 'relationship-key': 'cloud-region.cloud-owner',
+ 'relationship-value': self.cloud_owner
+ },
+ {
+ 'relationship-key': 'cloud-region.cloud-region-id',
+ 'relationship-value': self.cloud_region
+ }
+ ]
+ }
+ call_req(self.base_url, self.username, self.password,
+ rest_no_auth, resource, "PUT",
+ content=json.dumps(body),
+ headers=self.default_headers)
diff --git a/vio/vio/pub/vim/drivers/vimsdk/compute.py b/vio/vio/pub/vim/drivers/vimsdk/compute.py
index 1ed4b25..23a3637 100644
--- a/vio/vio/pub/vim/drivers/vimsdk/compute.py
+++ b/vio/vio/pub/vim/drivers/vimsdk/compute.py
@@ -125,3 +125,7 @@ class ComputeClient(base.DriverBase):
@sdk.translate_exception
def get_hypervisor(self, hypervisor, **query):
return self.conn.compute.get_hypervisor(hypervisor=hypervisor, **query)
+
+ @sdk.translate_exception
+ def list_hypervisors(self, **query):
+ return self.conn.compute.hypervisors(**query)
diff --git a/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py b/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py
index d48b421..96e77bc 100644
--- a/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py
+++ b/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py
@@ -29,3 +29,11 @@ class OperateHypervisor(OperateNova):
**kwargs)
except exceptions.ResourceNotFound:
return None
+
+ def list_hypervisors(self, data, **query):
+ try:
+ return self.request('list_hypervisors', data,
+ project_id=data['project_id'],
+ **query)
+ except exceptions.ResourceNotFound:
+ return None
diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py
index 920edb7..3448424 100644
--- a/vio/vio/swagger/urls.py
+++ b/vio/vio/swagger/urls.py
@@ -38,6 +38,10 @@ from vio.swagger.views.proxyplugin.neutron.views import NetWorkServer
from vio.swagger.views.proxyplugin.volumn.views import VolumeServer
from vio.swagger.views.proxyplugin.heat.views import HeatServer
+# Registry
+from vio.swagger.views.registry.views import Registry
+
+
urlpatterns = [
url(r'^api/multicloud-vio/v0/swagger.json$', SwaggerJsonView.as_view()),
url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-zA-Z_-]+)/'
@@ -96,6 +100,12 @@ urlpatterns = [
r'(?P<portid>[0-9a-zA-Z\-\_]+)$',
DeletePortView.as_view()),
+ # Registry
+ url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)/registry$',
+ Registry.as_view()),
+ # url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)$',
+ # Registry.as_view()),
+
# proxy
url(r'^api/multicloud-vio/v0/(?P<vimid>[0-9a-z-A-Z\-\_]+)/identity/v3',
TokenView.as_view()),
diff --git a/vio/vio/swagger/views/proxyplugin/identity/views.py b/vio/vio/swagger/views/proxyplugin/identity/views.py
index 0ce6312..cee11e7 100644
--- a/vio/vio/swagger/views/proxyplugin/identity/views.py
+++ b/vio/vio/swagger/views/proxyplugin/identity/views.py
@@ -93,9 +93,14 @@ class TokenView(BaseClient):
logger.info("vimid(%(vimid)s) get keystone url %(url)s ",
{"vimid": vimid, "url": keystoneURL})
try:
- res = requests.get(url=keystoneURL).json()
- res['version']['links'][0]['href'] = "http://" + \
- MSB_ADDRESS + "/multicloud-vio/v0/" + vimid + "/identity/v3"
+ res = requests.get(url=keystoneURL, verify=False)
+ if res.status_code != status.HTTP_200_OK:
+ return Response(data={"error": res.content},
+ status=res.status_code)
+ res = res.json()
+ res['version']['links'][0]['href'] = \
+ "http://" + MSB_ADDRESS + "/multicloud-vio/v0/" \
+ + vimid + "/identity/v3"
except Exception as e:
logging.exception("error %s" % e)
@@ -143,8 +148,11 @@ class TokenView(BaseClient):
{"vimid": vimid, "url": url})
try:
- res = requests.post(url=url, data=json.dumps(
- create_req), headers=headers)
+ res = requests.post(url=url, data=json.dumps(create_req),
+ headers=headers, verify=False)
+ if res.status_code != status.HTTP_201_CREATED:
+ return Response(data={"error": res.content},
+ status=res.status_code)
tokenInfo = res.json()
resHeader = dict(res.headers)
except Exception as e:
diff --git a/vio/vio/swagger/views/registry/__init__.py b/vio/vio/swagger/views/registry/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vio/vio/swagger/views/registry/__init__.py
diff --git a/vio/vio/swagger/views/registry/views.py b/vio/vio/swagger/views/registry/views.py
new file mode 100644
index 0000000..cde3b5d
--- /dev/null
+++ b/vio/vio/swagger/views/registry/views.py
@@ -0,0 +1,179 @@
+# Copyright (c) 2017 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 logging
+
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+
+from vio.pub.exceptions import VimDriverVioException
+from vio.pub.msapi import extsys
+from vio.pub.utils.restcall import AAIClient
+from vio.pub.vim.vimapi.keystone import OperateTenant
+from vio.pub.vim.vimapi.glance import OperateImage
+from vio.pub.vim.vimapi.nova import OperateFlavors
+from vio.pub.vim.vimapi.nova import OperateHypervisor
+
+
+logger = logging.getLogger(__name__)
+
+
+class Registry(APIView):
+ def _get_tenants(self, auth_info):
+ tenant_instance = OperateTenant.OperateTenant()
+ try:
+ projects = tenant_instance.get_projects(auth_info)
+ except Exception as e:
+ if hasattr(e, "http_status"):
+ return Response(data={'error': str(e)}, status=e.http_status)
+ else:
+ return Response(data={'error': str(e)},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ rsp = {"tenants": []}
+ for project in projects:
+ rsp['tenants'].append(project.to_dict())
+ return rsp
+
+ def _get_images(self, auth_info):
+ image_instance = OperateImage.OperateImage(auth_info)
+ try:
+ images = image_instance.get_vim_images()
+ except Exception as e:
+ if hasattr(e, "http_status"):
+ return Response(data={'error': str(e)}, status=e.http_status)
+ else:
+ return Response(data={'error': str(e)},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ rsp = {"images": []}
+ for image in images:
+ rsp['images'].append(image.to_dict())
+ return rsp
+
+ def _get_flavors(self, auth_info):
+ flavors_op = OperateFlavors.OperateFlavors()
+ try:
+ flavors = flavors_op.list_flavors(
+ auth_info, auth_info['tenant'])
+ except Exception as e:
+ if hasattr(e, "http_status"):
+ return Response(data={'error': str(e)}, status=e.http_status)
+ else:
+ return Response(data={'error': str(e)},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ rsp = {"flavors": []}
+ for flavor in flavors:
+ rsp['flavors'].append(flavor[0].to_dict())
+ return rsp
+
+ def _get_hypervisors(self, auth_info):
+ hypervisor_op = OperateHypervisor.OperateHypervisor()
+ try:
+ hypervisors = hypervisor_op.list_hypervisors(auth_info)
+ except Exception as e:
+ if hasattr(e, "http_status"):
+ return Response(data={'error': str(e)}, status=e.http_status)
+ else:
+ return Response(data={'error': str(e)},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ rsp = {"hypervisors": []}
+ for hypervisor in hypervisors:
+ rsp['hypervisors'].append(hypervisor.to_dict())
+ return rsp
+
+ def _find_tenant_id(self, name, tenants):
+ for tenant in tenants['tenants']:
+ if tenant['name'] == name:
+ return tenant['id']
+
+ def post(self, request, vimid):
+ try:
+ vim_info = extsys.get_vim_by_id(vimid)
+ except VimDriverVioException as e:
+ return Response(data={'error': str(e)}, status=e.status_code)
+ data = {}
+ data['vimId'] = vim_info['vimId']
+ data['username'] = vim_info['userName']
+ data['userName'] = vim_info['userName']
+ data['password'] = vim_info['password']
+ data['url'] = vim_info['url']
+ data['project_name'] = vim_info['tenant']
+
+ rsp = {}
+ # get tenants
+ try:
+ print('Updating tenants')
+ tenants = self._get_tenants(data)
+ rsp.update(tenants)
+ data['tenant'] = self._find_tenant_id(
+ data['project_name'], tenants)
+ data['project_id'] = data['tenant']
+ # set default tenant
+ # get images
+ print('Updating images')
+ images = self._get_images(data)
+ rsp.update(images)
+ # get flavors
+ print('Updating flavors')
+ flavors = self._get_flavors(data)
+ rsp.update(flavors)
+ # get hypervisors
+ print('Updating hypervisors')
+ hypervisors = self._get_hypervisors(data)
+ rsp.update(hypervisors)
+ # update A&AI
+ print('Put data into A&AI')
+ cloud_owner, cloud_region = extsys.split_vim_to_owner_region(
+ vimid)
+ aai_adapter = AAIClient(cloud_owner, cloud_region)
+ aai_adapter.update_vim(rsp)
+ except Exception as e:
+ return Response(data=e.message,
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return Response(data="", status=status.HTTP_200_OK)
+
+ def delete(self, request, vimid):
+ try:
+ vim_info = extsys.get_vim_by_id(vimid)
+ except VimDriverVioException as e:
+ return Response(data={'error': str(e)}, status=e.status_code)
+
+ data = {}
+ data['vimId'] = vim_info['vimId']
+ data['username'] = vim_info['userName']
+ data['password'] = vim_info['password']
+ data['url'] = vim_info['url']
+ data['project_name'] = vim_info['tenant']
+
+ query = dict(request.query_params)
+ tenant_instance = OperateTenant.OperateTenant()
+ try:
+ projects = tenant_instance.get_projects(data, **query)
+ except Exception as e:
+ if hasattr(e, "http_status"):
+ return Response(data={'error': str(e)}, status=e.http_status)
+ else:
+ return Response(data={'error': str(e)},
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+ rsp = {}
+ rsp['vimId'] = vim_info['vimId']
+ rsp['vimName'] = vim_info['name']
+ rsp['tenants'] = []
+
+ for project in projects:
+ tenant = {}
+ tenant['id'] = project.id
+ tenant['name'] = project.name
+ rsp['tenants'].append(tenant)
+ return Response(data=rsp, status=status.HTTP_200_OK)