summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kilo/.gitignore2
-rw-r--r--kilo/README.md12
-rw-r--r--kilo/assembly.xml54
-rwxr-xr-xkilo/initialize.sh13
-rw-r--r--kilo/kilo/__init__.py10
-rw-r--r--kilo/kilo/pub/__init__.py10
-rw-r--r--kilo/kilo/pub/config/__init__.py10
-rw-r--r--kilo/kilo/pub/config/config.py47
-rw-r--r--kilo/kilo/pub/database/__init__.py10
-rw-r--r--kilo/kilo/pub/database/models.py20
-rw-r--r--kilo/kilo/pub/exceptions.py14
-rw-r--r--kilo/kilo/pub/msapi/__init__.py10
-rw-r--r--kilo/kilo/pub/msapi/extsys.py34
-rw-r--r--kilo/kilo/pub/utils/__init__.py10
-rw-r--r--kilo/kilo/pub/utils/enumutil.py14
-rw-r--r--kilo/kilo/pub/utils/fileutil.py49
-rw-r--r--kilo/kilo/pub/utils/idutil.py17
-rw-r--r--kilo/kilo/pub/utils/restcall.py92
-rwxr-xr-xkilo/kilo/pub/utils/share_lock.py77
-rw-r--r--kilo/kilo/pub/utils/syscomm.py16
-rw-r--r--kilo/kilo/pub/utils/timeutil.py16
-rw-r--r--kilo/kilo/pub/utils/toscautil.py2603
-rw-r--r--kilo/kilo/pub/utils/values.py22
-rw-r--r--kilo/kilo/samples/__init__.py10
-rw-r--r--kilo/kilo/samples/tests.py29
-rw-r--r--kilo/kilo/samples/urls.py16
-rw-r--r--kilo/kilo/samples/views.py26
-rw-r--r--kilo/kilo/settings.py140
-rw-r--r--kilo/kilo/swagger/__init__.py10
-rw-r--r--kilo/kilo/swagger/multivim.flavor.swagger.json397
-rw-r--r--kilo/kilo/swagger/multivim.host.swagger.json183
-rw-r--r--kilo/kilo/swagger/multivim.image.swagger.json384
-rw-r--r--kilo/kilo/swagger/multivim.limit.swagger.json158
-rw-r--r--kilo/kilo/swagger/multivim.network.swagger.json360
-rw-r--r--kilo/kilo/swagger/multivim.server.swagger.json493
-rw-r--r--kilo/kilo/swagger/multivim.subnet.swagger.json428
-rw-r--r--kilo/kilo/swagger/multivim.tenant.swagger.json119
-rw-r--r--kilo/kilo/swagger/multivim.volume.swagger.json379
-rw-r--r--kilo/kilo/swagger/multivim.vport.swagger.json378
-rw-r--r--kilo/kilo/swagger/tests.py29
-rw-r--r--kilo/kilo/swagger/urls.py22
-rw-r--r--kilo/kilo/swagger/views.py89
-rw-r--r--kilo/kilo/urls.py25
-rw-r--r--kilo/kilo/wsgi.py19
-rw-r--r--kilo/manage.py19
-rw-r--r--kilo/pom.xml49
-rw-r--r--kilo/requirements.txt26
-rwxr-xr-xkilo/run.sh13
-rwxr-xr-xkilo/stop.sh13
-rw-r--r--kilo/tox.ini10
-rw-r--r--pom.xml1
51 files changed, 6987 insertions, 0 deletions
diff --git a/kilo/.gitignore b/kilo/.gitignore
new file mode 100644
index 00000000..821f62a6
--- /dev/null
+++ b/kilo/.gitignore
@@ -0,0 +1,2 @@
+logs/*.log
+*.pyc \ No newline at end of file
diff --git a/kilo/README.md b/kilo/README.md
new file mode 100644
index 00000000..ca2bb587
--- /dev/null
+++ b/kilo/README.md
@@ -0,0 +1,12 @@
+# Copyright (c) 2017 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.
+
+# Micro service of network service life cycle management.
diff --git a/kilo/assembly.xml b/kilo/assembly.xml
new file mode 100644
index 00000000..f2cae8f9
--- /dev/null
+++ b/kilo/assembly.xml
@@ -0,0 +1,54 @@
+<!--
+ Copyright (c) 2017 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.
+-->
+<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>kilo</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>kilo</directory>
+ <outputDirectory>/kilo</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>.</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>*.py</include>
+ <include>*.txt</include>
+ <include>*.sh</include>
+ <include>*.ini</include>
+ <include>*.md</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ <baseDirectory>kilo</baseDirectory>
+ <!--baseDirectory>multivimdriver-openstack/kilo</baseDirectory-->
+</assembly>
diff --git a/kilo/initialize.sh b/kilo/initialize.sh
new file mode 100755
index 00000000..5fed1714
--- /dev/null
+++ b/kilo/initialize.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright (c) 2017 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.
+
+pip install -r requirements.txt
diff --git a/kilo/kilo/__init__.py b/kilo/kilo/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/__init__.py b/kilo/kilo/pub/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/pub/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/config/__init__.py b/kilo/kilo/pub/config/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/pub/config/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/config/config.py b/kilo/kilo/pub/config/config.py
new file mode 100644
index 00000000..9a2eb801
--- /dev/null
+++ b/kilo/kilo/pub/config/config.py
@@ -0,0 +1,47 @@
+# Copyright (c) 2017 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.
+
+import os
+
+# [MSB]
+MSB_SERVICE_IP = '127.0.0.1'
+MSB_SERVICE_PORT = '10080'
+
+# [IMAGE LOCAL PATH]
+ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+# [REDIS]
+REDIS_HOST = '127.0.0.1'
+REDIS_PORT = '6379'
+REDIS_PASSWD = ''
+
+# [mysql]
+DB_IP = "127.0.0.1"
+DB_PORT = 3306
+DB_NAME = "multivimkilo"
+DB_USER = "root"
+DB_PASSWD = "password"
+
+# [register]
+REG_TO_MSB_WHEN_START = True
+REG_TO_MSB_REG_URL = "/openoapi/microservices/v1/services"
+REG_TO_MSB_REG_PARAM = {
+ "serviceName": "multivim-kilo",
+ "version": "v1",
+ "url": "/openoapi/multivim-kilo/v1",
+ "protocol": "REST",
+ "visualRange": "1",
+ "nodes": [{
+ "ip": "127.0.0.1",
+ "port": "9002",
+ "ttl": 0
+ }]
+}
diff --git a/kilo/kilo/pub/database/__init__.py b/kilo/kilo/pub/database/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/pub/database/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/database/models.py b/kilo/kilo/pub/database/models.py
new file mode 100644
index 00000000..0a23fc4e
--- /dev/null
+++ b/kilo/kilo/pub/database/models.py
@@ -0,0 +1,20 @@
+# Copyright (c) 2017 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.
+
+from django.db import models
+
+class VimInstModel(models.Model):
+ class Meta:
+ db_table = 'vim_inst_type_mapping'
+
+ vimid = models.CharField(db_column='VIMID', primary_key=True, max_length=200)
+ vimtype = models.CharField(db_column="VIMTYPE", max_length=200)
+ viminst_url = models.CharField(db_column="VIMINSTURL", max_length=200)
diff --git a/kilo/kilo/pub/exceptions.py b/kilo/kilo/pub/exceptions.py
new file mode 100644
index 00000000..7a9ee4e5
--- /dev/null
+++ b/kilo/kilo/pub/exceptions.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017 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.
+
+
+class VimDriverKiloException(Exception):
+ pass
diff --git a/kilo/kilo/pub/msapi/__init__.py b/kilo/kilo/pub/msapi/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/pub/msapi/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/msapi/extsys.py b/kilo/kilo/pub/msapi/extsys.py
new file mode 100644
index 00000000..4b4fd057
--- /dev/null
+++ b/kilo/kilo/pub/msapi/extsys.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2017 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.
+
+import json
+import logging
+
+from kilo.pub.exceptions import VimDriverKiloException
+from kilo.pub.utils.restcall import req_by_msb
+
+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 VimDrvierKiloException("Failed to query VIMs from extsys.")
+ return json.JSONDecoder().decode(ret[1])
+
+
+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 VimDrvierKiloException("Failed to query VIM with id (%s) from extsys." % vim_id)
+ return json.JSONDecoder().decode(ret[1])
diff --git a/kilo/kilo/pub/utils/__init__.py b/kilo/kilo/pub/utils/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/pub/utils/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/pub/utils/enumutil.py b/kilo/kilo/pub/utils/enumutil.py
new file mode 100644
index 00000000..4a5c3b10
--- /dev/null
+++ b/kilo/kilo/pub/utils/enumutil.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2017 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.
+
+
+def enum(**enums):
+ return type('Enum', (), enums)
diff --git a/kilo/kilo/pub/utils/fileutil.py b/kilo/kilo/pub/utils/fileutil.py
new file mode 100644
index 00000000..a33186ec
--- /dev/null
+++ b/kilo/kilo/pub/utils/fileutil.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2017 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.
+import os
+import shutil
+import logging
+import traceback
+import urllib2
+
+logger = logging.getLogger(__name__)
+
+
+def make_dirs(path):
+ if not os.path.exists(path):
+ os.makedirs(path, 0777)
+
+
+def delete_dirs(path):
+ try:
+ if os.path.exists(path):
+ shutil.rmtree(path)
+ except Exception as e:
+ logger.error(traceback.format_exc())
+ logger.error("Failed to delete %s:%s", path, e.message)
+
+
+def download_file_from_http(url, local_dir, file_name):
+ local_file_name = os.path.join(local_dir, file_name)
+ is_download_ok = False
+ try:
+ make_dirs(local_dir)
+ r = urllib2.Request(url)
+ req = urllib2.urlopen(r)
+ save_file = open(local_file_name, 'wb')
+ save_file.write(req.read())
+ save_file.close()
+ req.close()
+ is_download_ok = True
+ except:
+ logger.error(traceback.format_exc())
+ logger.error("Failed to download %s to %s.", url, local_file_name)
+ return is_download_ok, local_file_name
diff --git a/kilo/kilo/pub/utils/idutil.py b/kilo/kilo/pub/utils/idutil.py
new file mode 100644
index 00000000..8e344f30
--- /dev/null
+++ b/kilo/kilo/pub/utils/idutil.py
@@ -0,0 +1,17 @@
+# Copyright (c) 2017 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.
+from redisco import containers as cont
+
+
+def get_auto_id(id_type, id_group="auto_id_hash"):
+ auto_id_hash = cont.Hash(id_group)
+ auto_id_hash.hincrby(id_type, 1)
+ return auto_id_hash.hget(id_type)
diff --git a/kilo/kilo/pub/utils/restcall.py b/kilo/kilo/pub/utils/restcall.py
new file mode 100644
index 00000000..4b96d357
--- /dev/null
+++ b/kilo/kilo/pub/utils/restcall.py
@@ -0,0 +1,92 @@
+# Copyright (c) 2017 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.
+
+import sys
+import traceback
+import logging
+import urllib2
+import uuid
+import httplib2
+
+from kilo.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
+
+rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
+HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '200', '201', '204', '202'
+status_ok_list = [HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED]
+HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN, HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '404', '403', '401', '400'
+
+logger = logging.getLogger(__name__)
+
+
+def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
+ 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))
+ ret = None
+ resp_status = ''
+ try:
+ full_url = combine_url(base_url, resource)
+ headers = {'content-type': 'application/json', 'accept': 'application/json'}
+ if user:
+ headers['Authorization'] = 'Basic ' + ('%s:%s' % (user, passwd)).encode("base64")
+ ca_certs = None
+ for retry_times in range(3):
+ http = httplib2.Http(ca_certs=ca_certs, disable_ssl_certificate_validation=(auth_type == rest_no_auth))
+ http.follow_all_redirects = True
+ try:
+ 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))
+ if resp_status in status_ok_list:
+ ret = [0, resp_body, resp_status]
+ else:
+ ret = [1, resp_body, resp_status]
+ 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]
+ continue
+ raise ex
+ except urllib2.URLError as err:
+ ret = [2, str(err), resp_status]
+ 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]
+ except:
+ logger.error(traceback.format_exc())
+ ret = [4, str(sys.exc_info()), resp_status]
+
+ logger.debug("[%s]ret=%s" % (callid, str(ret)))
+ return ret
+
+
+def req_by_msb(resource, method, content=''):
+ base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT)
+ return call_req(base_url, "", "", rest_no_auth, resource, method, content)
+
+
+def combine_url(base_url, resource):
+ full_url = None
+ if base_url.endswith('/') and resource.startswith('/'):
+ full_url = base_url[:-1] + resource
+ elif base_url.endswith('/') and not resource.startswith('/'):
+ full_url = base_url + resource
+ elif not base_url.endswith('/') and resource.startswith('/'):
+ full_url = base_url + resource
+ else:
+ full_url = base_url + '/' + resource
+ return full_url
diff --git a/kilo/kilo/pub/utils/share_lock.py b/kilo/kilo/pub/utils/share_lock.py
new file mode 100755
index 00000000..0e806dae
--- /dev/null
+++ b/kilo/kilo/pub/utils/share_lock.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017 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.
+
+import time
+
+import redis
+
+from kilo.pub.config.config import REDIS_HOST, REDIS_PORT, REDIS_PASSWD
+
+
+class SharedLock:
+ def __init__(self, lock_key, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWD, db=9, lock_timeout=5 * 60):
+ self.lock_key = lock_key
+ self.lock_timeout = lock_timeout
+ self.redis = redis.Redis(host=host, port=port, db=db, password=password)
+ self.acquire_time = -1
+
+ def acquire(self):
+ begin = now = int(time.time())
+ while (now - begin) < self.lock_timeout:
+
+ result = self.redis.setnx(self.lock_key, now + self.lock_timeout + 1)
+ if result == 1 or result is True:
+ self.acquire_time = now
+ return True
+
+ current_lock_timestamp = self.redis.get(self.lock_key)
+ if not current_lock_timestamp:
+ time.sleep(1)
+ continue
+
+ current_lock_timestamp = int(current_lock_timestamp)
+
+ if now > current_lock_timestamp:
+ next_lock_timestamp = self.redis.getset(self.lock_key, now + self.lock_timeout + 1)
+ if not next_lock_timestamp:
+ time.sleep(1)
+ continue
+ next_lock_timestamp = int(next_lock_timestamp)
+
+ if next_lock_timestamp == current_lock_timestamp:
+ self.acquire_time = now
+ return True
+ else:
+ time.sleep(1)
+ continue
+ return False
+
+ def release(self):
+ now = int(time.time())
+ if now > self.acquire_time + self.lock_timeout:
+ # key expired, do nothing and let other clients handle it
+ return
+ self.acquire_time = None
+ self.redis.delete(self.lock_key)
+
+
+def do_biz_with_share_lock(lock_name, callback):
+ lock = SharedLock(lock_name)
+ try:
+ if not lock.acquire():
+ raise Exception(lock_name + " timeout")
+ callback()
+ except Exception as e:
+ raise e
+ finally:
+ lock.release()
diff --git a/kilo/kilo/pub/utils/syscomm.py b/kilo/kilo/pub/utils/syscomm.py
new file mode 100644
index 00000000..735129a6
--- /dev/null
+++ b/kilo/kilo/pub/utils/syscomm.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2017 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.
+
+import inspect
+
+
+def fun_name():
+ return inspect.stack()[1][3]
diff --git a/kilo/kilo/pub/utils/timeutil.py b/kilo/kilo/pub/utils/timeutil.py
new file mode 100644
index 00000000..984bb8d6
--- /dev/null
+++ b/kilo/kilo/pub/utils/timeutil.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2017 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.
+
+import datetime
+
+
+def now_time(fmt="%Y-%m-%d %H:%M:%S"):
+ return datetime.datetime.now().strftime(fmt)
diff --git a/kilo/kilo/pub/utils/toscautil.py b/kilo/kilo/pub/utils/toscautil.py
new file mode 100644
index 00000000..ec6e2009
--- /dev/null
+++ b/kilo/kilo/pub/utils/toscautil.py
@@ -0,0 +1,2603 @@
+# Copyright (c) 2017 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.
+
+import json
+
+def safe_get(key_val, key):
+ return key_val[key] if key in key_val else ""
+
+
+def find_node_name(node_id, node_list):
+ for node in node_list:
+ if node['id'] == node_id:
+ return node['template_name']
+ raise Exception('can not find node(%s).' % node_id)
+
+
+def find_node_type(node_id, node_list):
+ for node in node_list:
+ if node['id'] == node_id:
+ return node['type_name']
+ raise Exception('can not find node(%s).' % node_id)
+
+
+def find_related_node(node_id, src_json_model, requirement_name):
+ related_nodes = []
+ for model_tpl in safe_get(src_json_model, "node_templates"):
+ for rt in safe_get(model_tpl, 'requirement_templates'):
+ if safe_get(rt, 'name') == requirement_name and \
+ safe_get(rt, 'target_node_template_name') == node_id:
+ related_nodes.append(model_tpl['name'])
+ return related_nodes
+
+
+def convert_props(src_node, dest_node):
+ if 'properties' in src_node and src_node['properties']:
+ for prop_name, prop_info in src_node['properties'].items():
+ if 'value' in prop_info:
+ dest_node['properties'][prop_name] = prop_info['value']
+
+
+def convert_metadata(src_json):
+ return src_json['metadata'] if 'metadata' in src_json else {}
+
+
+def convert_inputs(src_json):
+ inputs = {}
+ if 'inputs' in src_json:
+ src_inputs = src_json['inputs']
+ for param_name, param_info in src_inputs.items():
+ input_param = {}
+ if 'type_name' in param_info:
+ input_param['type'] = param_info['type_name']
+ if 'description' in param_info:
+ input_param['description'] = param_info['description']
+ if 'value' in param_info:
+ input_param['value'] = param_info['value']
+ inputs[param_name] = input_param
+ return inputs
+
+
+def convert_vnf_node(src_node, src_json_model):
+ vnf_node = {'type': src_node['type_name'], 'vnf_id': src_node['template_name'],
+ 'description': '', 'properties': {}, 'dependencies': [], 'networks': []}
+ convert_props(src_node, vnf_node)
+ for model_tpl in safe_get(src_json_model, "node_templates"):
+ if model_tpl['name'] != vnf_node['vnf_id']:
+ continue
+ vnf_node['dependencies'] = [{
+ 'key_name': requirement['name'],
+ 'vl_id': requirement['target_node_template_name']} for \
+ requirement in safe_get(model_tpl, 'requirement_templates') if \
+ safe_get(requirement, 'target_capability_name') == 'virtual_linkable']
+ vnf_node['networks'] = [requirement['target_node_template_name'] for \
+ requirement in safe_get(model_tpl, 'requirement_templates') if \
+ safe_get(requirement, 'name') == 'dependency']
+ return vnf_node
+
+
+def convert_pnf_node(src_node, src_json_model):
+ pnf_node = {'pnf_id': src_node['template_name'], 'description': '', 'properties': {}}
+ convert_props(src_node, pnf_node)
+ pnf_node['cps'] = find_related_node(src_node['id'], src_json_model, 'virtualbinding')
+ return pnf_node
+
+
+def convert_vl_node(src_node, src_node_list):
+ vl_node = {'vl_id': src_node['template_name'], 'description': '', 'properties': {}}
+ convert_props(src_node, vl_node)
+ vl_node['route_id'] = ''
+ for relation in safe_get(src_node, 'relationships'):
+ if safe_get(relation, 'type_name').endswith('.VirtualLinksTo'):
+ vl_node['route_id'] = find_node_name(relation['target_node_id'], src_node_list)
+ break
+ vl_node['route_external'] = (src_node['type_name'].find('.RouteExternalVL') > 0)
+ return vl_node
+
+
+def convert_cp_node(src_node, src_node_list, model_type='NSD'):
+ cp_node = {'cp_id': src_node['template_name'], 'description': '', 'properties': {}}
+ convert_props(src_node, cp_node)
+ src_relationships = src_node['relationships']
+ for relation in src_relationships:
+ if safe_get(relation, 'name') == 'virtualLink':
+ cp_node['vl_id'] = find_node_name(relation['target_node_id'], src_node_list)
+ elif safe_get(relation, 'name') == 'virtualbinding':
+ node_key = 'pnf_id' if model_type == 'NSD' else 'vdu_id'
+ cp_node[node_key] = find_node_name(relation['target_node_id'], src_node_list)
+ return cp_node
+
+
+def convert_router_node(src_node, src_node_list):
+ router_node = {'router_id': src_node['template_name'], 'description': '', 'properties': {}}
+ convert_props(src_node, router_node)
+ for relation in src_node['relationships']:
+ if safe_get(relation, 'name') != 'external_virtual_link':
+ continue
+ router_node['external_vl_id'] = find_node_name(relation['target_node_id'], src_node_list)
+ router_node['external_ip_addresses'] = []
+ if 'properties' not in relation:
+ continue
+ for prop_name, prop_info in relation['properties'].items():
+ if prop_name == 'router_ip_address':
+ router_node['external_ip_addresses'].append(prop_info['value'])
+ break
+ return router_node
+
+
+def convert_fp_node(src_node, src_node_list, src_json_model):
+ fp_node = {'fp_id': src_node['template_name'], 'description': '',
+ 'properties': {}, 'forwarder_list': []}
+ convert_props(src_node, fp_node)
+ for relation in safe_get(src_node, 'relationships'):
+ if safe_get(relation, 'name') != 'forwarder':
+ continue
+ forwarder_point = {'type': 'vnf'}
+ target_node_type = find_node_type(relation['target_node_id'], src_node_list).upper()
+ if target_node_type.find('.CP.') >= 0 or target_node_type.endswith('.CP'):
+ forwarder_point['type'] = 'cp'
+ forwarder_point['node_name'] = find_node_name(relation['target_node_id'], src_node_list)
+ forwarder_point['capability'] = ''
+ if forwarder_point['type'] == 'vnf':
+ for node_tpl in src_json_model["node_templates"]:
+ if fp_node['fp_id'] != node_tpl["name"]:
+ continue
+ for r_tpl in safe_get(node_tpl, "requirement_templates"):
+ if safe_get(r_tpl, "target_node_template_name") != forwarder_point['node_name']:
+ continue
+ forwarder_point['capability'] = safe_get(r_tpl, "target_capability_name")
+ break
+ break
+ fp_node['forwarder_list'].append(forwarder_point)
+ return fp_node
+
+
+def convert_vnffg_group(src_group, src_group_list, src_node_list):
+ vnffg = {'vnffg_id': src_group['template_name'], 'description': '',
+ 'properties': {}, 'members': []}
+ convert_props(src_group, vnffg)
+ for member_node_id in src_group['member_node_ids']:
+ vnffg['members'].append(find_node_name(member_node_id, src_node_list))
+ return vnffg
+
+
+def convert_imagefile_node(src_node, src_node_list):
+ image_node = {'image_file_id': src_node['template_name'], 'description': '',
+ 'properties': {}}
+ convert_props(src_node, image_node)
+ return image_node
+
+
+def convert_localstorage_node(src_node, src_node_list):
+ localstorage_node = {'local_storage_id': src_node['template_name'], 'description': '',
+ 'properties': {}}
+ convert_props(src_node, localstorage_node)
+ return localstorage_node
+
+
+def convert_vdu_node(src_node, src_node_list, src_json_model):
+ vdu_node = {'vdu_id': src_node['template_name'], 'description': '', 'properties': {},
+ 'image_file': '', 'local_storages': [], 'dependencies': [], 'nfv_compute': {},
+ 'vls': [], 'artifacts': []}
+ convert_props(src_node, vdu_node)
+
+ for relation in src_node['relationships']:
+ r_id, r_name = safe_get(relation, 'target_node_id'), safe_get(relation, 'name')
+ if r_name == 'guest_os':
+ vdu_node['image_file'] = find_node_name(r_id, src_node_list)
+ elif r_name == 'local_storage':
+ vdu_node['local_storages'].append(find_node_name(r_id, src_node_list))
+ elif r_name.endswith('.AttachesTo'):
+ nt = find_node_type(r_id, src_node_list)
+ if nt.endswith('.BlockStorage.Local') or nt.endswith('.LocalStorage'):
+ vdu_node['local_storages'].append(find_node_name(r_id, src_node_list))
+
+ for capability in src_node['capabilities']:
+ if capability['name'] != 'nfv_compute':
+ continue
+ for prop_name, prop_info in capability['properties'].items():
+ if 'value' in prop_info:
+ vdu_node['nfv_compute'][prop_name] = prop_info['value']
+
+ vdu_node['cps'] = find_related_node(src_node['id'], src_json_model, 'virtualbinding')
+
+ for cp_node in vdu_node['cps']:
+ for src_cp_node in src_node_list:
+ if src_cp_node['template_name'] != cp_node:
+ continue
+ for relation in safe_get(src_cp_node, 'relationships'):
+ if relation['name'] != 'virtualLink':
+ continue
+ vl_node_name = find_node_name(relation['target_node_id'], src_node_list)
+ if vl_node_name not in vdu_node['vls']:
+ vdu_node['vls'].append(vl_node_name)
+
+ for item in safe_get(src_node, 'artifacts'):
+ artifact = {'artifact_name': item['name'], 'type': item['type_name'],
+ 'file': item['source_path']}
+ vdu_node['artifacts'].append(artifact)
+
+ return vdu_node
+
+
+def convert_exposed_node(src_json, src_nodes, exposed):
+ for item in safe_get(safe_get(src_json, 'substitution'), 'requirements'):
+ exposed['external_cps'].append({'key_name': item['mapped_name'],
+ "cp_id": find_node_name(item['node_id'], src_nodes)})
+ for item in safe_get(safe_get(src_json, 'substitution'), 'capabilities'):
+ exposed['forward_cps'].append({'key_name': item['mapped_name'],
+ "cp_id": find_node_name(item['node_id'], src_nodes)})
+
+
+def convert_vnffgs(src_json_inst, src_nodes):
+ vnffgs = []
+ src_groups = safe_get(src_json_inst, 'groups')
+ for group in src_groups:
+ type_name = group['type_name'].upper()
+ if type_name.find('.VNFFG.') >= 0 or type_name.endswith('.VNFFG'):
+ vnffgs.append(convert_vnffg_group(group, src_groups, src_nodes))
+ return vnffgs
+
+
+def convert_common(src_json, target_json):
+ if isinstance(src_json, (unicode, str)):
+ src_json_dict = json.loads(src_json)
+ else:
+ src_json_dict = src_json
+ src_json_inst = src_json_dict["instance"]
+ src_json_model = src_json_dict["model"] if "model" in src_json_dict else {}
+
+ target_json['metadata'] = convert_metadata(src_json_inst)
+ target_json['inputs'] = convert_inputs(src_json_inst)
+ target_json['vls'] = []
+ target_json['cps'] = []
+ target_json['routers'] = []
+
+ return src_json_inst, src_json_model
+
+
+def convert_nsd_model(src_json):
+ target_json = {'vnfs': [], 'pnfs': [], 'fps': []}
+ src_json_inst, src_json_model = convert_common(src_json, target_json)
+
+ src_nodes = src_json_inst['nodes']
+ for node in src_nodes:
+ type_name = node['type_name']
+ if type_name.find('.VNF.') > 0 or type_name.endswith('.VNF'):
+ target_json['vnfs'].append(convert_vnf_node(node, src_json_model))
+ elif type_name.find('.PNF.') > 0 or type_name.endswith('.PNF'):
+ target_json['pnfs'].append(convert_pnf_node(node, src_json_model))
+ elif type_name.find('.VL.') > 0 or type_name.endswith('.VL') \
+ or node['type_name'].find('.RouteExternalVL') > 0:
+ target_json['vls'].append(convert_vl_node(node, src_nodes))
+ elif type_name.find('.CP.') > 0 or type_name.endswith('.CP'):
+ target_json['cps'].append(convert_cp_node(node, src_nodes))
+ elif type_name.find('.FP.') > 0 or type_name.endswith('.FP'):
+ target_json['fps'].append(convert_fp_node(node, src_nodes, src_json_model))
+ elif type_name.endswith('.Router'):
+ target_json['routers'].append(convert_router_node(node, src_nodes))
+
+ target_json['vnffgs'] = convert_vnffgs(src_json_inst, src_nodes)
+
+ target_json['ns_exposed'] = {'external_cps': [], 'forward_cps': []}
+ convert_exposed_node(src_json_inst, src_nodes, target_json['ns_exposed'])
+ return json.dumps(target_json)
+
+
+def convert_vnfd_model(src_json):
+ target_json = {'image_files': [], 'local_storages': [], 'vdus': []}
+ src_json_inst, src_json_model = convert_common(src_json, target_json)
+
+ src_nodes = src_json_inst['nodes']
+ for node in src_nodes:
+ type_name = node['type_name']
+ if type_name.endswith('.ImageFile'):
+ target_json['image_files'].append(convert_imagefile_node(node, src_nodes))
+ elif type_name.endswith('.BlockStorage.Local') or type_name.endswith('.LocalStorage'):
+ target_json['local_storages'].append(convert_localstorage_node(node, src_nodes))
+ elif type_name.find('.VDU.') > 0 or type_name.endswith('.VDU'):
+ target_json['vdus'].append(convert_vdu_node(node, src_nodes, src_json_model))
+ elif type_name.find('.VL.') > 0 or type_name.endswith('.VL') \
+ or node['type_name'].find('.RouteExternalVL') > 0:
+ target_json['vls'].append(convert_vl_node(node, src_nodes))
+ elif type_name.find('.CP.') > 0 or type_name.endswith('.CP'):
+ target_json['cps'].append(convert_cp_node(node, src_nodes, 'VNFD'))
+ elif type_name.endswith('.Router'):
+ target_json['routers'].append(convert_router_node(node, src_nodes))
+
+ target_json['vnf_exposed'] = {'external_cps': [], 'forward_cps': []}
+ convert_exposed_node(src_json_inst, src_nodes, target_json['vnf_exposed'])
+ return json.dumps(target_json)
+
+if __name__ == '__main__':
+ src_json = json.dumps(
+ {
+ "instance":{
+ "metadata":{
+ "vendor":"ZTE",
+ "name":"VCPE_NS",
+ "csarVersion":"v1.0",
+ "csarType":"NSAR",
+ "csarProvider":"ZTE",
+ "version":1,
+ "invariant_id":"vcpe_ns_sff_1",
+ "id":"VCPE_NS",
+ "description":"vcpe_ns"
+ },
+ "nodes":[
+ {
+ "id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "type_name":"tosca.nodes.nfv.ext.FP",
+ "template_name":"path2",
+ "properties":{
+ "symmetric":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "policy":{
+ "type_name":"tosca.datatypes.nfv.ext.FPPolicy",
+ "value":{
+ "type":"ACL",
+ "criteria":{
+ "dest_port_range":"1-100",
+ "ip_protocol":"tcp",
+ "source_ip_range":[
+ "119.1.1.1-119.1.1.10"
+ ],
+ "dest_ip_range":[
+ {"get_input":"NatIpRange"}
+ ],
+ "dscp":0,
+ "source_port_range":"1-100"
+ }
+ }
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"forwarder",
+ "source_requirement_index":0,
+ "target_node_id":"m6000_data_out_qeukdtf6g87cnparxi51fa8s6"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":1,
+ "target_node_id":"m600_tunnel_cp_imwfk5l48ljz0g9knc6d68hv5"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"VNAT_cfdljtspvkp234irka59wgab0",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"path1_bv53fblv26hawr8dj4fxe2rsd",
+ "type_name":"tosca.nodes.nfv.ext.FP",
+ "template_name":"path1",
+ "properties":{
+ "symmetric":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "policy":{
+ "type_name":"tosca.datatypes.nfv.ext.FPPolicy",
+ "value":{
+ "type":"ACL",
+ "criteria":{
+ "dest_port_range":"1-100",
+ "ip_protocol":"tcp",
+ "source_ip_range":[
+ "1-100"
+ ],
+ "dest_ip_range":[
+ "1-100"
+ ],
+ "dscp":4,
+ "source_port_range":"1-100"
+ }
+ }
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"forwarder",
+ "source_requirement_index":0,
+ "target_node_id":"m6000_data_in_eldly5txw4frny3cc349uz3nc"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":1,
+ "target_node_id":"m600_tunnel_cp_imwfk5l48ljz0g9knc6d68hv5"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"VFW_57z0ua89aiyl8ncvw7h7mjf34",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":3,
+ "target_node_id":"VNAT_cfdljtspvkp234irka59wgab0",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":4,
+ "target_node_id":"m600_tunnel_cp_imwfk5l48ljz0g9knc6d68hv5"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":5,
+ "target_node_id":"m6000_data_out_qeukdtf6g87cnparxi51fa8s6"
+ }
+ ]
+ },
+ {
+ "id":"m6000_data_out_qeukdtf6g87cnparxi51fa8s6",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "template_name":"m6000_data_out",
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"11-22-33-22-11-44"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"xgei-0/4/1/5"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"176.1.1.2"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"virtualbinding",
+ "source_requirement_index":0,
+ "target_node_id":"m6000_s_7qtzo5nuocyfmebc6kp9raq18",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualLink",
+ "source_requirement_index":1,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"VFW_57z0ua89aiyl8ncvw7h7mjf34",
+ "type_name":"tosca.nodes.nfv.ext.zte.VNF.VFW",
+ "template_name":"VFW",
+ "properties":{
+ "is_shared":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "plugin_info":{
+ "type_name":"string",
+ "value":"vbrasplugin_1.0"
+ },
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_extend_type":{
+ "type_name":"string",
+ "value":"driver"
+ },
+ "name":{
+ "type_name":"string",
+ "value":"VFW"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "cross_dc":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_type":{
+ "type_name":"string",
+ "value":"VFW"
+ },
+ "vnfd_version":{
+ "type_name":"string",
+ "value":"1.0.0"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"vcpe_vfw_zte_1_0"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "adjust_vnf_capacity":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "vmnumber_overquota_alarm":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "csarProvider":{
+ "type_name":"string",
+ "value":"ZTE"
+ },
+ "csarVersion":{
+ "type_name":"string",
+ "value":"v1.0"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ },
+ "csarType":{
+ "type_name":"string",
+ "value":"NFAR"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ },
+ {
+ "name":"vfw_fw_inout",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"vfw_ctrl_by_manager_cp",
+ "source_requirement_index":0,
+ "target_node_id":"ext_mnet_net_au2otee5mcy0dnpqykj487zr3",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"vfw_data_cp",
+ "source_requirement_index":1,
+ "target_node_id":"sfc_data_network_vx3pc1oahn0k0pa5q722yafee",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualLink",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":3,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"m600_tunnel_cp_imwfk5l48ljz0g9knc6d68hv5",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "template_name":"m600_tunnel_cp",
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"00-11-00-22-33-00"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/13"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"191.167.100.5"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"virtualLink",
+ "source_requirement_index":0,
+ "target_node_id":"ext_datanet_net_qtqzlx5dsthzs883hxjn6hyhd",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualbinding",
+ "source_requirement_index":1,
+ "target_node_id":"m6000_s_7qtzo5nuocyfmebc6kp9raq18",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"ext_mnet_net_au2otee5mcy0dnpqykj487zr3",
+ "type_name":"tosca.nodes.nfv.ext.VL.Vmware",
+ "template_name":"ext_mnet_net",
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "id":"m6000_data_in_eldly5txw4frny3cc349uz3nc",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "template_name":"m6000_data_in",
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"11-22-33-22-11-41"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/7"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"1.1.1.1"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ },
+ "bond":{
+ "type_name":"string",
+ "value":"none"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"virtualbinding",
+ "source_requirement_index":0,
+ "target_node_id":"m6000_s_7qtzo5nuocyfmebc6kp9raq18",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualLink",
+ "source_requirement_index":1,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"ext_datanet_net_qtqzlx5dsthzs883hxjn6hyhd",
+ "type_name":"tosca.nodes.nfv.ext.VL.Vmware",
+ "template_name":"ext_datanet_net",
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "id":"m600_mnt_cp_l3488y2a8ilyfdn0l89ni4os7",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "template_name":"m600_mnt_cp",
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"00-11-00-22-33-11"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/1"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"10.46.244.51"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ },
+ "bond":{
+ "type_name":"string",
+ "value":"none"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"virtualLink",
+ "source_requirement_index":0,
+ "target_node_id":"ext_mnet_net_au2otee5mcy0dnpqykj487zr3",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualbinding",
+ "source_requirement_index":1,
+ "target_node_id":"m6000_s_7qtzo5nuocyfmebc6kp9raq18",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"sfc_data_network_vx3pc1oahn0k0pa5q722yafee",
+ "type_name":"tosca.nodes.nfv.ext.zte.VL",
+ "template_name":"sfc_data_network",
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "is_predefined":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "id":"m6000_s_7qtzo5nuocyfmebc6kp9raq18",
+ "type_name":"tosca.nodes.nfv.ext.PNF",
+ "template_name":"m6000_s",
+ "properties":{
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "pnf_type":{
+ "type_name":"string",
+ "value":"m6000s"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "management_address":{
+ "type_name":"string",
+ "value":"111111"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"m6000_s"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":False
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtualBinding",
+ "type_name":"tosca.capabilities.nfv.VirtualBindable"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"forwarder",
+ "source_requirement_index":0,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ },
+ {
+ "id":"VNAT_cfdljtspvkp234irka59wgab0",
+ "type_name":"tosca.nodes.nfv.ext.zte.VNF.VNAT",
+ "template_name":"VNAT",
+ "properties":{
+ "is_shared":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "plugin_info":{
+ "type_name":"string",
+ "value":"vbrasplugin_1.0"
+ },
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "name":{
+ "type_name":"string",
+ "value":"VNAT"
+ },
+ "vnf_extend_type":{
+ "type_name":"string",
+ "value":"driver"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "cross_dc":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_type":{
+ "type_name":"string",
+ "value":"VNAT"
+ },
+ "vnfd_version":{
+ "type_name":"string",
+ "value":"1.0.0"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"vcpe_vnat_zte_1"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "adjust_vnf_capacity":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "vmnumber_overquota_alarm":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "csarProvider":{
+ "type_name":"string",
+ "value":"ZTE"
+ },
+ "NatIpRange":{
+ "type_name":"string",
+ "value":"192.167.0.10-192.168.0.20"
+ },
+ "csarVersion":{
+ "type_name":"string",
+ "value":"v1.0"
+ },
+ "csarType":{
+ "type_name":"string",
+ "value":"NFAR"
+ }
+ },
+ "interfaces":[
+ {
+ "name":"Standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "capabilities":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ },
+ {
+ "name":"vnat_fw_inout",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "relationships":[
+ {
+ "name":"vnat_ctrl_by_manager_cp",
+ "source_requirement_index":0,
+ "target_node_id":"ext_mnet_net_au2otee5mcy0dnpqykj487zr3",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"vnat_data_cp",
+ "source_requirement_index":1,
+ "target_node_id":"sfc_data_network_vx3pc1oahn0k0pa5q722yafee",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"virtualLink",
+ "source_requirement_index":2,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ },
+ {
+ "name":"forwarder",
+ "source_requirement_index":3,
+ "target_node_id":"path2_kgmfqr5ldqs9lj3oscrgxqefc",
+ "target_capability_name":"feature"
+ }
+ ]
+ }
+ ],
+ "groups":[
+ {
+ "id":"vnffg1_wk1aqhk6exoh5fmds2unu0uyc",
+ "type_name":"tosca.groups.nfv.VNFFG",
+ "template_name":"vnffg1",
+ "properties":{
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "connection_point":{
+ "type_name":"list",
+ "value":[
+ "m6000_data_in",
+ "m600_tunnel_cp",
+ "m6000_data_out"
+ ]
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "constituent_vnfs":{
+ "type_name":"list",
+ "value":[
+ "VFW",
+ "VNAT"
+ ]
+ },
+ "number_of_endpoints":{
+ "type_name":"integer",
+ "value":3
+ },
+ "dependent_virtual_link":{
+ "type_name":"list",
+ "value":[
+ "sfc_data_network",
+ "ext_datanet_net",
+ "ext_mnet_net"
+ ]
+ }
+ },
+ "interfaces":[
+ {
+ "name":"standard",
+ "description":"This lifecycle interface defines the essential, normative operations that TOSCA nodes may support.",
+ "type_name":"tosca.interfaces.node.lifecycle.Standard",
+ "operations":[
+ {
+ "name":"create",
+ "description":"Standard lifecycle create operation."
+ },
+ {
+ "name":"stop",
+ "description":"Standard lifecycle stop operation."
+ },
+ {
+ "name":"start",
+ "description":"Standard lifecycle start operation."
+ },
+ {
+ "name":"delete",
+ "description":"Standard lifecycle delete operation."
+ },
+ {
+ "name":"configure",
+ "description":"Standard lifecycle configure operation."
+ }
+ ]
+ }
+ ],
+ "member_node_ids":[
+ "path1_bv53fblv26hawr8dj4fxe2rsd",
+ "path2_kgmfqr5ldqs9lj3oscrgxqefc"
+ ]
+ }
+ ],
+ "substitution":{
+ "node_type_name":"tosca.nodes.nfv.NS.VCPE_NS"
+ },
+ "inputs":{
+ "externalDataNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "sfc_data_network":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "NatIpRange":{
+ "type_name":"string",
+ "value":"192.167.0.10-192.168.0.20"
+ },
+ "externalManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ }
+ }
+ },
+ "model":{
+ "metadata":{
+ "vendor":"ZTE",
+ "name":"VCPE_NS",
+ "csarVersion":"v1.0",
+ "csarType":"NSAR",
+ "csarProvider":"ZTE",
+ "version":1,
+ "invariant_id":"vcpe_ns_sff_1",
+ "id":"VCPE_NS",
+ "description":"vcpe_ns"
+ },
+ "node_templates":[
+ {
+ "name":"path2",
+ "type_name":"tosca.nodes.nfv.ext.FP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "symmetric":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "policy":{
+ "type_name":"tosca.datatypes.nfv.ext.FPPolicy",
+ "value":{
+ "type":"ACL",
+ "criteria":{
+ "dest_port_range":"1-100",
+ "ip_protocol":"tcp",
+ "source_ip_range":[
+ "119.1.1.1-119.1.1.10"
+ ],
+ "dest_ip_range":[
+ {"get_input":"NatIpRange"}
+ ],
+ "dscp":0,
+ "source_port_range":"1-100"
+ }
+ }
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ed0288a10>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m6000_data_out"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m600_tunnel_cp"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"VNAT",
+ "target_capability_name":"vnat_fw_inout"
+ }
+ ]
+ },
+ {
+ "name":"path1",
+ "type_name":"tosca.nodes.nfv.ext.FP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "symmetric":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "policy":{
+ "type_name":"tosca.datatypes.nfv.ext.FPPolicy",
+ "value":{
+ "type":"ACL",
+ "criteria":{
+ "dest_port_range":"1-100",
+ "ip_protocol":"tcp",
+ "source_ip_range":[
+ "1-100"
+ ],
+ "dest_ip_range":[
+ "1-100"
+ ],
+ "dscp":4,
+ "source_port_range":"1-100"
+ }
+ }
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec81df090>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m6000_data_in"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m600_tunnel_cp"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"VFW",
+ "target_capability_name":"vfw_fw_inout"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"VNAT",
+ "target_capability_name":"vnat_fw_inout"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m600_tunnel_cp"
+ },
+ {
+ "name":"forwarder",
+ "target_node_template_name":"m6000_data_out"
+ }
+ ]
+ },
+ {
+ "name":"m6000_data_out",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"11-22-33-22-11-44"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"xgei-0/4/1/5"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"176.1.1.2"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec82c6610>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"virtualbinding",
+ "target_node_template_name":"m6000_s",
+ "target_capability_name":"virtualBinding"
+ },
+ {
+ "name":"virtualLink",
+ "target_node_type_name":"tosca.nodes.Root"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"VFW",
+ "type_name":"tosca.nodes.nfv.ext.zte.VNF.VFW",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "is_shared":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "plugin_info":{
+ "type_name":"string",
+ "value":"vbrasplugin_1.0"
+ },
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_extend_type":{
+ "type_name":"string",
+ "value":"driver"
+ },
+ "name":{
+ "type_name":"string",
+ "value":"VFW"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "cross_dc":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_type":{
+ "type_name":"string",
+ "value":"VFW"
+ },
+ "vnfd_version":{
+ "type_name":"string",
+ "value":"1.0.0"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"vcpe_vfw_zte_1_0"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "adjust_vnf_capacity":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "vmnumber_overquota_alarm":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "csarProvider":{
+ "type_name":"string",
+ "value":"ZTE"
+ },
+ "csarVersion":{
+ "type_name":"string",
+ "value":"v1.0"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ },
+ "csarType":{
+ "type_name":"string",
+ "value":"NFAR"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec8281950>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ },
+ {
+ "name":"vfw_fw_inout",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"vfw_ctrl_by_manager_cp",
+ "target_node_template_name":"ext_mnet_net",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"vfw_data_cp",
+ "target_node_template_name":"sfc_data_network",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"virtualLink",
+ "target_node_type_name":"tosca.nodes.Root"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"m600_tunnel_cp",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"00-11-00-22-33-00"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/13"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"191.167.100.5"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x1ae39d0>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"virtualLink",
+ "target_node_template_name":"ext_datanet_net",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"virtualbinding",
+ "target_node_template_name":"m6000_s",
+ "target_capability_name":"virtualBinding"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"ext_mnet_net",
+ "type_name":"tosca.nodes.nfv.ext.VL.Vmware",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ed00f89d0>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "name":"m6000_data_in",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"11-22-33-22-11-41"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/7"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"1.1.1.1"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ },
+ "bond":{
+ "type_name":"string",
+ "value":"none"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x1745710>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"virtualbinding",
+ "target_node_template_name":"m6000_s",
+ "target_capability_name":"virtualBinding"
+ },
+ {
+ "name":"virtualLink",
+ "target_node_type_name":"tosca.nodes.Root"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"ext_datanet_net",
+ "type_name":"tosca.nodes.nfv.ext.VL.Vmware",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8eac063990>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "name":"m600_mnt_cp",
+ "type_name":"tosca.nodes.nfv.ext.zte.CP",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "direction":{
+ "type_name":"string",
+ "value":"bidirectional"
+ },
+ "vnic_type":{
+ "type_name":"string",
+ "value":"normal"
+ },
+ "bandwidth":{
+ "type_name":"integer",
+ "value":0
+ },
+ "mac_address":{
+ "type_name":"string",
+ "value":"00-11-00-22-33-11"
+ },
+ "interface_name":{
+ "type_name":"string",
+ "value":"gei-0/4/0/1"
+ },
+ "ip_address":{
+ "type_name":"string",
+ "value":"10.46.244.51"
+ },
+ "order":{
+ "type_name":"integer",
+ "value":0
+ },
+ "sfc_encapsulation":{
+ "type_name":"string",
+ "value":"mac"
+ },
+ "bond":{
+ "type_name":"string",
+ "value":"none"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec81264d0>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"virtualLink",
+ "target_node_template_name":"ext_mnet_net",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"virtualbinding",
+ "target_node_template_name":"m6000_s",
+ "target_capability_name":"virtualBinding"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"sfc_data_network",
+ "type_name":"tosca.nodes.nfv.ext.zte.VL",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "name":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "dhcp_enabled":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "is_predefined":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "location_info":{
+ "type_name":"tosca.datatypes.nfv.ext.LocationInfo",
+ "value":{
+ "tenant":"admin",
+ "vimid":2,
+ "availability_zone":"nova"
+ }
+ },
+ "ip_version":{
+ "type_name":"integer",
+ "value":4
+ },
+ "mtu":{
+ "type_name":"integer",
+ "value":1500
+ },
+ "network_name":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "network_type":{
+ "type_name":"string",
+ "value":"vlan"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec813c6d0>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtual_linkable",
+ "type_name":"tosca.capabilities.nfv.VirtualLinkable"
+ }
+ ]
+ },
+ {
+ "name":"m6000_s",
+ "type_name":"tosca.nodes.nfv.ext.PNF",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "pnf_type":{
+ "type_name":"string",
+ "value":"m6000s"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "management_address":{
+ "type_name":"string",
+ "value":"111111"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"m6000_s"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":False
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec8132490>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"virtualBinding",
+ "type_name":"tosca.capabilities.nfv.VirtualBindable"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ },
+ {
+ "name":"VNAT",
+ "type_name":"tosca.nodes.nfv.ext.zte.VNF.VNAT",
+ "default_instances":1,
+ "min_instances":0,
+ "properties":{
+ "is_shared":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "plugin_info":{
+ "type_name":"string",
+ "value":"vbrasplugin_1.0"
+ },
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "request_reclassification":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "name":{
+ "type_name":"string",
+ "value":"VNAT"
+ },
+ "vnf_extend_type":{
+ "type_name":"string",
+ "value":"driver"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "cross_dc":{
+ "type_name":"boolean",
+ "value":False
+ },
+ "vnf_type":{
+ "type_name":"string",
+ "value":"VNAT"
+ },
+ "vnfd_version":{
+ "type_name":"string",
+ "value":"1.0.0"
+ },
+ "id":{
+ "type_name":"string",
+ "value":"vcpe_vnat_zte_1"
+ },
+ "nsh_aware":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "adjust_vnf_capacity":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "vmnumber_overquota_alarm":{
+ "type_name":"boolean",
+ "value":True
+ },
+ "csarProvider":{
+ "type_name":"string",
+ "value":"ZTE"
+ },
+ "NatIpRange":{
+ "type_name":"string",
+ "value":"192.167.0.10-192.168.0.20"
+ },
+ "csarVersion":{
+ "type_name":"string",
+ "value":"v1.0"
+ },
+ "csarType":{
+ "type_name":"string",
+ "value":"NFAR"
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x1bba810>"
+ ],
+ "capability_templates":[
+ {
+ "name":"feature",
+ "type_name":"tosca.capabilities.Node"
+ },
+ {
+ "name":"forwarder",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ },
+ {
+ "name":"vnat_fw_inout",
+ "type_name":"tosca.capabilities.nfv.Forwarder"
+ }
+ ],
+ "requirement_templates":[
+ {
+ "name":"vnat_ctrl_by_manager_cp",
+ "target_node_template_name":"ext_mnet_net",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"vnat_data_cp",
+ "target_node_template_name":"sfc_data_network",
+ "target_capability_name":"virtual_linkable"
+ },
+ {
+ "name":"virtualLink",
+ "target_node_type_name":"tosca.nodes.Root"
+ },
+ {
+ "name":"forwarder",
+ "target_node_type_name":"tosca.nodes.Root"
+ }
+ ]
+ }
+ ],
+ "group_templates":[
+ {
+ "name":"vnffg1",
+ "type_name":"tosca.groups.nfv.VNFFG",
+ "properties":{
+ "vendor":{
+ "type_name":"string",
+ "value":"zte"
+ },
+ "connection_point":{
+ "type_name":"list",
+ "value":[
+ "m6000_data_in",
+ "m600_tunnel_cp",
+ "m6000_data_out"
+ ]
+ },
+ "version":{
+ "type_name":"string",
+ "value":"1.0"
+ },
+ "constituent_vnfs":{
+ "type_name":"list",
+ "value":[
+ "VFW",
+ "VNAT"
+ ]
+ },
+ "number_of_endpoints":{
+ "type_name":"integer",
+ "value":3
+ },
+ "dependent_virtual_link":{
+ "type_name":"list",
+ "value":[
+ "sfc_data_network",
+ "ext_datanet_net",
+ "ext_mnet_net"
+ ]
+ }
+ },
+ "interface_templates":[
+ "<aria.modeling.model_elements.InterfaceTemplate object at 0x7f8ec811cd10>"
+ ],
+ "member_node_template_names":[
+ "path1",
+ "path2"
+ ]
+ }
+ ],
+ "substitution_template":{
+ "node_type_name":"tosca.nodes.nfv.NS.VCPE_NS"
+ },
+ "inputs":{
+ "externalDataNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4004_tunnel_net"
+ },
+ "sfc_data_network":{
+ "type_name":"string",
+ "value":"sfc_data_network"
+ },
+ "NatIpRange":{
+ "type_name":"string",
+ "value":"192.167.0.10-192.168.0.20"
+ },
+ "externalManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4008_mng_net"
+ },
+ "externalPluginManageNetworkName":{
+ "type_name":"string",
+ "value":"vlan_4007_plugin_net"
+ }
+ }
+ }
+ }
+ )
+ print convert_nsd_model(src_json)
+
+
+
+
diff --git a/kilo/kilo/pub/utils/values.py b/kilo/kilo/pub/utils/values.py
new file mode 100644
index 00000000..a5b5e3a3
--- /dev/null
+++ b/kilo/kilo/pub/utils/values.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2017 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.
+
+
+def ignore_case_get(args, key, def_val=""):
+ if not key:
+ return def_val
+ if key in args:
+ return args[key]
+ for old_key in args:
+ if old_key.upper() == key.upper():
+ return args[old_key]
+ return def_val
+
diff --git a/kilo/kilo/samples/__init__.py b/kilo/kilo/samples/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/samples/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/samples/tests.py b/kilo/kilo/samples/tests.py
new file mode 100644
index 00000000..50b571a3
--- /dev/null
+++ b/kilo/kilo/samples/tests.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017 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.
+
+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 = json.loads(response.content)
+ self.assertEqual({"status": "active"}, resp_data)
diff --git a/kilo/kilo/samples/urls.py b/kilo/kilo/samples/urls.py
new file mode 100644
index 00000000..91a9860a
--- /dev/null
+++ b/kilo/kilo/samples/urls.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2017 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.
+
+from django.conf.urls import url
+from kilo.samples import views
+
+urlpatterns = [
+ url(r'^samples/$', views.SampleList.as_view()), ]
diff --git a/kilo/kilo/samples/views.py b/kilo/kilo/samples/views.py
new file mode 100644
index 00000000..e51044ad
--- /dev/null
+++ b/kilo/kilo/samples/views.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2017 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.
+
+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/kilo/kilo/settings.py b/kilo/kilo/settings.py
new file mode 100644
index 00000000..c6ad62b3
--- /dev/null
+++ b/kilo/kilo/settings.py
@@ -0,0 +1,140 @@
+# Copyright (c) 2017 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.
+
+import os
+import sys
+
+import redisco
+
+from kilo.pub.config.config import REDIS_HOST, REDIS_PORT, REDIS_PASSWD
+from kilo.pub.config.config import DB_NAME, DB_IP, DB_USER, DB_PASSWD, DB_PORT
+
+# 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',
+ 'kilo.pub.database',
+]
+
+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',
+]
+
+ROOT_URLCONF = 'kilo.urls'
+
+WSGI_APPLICATION = 'kilo.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',
+ )
+}
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql',
+ 'NAME': DB_NAME,
+ 'HOST': DB_IP,
+ 'PORT': DB_PORT,
+ 'USER': DB_USER,
+ 'PASSWORD': DB_PASSWD,
+ },
+}
+
+redisco.connection_setup(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWD, db=0)
+# CACHE_BACKEND = 'redis_cache.cache://%s@%s:%s' % (REDIS_PASSWD, REDIS_HOST, REDIS_PORT)
+
+TIME_ZONE = 'UTC'
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.6/howto/static-files/
+
+STATIC_URL = '/static/'
+
+LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': True,
+ 'formatters': {
+ 'standard': {
+ 'format': '%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s',
+ },
+ },
+ 'filters': {
+ },
+ 'handlers': {
+ 'kilo_handler': {
+ 'level': 'DEBUG',
+ 'class': 'logging.handlers.RotatingFileHandler',
+ 'filename': os.path.join(BASE_DIR, 'logs/runtime_kilo.log'),
+ 'formatter': 'standard',
+ 'maxBytes': 1024 * 1024 * 50,
+ 'backupCount': 5,
+ },
+ },
+
+ 'loggers': {
+ 'kilo': {
+ 'handlers': ['kilo_handler'],
+ 'level': 'DEBUG',
+ 'propagate': False
+ },
+ }
+}
+
+if 'test' in sys.argv:
+ from kilo.pub.config import config
+ config.REG_TO_MSB_WHEN_START = False
+ DATABASES = {}
+ DATABASES['default'] = {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': ':memory:',
+ }
+ 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/kilo/kilo/swagger/__init__.py b/kilo/kilo/swagger/__init__.py
new file mode 100644
index 00000000..802f3fba
--- /dev/null
+++ b/kilo/kilo/swagger/__init__.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 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.
diff --git a/kilo/kilo/swagger/multivim.flavor.swagger.json b/kilo/kilo/swagger/multivim.flavor.swagger.json
new file mode 100644
index 00000000..60dc7d8b
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.flavor.swagger.json
@@ -0,0 +1,397 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/flavors": {
+ "post": {
+ "tags": [
+ "vim flavors"
+ ],
+ "summary": "create a flavor",
+ "description": "create a flavor",
+ "operationId": "create_vim_flavor",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim flavor request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimFlavor"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimFlavorInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim flavor is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim flavors"
+ ],
+ "summary": "query vim flavors list",
+ "description": "query vim flavors list",
+ "operationId": "query_vim_flavors",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim flavors request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimFlavors"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimFlavorsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim flavor is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/flavors/{flavorid}": {
+ "delete": {
+ "tags": [
+ "vim flavors"
+ ],
+ "summary": "delete specific vim flavor",
+ "description": "delete specific vim flavor",
+ "operationId": "delete_vim_flavor",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "flavorid",
+ "in": "path",
+ "description": "vim flavor id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim flavor is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim flavors"
+ ],
+ "summary": "query specific vim flavor",
+ "description": "query specific vim flavor",
+ "operationId": "query_vim_flavor",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "flavorid",
+ "in": "path",
+ "description": "vim flavor id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimFlavorInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim flavor is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimFlavor": {
+ "type": "object",
+ "required": [
+ "vcpu",
+ "name",
+ "memory",
+ "disk"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "flavor name"
+ },
+ "vcpu": {
+ "type": "integer",
+ "description": "virtual cpu number"
+ },
+ "memory": {
+ "type": "integer",
+ "description": "memory size"
+ },
+ "disk": {
+ "type": "integer",
+ "description": "The size of the root disk"
+ },
+ "ephemeral": {
+ "type": "integer",
+ "description": "The size of the ephemeral disk"
+ },
+ "swap": {
+ "type": "integer",
+ "description": "The size of the swap disk"
+ },
+ "isPublic": {
+ "type": "boolean",
+ "description": "whether the flavor is public"
+ },
+ "extraSpecs": {
+ "type": "array",
+ "description": "list of extra specs",
+ "items": {
+ "$ref": "#/definitions/VimFlavorExtraSpecInfo"
+ }
+ }
+ }
+ },
+ "VimFlavorExtraSpecInfo": {
+ "type": "object",
+ "properties": {
+ "keyName": {
+ "type": "string",
+ "description": "extra spec key"
+ },
+ "value": {
+ "type": "string",
+ "description": "extra spec value"
+ }
+ }
+ },
+ "ListVimFlavors": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "flavor name to filter flavor list"
+ },
+ "limit": {
+ "type": "integer",
+ "description": "Requests a page size of items"
+ },
+ "marker": {
+ "type": "string",
+ "description": "flavor ID of the last-seen item"
+ }
+ }
+ },
+ "VimFlavorsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "flavors"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "flavors": {
+ "type": "array",
+ "description": "flavor list information",
+ "items": {
+ "$ref": "#/definitions/VimFlavorInfo"
+ }
+ }
+ }
+ },
+ "VimFlavorInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "id",
+ "vcpu",
+ "memory",
+ "disk",
+ "ephemeral",
+ "swap",
+ "isPublic"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "flavor name"
+ },
+ "id": {
+ "type": "string",
+ "description": "flavor UUID"
+ },
+ "vcpu": {
+ "type": "integer",
+ "description": "virtual cpu number"
+ },
+ "memory": {
+ "type": "integer",
+ "description": "memory size"
+ },
+ "disk": {
+ "type": "integer",
+ "description": "The size of the root disk"
+ },
+ "ephemeral": {
+ "type": "integer",
+ "description": "The size of the ephemeral disk"
+ },
+ "swap": {
+ "type": "integer",
+ "description": "The size of the swap disk"
+ },
+ "isPublic": {
+ "type": "boolean",
+ "description": "whether the flavor is public"
+ },
+ "extraSpecs": {
+ "type": "array",
+ "description": "list of extra specs",
+ "items": {
+ "$ref": "#/definitions/VimFlavorExtraSpecInfo"
+ }
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.host.swagger.json b/kilo/kilo/swagger/multivim.host.swagger.json
new file mode 100644
index 00000000..db24a17c
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.host.swagger.json
@@ -0,0 +1,183 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/hosts": {
+ "get": {
+ "tags": [
+ "vim hosts"
+ ],
+ "summary": "query vim hosts list",
+ "description": "query vim hosts list",
+ "operationId": "query_vim_hosts",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim hosts request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimHosts"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimHostsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim host is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/hosts/{hostname}": {
+ "get": {
+ "tags": [
+ "vim hosts"
+ ],
+ "summary": "query specific vim host",
+ "description": "query specific vim host",
+ "operationId": "query_vim_host",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "hostname",
+ "in": "path",
+ "description": "vim host name",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimHostInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim host is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "VimHostsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "hosts"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "hosts": {
+ "type": "array",
+ "description": "list of host information",
+ "items": {
+ "$ref": "#/definitions/VimHostInfo"
+ }
+ }
+ }
+ },
+ "VimHostInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "service"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "host name"
+ },
+ "service": {
+ "type": "string",
+ "description": "service name running on the host"
+ },
+ "zone": {
+ "type": "string",
+ "description": "available zone name of the host"
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.image.swagger.json b/kilo/kilo/swagger/multivim.image.swagger.json
new file mode 100644
index 00000000..b6102ec5
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.image.swagger.json
@@ -0,0 +1,384 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/images": {
+ "post": {
+ "tags": [
+ "vim images"
+ ],
+ "summary": "create a image",
+ "description": "create a image",
+ "operationId": "create_vim_image",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim image request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimImage"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimImageInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim image is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim images"
+ ],
+ "summary": "query vim images list",
+ "description": "query vim images list",
+ "operationId": "query_vim_images",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim images request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimImages"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimImagesInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim image is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/images/{imageid}": {
+ "delete": {
+ "tags": [
+ "vim images"
+ ],
+ "summary": "delete specific vim image",
+ "description": "delete specific vim image",
+ "operationId": "delete_vim_image",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "imageid",
+ "in": "path",
+ "description": "vim image id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim image is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim images"
+ ],
+ "summary": "query specific vim image",
+ "description": "query specific vim image",
+ "operationId": "query_vim_image",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "imageid",
+ "in": "path",
+ "description": "vim image id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimImageInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim image is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimImage": {
+ "type": "object",
+ "required": [
+ "imagePath",
+ "name",
+ "imageType",
+ "containerFormat"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "image name"
+ },
+ "imageType": {
+ "type": "string",
+ "description": "image type: ami, ari, aki, vhd, vhdx, vmdk, raw, qcow2, vdi, iso"
+ },
+ "imagePath": {
+ "type": "string",
+ "description": "image url to catalog"
+ },
+ "containerFormat": {
+ "type": "string",
+ "description": "image container format: ami, ari, aki, bare, ovf, ova, docker"
+ },
+ "visibility": {
+ "type": "string",
+ "description": "public, private, shared, or community"
+ },
+ "properties": {
+ "type": "array",
+ "description": "list of properties",
+ "items": {
+ "$ref": "#/definitions/VimImagePropertyInfo"
+ }
+ }
+ }
+ },
+ "VimImagePropertyInfo": {
+ "type": "object",
+ "properties": {
+ "keyName": {
+ "type": "string",
+ "description": "property name"
+ },
+ "value": {
+ "type": "string",
+ "description": "property value"
+ }
+ }
+ },
+ "ListVimImages": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "image name to filter image list"
+ },
+ "limit": {
+ "type": "string",
+ "description": "Requests a page size of items"
+ },
+ "marker": {
+ "type": "string",
+ "description": "image ID of the last-seen item"
+ }
+ }
+ },
+ "VimImagesInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "images"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "images": {
+ "type": "array",
+ "description": "image list information",
+ "items": {
+ "$ref": "#/definitions/VimImageInfo"
+ }
+ }
+ }
+ },
+ "VimImageInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "id"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "image name"
+ },
+ "id": {
+ "type": "string",
+ "description": "image UUID"
+ },
+ "imageType": {
+ "type": "string",
+ "description": "image type: ami, ari, aki, vhd, vhdx, vmdk, raw, qcow2, vdi, iso"
+ },
+ "imagePath": {
+ "type": "string",
+ "description": "image url to catalog"
+ },
+ "containerFormat": {
+ "type": "string",
+ "description": "image container format: ami, ari, aki, bare, ovf, ova, docker"
+ },
+ "visibility": {
+ "type": "string",
+ "description": "public, private, shared, or community"
+ },
+ "properties": {
+ "type": "array",
+ "description": "list of properties",
+ "items": {
+ "$ref": "#/definitions/VimImagePropertyInfo"
+ }
+ },
+ "status": {
+ "type": "string",
+ "description": "image status"
+ },
+ "size": {
+ "type": "string",
+ "description": "image size"
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.limit.swagger.json b/kilo/kilo/swagger/multivim.limit.swagger.json
new file mode 100644
index 00000000..f5605b5c
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.limit.swagger.json
@@ -0,0 +1,158 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/limits": {
+ "get": {
+ "tags": [
+ "vim limits"
+ ],
+ "summary": "query vim limits list",
+ "description": "query vim limits list",
+ "operationId": "query_vim_limits",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimLimitsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim limits is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "VimLimitsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "maxPersonality": {
+ "type": "integer",
+ "description": "The number of allowed injected files for each tenant"
+ },
+ "maxPersonalitySize": {
+ "type": "integer",
+ "description": "The number of allowed bytes of content for each injected file"
+ },
+ "maxServerGroupMembers": {
+ "type": "integer",
+ "description": "The number of allowed members for each server group"
+ },
+ "maxServerGroups": {
+ "type": "integer",
+ "description": "The number of allowed server groups for each tenant"
+ },
+ "maxServerMeta": {
+ "type": "integer",
+ "description": "The number of allowed metadata items for each instance"
+ },
+ "maxTotalCores": {
+ "type": "integer",
+ "description": "The number of allowed instance cores for each tenant"
+ },
+ "maxTotalInstances": {
+ "type": "integer",
+ "description": "The number of allowed instances for each tenant"
+ },
+ "maxTotalKeypairs": {
+ "type": "integer",
+ "description": "The number of allowed key pairs for each user"
+ },
+ "maxTotalRAMSize": {
+ "type": "integer",
+ "description": "The amount of allowed instance RAM, in MB, for each tenant"
+ },
+ "maxTotalVolumeGigabytes": {
+ "type": "integer",
+ "description": "The maximum total amount of volumes, in gibibytes (GiB)."
+ },
+ "maxTotalVolumes": {
+ "type": "integer",
+ "description": "The maximum number of volumes"
+ },
+ "totalGigabytesUsed": {
+ "type": "integer",
+ "description": "The total number of gibibytes (GiB) used"
+ },
+ "network": {
+ "type": "integer",
+ "description": "The number of networks allowed for each project"
+ },
+ "subnet": {
+ "type": "integer",
+ "description": "The number of subnets allowed for each project"
+ },
+ "subnetpool": {
+ "type": "integer",
+ "description": "The number of subnet pools allowed for each project"
+ },
+ "security_group_rule": {
+ "type": "integer",
+ "description": "The number of security group rules allowed for each project"
+ },
+ "security_group": {
+ "type": "integer",
+ "description": "The number of security groups allowed for each project"
+ },
+ "router": {
+ "type": "integer",
+ "description": "The number of routers allowed for each project"
+ },
+ "port": {
+ "type": "integer",
+ "description": "The number of ports allowed for each project"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.network.swagger.json b/kilo/kilo/swagger/multivim.network.swagger.json
new file mode 100644
index 00000000..fb120b29
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.network.swagger.json
@@ -0,0 +1,360 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/networks": {
+ "post": {
+ "tags": [
+ "vim networks"
+ ],
+ "summary": "create a network",
+ "description": "create a network",
+ "operationId": "create_vim_network",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim network request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimNetwork"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimNetworkInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim network is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim networks"
+ ],
+ "summary": "query vim networks list",
+ "description": "query vim networks list",
+ "operationId": "query_vim_networks",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim networks request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimNetworks"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimNetworksInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim network is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/networks/{networkid}": {
+ "delete": {
+ "tags": [
+ "vim networks"
+ ],
+ "summary": "delete specific vim network",
+ "description": "delete specific vim network",
+ "operationId": "delete_vim_network",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "networkid",
+ "in": "path",
+ "description": "vim network id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the network is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim networks"
+ ],
+ "summary": "query specific vim network",
+ "description": "query specific vim network",
+ "operationId": "query_vim_network",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "networkid",
+ "in": "path",
+ "description": "vim network id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimNetworkInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim network is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimNetwork": {
+ "type": "object",
+ "required": [
+ "networkType",
+ "name",
+ "shared"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "network name"
+ },
+ "networkType": {
+ "type": "string",
+ "description": "network type"
+ },
+ "physicalNetwork": {
+ "type": "string",
+ "description": "physical network name"
+ },
+ "segmentationId": {
+ "type": "integer",
+ "description": "segmentation ID of physical network"
+ },
+ "vlanTransparent": {
+ "type": "boolean",
+ "description": "vlan transparent"
+ },
+ "shared": {
+ "type": "boolean",
+ "description": "network is shared across tenants"
+ },
+ "routerExternal": {
+ "type": "boolean",
+ "description": "network can provide floating IPs via a router"
+ }
+ }
+ },
+ "ListVimNetworks": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "network name"
+ }
+ }
+ },
+ "VimNetworksInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "networks"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "networks": {
+ "type": "array",
+ "description": "network information",
+ "items": {
+ "$ref": "#/definitions/VimNetworkInfo"
+ }
+ }
+ }
+ },
+ "VimNetworkInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "id"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "network name"
+ },
+ "id": {
+ "type": "string",
+ "description": "network UUID"
+ },
+ "status": {
+ "type": "string",
+ "description": "network status"
+ },
+ "networkType": {
+ "type": "string",
+ "description": "network type"
+ },
+ "physicalNetwork": {
+ "type": "string",
+ "description": "physical network name"
+ },
+ "segmentationId": {
+ "type": "boolean",
+ "description": "segmentationId of physical network"
+ },
+ "vlanTransparent": {
+ "type": "boolean",
+ "description": "vlan transparent"
+ },
+ "shared": {
+ "type": "boolean",
+ "description": "network is shared across tenants"
+ },
+ "routerExternal": {
+ "type": "boolean",
+ "description": "network can provide floating IPs via a router"
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.server.swagger.json b/kilo/kilo/swagger/multivim.server.swagger.json
new file mode 100644
index 00000000..82de1223
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.server.swagger.json
@@ -0,0 +1,493 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/servers": {
+ "post": {
+ "tags": [
+ "vim servers"
+ ],
+ "summary": "create a server",
+ "description": "create a server",
+ "operationId": "create_vim_server",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim server request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimServer"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimServerInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim server is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim servers"
+ ],
+ "summary": "query vim servers list",
+ "description": "query vim servers list",
+ "operationId": "query_vim_servers",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim servers request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimServers"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimServersInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim server is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/servers/{serverid}": {
+ "delete": {
+ "tags": [
+ "vim servers"
+ ],
+ "summary": "delete specific vim server",
+ "description": "delete specific vim server",
+ "operationId": "delete_vim_server",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "serverid",
+ "in": "path",
+ "description": "vim server id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim server is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim servers"
+ ],
+ "summary": "query specific vim server",
+ "description": "query specific vim server",
+ "operationId": "query_vim_server",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "serverid",
+ "in": "path",
+ "description": "vim server id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimServerInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim server is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimServer": {
+ "type": "object",
+ "required": [
+ "name",
+ "boot",
+ "flavorId"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "server name"
+ },
+ "boot": {
+ "type": "object",
+ "description": "Parameters to start a server",
+ "properties": {
+ "type": {
+ "type": "integer",
+ "description": "boot type: 1: boot from volume, 2: boot from image"
+ },
+ "volumeId": {
+ "type": "string",
+ "description": "volume UUID to boot server"
+ },
+ "imageId": {
+ "type": "string",
+ "description": "image UUID to boot server"
+ }
+ }
+ },
+ "flavorId": {
+ "type": "string",
+ "description": "flavor uuid to start server"
+ },
+ "contextArray": {
+ "type": "array",
+ "description": "list of injected files",
+ "items": {
+ "$ref": "#/definitions/VimServerContextInfo"
+ }
+ },
+ "volumeArray": {
+ "type": "array",
+ "description": "list of volumes attached to a server",
+ "items": {
+ "$ref": "#/definitions/VimServerVolumeInfo"
+ }
+ },
+ "nicArray": {
+ "type": "array",
+ "description": "list of volumes attached to a server",
+ "items": {
+ "$ref": "#/definitions/VimServerNicInfo"
+ }
+ },
+ "availabilityZone": {
+ "type": "string",
+ "description": "The availability zone from which to launch the server."
+ },
+ "metadata": {
+ "type": "array",
+ "description": "list of key-value pairs for metadata to start a server",
+ "items": {
+ "$ref": "#/definitions/VimServerKeyValuePair"
+ }
+ },
+ "userdata": {
+ "type": "string",
+ "description": "user data to start a aserver"
+ },
+ "securityGroups": {
+ "type": "array",
+ "description": "list of security groups for a server",
+ "items": {
+ "type": "string",
+ "description": "name of security group"
+ }
+ },
+ "serverGroup": {
+ "type": "string",
+ "description": "server group"
+ }
+ }
+ },
+ "VimServerKeyValuePair": {
+ "type": "object",
+ "properties": {
+ "keyName": {
+ "type": "string",
+ "description": "key name"
+ },
+ "value": {
+ "type": "string",
+ "description": "value "
+ }
+ }
+ },
+ "VimServerContextInfo": {
+ "type": "object",
+ "properties": {
+ "fileName": {
+ "type": "string",
+ "description": "Injected file name"
+ },
+ "fileData": {
+ "type": "string",
+ "description": "Injected file content "
+ }
+ }
+ },
+ "VimServerVolumeInfo": {
+ "type": "object",
+ "properties": {
+ "volumeId": {
+ "type": "string",
+ "description": "volume UUID"
+ }
+ }
+ },
+ "VimServerNicInfo": {
+ "type": "object",
+ "properties": {
+ "portId": {
+ "type": "string",
+ "description": "virtual port UUID to boot a server"
+ }
+ }
+ },
+ "ListVimServers": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "server name to filter server list"
+ },
+ "limit": {
+ "type": "integer",
+ "description": "Requests a page size of items"
+ },
+ "marker": {
+ "type": "string",
+ "description": "server ID of the last-seen item"
+ }
+ }
+ },
+ "VimServersInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "servers"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "servers": {
+ "type": "array",
+ "description": "server list information",
+ "items": {
+ "$ref": "#/definitions/VimServerInfo"
+ }
+ }
+ }
+ },
+ "VimServerInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "id"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "server name"
+ },
+ "id": {
+ "type": "string",
+ "description": "server UUID"
+ },
+ "status": {
+ "type": "string",
+ "description": "server status,0:INACTIVE,1:ACTIVE,2:ERROR"
+ },
+ "boot": {
+ "type": "object",
+ "description": "Parameters to start a server",
+ "properties": {
+ "type": {
+ "type": "integer",
+ "description": "boot type: 1: boot from volume, 2: boot from image"
+ },
+ "volumeId": {
+ "type": "string",
+ "description": "volume UUID to boot server"
+ },
+ "ImageId": {
+ "type": "string",
+ "description": "image UUID to boot server"
+ }
+ }
+ },
+ "flavorId": {
+ "type": "string",
+ "description": "flavor uuid to start server"
+ },
+ "volumeArray": {
+ "type": "array",
+ "description": "list of volumes attached to a server",
+ "items": {
+ "$ref": "#/definitions/VimServerVolumeInfo"
+ }
+ },
+ "nicArray": {
+ "type": "array",
+ "description": "list of volumes attached to a server",
+ "items": {
+ "$ref": "#/definitions/VimServerNicInfo"
+ }
+ },
+ "availabilityZone": {
+ "type": "string",
+ "description": "available zone for a server"
+ },
+ "metadata": {
+ "type": "array",
+ "description": "list of key-value pairs for metadata to start a server",
+ "items": {
+ "$ref": "#/definitions/VimServerKeyValuePair"
+ }
+ },
+ "securityGroups": {
+ "type": "array",
+ "description": "list of security groups for a server",
+ "items": {
+ "type": "string",
+ "description": "name of security group"
+ }
+ },
+ "serverGroup": {
+ "type": "string",
+ "description": "server group"
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.subnet.swagger.json b/kilo/kilo/swagger/multivim.subnet.swagger.json
new file mode 100644
index 00000000..d862a68f
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.subnet.swagger.json
@@ -0,0 +1,428 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/subnets": {
+ "post": {
+ "tags": [
+ "vim subnets"
+ ],
+ "summary": "create a subnet",
+ "description": "create a subnet",
+ "operationId": "create_vim_subnet",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim subnet request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimSubnet"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimSubnetInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim subnet is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim subnets"
+ ],
+ "summary": "query vim subnets list",
+ "description": "query vim subnets list",
+ "operationId": "query_vim_subnets",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim subnets request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimSubnets"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimSubnetsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim subnet is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/subnets/{subnetid}": {
+ "delete": {
+ "tags": [
+ "vim subnets"
+ ],
+ "summary": "delete specific vim subnet",
+ "description": "delete specific vim subnet",
+ "operationId": "delete_vim_subnet",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "subnetid",
+ "in": "path",
+ "description": "vim subnet id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the subnet is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim subnets"
+ ],
+ "summary": "query specific vim subnet",
+ "description": "query specific vim subnet",
+ "operationId": "query_vim_subnet",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "subnetid",
+ "in": "path",
+ "description": "vim subnet id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimSubnetInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim subnet id is invalid"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimSubnet": {
+ "type": "object",
+ "required": [
+ "networkId",
+ "name",
+ "cidr",
+ "ipVersion"
+ ],
+ "properties": {
+ "networkId": {
+ "type": "string",
+ "description": "network UUID"
+ },
+ "name": {
+ "type": "string",
+ "description": "subnet name"
+ },
+ "cidr": {
+ "type": "string",
+ "description": "subnet CIDR"
+ },
+ "ipVersion": {
+ "type": "integer",
+ "description": "IP version: 4 for IPv4, 6 for IPv6"
+ },
+ "enableDhcp": {
+ "type": "boolean",
+ "description": "Enable DHCP or not"
+ },
+ "gatewayIp": {
+ "type": "string",
+ "description": "gateway IP address"
+ },
+ "dnsNameservers": {
+ "type": "array",
+ "description": "DNS Nameservers",
+ "items": {
+ "type": "string"
+ }
+ },
+ "hostRoutes": {
+ "type": "array",
+ "description": "Host route entries",
+ "items": {
+ "$ref": "#/definitions/VimHostRouteInfo"
+ }
+ },
+ "allocationPools": {
+ "type": "array",
+ "description": "IP address allocation pools",
+ "items": {
+ "$ref": "#/definitions/VimIpAllocationPoolInfo"
+ }
+ }
+ }
+ },
+ "VimHostRouteInfo": {
+ "type": "object",
+ "properties": {
+ "destination": {
+ "type": "string",
+ "description": "destination field of a route entry"
+ },
+ "nexthop ": {
+ "type": "string",
+ "description": "next hop of a route entry"
+ }
+ }
+ },
+ "VimIpAllocationPoolInfo": {
+ "type": "object",
+ "properties": {
+ "start": {
+ "type": "string",
+ "description": "start IP address of a pool"
+ },
+ "end ": {
+ "type": "string",
+ "description": "end IP address of a pool"
+ }
+ }
+ },
+ "ListVimSubnets": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "subnet name"
+ }
+ }
+ },
+ "VimSubnetsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "subnets"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "subnets": {
+ "type": "array",
+ "description": "subnets information",
+ "items": {
+ "$ref": "#/definitions/VimSubnetInfo"
+ }
+ }
+ }
+ },
+ "VimSubnetInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "id",
+ "networkId",
+ "cidr",
+ "ipVersion"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "subnet name"
+ },
+ "id": {
+ "type": "string",
+ "description": "subnet UUID"
+ },
+ "status": {
+ "type": "string",
+ "description": "subnet status"
+ },
+ "networkId": {
+ "type": "string",
+ "description": "network UUID"
+ },
+ "networkName": {
+ "type": "string",
+ "description": "network name"
+ },
+ "cidr": {
+ "type": "string",
+ "description": "subnet CIDR"
+ },
+ "ipVersion": {
+ "type": "integer",
+ "description": "IP version: 4 for IPv4, 6 for IPv6"
+ },
+ "enableDhcp": {
+ "type": "boolean",
+ "description": "Enable DHCP or not"
+ },
+ "gatewayIp": {
+ "type": "string",
+ "description": "gateway IP address"
+ },
+ "dnsNameservers": {
+ "type": "array",
+ "description": "DNS Nameservers",
+ "items": {
+ "type": "string"
+ }
+ },
+ "hostRoutes": {
+ "type": "array",
+ "description": "Host route entries",
+ "items": {
+ "$ref": "#/definitions/VimHostRouteInfo"
+ }
+ },
+ "allocationPools": {
+ "type": "array",
+ "description": "IP address allocation pools",
+ "items": {
+ "$ref": "#/definitions/VimIpAllocationPoolInfo"
+ }
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.tenant.swagger.json b/kilo/kilo/swagger/multivim.tenant.swagger.json
new file mode 100644
index 00000000..062a0bda
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.tenant.swagger.json
@@ -0,0 +1,119 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/tenants": {
+ "get": {
+ "tags": [
+ "vim tenants"
+ ],
+ "summary": "query vim tenants list",
+ "description": "query vim tenants list",
+ "operationId": "query_vim_tenants",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim tenants request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimTenants"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimTenantsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id is wrong"
+ },
+ "500": {
+ "description": "the vim tenants is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "ListVimTenants": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "tenant name to filter tenant list"
+ }
+ }
+ },
+ "VimTenantsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenants"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenants": {
+ "type": "array",
+ "description": "tenant list information",
+ "items": {
+ "$ref": "#/definitions/VimTenantInfo"
+ }
+ }
+ }
+ },
+ "VimTenantInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "id"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "tenant name"
+ },
+ "id": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.volume.swagger.json b/kilo/kilo/swagger/multivim.volume.swagger.json
new file mode 100644
index 00000000..5b26d8c0
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.volume.swagger.json
@@ -0,0 +1,379 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/volumes": {
+ "post": {
+ "tags": [
+ "vim volumes"
+ ],
+ "summary": "create a volume",
+ "description": "create a volume",
+ "operationId": "create_vim_volume",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim volume request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimVolume"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimVolumeInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim volume is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim volumes"
+ ],
+ "summary": "query vim volumes list",
+ "description": "query vim volumes list",
+ "operationId": "query_vim_volumes",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim volumes request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimVolumes"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimVolumesInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim volume is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/volumes/{volumeid}": {
+ "delete": {
+ "tags": [
+ "vim volumes"
+ ],
+ "summary": "delete specific vim volume",
+ "description": "delete specific vim volume",
+ "operationId": "delete_vim_volume",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "volumeid",
+ "in": "path",
+ "description": "vim volume id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim volume is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim volumes"
+ ],
+ "summary": "query specific vim volume",
+ "description": "query specific vim volume",
+ "operationId": "query_vim_volume",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "volumeid",
+ "in": "path",
+ "description": "vim volume id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimVolumeInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim volume is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimVolume": {
+ "type": "object",
+ "required": [
+ "name",
+ "volumeSize"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "volume name"
+ },
+ "volumeSize": {
+ "type": "integer",
+ "description": "volume size"
+ },
+ "imageName": {
+ "type": "string",
+ "description": "image name to create volume"
+ },
+ "volumeType": {
+ "type": "string",
+ "description": "volume type"
+ },
+ "availabilityZone": {
+ "type": "integer",
+ "description": "available zone for volume"
+ }
+ }
+ },
+ "ListVimVolumes": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "volume name to filter volume list"
+ },
+ "limit": {
+ "type": "integer",
+ "description": "Requests a page size of items"
+ },
+ "marker": {
+ "type": "string",
+ "description": "volume ID of the last-seen item"
+ }
+ }
+ },
+ "VimVolumesInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "volumes"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "volumes": {
+ "type": "array",
+ "description": "volume list information",
+ "items": {
+ "$ref": "#/definitions/VimVolumeInfo"
+ }
+ }
+ }
+ },
+ "VimVolumeInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "id",
+ "status"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "volume name"
+ },
+ "id": {
+ "type": "string",
+ "description": "volume UUID"
+ },
+ "createTime": {
+ "type": "string",
+ "description": "created time"
+ },
+ "volumeSize": {
+ "type": "integer",
+ "description": "volume size"
+ },
+ "volumeType": {
+ "type": "string",
+ "description": "volume type"
+ },
+ "availabilityZone": {
+ "type": "integer",
+ "description": "available zone for volume"
+ },
+ "attachments": {
+ "type": "array",
+ "description": "attachment list information",
+ "items": {
+ "$ref": "#/definitions/VimVolumeAttachmentInfo"
+ }
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "return code: 0: Already exist 1: Newly created"
+ }
+ }
+ },
+ "VimVolumeAttachmentInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "attachment UUID"
+ },
+ "serverId": {
+ "type": "string",
+ "description": "server UUID"
+ },
+ "volumeId": {
+ "type": "string",
+ "description": "volume UUID"
+ },
+ "deviceId": {
+ "type": "string",
+ "description": "device UUID"
+ },
+ "hostName": {
+ "type": "string",
+ "description": "host name"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/multivim.vport.swagger.json b/kilo/kilo/swagger/multivim.vport.swagger.json
new file mode 100644
index 00000000..f722c26f
--- /dev/null
+++ b/kilo/kilo/swagger/multivim.vport.swagger.json
@@ -0,0 +1,378 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "version": "1.0.0",
+ "title": "MultiVIM Service rest API"
+ },
+ "basePath": "/openoapi/multivim/v1/",
+ "tags": [
+ {
+ "name": "MultiVIM broker"
+ }
+ ],
+ "paths": {
+ "/{vimid}/{tenantid}/ports": {
+ "post": {
+ "tags": [
+ "vim virtual ports"
+ ],
+ "summary": "create a virtual port",
+ "description": "create a virtual port",
+ "operationId": "create_vim_port",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "create vim virtual port request param",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateVimPort"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimPortInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim virtual port is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim virtual ports"
+ ],
+ "summary": "query vim ports list",
+ "description": "query vim ports list",
+ "operationId": "query_vim_ports",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "get a list of vim virtual ports request param",
+ "required": false,
+ "schema": {
+ "$ref": "#/definitions/ListVimPorts"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimPortsInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim virtual port is not accessable"
+ }
+ }
+ }
+ },
+ "/{vimid}/{tenantid}/ports/{portid}": {
+ "delete": {
+ "tags": [
+ "vim virtual ports"
+ ],
+ "summary": "delete specific vim virtual port",
+ "description": "delete specific vim virtual port",
+ "operationId": "delete_vim_port",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "portid",
+ "in": "path",
+ "description": "vim virtual port id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "successful operation"
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the virtual port is not accessable"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "vim virtual ports"
+ ],
+ "summary": "query specific vim virtual port",
+ "description": "query specific vim virtual port",
+ "operationId": "query_vim_port",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "vimid",
+ "in": "path",
+ "description": "vim instance id",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "tenantid",
+ "in": "path",
+ "description": "tenant UUID",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "portid",
+ "in": "path",
+ "description": "vim virtual port id",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/VimPortInfo"
+ }
+ },
+ "404": {
+ "description": "the vim id or tenant UUID is wrong"
+ },
+ "500": {
+ "description": "the vim virtual port id is not accessable"
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "CreateVimPort": {
+ "type": "object",
+ "required": [
+ "networkId",
+ "subnetId",
+ "name",
+ "cidr",
+ "ipVersion"
+ ],
+ "properties": {
+ "networkId": {
+ "type": "string",
+ "description": "network UUID"
+ },
+ "subnetId": {
+ "type": "string",
+ "description": "subnet UUID"
+ },
+ "name": {
+ "type": "string",
+ "description": "virtual port name"
+ },
+ "ip": {
+ "type": "string",
+ "description": "virtual port fixed IP"
+ },
+ "macAddress": {
+ "type": "string",
+ "description": "virtual port MAC address"
+ },
+ "vnicType": {
+ "type": "string",
+ "description": "vnicType: normal,direct,macvtap"
+ },
+ "securityGroups": {
+ "type": "array",
+ "description": "List of security group names",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "ListVimPorts": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "virtual port name"
+ }
+ }
+ },
+ "VimPortsInfo": {
+ "type": "object",
+ "required": [
+ "vimId",
+ "tenantId",
+ "ports"
+ ],
+ "properties": {
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "ports": {
+ "type": "array",
+ "description": "ports information",
+ "items": {
+ "$ref": "#/definitions/VimPortInfo"
+ }
+ }
+ }
+ },
+ "VimPortInfo": {
+ "type": "object",
+ "required": [
+ "name",
+ "status",
+ "id",
+ "networkId",
+ "subnetId"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "virtual port name"
+ },
+ "id": {
+ "type": "string",
+ "description": "virtual port UUID"
+ },
+ "status": {
+ "type": "string",
+ "description": "subnet status"
+ },
+ "networkId": {
+ "type": "string",
+ "description": "network UUID"
+ },
+ "networkName": {
+ "type": "string",
+ "description": "network name"
+ },
+ "subnetName": {
+ "type": "string",
+ "description": "subnet name"
+ },
+ "subnetId": {
+ "type": "string",
+ "description": "subnet UUID"
+ },
+ "ip": {
+ "type": "string",
+ "description": "virtual port fixed IP"
+ },
+ "macAddress": {
+ "type": "string",
+ "description": "virtual port MAC address"
+ },
+ "vnicType": {
+ "type": "string",
+ "description": "vnicType: normal,direct,macvtap"
+ },
+ "securityGroups": {
+ "type": "array",
+ "description": "list of securityGroups names",
+ "items": {
+ "type": "string"
+ }
+ },
+ "vimId": {
+ "type": "string"
+ },
+ "vimName": {
+ "type": "string"
+ },
+ "tenantId": {
+ "type": "string",
+ "description": "tenant UUID"
+ },
+ "returnCode": {
+ "type": "integer",
+ "description": "0: Already exist 1: Newly created"
+ }
+ }
+ }
+ }
+}
diff --git a/kilo/kilo/swagger/tests.py b/kilo/kilo/swagger/tests.py
new file mode 100644
index 00000000..194a34ef
--- /dev/null
+++ b/kilo/kilo/swagger/tests.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017 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.
+
+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("/openoapi/multivim-kilo/v1/swagger.json")
+ self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
+# resp_data = json.loads(response.content)
+# self.assertEqual({"status": "active"}, resp_data)
diff --git a/kilo/kilo/swagger/urls.py b/kilo/kilo/swagger/urls.py
new file mode 100644
index 00000000..91829930
--- /dev/null
+++ b/kilo/kilo/swagger/urls.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2017 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.
+
+from django.conf.urls import patterns, url
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from kilo.swagger import views
+from kilo.swagger.views import SwaggerJsonView
+
+urlpatterns = [
+ url(r'^openoapi/multivim-kilo/v1/swagger.json$', SwaggerJsonView.as_view()),
+]
+
+urlpatterns = format_suffix_patterns(urlpatterns)
diff --git a/kilo/kilo/swagger/views.py b/kilo/kilo/swagger/views.py
new file mode 100644
index 00000000..fe24ffff
--- /dev/null
+++ b/kilo/kilo/swagger/views.py
@@ -0,0 +1,89 @@
+# Copyright (c) 2017 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.
+
+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 kilo.pub.exceptions import VimDriverKiloException
+
+logger = logging.getLogger(__name__)
+
+
+class SwaggerJsonView(APIView):
+ def get(self, request):
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.flavor.swagger.json')
+ f = open(json_file)
+ json_data = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.image.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.network.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.subnet.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.server.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.volume.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.vport.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.tenant.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.host.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_file = os.path.join(os.path.dirname(__file__), 'multivim.limit.swagger.json')
+ f = open(json_file)
+ json_data_temp = json.JSONDecoder().decode(f.read())
+ f.close()
+ json_data["paths"].update(json_data_temp["paths"])
+ json_data["definitions"].update(json_data_temp["definitions"])
+ json_data["basePath"] = "/openoapi/multivim-kilo/v1/"
+ json_data["info"]["title"] = "MultiVIM driver of OpenStack Kilo Service NBI"
+ return Response(json_data)
+
diff --git a/kilo/kilo/urls.py b/kilo/kilo/urls.py
new file mode 100644
index 00000000..1a561f95
--- /dev/null
+++ b/kilo/kilo/urls.py
@@ -0,0 +1,25 @@
+# Copyright (c) 2017 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.
+
+from django.conf.urls import include, url
+from kilo.pub.config.config import REG_TO_MSB_WHEN_START, REG_TO_MSB_REG_URL, REG_TO_MSB_REG_PARAM
+
+urlpatterns = [
+ url(r'^', include('kilo.swagger.urls')),
+ url(r'^', include('kilo.samples.urls')),
+]
+#url(r'^', include('kilo.forward.urls')),
+
+# regist to MSB when startup
+if REG_TO_MSB_WHEN_START:
+ import json
+ from kilo.pub.utils.restcall import req_by_msb
+ req_by_msb(REG_TO_MSB_REG_URL, "POST", json.JSONEncoder().encode(REG_TO_MSB_REG_PARAM))
diff --git a/kilo/kilo/wsgi.py b/kilo/kilo/wsgi.py
new file mode 100644
index 00000000..0035bb4e
--- /dev/null
+++ b/kilo/kilo/wsgi.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2017 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.
+
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kilo.settings")
+
+application = get_wsgi_application()
diff --git a/kilo/manage.py b/kilo/manage.py
new file mode 100644
index 00000000..94444d1a
--- /dev/null
+++ b/kilo/manage.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2017 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.
+
+import os
+import sys
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kilo.settings")
+
+if __name__ == "__main__":
+ from django.core.management import execute_from_command_line
+ execute_from_command_line(sys.argv)
diff --git a/kilo/pom.xml b/kilo/pom.xml
new file mode 100644
index 00000000..65e5a878
--- /dev/null
+++ b/kilo/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (c) 2017 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.
+-->
+<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.openo.multivimdriver.openstack</groupId>
+ <artifactId>multivimdriver-openstack-root</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.openo.multivimdriver.openstack</groupId>
+ <artifactId>multivimdriver-openstack-kilo</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>multivimdriver/openstack/kilo</name>
+ <description>multivimdriver for openstack kilo</description>
+ <build>
+ <plugins>
+ <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/kilo/requirements.txt b/kilo/requirements.txt
new file mode 100644
index 00000000..25904796
--- /dev/null
+++ b/kilo/requirements.txt
@@ -0,0 +1,26 @@
+# rest framework
+Django==1.9.6
+djangorestframework==3.3.3
+
+# for access MySQL
+MySQL-python==1.2.5
+
+# redis cache
+redis==2.10.5
+
+# for access redis cache
+redisco==0.1.4
+django-redis-cache==0.13.1
+
+# for call rest api
+httplib2==0.9.2
+
+# for call openstack api
+python-keystoneclient==3.6.0
+python-glanceclient==2.5.0
+python-neutronclient==6.0.0
+
+# for unit test
+coverage==4.2
+mock==2.0.0
+unittest_xml_reporting==1.12.0
diff --git a/kilo/run.sh b/kilo/run.sh
new file mode 100755
index 00000000..113a545e
--- /dev/null
+++ b/kilo/run.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright (c) 2017 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.
+
+nohup python manage.py runserver 127.0.0.1:9002 > /dev/null &
diff --git a/kilo/stop.sh b/kilo/stop.sh
new file mode 100755
index 00000000..5dce4d66
--- /dev/null
+++ b/kilo/stop.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright (c) 2017 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.
+
+ps auxww | grep 'manage.py runserver 127.0.0.1:9002' | awk '{print $2}' | xargs kill -9
diff --git a/kilo/tox.ini b/kilo/tox.ini
new file mode 100644
index 00000000..14c93b5c
--- /dev/null
+++ b/kilo/tox.ini
@@ -0,0 +1,10 @@
+[tox]
+envlist = py27
+skipsdist = true
+
+[tox:jenkins]
+downloadcache = ~/cache/pip
+
+[testenv]
+deps = -r{toxinidir}/requirements.txt
+commands = coverage run --branch manage.py test kilo
diff --git a/pom.xml b/pom.xml
index 8557cd94..2c279811 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@
<modules>
<module>newton</module>
+ <module>kilo</module>
</modules>
<build>