diff options
author | xinhuili <lxinhui@vmware.com> | 2017-03-08 23:35:40 -0800 |
---|---|---|
committer | xinhuili <lxinhui@vmware.com> | 2017-03-10 04:05:17 -0800 |
commit | 3ea554ca920a0a21e5dca667f366379ca9c146c4 (patch) | |
tree | 8f8871c6663f3df1cf6e389948c4ff7f94e684dc | |
parent | 2fbc2b268c8ef2c7329fb613ce1599084e2c91bb (diff) |
Add basic VIM function into VIO NFVI
This patch is to add basic VIM function for VIO.
Change-Id: I5867680ce3f6881fce55f10551368cc82ff1d592
Issue-ids: MULTIVIM-36
Signed-off-by: xinhuili <lxinhui@vmware.com>
72 files changed, 5912 insertions, 6 deletions
diff --git a/vio/requirements.txt b/vio/requirements.txt index fba25ad..ca74dbc 100644 --- a/vio/requirements.txt +++ b/vio/requirements.txt @@ -13,7 +13,7 @@ django-redis-cache==0.13.1 httplib2==0.9.2 # for call openstack api -openstacksdk==0.8.1 +openstacksdk==0.9.14 # for unit test coverage==4.2 diff --git a/vio/vio/pub/config/config.py b/vio/vio/pub/config/config.py index 7b05698..71a44aa 100644 --- a/vio/vio/pub/config/config.py +++ b/vio/vio/pub/config/config.py @@ -25,11 +25,11 @@ REDIS_PORT = '6379' REDIS_PASSWD = '' # [mysql] -DB_IP = "127.0.0.1" +DB_IP = '127.0.0.1' DB_PORT = 3306 -DB_NAME = "multivimvio" -DB_USER = "root" -DB_PASSWD = "password" +DB_NAME = 'multivimvio' +DB_USER = 'root' +DB_PASSWD = 'password' # [register] REG_TO_MSB_WHEN_START = True diff --git a/vio/vio/pub/vim/__init__.py b/vio/vio/pub/vim/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/__init__.py diff --git a/vio/vio/pub/vim/const.py b/vio/vio/pub/vim/const.py new file mode 100644 index 0000000..9580148 --- /dev/null +++ b/vio/vio/pub/vim/const.py @@ -0,0 +1,26 @@ +# Copyright 2016 ZTE Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +VIM_OPENSTACK = "vmware" +RES_TYPE_KEY = "res_type" +RES_TYPE_NEW = 1 +RES_TYPE_EXIST = 0 +SHARED_NET = 1 +SUPPORT_VLAN_TRANSPARENT = 1 +DEFAULT_MTU = 1500 +IPV4 = 4 +IPV6 = 6 +ENABLE_DHCP = 1 + diff --git a/vio/vio/pub/vim/drivers/__init__.py b/vio/vio/pub/vim/drivers/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/drivers/__init__.py diff --git a/vio/vio/pub/vim/drivers/base.py b/vio/vio/pub/vim/drivers/base.py new file mode 100644 index 0000000..22402c9 --- /dev/null +++ b/vio/vio/pub/vim/drivers/base.py @@ -0,0 +1,21 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import copy + + + +class DriverBase(object): + '''Base class for all drivers.''' + + def __init__(self, params): + self.conn_params = copy.deepcopy(params) diff --git a/vio/vio/pub/vim/drivers/openstacksdk/__init__.py b/vio/vio/pub/vim/drivers/openstacksdk/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/__init__.py diff --git a/vio/vio/pub/vim/drivers/openstacksdk/cinder_v2.py b/vio/vio/pub/vim/drivers/openstacksdk/cinder_v2.py new file mode 100644 index 0000000..0e0c11c --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/cinder_v2.py @@ -0,0 +1,51 @@ +# Copyright 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from vio.pub.vim.drivers import base +from vio.pub.vim.drivers.openstacksdk import sdk + +LOG = logging.getLogger(__name__) + +class CinderClient(base.DriverBase): + '''Cinder V2 driver.''' + + def __init__(self, params): + super(CinderClient, self).__init__(params) + LOG.info("%s", str(params)) + self.conn = sdk.create_connection(params) + self.session = self.conn.session + + @sdk.translate_exception + def list_volumes(self, **query): + volumes = self.conn.block_store.volumes(**query) + return volumes + + + @sdk.translate_exception + def create_volume(self, **body): + volume_info = self.conn.block_store.create_volume(**body) + return volume_info + + + @sdk.translate_exception + def delete_volume(self, volumeid): + self.conn.block_store.delete_volume(volumeid) + + + @sdk.translate_exception + def get_volume(self, volumeid): + volume_info = self.conn.block_store.get_volume(volumeid) + return volume_info diff --git a/vio/vio/pub/vim/drivers/openstacksdk/compute.py b/vio/vio/pub/vim/drivers/openstacksdk/compute.py new file mode 100644 index 0000000..cfe9461 --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/compute.py @@ -0,0 +1,95 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import base64 +import logging + +from vio.pub.vim.drivers import base +from vio.pub.vim.drivers.openstacksdk import sdk + +LOG = logging.getLogger(__name__) + + +class ComputeClient(base.DriverBase): + """Compute driver.""" + + def __init__(self, params): + super(ComputeClient, self).__init__(params) + self.conn = sdk.create_connection(params) + self.session = self.conn.session + + @sdk.translate_exception + def create_server(self, **kwargs): + server = self.conn.compute.create_server(**kwargs) + return server + + @sdk.translate_exception + def list_servers(self): + servers = self.conn.compute.servers() + return servers + + @sdk.translate_exception + def get_server(self, server_id, **query): + server = self.conn.compute.get_server(server=server_id) + return server + + @sdk.translate_exception + def delete_server(self, server_id, **query): + self.conn.compute.delete_server(server=server_id) + + @sdk.translate_exception + def list_server_interfaces(self, server_id): + ifaces = self.conn.compute.server_interfaces(server_id) + return list(ifaces) + + @sdk.translate_exception + def list_flavors(self, **query): + flavors = self.conn.compute.flavors() + return flavors + + @sdk.translate_exception + def create_flavor(self, **kwargs): + return self.conn.compute.create_flavor(**kwargs) + + @sdk.translate_exception + def get_flavor(self, flavor_id, **query): + return self.conn.compute.get_flavor(flavor=flavor_id) + + @sdk.translate_exception + def find_flavor(self, flavor_id): + return self.conn.compute.find_flavor(flavor_id, ignore_missing=False) + + @sdk.translate_exception + def delete_flavor(self, flavor_id, **query): + self.conn.compute.delete_flavor(flavor=flavor_id) + + @sdk.translate_exception + def get_flavor_extra_specs(self, flavor_id, **query): + return None + + @sdk.translate_exception + def find_image(self, image_id, ignore_missing=False): + return self.conn.compute.find_image( + image_id, ignore_missing=ignore_missing) + + @sdk.translate_exception + def get_limits(self, **kwargs): + return self.conn.compute.get_limits() + + @sdk.translate_exception + def list_services(self, **kwargs): + return self.conn.compute.services() + + @sdk.translate_exception + def get_hypervisor(self, hypervisor, **kwargs): + return self.conn.compute.get_hypervisor(hypervisor=hypervisor) diff --git a/vio/vio/pub/vim/drivers/openstacksdk/image_v2.py b/vio/vio/pub/vim/drivers/openstacksdk/image_v2.py new file mode 100644 index 0000000..79ccfba --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/image_v2.py @@ -0,0 +1,67 @@ +# Copyright 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + +from vio.pub.vim.drivers import base +from vio.pub.vim.drivers.openstacksdk import sdk +from openstack.image.v2 import image as _image + +LOG = logging.getLogger(__name__) + + +class GlanceClient(base.DriverBase): + + def __init__(self, params): + super(GlanceClient, self).__init__(params) + LOG.info("%s", str(params)) + self.conn = sdk.create_connection(params) + self.session = self.conn.session + self._proxy = self.conn.image + + @sdk.translate_exception + def list_images(self, **query): + images = self._proxy.images(**query) + return images + + @sdk.translate_exception + def get_image(self, imageid): + image = self._proxy.get_image(imageid) + return image + + @sdk.translate_exception + def delete_image(self, imageid): + self._proxy.delete_image(imageid) + + @sdk.translate_exception + def create_image(self, **data): + + disk_format = data.pop('disk_format') + container_format = data.pop('container_format') + + if not all([container_format, disk_format]): + LOG.error( "Both container_format and disk_format are required") + + try: + img = self._proxy._create(_image.Image, disk_format=disk_format, + container_format=container_format, **data) + except Exception as ex: + pass + return img + + @sdk.translate_exception + def upload_image(self, data, image): + image.data = data + image.upload(self.session)
\ No newline at end of file diff --git a/vio/vio/pub/vim/drivers/openstacksdk/keystone_v3.py b/vio/vio/pub/vim/drivers/openstacksdk/keystone_v3.py new file mode 100644 index 0000000..7628477 --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/keystone_v3.py @@ -0,0 +1,34 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from vio.pub.vim.drivers import base +from vio.pub.vim.drivers.openstacksdk import sdk + +LOG = logging.getLogger(__name__) + + +class KeystoneClient(base.DriverBase): + '''Keystone V3 driver.''' + + def __init__(self, params): + super(KeystoneClient, self).__init__(params) + self.conn = sdk.create_connection(params) + self.session = self.conn.session + + @sdk.translate_exception + def project_list(self): + projects = self.conn.identity.projects() + return projects diff --git a/vio/vio/pub/vim/drivers/openstacksdk/neutron_v2_0.py b/vio/vio/pub/vim/drivers/openstacksdk/neutron_v2_0.py new file mode 100644 index 0000000..6ab7535 --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/neutron_v2_0.py @@ -0,0 +1,87 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from vio.pub.vim.drivers import base +from vio.pub.vim.drivers.openstacksdk import sdk + + +class NeutronClient(base.DriverBase): + '''Neutron V2.0 driver.''' + + def __init__(self, params): + super(NeutronClient, self).__init__(params) + self.conn = sdk.create_connection(params) + + @sdk.translate_exception + def subnet_create(self, **args): + network = self.conn.network.create_subnet(**args) + return network + + @sdk.translate_exception + def network_create(self, **args): + network = self.conn.network.create_network(**args) + return network + + @sdk.translate_exception + def network_get(self, name_or_id): + network = self.conn.network.find_network(name_or_id) + return network + + @sdk.translate_exception + def network_delete(self, name_or_id): + res = self.conn.network.delete_network(name_or_id) + return res + + @sdk.translate_exception + def networks_get(self, **kwargs): + network = self.conn.network.networks(**kwargs) + return network + + @sdk.translate_exception + def subnets_get(self, **kwargs): + subnets = self.conn.network.subnets(**kwargs) + return subnets + + @sdk.translate_exception + def subnet_delete(self, name_or_id): + res = self.conn.network.delete_subnet(name_or_id) + return res + + @sdk.translate_exception + def port_find(self, name_or_id, ignore_missing=False): + port = self.conn.network.find_port(name_or_id, ignore_missing) + return port + + @sdk.translate_exception + def subnet_get(self, name_or_id, ignore_missing=False): + subnet = self.conn.network.find_subnet(name_or_id, ignore_missing) + return subnet + + @sdk.translate_exception + def port_create(self, **attr): + res = self.conn.network.create_port(**attr) + return res + + @sdk.translate_exception + def port_delete(self, port, ignore_missing=True): + res = self.conn.network.delete_port( + port=port, ignore_missing=ignore_missing) + return res + + @sdk.translate_exception + def ports_get(self, **kwargs): + ports = self.conn.network.ports(**kwargs) + return ports + + diff --git a/vio/vio/pub/vim/drivers/openstacksdk/sdk.py b/vio/vio/pub/vim/drivers/openstacksdk/sdk.py new file mode 100644 index 0000000..9f01a4d --- /dev/null +++ b/vio/vio/pub/vim/drivers/openstacksdk/sdk.py @@ -0,0 +1,132 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +''' +SDK Client +''' +import functools +import json +import logging +import six + +from openstack import connection +from openstack import exceptions as sdk_exc +from openstack import profile +from requests import exceptions as req_exc + + +USER_AGENT = 'vimdriver-vio' +exc = sdk_exc +LOG = logging.getLogger(__name__) + + +def parse_exception(ex): + '''Parse exception code and yield useful information.''' + code = 500 + + if isinstance(ex, sdk_exc.HttpException): + # some exceptions don't contain status_code + if ex.http_status is not None: + code = ex.http_status + message = ex.message + data = {} + if ex.details is None and ex.response is not None: + data = ex.response.json() + else: + try: + data = json.loads(ex.details) + except Exception: + # Some exceptions don't have details record or + # are not in JSON format + pass + + # try dig more into the exception record + # usually 'data' has two types of format : + # type1: {"forbidden": {"message": "error message", "code": 403} + # type2: {"code": 404, "error": { "message": "not found"}} + if data: + code = data.get('code', code) + message = data.get('message', message) + error = data.get('error', None) + if error: + code = data.get('code', code) + message = data['error'].get('message', message) + else: + for value in data.values(): + code = value.get('code', code) + message = value.get('message', message) + + elif isinstance(ex, sdk_exc.SDKException): + # Besides HttpException there are some other exceptions like + # ResourceTimeout can be raised from SDK, handle them here. + message = ex.message + elif isinstance(ex, req_exc.RequestException): + # Exceptions that are not captured by SDK + code = ex.errno + message = six.text_type(ex) + else: + # This could be a generic exception or something we don't understand + message = six.text_type(ex) + + import traceback + traceback.print_exc() + raise ex +# raise senlin_exc.InternalError(code=code, message=message) + + +def translate_exception(func): + """Decorator for exception translation.""" + + @functools.wraps(func) + def invoke_with_catch(driver, *args, **kwargs): + try: + return func(driver, *args, **kwargs) + except Exception as ex: + LOG.exception(ex) + raise parse_exception(ex) + + return invoke_with_catch + + +def create_connection(params=None): + if params is None: + params = {} + + auth_plugin = 'password' + + prof = profile.Profile() + prof.set_version('identity', 'v3') + prof.set_version('image', 'v2') + + try: + conn = connection.Connection(profile=prof, verify=False, user_agent=USER_AGENT, + auth_plugin=auth_plugin, **params) + except Exception as ex: + raise parse_exception(ex) + + return conn + + +def authenticate(**kwargs): + '''Authenticate using openstack sdk based on user credential''' + + conn = create_connection(kwargs) + access_info = { + 'token': conn.session.get_token(), + 'user_id': conn.session.get_user_id(), + 'project_id': conn.session.get_project_id() + } + + return access_info + diff --git a/vio/vio/pub/vim/drivers/vimdriver.py b/vio/vio/pub/vim/drivers/vimdriver.py new file mode 100644 index 0000000..3fb5bc0 --- /dev/null +++ b/vio/vio/pub/vim/drivers/vimdriver.py @@ -0,0 +1,29 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from vio.pub.vim.drivers.openstacksdk import image_v2 +from vio.pub.vim.drivers.openstacksdk import keystone_v3 +from vio.pub.vim.drivers.openstacksdk import cinder_v2 +from vio.pub.vim.drivers.openstacksdk import compute + + +class VimDriver(object): + '''Generic driver class''' + + def __init__(self): + self.identity = keystone_v3.KeystoneClient + self.glance = image_v2.GlanceClient + self.cinder = cinder_v2.CinderClient + self.compute = compute.ComputeClient diff --git a/vio/vio/pub/vim/vimapi/__init__.py b/vio/vio/pub/vim/vimapi/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/__init__.py diff --git a/vio/vio/pub/vim/vimapi/baseclient.py b/vio/vio/pub/vim/vimapi/baseclient.py new file mode 100644 index 0000000..44b2739 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/baseclient.py @@ -0,0 +1,60 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from vio.pub.vim.drivers import vimdriver as driver_base + +LOG = logging.getLogger(__name__) + + +class baseclient(object): + + def __init__(self, **kwargs): + # initialize clients + self._identityclient = None + self._glanceclient = None + self._computeClient = None + self._cinderclient = None + + def identity(self, data): + '''Construct compute client based on object. + + :param obj: Object for which the client is created. It is expected to + be None when retrieving an existing client. When creating + a client, it contains the user and project to be used. + ''' + + if self._identityclient is not None: + return self._identityclient + self._identityclient = driver_base.VimDriver().identity(data) + return self._identityclient + + def glance(self, data): + if self._glanceclient is not None: + return self._glanceclient + self._glanceclient = driver_base.VimDriver().glance(data) + return self._glanceclient + + def compute(self, data): + if self._computeClient is not None: + return self._computeClient + + self._computeClient = driver_base.VimDriver().compute(data) + return self._computeClient + + def cinder(self, data): + if self._cinderclient is not None: + return self._cinderclient + + self._cinderclient = driver_base.VimDriver().cinder(data) + return self._cinderclient diff --git a/vio/vio/pub/vim/vimapi/cinder/OperateVolume.py b/vio/vio/pub/vim/vimapi/cinder/OperateVolume.py new file mode 100644 index 0000000..4458309 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/cinder/OperateVolume.py @@ -0,0 +1,50 @@ +# Copyright 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.baseclient import baseclient +from vio.swagger import volume_utils + +logger = logging.getLogger(__name__) + + +class OperateVolume(baseclient): + + def __init__(self, params): + super(OperateVolume, self).__init__() + self.param = volume_utils.sdk_param_formatter(params) + + def get_vim_volumes(self, **query): + + volumes = self.cinder(self.param).list_volumes(**query) + return volumes + + def create_vim_volume(self, **body): + + volume = self.cinder(self.param).create_volume(**body) + return volume + + def get_vim_volume(self, volume_id): + + volume = self.cinder(self.param).get_volume(volume_id) + return volume + + def delete_vim_volume(self, volume_id): + + volume = self.cinder(self.param).delete_volume(volume_id) + return volume
\ No newline at end of file diff --git a/vio/vio/pub/vim/vimapi/cinder/__init__.py b/vio/vio/pub/vim/vimapi/cinder/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/cinder/__init__.py diff --git a/vio/vio/pub/vim/vimapi/glance/OperateImage.py b/vio/vio/pub/vim/vimapi/glance/OperateImage.py new file mode 100644 index 0000000..446f808 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/glance/OperateImage.py @@ -0,0 +1,100 @@ +# Copyright 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging +import threading +import urllib2 + + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.baseclient import baseclient +from vio.swagger import image_utils + +logger = logging.getLogger(__name__) + + +running_threads = {} +running_thread_lock = threading.Lock() + +class imageThread(threading.Thread): + def __init__(self, vimid, tenantid, image, imagefd): + + threading.Thread.__init__(self) + self.imageid = image.id + self.imagefd = imagefd + self.vimid = vimid + self.tenantid = tenantid + self.image = image + + + def run(self): + + logger.debug("start imagethread") + self.transfer_image(self.vimid, self.tenantid, self.image, self.imagefd) + running_thread_lock.acquire() + running_threads.pop(self.imageid) + running_thread_lock.release() + + + def transfer_image(self, vimid, tenantid, image, imagefd): + + logger.debug("Image----transfer_image") + vim_info = extsys.get_vim_by_id(vimid) + + param = image_utils.sdk_param_formatter(vim_info) + data = imagefd.read() + client = baseclient() + client.glance(param).upload_image(data, image) + + +class OperateImage(baseclient): + + def __init__(self, params): + + super(OperateImage, self).__init__() + self.param = image_utils.sdk_param_formatter(params) + + def get_vim_images(self, **query): + + images = self.glance(self.param).list_images(**query) + return images + + def get_vim_image(self, imageid): + + image = self.glance(self.param).get_image(imageid) + return image + + def delete_vim_image(self, imageid): + + image = self.glance(self.param).delete_image(imageid) + return image + + def create_vim_image(self, vimid, tenantid, **req_body): + + imageurl = req_body.pop('imagePath', None) + imagefd = urllib2.urlopen(imageurl) + + image = self.glance(self.param).create_image(**req_body) + + upload_image_thread = imageThread(vimid, tenantid, image, imagefd) + logger.debug("launch thread to upload image: %s" % image.id) + running_thread_lock.acquire() + running_threads[image.id] = image.id + running_thread_lock.release() + try: + upload_image_thread.start() + except Exception as ex: + pass + return image
\ No newline at end of file diff --git a/vio/vio/pub/vim/vimapi/glance/__init__.py b/vio/vio/pub/vim/vimapi/glance/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/glance/__init__.py diff --git a/vio/vio/pub/vim/vimapi/keystone/OperateTenant.py b/vio/vio/pub/vim/vimapi/keystone/OperateTenant.py new file mode 100644 index 0000000..31e1752 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/keystone/OperateTenant.py @@ -0,0 +1,38 @@ +# Copyright 2016 ZTE Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.baseclient import baseclient + +logger = logging.getLogger(__name__) + + + +class OperateTenant(baseclient): + + def get_projects(self, data): + param = {} + param['username'] = data['username'] + param['user_domain_name'] = 'default' + param['project_domain_name'] = 'default' + param['password'] = data['password'] + param['auth_url'] = data['url'] + param['project_name'] = data['project_name'] + projects = self.identity(param).project_list() + return projects + diff --git a/vio/vio/pub/vim/vimapi/keystone/__init__.py b/vio/vio/pub/vim/vimapi/keystone/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/keystone/__init__.py diff --git a/vio/vio/pub/vim/vimapi/keystone/auth.py b/vio/vio/pub/vim/vimapi/keystone/auth.py new file mode 100644 index 0000000..86f03c2 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/keystone/auth.py @@ -0,0 +1,27 @@ +# Copyright 2016 ZTE Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + + +from vio.pub.msapi import extsys +from vio.pub.vim.drivers import base + +logger = logging.getLogger(__name__) + +def login(data): + + print data + diff --git a/vio/vio/pub/vim/vimapi/network/OperateNetwork.py b/vio/vio/pub/vim/vimapi/network/OperateNetwork.py new file mode 100644 index 0000000..848878e --- /dev/null +++ b/vio/vio/pub/vim/vimapi/network/OperateNetwork.py @@ -0,0 +1,112 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +from vio.pub.msapi.extsys import get_vim_by_id +from vio.pub.vim.drivers.openstacksdk import neutron_v2_0 + + +logger = logging.getLogger(__name__) + + +def translate(mapping, data, revert=True): + if revert: + for key in mapping: + if key in data: + data[mapping[key]] = data.pop(key) + else: + for key in mapping: + if mapping[key] in data: + data[key] = data.pop(mapping[key]) + return data + + +class BaseNet(object): + def get_vim_info(self, vimid): + return get_vim_by_id(vimid) + + def auth(self, vim_info): + param = {} + param['username'] = vim_info['userName'] + param['user_domain_name'] = 'default' + param['project_domain_name'] = 'default' + param['password'] = vim_info['password'] + param['auth_url'] = vim_info['url'] + param['project_name'] = vim_info['tenant'] + return neutron_v2_0.NeutronClient(param) + + +class OperateNetwork(BaseNet): + service = {'service_type': 'network', + 'interface': 'public', + 'region_name': 'RegionOne'} + keys_mapping = {"segmentationId": "provider:segmentation_id", + "physicalNetwork": "provider:physical_network", + "routerExternal": "router:external", + "networkType": "provider:network_type", + "vlanTransparent": "vlan_transparent", + "tenantId": "project_id" + } + + def ___init__(self, params): + super(Network, self).__init__(params) + + def _convert(self, network): + result = {} + result['status'] = network.status + result['id'] = network.id + result['name'] = network.name + result['tenantId'] = network.project_id + result['segmentationId'] = network.provider_segmentation_id + result['networkType'] = network.provider_network_type + result['physicalNetwork'] = network.provider_physical_network + result['vlanTransparent'] = True + result['shared'] = network.is_shared + result['routerExternal'] = network.is_router_external + return result + + def create_network(self, vimid, tenantid, body): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + body = translate(self.keys_mapping, body) + net = network.network_create(**body) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(net) + resp.update(vim_dict) + return resp + + def list_network(self, vimid, tenantid, networkid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + net = network.network_get(networkid) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(net) + resp.update(vim_dict) + return resp + + def delete_network(self, vimid, tenantid, networkid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + return network.network_delete(networkid) + + def list_networks(self, vimid, tenantid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + tenant = {"project_id": tenantid} + resp = network.networks_get(**tenant) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + networks = {'networks': []} + if resp: + for net in resp: + networks['networks'].append(self._convert(net)) + networks.update(vim_dict) + return networks diff --git a/vio/vio/pub/vim/vimapi/network/OperatePort.py b/vio/vio/pub/vim/vimapi/network/OperatePort.py new file mode 100644 index 0000000..4ed0112 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/network/OperatePort.py @@ -0,0 +1,82 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +from vio.pub.msapi.extsys import get_vim_by_id +from vio.pub.vim.drivers.openstacksdk import neutron_v2_0 +from vio.pub.vim.vimapi.network.OperateNetwork import BaseNet, translate + + +logger = logging.getLogger(__name__) + + +class OperatePort(BaseNet): + keys_mapping = {"tenantId": "project_id", + "networkId": "network_id", + "vnicType": "binding:vnic_type", + "securityGroups": "security_groups", + "macAddress": "mac_address", + "subnetId": "subnet_id", + "ip": "ip_address" + } + + def ___init__(self, params): + super(OperatePort, self).__init__(params) + + def _convert(self, port): + result = {} + result['status'] = 'ok' + result['id'] = port.id + result['networkId'] = port.network_id + result['name'] = port.name + result['vnicType'] = port.binding_vnic_type + result['macAddress'] = port.mac_address + result['subnetId'] = port.subnet_id + result['securityGroups'] = port.security_group_ids + return result + + def create_port(self, vimid, tenantid, body): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + body = translate(self.keys_mapping, body) + port = network.port_create(**body) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(port) + resp.update(vim_dict) + return resp + + def list_port(self, vimid, tenantid, portid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + port = network.port_find(portid) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(port) + resp.update(vim_dict) + return resp + + def delete_port(self, vimid, tenantid, portid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + return network.port_delete(portid) + + def list_ports(self, vimid, tenantid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + tenant = {"project_id": tenantid} + resp = network.ports_get(**tenant) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + ports = {'ports': []} + if resp: + for port in resp: + ports['ports'].append(self._convert(port)) + ports.update(vim_dict) + return ports diff --git a/vio/vio/pub/vim/vimapi/network/OperateSubnet.py b/vio/vio/pub/vim/vimapi/network/OperateSubnet.py new file mode 100644 index 0000000..b9b4c27 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/network/OperateSubnet.py @@ -0,0 +1,85 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +from vio.pub.msapi.extsys import get_vim_by_id +from vio.pub.vim.drivers.openstacksdk import neutron_v2_0 +from vio.pub.vim.vimapi.network.OperateNetwork import BaseNet,translate + + +logger = logging.getLogger(__name__) + + +class OperateSubnet(BaseNet): + keys_mapping = {"tenantId": "project_id", + "networkId": "network_id", + "ipVersion": "ip_version", + "gaetwayIp": "gateway_ip", + "dnsNameservers": "dns_nameservers", + "hostRoutes": "host_routes", + "allocationPools": "allocation_pools" + } + + def ___init__(self, params): + super(OperateSubnet, self).__init__(params) + + def _convert(self, subnet): + result = {} + result['status'] = 'ok' + result['id'] = subnet.id + result['networkId'] = subnet.network_id + result['name'] = subnet.name + result['allocationPools'] = subnet.allocation_pools + result['gatewayIp'] = subnet.gateway_ip + result['dnsNameServers'] = subnet.dns_nameservers + result['ipVersion'] = subnet.ip_version + result['enableDhcp'] = subnet.is_dhcp_enabled + result['hostRoutes'] = subnet.host_routes + result['cidr'] = subnet.cidr + return result + + def create_subnet(self, vimid, tenantid, body): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + body = translate(self.keys_mapping, body) + subnet = network.subnet_create(**body) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(subnet) + resp.update(vim_dict) + return resp + + def list_subnet(self, vimid, tenantid, subnetid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + subnet = network.subnet_get(subnetid) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + resp = self._convert(subnet) + resp.update(vim_dict) + return resp + + def delete_subnet(self, vimid, tenantid, subnetid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + return network.subnet_delete(subnetid) + + def list_subnets(self, vimid, tenantid): + vim_info = self.get_vim_info(vimid) + network = self.auth(vim_info) + tenant = {"project_id": tenantid} + resp = network.subnets_get(**tenant) + vim_dict = {"vimName": vim_info['name'], "vimId": vim_info['vimId']} + subnets = {'subnets': []} + if resp: + for subnet in resp: + subnets['subnets'].append(self._convert(subnet)) + subnets.update(vim_dict) + return subnets diff --git a/vio/vio/pub/vim/vimapi/network/__init__.py b/vio/vio/pub/vim/vimapi/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/network/__init__.py diff --git a/vio/vio/pub/vim/vimapi/nova/OperateFlavors.py b/vio/vio/pub/vim/vimapi/nova/OperateFlavors.py new file mode 100644 index 0000000..92dfbbf --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateFlavors.py @@ -0,0 +1,64 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging + +from openstack import exceptions + +from vio.pub.vim.vimapi.nova.OperateNova import OperateNova + +logger = logging.getLogger(__name__) + + +class OperateFlavors(OperateNova): + + def __init__(self, **kwargs): + super(OperateFlavors, self).__init__(**kwargs) + + def create_flavor(self, data, project_id, create_req): + req = { + "name": create_req.get('name'), + "vcpus": create_req.get('vcpu'), + "ram": create_req.get('memory'), + "disk": create_req.get('disk'), + "ephemeral": create_req.get('ephemeral', 0), + "swap": create_req.get('swap', 0), + "is_public": create_req.get('isPublic', True) + } + # TODO: support extraSpecs + return self.request('create_flavor', data, + project_id=project_id, **req), None + + def list_flavors(self, data, project_id): + flavors = self.request('list_flavors', data, project_id=project_id) + flavors = list(flavors) + result = [] + for flavor in flavors: + extra_specs = self.request('get_flavor_extra_specs', data, + project_id=project_id, flavor_id=flavor.id) + result.append((flavor, extra_specs)) + return result + + def get_flavor(self, data, project_id, flavor_id): + try: + flavor = self.request('get_flavor', data, + project_id=project_id, flavor_id=flavor_id) + extra_specs = self.request('get_flavor_extra_specs', data, + project_id=project_id, flavor_id=flavor_id) + return flavor, extra_specs + + except exceptions.ResourceNotFound: + return None, None + + def delete_flavor(self, data, project_id, flavor_id): + return self.request('delete_flavor', data, project_id=project_id, + flavor_id=flavor_id) diff --git a/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py b/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py new file mode 100644 index 0000000..8b3de91 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateHypervisor.py @@ -0,0 +1,31 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging + +from openstack import exceptions + +from vio.pub.vim.vimapi.nova.OperateNova import OperateNova + +logger = logging.getLogger(__name__) + + +class OperateHypervisor(OperateNova): + + def get_hypervisor(self, data, hypervisor, **kwargs): + try: + return self.request('get_hypervisor', data, + project_name=data['project_name'], + hypervisor=hypervisor, + **kwargs) + except exceptions.ResourceNotFound: + return None diff --git a/vio/vio/pub/vim/vimapi/nova/OperateLimits.py b/vio/vio/pub/vim/vimapi/nova/OperateLimits.py new file mode 100644 index 0000000..34e0584 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateLimits.py @@ -0,0 +1,23 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging + +from vio.pub.vim.vimapi.nova.OperateNova import OperateNova + +logger = logging.getLogger(__name__) + + +class OperateLimits(OperateNova): + + def get_limits(self, data, project_id, **kwargs): + return self.request('get_limits', data, **kwargs) diff --git a/vio/vio/pub/vim/vimapi/nova/OperateNova.py b/vio/vio/pub/vim/vimapi/nova/OperateNova.py new file mode 100644 index 0000000..49461a2 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateNova.py @@ -0,0 +1,39 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging + +from vio.pub.vim.vimapi.baseclient import baseclient + + +logger = logging.getLogger(__name__) + + +class OperateNova(baseclient): + + def __init__(self, **kwargs): + super(OperateNova, self).__init__(**kwargs) + + def request(self, op, data, **kwargs): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url']} + project_id = kwargs.get('project_id') + if project_id: + param['project_id'] = project_id + else: + param['project_name'] = kwargs.get('project_name') + compute = self.compute(param) + func = getattr(compute, op) + return func(**kwargs) diff --git a/vio/vio/pub/vim/vimapi/nova/OperateServers.py b/vio/vio/pub/vim/vimapi/nova/OperateServers.py new file mode 100644 index 0000000..eb44eb8 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateServers.py @@ -0,0 +1,109 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import base64 +import logging + +from openstack import exceptions + +from vio.pub.vim.vimapi.nova.OperateNova import OperateNova + +logger = logging.getLogger(__name__) + + +class OperateServers(OperateNova): + + def create_server(self, data, project_id, create_req): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url'], + 'project_id': project_id} + cc = self.compute(param) + req = { + "name": create_req.get('name'), + "flavorRef": cc.find_flavor(create_req.get('flavorId')).id + } + boot = create_req.get('boot') + boot_type = boot.get('type') + if boot_type == 1: + # boot from vol + req['block_device_mapping_v2'] = { + 'uuid': boot["volumeId"], + 'source_type': 'volume', + 'destination_type': 'volume', + 'delete_on_termination': False + } + elif boot_type == 2: + req['imageRef'] = cc.find_image(boot.get('imageId')).id + networks = create_req.get('nicArray', []) + if networks: + req['networks'] = [{'port': n['portId']} for n in networks] + az = create_req.get('availabilityZone', None) + if az: + req['availability_zone'] = az + md = create_req.get('metadata', []) + if md: + req['metadata'] = [{n['keyName']: n['Value']} for n in md] + userdata = create_req.get('userdata', None) + if userdata: + req['user_data'] = base64.encodestring(userdata) + sg = create_req.get('securityGroups', []) + if sg: + req['security_groups'] = sg + # todo attach volumes after server created + volumes = create_req.get('volumeArray', []) + return cc.create_server(**req) + + def list_servers(self, data, project_id): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url'], + 'project_id': project_id} + projects = self.compute(param).list_servers() + return projects + + def list_server_interfaces(self, data, project_id, server): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url'], + 'project_id': project_id} + interfaces = self.compute(param).list_server_interfaces(server) + return list(interfaces) + + def get_server(self, data, project_id, server_id): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url'], + 'project_id': project_id} + try: + project = self.compute(param).get_server(server_id=server_id) + return project + except exceptions.ResourceNotFound: + return None + + def delete_server(self, data, project_id, server_id): + param = {'username': data['username'], + 'user_domain_name': 'default', + 'project_domain_name': 'default', + 'password': data['password'], + 'auth_url': data['url'], + 'project_id': project_id} + project = self.compute(param).delete_server(server_id) + return project diff --git a/vio/vio/pub/vim/vimapi/nova/OperateService.py b/vio/vio/pub/vim/vimapi/nova/OperateService.py new file mode 100644 index 0000000..d29779a --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/OperateService.py @@ -0,0 +1,25 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging + +from openstack import exceptions + +from vio.pub.vim.vimapi.nova.OperateNova import OperateNova + +logger = logging.getLogger(__name__) + + +class OperateService(OperateNova): + + def list_services(self, data, project_id, **kwargs): + return self.request('list_services', data, **kwargs) diff --git a/vio/vio/pub/vim/vimapi/nova/__init__.py b/vio/vio/pub/vim/vimapi/nova/__init__.py new file mode 100644 index 0000000..8770c43 --- /dev/null +++ b/vio/vio/pub/vim/vimapi/nova/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + diff --git a/vio/vio/swagger/image_utils.py b/vio/vio/swagger/image_utils.py new file mode 100644 index 0000000..6380688 --- /dev/null +++ b/vio/vio/swagger/image_utils.py @@ -0,0 +1,55 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +def image_formatter(image): + + return { + 'id' : image.id, + 'name' : image.name, + 'imageType' : image.disk_format, + 'status' : image.status, + 'size' : image.size, + 'containerFormat' : image.container_format, + 'visibility' : image.visibility + } + + +def vim_formatter(vim_info, tenantid): + + rsp = {} + rsp['vimId'] = vim_info.get('vimId') + rsp['vimName'] = vim_info.get('name') + rsp['tenantId'] = tenantid + return rsp + + +def sdk_param_formatter(data): + + param = {} + param['username'] = data.get('userName') + param['password'] = data.get('password') + param['auth_url'] = data.get('url') + param['project_name'] = data.get('tenant') + param['user_domain_name'] = 'default' + param['project_domain_name'] = 'default' + return param + +def req_body_formatter(body): + + param = {} + param['name'] = body.get('name') + param['disk_format'] = body.get('imageType') + param['container_format'] = body.get('containerFormat') + param['visibility'] = body.get('visibility') + param['imagePath'] = body.get('imagePath') + return param
\ No newline at end of file diff --git a/vio/vio/swagger/nova_utils.py b/vio/vio/swagger/nova_utils.py new file mode 100644 index 0000000..6084317 --- /dev/null +++ b/vio/vio/swagger/nova_utils.py @@ -0,0 +1,109 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import six + + +def server_formatter(server, interfaces=[]): + r = { + "id": server.id, + "name": server.name, + "tenantId": server.project_id, + "availabilityZone": server.availability_zone, + "flavorId": server.flavor_id or server.flavor['id'], + "volumeArray": [], + "metadata": [], + "securityGroups": [], + # TODO finish following attributes + "serverGroup": "", + "contextArray": [], + "userdata": server.user_data, + "nicArray": [], + } + if interfaces: + r['nicArray'] = [{'portId': i.port_id} for i in interfaces] + elif server.networks: + r['nicArray'] = [{'portId': n['port']} for n in server.networks] + if server.attached_volumes: + r["volumeArray"] = [{'volumeId': v['id']} for v in server.attached_volumes] + if server.image_id or server.image: + r['boot'] = { + 'type': 2, + 'imageId': server.image_id or server.image['id'] + } + else: + r['boot'] = { + 'type': 1, + 'volumeId': r['volumeArray'][0]['volumeId'] + } + if server.metadata: + r["metadata"] = [{'keyName': k, 'value': v} + for k, v in six.iteritems(server.metadata)] + if server.security_groups: + r["securityGroups"] = [i['name'] for i in server.security_groups] + return r + + +def flavor_formatter(flavor, extra_specs): + return { + "id": flavor.id, + "name": flavor.name, + "vcpu": flavor.vcpus, + "memory": flavor.ram, + "disk": flavor.disk, + "ephemeral": flavor.ephemeral, + "swap": flavor.swap, + "isPublic": flavor.is_public, + "extraSpecs": extra_specs_formatter(extra_specs) + } + + +def extra_specs_formatter(extra_specs): + return { + } + + +def server_limits_formatter(limits): + return { + # nova + 'maxPersonality': limits.absolute.personality, + 'maxPersonalitySize': limits.absolute.personality_size, + 'maxServerGroupMembers': limits.absolute.server_group_members, + 'maxServerGroups': limits.absolute.server_groups, + 'maxImageMeta': limits.absolute.image_meta, + 'maxTotalCores': limits.absolute.total_cores, + 'maxTotalInstances': limits.absolute.instances, + 'maxTotalKeypairs': limits.absolute.keypairs, + 'maxTotalRAMSize': limits.absolute.total_ram, + 'security_group_rules': limits.absolute.security_group_rules, + 'security_group': limits.absolute.security_groups, + + # cinder + # neutron + } + + +def service_formatter(service): + return { + 'service': service.binary, + 'name': service.host, + 'zone': service.zone, + } + + +def hypervisor_formatter(hypervisor): + return { + 'name': hypervisor.name, + 'cpu': hypervisor.vcpus, + 'disk_gb': hypervisor.local_disk_size, + 'memory_mb': hypervisor.memory_size, + } diff --git a/vio/vio/swagger/urls.py b/vio/vio/swagger/urls.py index 824aea1..c058df0 100644 --- a/vio/vio/swagger/urls.py +++ b/vio/vio/swagger/urls.py @@ -13,10 +13,72 @@ from django.conf.urls import patterns, url from rest_framework.urlpatterns import format_suffix_patterns -from vio.swagger.views import SwaggerJsonView +from vio.swagger.views.hypervisor.views import HostView +from vio.swagger.views.limits.views import LimitsView +from vio.swagger.views.service.views import HostsView +from vio.swagger.views.swagger_json import SwaggerJsonView +from vio.swagger.views.tenant.views import ListTenantsView +from vio.swagger.views.image.views import CreateListImagesView +from vio.swagger.views.image.views import GetDeleteImageView +from vio.swagger.views.volume.views import CreateListVolumeView +from vio.swagger.views.volume.views import GetDeleteVolumeView +from vio.swagger.views.server.views import ListServersView, GetServerView +from vio.swagger.views.flavor.views import FlavorsView, FlavorView +from vio.swagger.views.network.views import CreateNetworkView, DeleteNetworkView +from vio.swagger.views.subnet.views import CreateSubnetView, DeleteSubnetView +from vio.swagger.views.port.views import CreatePortView, DeletePortView urlpatterns = [ url(r'^openoapi/multivim-vio/v1/swagger.json$', SwaggerJsonView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'tenants$', ListTenantsView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z_-]+)/images$', + CreateListImagesView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z_-]+)/images/(?P<imageid>[0-9a-zA-Z_-]+)$', + GetDeleteImageView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z_-]+)/volumes$', + CreateListVolumeView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z_-]+)/volumes/(?P<volumeid>[0-9a-zA-Z_-]+)$', + GetDeleteVolumeView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/servers$', ListServersView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/servers/(?P<serverid>[0-9a-zA-Z_-]+)$', + GetServerView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/flavors$', + FlavorsView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/flavors/(?P<flavorid>[0-9a-zA-Z_-]+)$', + FlavorView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/limits$', + LimitsView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/hosts$', + HostsView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z_-]+)/' + r'(?P<tenantid>[0-9a-zA-Z]+)/hosts/(?P<hostname>[0-9a-zA-Z_-]+)$', + HostView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/networks$', + CreateNetworkView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/networks/' + r'(?P<networkid>[0-9a-zA-Z\-\_]+)$', + DeleteNetworkView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/subnets$', + CreateSubnetView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/subnets/' + r'(?P<subnetid>[0-9a-zA-Z\-\_]+)$', + DeleteSubnetView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/ports$', + CreatePortView.as_view()), + url(r'^openoapi/multivim-vio/v1/(?P<vimid>[0-9a-zA-Z\-\_]+)/(?P<tenantid>[0-9a-zA-Z\-\_]+)/ports/' + r'(?P<portid>[0-9a-zA-Z\-\_]+)$', + DeletePortView.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/vio/vio/swagger/views/__init__.py b/vio/vio/swagger/views/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/flavor/__init__.py b/vio/vio/swagger/views/flavor/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/flavor/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/flavor/views.py b/vio/vio/swagger/views/flavor/views.py new file mode 100644 index 0000000..ec22c65 --- /dev/null +++ b/vio/vio/swagger/views/flavor/views.py @@ -0,0 +1,99 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +import json + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.nova import OperateFlavors +from vio.swagger import nova_utils + + +class FlavorsView(APIView): + + def post(self, request, vimid, tenantid): + create_req = json.loads(request.body) + + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + flavors_op = OperateFlavors.OperateFlavors() + flavor, extra_specs = flavors_op.create_flavor(data, tenantid, create_req) + flavor_dict = nova_utils.flavor_formatter(flavor, extra_specs) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid, + 'returnCode': 1} + rsp.update(flavor_dict) + return Response(data=rsp, status=status.HTTP_200_OK) + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + flavors_op = OperateFlavors.OperateFlavors() + flavors_result = flavors_op.list_flavors(data, tenantid) + flavors_dict = [nova_utils.flavor_formatter(flavor, extra) + for flavor, extra in flavors_result] + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'flavors': flavors_dict} + + return Response(data=rsp, status=status.HTTP_200_OK) + + +class FlavorView(APIView): + + def get(self, request, vimid, tenantid, flavorid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + flavors_op = OperateFlavors.OperateFlavors() + flavor, extra_specs = flavors_op.get_flavor(data, tenantid, flavorid) + flavor_dict = nova_utils.flavor_formatter(flavor, extra_specs) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid} + rsp.update(flavor_dict) + return Response(data=rsp, status=status.HTTP_200_OK) + + def delete(self, request, vimid, tenantid, flavorid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + flavors_op = OperateFlavors.OperateFlavors() + flavors_op.delete_flavor(data, tenantid, flavorid) + return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/vio/vio/swagger/views/hypervisor/__init__.py b/vio/vio/swagger/views/hypervisor/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/hypervisor/__init__.py diff --git a/vio/vio/swagger/views/hypervisor/views.py b/vio/vio/swagger/views/hypervisor/views.py new file mode 100644 index 0000000..9019047 --- /dev/null +++ b/vio/vio/swagger/views/hypervisor/views.py @@ -0,0 +1,45 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.nova import OperateHypervisor +from vio.pub.vim.vimapi.nova import OperateServers +from vio.pub.vim.vimapi.nova import OperateService + +from vio.swagger import nova_utils + + +class HostView(APIView): + + def get(self, request, vimid, tenantid, hostname): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + hypervisor_op = OperateHypervisor.OperateHypervisor() + hv = hypervisor_op.get_hypervisor(data, hypervisor=hostname) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid, + 'host': nova_utils.hypervisor_formatter(hv)} + + return Response(data=rsp, status=status.HTTP_200_OK) diff --git a/vio/vio/swagger/views/image/__init__.py b/vio/vio/swagger/views/image/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/image/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/image/views.py b/vio/vio/swagger/views/image/views.py new file mode 100644 index 0000000..7d909f3 --- /dev/null +++ b/vio/vio/swagger/views/image/views.py @@ -0,0 +1,95 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.glance import OperateImage +from vio.swagger import image_utils + + +class GetDeleteImageView(APIView): + + def get(self, request, vimid, tenantid, imageid): + vim_info = extsys.get_vim_by_id(vimid) + image_op = OperateImage.OperateImage(vim_info) + + try: + image = image_op.get_vim_image(imageid) + vim_rsp = image_utils.vim_formatter(vim_info, tenantid) + rsp = image_utils.image_formatter(image) + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, vimid, tenantid, imageid): + vim_info = extsys.get_vim_by_id(vimid) + image_op = OperateImage.OperateImage(vim_info) + + try: + image_op.delete_vim_image(imageid) + return Response(status=status.HTTP_204_NO_CONTENT) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class CreateListImagesView(APIView): + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + query_data = dict(request.query_params) + image_instance = OperateImage.OperateImage(vim_info) + + try: + images = image_instance.get_vim_images(**query_data) + rsp = {} + rsp['images'] = [] + vim_rsp = image_utils.vim_formatter(vim_info, tenantid) + for image in images: + rsp['images'].append(image_utils.image_formatter(image)) + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def post(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + req_body = json.loads(request.body) + vim_rsp = image_utils.vim_formatter(vim_info, tenantid) + image_instance = OperateImage.OperateImage(vim_info) + + try: + images = image_instance.get_vim_images() + for image in images: + if image.name == req_body.get('name'): + image_info = image_instance.get_vim_image(image.id) + rsp = image_utils.image_formatter(image_info) + rsp['returnCode'] = '0' + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + + param = image_utils.req_body_formatter(req_body) + image = image_instance.create_vim_image(vimid, tenantid, **param) + + rsp = image_utils.image_formatter(image) + rsp.update(vim_rsp) + rsp['returnCode'] = '1' + return Response(data=rsp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR)
\ No newline at end of file diff --git a/vio/vio/swagger/views/limits/__init__.py b/vio/vio/swagger/views/limits/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/limits/__init__.py diff --git a/vio/vio/swagger/views/limits/views.py b/vio/vio/swagger/views/limits/views.py new file mode 100644 index 0000000..5122223 --- /dev/null +++ b/vio/vio/swagger/views/limits/views.py @@ -0,0 +1,42 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.nova import OperateLimits +from vio.swagger import nova_utils + + +class LimitsView(APIView): + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + servers_op = OperateLimits.OperateLimits() + server_limits = servers_op.get_limits(data, tenantid) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid} + rsp.update(nova_utils.server_limits_formatter(server_limits)) + + return Response(data=rsp, status=status.HTTP_200_OK) diff --git a/vio/vio/swagger/views/multivim.flavor.swagger.json b/vio/vio/swagger/views/multivim.flavor.swagger.json new file mode 100644 index 0000000..ddc7045 --- /dev/null +++ b/vio/vio/swagger/views/multivim.flavor.swagger.json @@ -0,0 +1,392 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "flavor name to filter list", + "required": false, + "type": "string" + }, + { + "name": "limit", + "in": "query", + "description": "Requests a page size of items", + "required": false, + "type": "string" + }, + { + "name": "marker", + "in": "query", + "description": "image ID of the last-seen item", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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/vio/vio/swagger/views/multivim.host.swagger.json b/vio/vio/swagger/views/multivim.host.swagger.json new file mode 100644 index 0000000..ec797c0 --- /dev/null +++ b/vio/vio/swagger/views/multivim.host.swagger.json @@ -0,0 +1,233 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + } + ], + "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/VimHostDetail" + } + }, + "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" + } + } + }, + "VimHostDetail": { + "type": "object", + "required": [ + "vimId", + "tenantId", + "host" + ], + "properties": { + "host": { + "type": "array", + "description": "list of host information", + "items": { + "$ref": "#/definitions/VimHostResource" + } + }, + "vimId": { + "type": "string" + }, + "vimName": { + "type": "string" + }, + "tenantId": { + "type": "string", + "description": "tenant UUID" + } + } + }, + "VimHostResource": { + "type": "object", + "required": [ + "name", + "cpu", + "memory_mb", + "disk_gb", + "project" + ], + "properties": { + "name": { + "type": "string", + "description": "host name" + }, + "cpu": { + "type": "integer", + "description": "The cpu info on the host" + }, + "memory_mb": { + "type": "integer", + "description": "The memory info on the host (in MB)" + }, + "disk_gb": { + "type": "integer", + "description": "The disk info on the host (in GB)" + }, + "project": { + "type": "string", + "description": "The project id (or special name like total, used_now, used_max)." + } + } + } + } +} diff --git a/vio/vio/swagger/views/multivim.image.swagger.json b/vio/vio/swagger/views/multivim.image.swagger.json new file mode 100644 index 0000000..4604445 --- /dev/null +++ b/vio/vio/swagger/views/multivim.image.swagger.json @@ -0,0 +1,359 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "images name to filter list", + "required": false, + "type": "string" + }, + { + "name": "limit", + "in": "query", + "description": "Requests a page size of items", + "required": false, + "type": "string" + }, + { + "name": "marker", + "in": "query", + "description": "image ID of the last-seen item", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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/vio/vio/swagger/views/multivim.limit.swagger.json b/vio/vio/swagger/views/multivim.limit.swagger.json new file mode 100644 index 0000000..08008cf --- /dev/null +++ b/vio/vio/swagger/views/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 VIO services" + } + ], + "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/vio/vio/swagger/views/multivim.network.swagger.json b/vio/vio/swagger/views/multivim.network.swagger.json new file mode 100644 index 0000000..6a76164 --- /dev/null +++ b/vio/vio/swagger/views/multivim.network.swagger.json @@ -0,0 +1,349 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "network name to filter list", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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/vio/vio/swagger/views/multivim.server.swagger.json b/vio/vio/swagger/views/multivim.server.swagger.json new file mode 100644 index 0000000..d598b48 --- /dev/null +++ b/vio/vio/swagger/views/multivim.server.swagger.json @@ -0,0 +1,488 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "server name to filter list", + "required": false, + "type": "string" + }, + { + "name": "limit", + "in": "query", + "description": "Requests a page size of items", + "required": false, + "type": "string" + }, + { + "name": "marker", + "in": "query", + "description": "image ID of the last-seen item", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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/vio/vio/swagger/views/multivim.subnet.swagger.json b/vio/vio/swagger/views/multivim.subnet.swagger.json new file mode 100644 index 0000000..4c18b13 --- /dev/null +++ b/vio/vio/swagger/views/multivim.subnet.swagger.json @@ -0,0 +1,417 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "subnet name to filter list", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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/vio/vio/swagger/views/multivim.tenant.swagger.json b/vio/vio/swagger/views/multivim.tenant.swagger.json new file mode 100644 index 0000000..75c2c40 --- /dev/null +++ b/vio/vio/swagger/views/multivim.tenant.swagger.json @@ -0,0 +1,102 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "tenant name to filter tenant list", + "required": false, + "type": "string" + } + ], + "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": { + "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" + } + } + } + } +} diff --git a/vio/vio/swagger/views/multivim.volume.swagger.json b/vio/vio/swagger/views/multivim.volume.swagger.json new file mode 100644 index 0000000..6609c90 --- /dev/null +++ b/vio/vio/swagger/views/multivim.volume.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 VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "volumn name to filter list", + "required": false, + "type": "string" + }, + { + "name": "limit", + "in": "query", + "description": "Requests a page size of items", + "required": false, + "type": "string" + }, + { + "name": "marker", + "in": "query", + "description": "image ID of the last-seen item", + "required": false, + "type": "string" + } + ], + "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" + } + } + }, + "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" + } + }, + "status": { + "type": "string", + "description": "volume status" + }, + "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" + }, + "device": { + "type": "string", + "description": "device to be attached" + }, + "hostName": { + "type": "string", + "description": "host name" + } + } + } + } +} diff --git a/vio/vio/swagger/views/multivim.vport.swagger.json b/vio/vio/swagger/views/multivim.vport.swagger.json new file mode 100644 index 0000000..c621150 --- /dev/null +++ b/vio/vio/swagger/views/multivim.vport.swagger.json @@ -0,0 +1,363 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "MultiVIM Service rest API" + }, + "basePath": "/openoapi/multivim/v1/", + "tags": [ + { + "name": "MultiVIM VIO services" + } + ], + "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" + }, + { + "name": "name", + "in": "query", + "description": "virtual port name to filter list", + "required": false, + "type": "string" + } + ], + "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", + "name" + ], + "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" + } + } + } + }, + "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" + ], + "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/vio/vio/swagger/views/network/__init__.py b/vio/vio/swagger/views/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/network/__init__.py diff --git a/vio/vio/swagger/views/network/views.py b/vio/vio/swagger/views/network/views.py new file mode 100644 index 0000000..cb7adfe --- /dev/null +++ b/vio/vio/swagger/views/network/views.py @@ -0,0 +1,76 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging +import json + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.utils import syscomm +from vio.pub.vim.vimapi.network import OperateNetwork + +logger = logging.getLogger(__name__) + + +class CreateNetworkView(APIView): + def post(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + net = OperateNetwork.OperateNetwork() + body = json.loads(request.body) + try: + resp = net.create_network(vimid, tenantid, body) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def get(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + net = OperateNetwork.OperateNetwork() + try: + resp = net.list_networks(vimid, tenantid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +class DeleteNetworkView(APIView): + + def get(self, request, vimid, tenantid, networkid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + net = OperateNetwork.OperateNetwork() + try: + resp = net.list_network(vimid, tenantid, networkid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, vimid, tenantid, networkid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + net = OperateNetwork.OperateNetwork() + try: + resp = net.delete_network(vimid, tenantid, networkid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + diff --git a/vio/vio/swagger/views/port/__init__.py b/vio/vio/swagger/views/port/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/port/__init__.py diff --git a/vio/vio/swagger/views/port/views.py b/vio/vio/swagger/views/port/views.py new file mode 100644 index 0000000..9a4af3f --- /dev/null +++ b/vio/vio/swagger/views/port/views.py @@ -0,0 +1,76 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging +import json + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.utils import syscomm +from vio.pub.vim.vimapi.network import OperatePort + +logger = logging.getLogger(__name__) + + +class CreatePortView(APIView): + def post(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + port = OperatePort.OperatePort() + body = json.loads(request.body) + try: + resp = port.create_port(vimid, tenantid, body) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def get(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + port = OperatePort.OperatePort() + try: + resp = port.list_ports(vimid, tenantid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +class DeletePortView(APIView): + + def get(self, request, vimid, tenantid, portid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + port = OperatePort.OperatePort() + try: + resp = port.list_port(vimid, tenantid, portid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, vimid, tenantid, portid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + port = OperatePort.OperatePort() + try: + resp = port.delete_port(vimid, tenantid, portid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + diff --git a/vio/vio/swagger/views/server/__init__.py b/vio/vio/swagger/views/server/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/server/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/server/views.py b/vio/vio/swagger/views/server/views.py new file mode 100644 index 0000000..3348754 --- /dev/null +++ b/vio/vio/swagger/views/server/views.py @@ -0,0 +1,111 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +import json +import logging + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.nova import OperateServers +from vio.swagger import nova_utils + +logger = logging.getLogger(__name__) + + +class ListServersView(APIView): + + def post(self, request, vimid, tenantid): + create_req = json.loads(request.body) + + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + servers_op = OperateServers.OperateServers() + try: + server = servers_op.create_server(data, tenantid, create_req) + except Exception as ex: + return Response(data=str(ex), + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + server_dict = nova_utils.server_formatter(server) + + rsp = {'vimId': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid} + rsp.update(server_dict) + return Response(data=rsp, status=status.HTTP_200_OK) + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + servers_op = OperateServers.OperateServers() + servers = servers_op.list_servers(data, tenantid) + + servers_resp = [] + for server in servers: + intfs = servers_op.list_server_interfaces(data, tenantid, server) + servers_resp.append(nova_utils.server_formatter( + server, interfaces=intfs)) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'servers': servers_resp} + + return Response(data=rsp, status=status.HTTP_200_OK) + + +class GetServerView(APIView): + + def get(self, request, vimid, tenantid, serverid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + servers_op = OperateServers.OperateServers() + server = servers_op.get_server(data, tenantid, serverid) + intfs = servers_op.list_server_interfaces(data, tenantid, server) + server_dict = nova_utils.server_formatter(server, interfaces=intfs) + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid} + rsp.update(server_dict) + + return Response(data=rsp, status=status.HTTP_200_OK) + + def delete(self, request, vimid, tenantid, serverid): + servers_op = OperateServers.OperateServers() + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + servers_op.delete_server(data, tenantid, serverid) + return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/vio/vio/swagger/views/service/__init__.py b/vio/vio/swagger/views/service/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/service/__init__.py diff --git a/vio/vio/swagger/views/service/views.py b/vio/vio/swagger/views/service/views.py new file mode 100644 index 0000000..535f2d2 --- /dev/null +++ b/vio/vio/swagger/views/service/views.py @@ -0,0 +1,44 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.nova import OperateServers +from vio.pub.vim.vimapi.nova import OperateService + +from vio.swagger import nova_utils + + +class HostsView(APIView): + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + data = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'username': vim_info['userName'], + 'password': vim_info['password'], + 'url': vim_info['url'], + 'project_name': vim_info['tenant']} + + services_op = OperateService.OperateService() + + rsp = {'vimid': vim_info['vimId'], + 'vimName': vim_info['name'], + 'tenantId': tenantid, + 'hosts': [nova_utils.service_formatter(svc) + for svc in services_op.list_services(data, tenantid)]} + + return Response(data=rsp, status=status.HTTP_200_OK) diff --git a/vio/vio/swagger/views/subnet/__init__.py b/vio/vio/swagger/views/subnet/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vio/vio/swagger/views/subnet/__init__.py diff --git a/vio/vio/swagger/views/subnet/views.py b/vio/vio/swagger/views/subnet/views.py new file mode 100644 index 0000000..f95da54 --- /dev/null +++ b/vio/vio/swagger/views/subnet/views.py @@ -0,0 +1,76 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +import logging +import json + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.utils import syscomm +from vio.pub.vim.vimapi.network import OperateSubnet + +logger = logging.getLogger(__name__) + + +class CreateSubnetView(APIView): + def post(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + subnet = OperateSubnet.OperateSubnet() + body = json.loads(request.body) + try: + resp = subnet.create_subnet(vimid, tenantid, body) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def get(self, request, vimid, tenantid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + subnet = OperateSubnet.OperateSubnet() + try: + resp = subnet.list_subnets(vimid, tenantid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +class DeleteSubnetView(APIView): + + def get(self, request, vimid, tenantid, subnetid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + subnet = OperateSubnet.OperateSubnet() + try: + resp = subnet.list_subnet(vimid, tenantid, subnetid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, vimid, tenantid, subnetid): + logger.info("Enter %s, method is %s, vim_id is %s", + syscomm.fun_name(), request.method, vimid) + subnet = OperateSubnet.OperateSubnet() + try: + resp = subnet.delete_subnet(vimid, tenantid, subnetid) + return Response(data=resp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + diff --git a/vio/vio/swagger/views/swagger_json.py b/vio/vio/swagger/views/swagger_json.py new file mode 100644 index 0000000..cf401b5 --- /dev/null +++ b/vio/vio/swagger/views/swagger_json.py @@ -0,0 +1,87 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +import json +import logging +import os + +from rest_framework.response import Response +from rest_framework.views import APIView + + +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-vio/v1/" + json_data["info"]["title"] = "MultiVIM driver of OpenStack VIO Service NBI" + return Response(json_data) diff --git a/vio/vio/swagger/views/tenant/__init__.py b/vio/vio/swagger/views/tenant/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/tenant/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/tenant/views.py b/vio/vio/swagger/views/tenant/views.py new file mode 100644 index 0000000..13bce23 --- /dev/null +++ b/vio/vio/swagger/views/tenant/views.py @@ -0,0 +1,51 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +import logging + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.keystone import OperateTenant + +logger = logging.getLogger(__name__) + + +class ListTenantsView(APIView): + def get(self, request, vimid): + vim_info = extsys.get_vim_by_id(vimid) + + data = {} + data['vimid'] = vim_info['vimId'] + data['vimName'] = vim_info['name'] + data['username'] = vim_info['userName'] + data['password'] = vim_info['password'] + data['url'] = vim_info['url'] + data['project_name'] = vim_info['tenant'] + + tenant_instance = OperateTenant.OperateTenant() + projects = tenant_instance.get_projects(data) + + rsp = {} + rsp['vimid'] = vim_info['vimId'] + rsp['vimName'] = vim_info['name'] + rsp['tenants'] = [] + + for project in projects: + tenant = {} + tenant['id'] = project.id + tenant['name'] = project.name + rsp['tenants'].append(tenant) + return Response(data=rsp, status=status.HTTP_200_OK) diff --git a/vio/vio/swagger/views/volume/__init__.py b/vio/vio/swagger/views/volume/__init__.py new file mode 100644 index 0000000..a8fe66a --- /dev/null +++ b/vio/vio/swagger/views/volume/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/vio/vio/swagger/views/volume/views.py b/vio/vio/swagger/views/volume/views.py new file mode 100644 index 0000000..91f79f0 --- /dev/null +++ b/vio/vio/swagger/views/volume/views.py @@ -0,0 +1,106 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +import json +import logging + +from rest_framework import status +from rest_framework.response import Response +from rest_framework.views import APIView + +from vio.pub.msapi import extsys +from vio.pub.vim.vimapi.cinder import OperateVolume + +from vio.swagger import volume_utils + +logger = logging.getLogger(__name__) + + +class GetDeleteVolumeView(APIView): + + def get(self, request, vimid, tenantid, volumeid): + vim_info = extsys.get_vim_by_id(vimid) + volume_op = OperateVolume.OperateVolume(vim_info) + + try: + volume = volume_op.get_vim_volume(volumeid) + vim_rsp = volume_utils.vim_formatter(vim_info, tenantid) + rsp = volume_utils.volume_formatter(volume) + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, vimid, tenantid, volumeid): + vim_info = extsys.get_vim_by_id(vimid) + volume_op = OperateVolume.OperateVolume(vim_info) + + try: + volume_op.delete_vim_volume(volumeid) + return Response(status=status.HTTP_204_NO_CONTENT) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +class CreateListVolumeView(APIView): + + def get(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + query_data = dict(request.query_params) + volume_op = OperateVolume.OperateVolume(vim_info) + + try: + volumes = volume_op.get_vim_volumes(**query_data) + rsp = {} + rsp['volumes'] = [] + + vim_rsp = volume_utils.vim_formatter(vim_info, tenantid) + for volume in volumes: + volume_info = volume_op.get_vim_volume(volume.id) + rsp['volumes'].append(volume_utils.volume_formatter(volume_info)) + + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + def post(self, request, vimid, tenantid): + vim_info = extsys.get_vim_by_id(vimid) + volume_op = OperateVolume.OperateVolume(vim_info) + + try: + volumes_detail = volume_op.get_vim_volumes() + json_body = json.loads(request.body) + + vim_rsp = volume_utils.vim_formatter(vim_info, tenantid) + for volume in volumes_detail: + if volume.name == json_body.get('name'): + volume_info = volume_op.get_vim_volume(volume.id) + rsp = volume_utils.volume_formatter(volume_info) + rsp['returnCode'] = 0 + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_200_OK) + + param = volume_utils.req_body_formatter(json_body) + volume_info = volume_op.create_vim_volume(**param) + rsp = volume_utils.volume_formatter(volume_info) + rsp['returnCode'] = 1 + rsp.update(vim_rsp) + return Response(data=rsp, status=status.HTTP_202_ACCEPTED) + except Exception as e: + return Response(data={'error': str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR)
\ No newline at end of file diff --git a/vio/vio/swagger/volume_utils.py b/vio/vio/swagger/volume_utils.py new file mode 100644 index 0000000..562a381 --- /dev/null +++ b/vio/vio/swagger/volume_utils.py @@ -0,0 +1,68 @@ +# Copyright (c) 2017 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: + +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + +def volume_formatter(volume): + + attachments = [] + for attach in volume.attachments: + vim_attach = { + 'device' : attach['device'], + 'volumeId' : attach['volume_id'], + 'hostName' : attach['host_name'], + 'Id' : attach['attachment_id'], + 'serverId' : attach['server_id'] + } + attachments.append(vim_attach) + + return { + 'id' : volume.id, + 'name' : volume.name, + 'createTime' : volume.created_at, + 'status' : volume.status, + 'type' : volume.volume_type, + 'size' : volume.size, + 'availabilityZone' : volume.availability_zone, + 'attachments' : attachments + } + + +def vim_formatter(vim_info, tenantid): + + rsp = {} + rsp['vimId'] = vim_info.get('vimId') + rsp['vimName'] = vim_info.get('name') + rsp['tenantId'] = tenantid + return rsp + + +def sdk_param_formatter(data): + + param = {} + param['username'] = data.get('userName') + param['password'] = data.get('password') + param['auth_url'] = data.get('url') + param['project_name'] = data.get('tenant') + param['user_domain_name'] = 'default' + param['project_domain_name'] = 'default' + return param + + +def req_body_formatter(body): + + param = {} + param['size'] = body.get('volumeSize') + param['volume_type'] = body.get('volumeType') + param['name'] = body.get('name') + param['availability_zone'] = body.get('availabilityZone') + param['image_id'] = body.get('imageName') + return param |