Revert "Removing deprecated/unused/outdated code" 12/10612/1
authorsousaedu <eduardo.sousa@canonical.com>
Fri, 9 Apr 2021 16:03:02 +0000 (18:03 +0200)
committersousaedu <eduardo.sousa@canonical.com>
Fri, 9 Apr 2021 16:03:22 +0000 (18:03 +0200)
This reverts commit 9f40121f66e644ddf700720d8d4bdf464f6dd414.

Change-Id: I3a414c4f253285c87b662af89ec418b762c0c44b
Signed-off-by: sousaedu <eduardo.sousa@canonical.com>
187 files changed:
RO-client/Makefile [new file with mode: 0644]
RO-client/README.rst [new file with mode: 0644]
RO-client/debian/python3-osm-roclient.postinst [new file with mode: 0755]
RO-client/osm_roclient/roclient.py [new file with mode: 0755]
RO-client/requirements.txt [new file with mode: 0644]
RO-client/setup.py [new file with mode: 0644]
RO-client/stdeb.cfg [new file with mode: 0644]
RO-client/tox.ini [new file with mode: 0644]
RO/MANIFEST.in [new file with mode: 0644]
RO/Makefile [new file with mode: 0644]
RO/README.rst [new file with mode: 0644]
RO/debian/python3-osm-ro.postinst [new file with mode: 0755]
RO/osm_ro/__init__.py [new file with mode: 0644]
RO/osm_ro/console_proxy_thread.py [new file with mode: 0644]
RO/osm_ro/database_utils/dump_db.sh [new file with mode: 0755]
RO/osm_ro/database_utils/init_mano_db.sh [new file with mode: 0755]
RO/osm_ro/database_utils/install-db-server.sh [new file with mode: 0755]
RO/osm_ro/database_utils/mano_db_structure.sql [new file with mode: 0644]
RO/osm_ro/database_utils/migrate_mano_db.sh [new file with mode: 0755]
RO/osm_ro/database_utils/migrations/down/34_remove_wim_tables.sql [new file with mode: 0644]
RO/osm_ro/database_utils/migrations/down/35_remove_sfc_ingress_and_egress.sql [new file with mode: 0644]
RO/osm_ro/database_utils/migrations/up/34_add_wim_tables.sql [new file with mode: 0644]
RO/osm_ro/database_utils/migrations/up/35_add_sfc_ingress_and_egress.sql [new file with mode: 0644]
RO/osm_ro/db_base.py [new file with mode: 0644]
RO/osm_ro/http_tools/__init__.py [new file with mode: 0644]
RO/osm_ro/http_tools/errors.py [new file with mode: 0644]
RO/osm_ro/http_tools/handler.py [new file with mode: 0644]
RO/osm_ro/http_tools/request_processing.py [new file with mode: 0644]
RO/osm_ro/http_tools/tests/__init__.py [new file with mode: 0644]
RO/osm_ro/http_tools/tests/test_errors.py [new file with mode: 0644]
RO/osm_ro/http_tools/tests/test_handler.py [new file with mode: 0644]
RO/osm_ro/http_tools/tox.ini [new file with mode: 0644]
RO/osm_ro/httpserver.py [new file with mode: 0644]
RO/osm_ro/nfvo.py [new file with mode: 0644]
RO/osm_ro/nfvo_db.py [new file with mode: 0644]
RO/osm_ro/openmano_schemas.py [new file with mode: 0644]
RO/osm_ro/openmanoclient.py [new file with mode: 0644]
RO/osm_ro/openmanod.cfg [new file with mode: 0644]
RO/osm_ro/openmanod.py [new file with mode: 0755]
RO/osm_ro/osm-ro.service [new file with mode: 0644]
RO/osm_ro/scripts/RO-of [new file with mode: 0755]
RO/osm_ro/scripts/RO-start.sh [new file with mode: 0755]
RO/osm_ro/scripts/get-options.sh [new file with mode: 0644]
RO/osm_ro/scripts/install-lib-osm-openvim.sh [new file with mode: 0755]
RO/osm_ro/scripts/install-openmano-service.sh [new file with mode: 0755]
RO/osm_ro/scripts/install-openmano.sh [new file with mode: 0755]
RO/osm_ro/scripts/install-osm-im.sh [new file with mode: 0755]
RO/osm_ro/scripts/openmano-report [new file with mode: 0755]
RO/osm_ro/scripts/service-openmano [new file with mode: 0755]
RO/osm_ro/sdn.py [new file with mode: 0755]
RO/osm_ro/tests/__init__.py [new file with mode: 0644]
RO/osm_ro/tests/db_helpers.py [new file with mode: 0644]
RO/osm_ro/tests/helpers.py [new file with mode: 0644]
RO/osm_ro/tests/test_db.py [new file with mode: 0644]
RO/osm_ro/tests/test_utils.py [new file with mode: 0644]
RO/osm_ro/utils.py [new file with mode: 0644]
RO/osm_ro/vim_thread.py [new file with mode: 0644]
RO/osm_ro/vmwarecli.py [new file with mode: 0755]
RO/osm_ro/wim/__init__.py [new file with mode: 0644]
RO/osm_ro/wim/actions.py [new file with mode: 0644]
RO/osm_ro/wim/engine.py [new file with mode: 0644]
RO/osm_ro/wim/errors.py [new file with mode: 0644]
RO/osm_ro/wim/http_handler.py [new file with mode: 0644]
RO/osm_ro/wim/persistence.py [new file with mode: 0644]
RO/osm_ro/wim/schemas.py [new file with mode: 0644]
RO/osm_ro/wim/tests/__init__.py [new file with mode: 0644]
RO/osm_ro/wim/tests/fixtures.py [new file with mode: 0644]
RO/osm_ro/wim/tests/test_actions.py [new file with mode: 0644]
RO/osm_ro/wim/tests/test_engine.py [new file with mode: 0644]
RO/osm_ro/wim/tests/test_http_handler.py [new file with mode: 0644]
RO/osm_ro/wim/tests/test_persistence.py [new file with mode: 0644]
RO/osm_ro/wim/tests/test_wim_thread.py [new file with mode: 0644]
RO/osm_ro/wim/tox.ini [new file with mode: 0644]
RO/osm_ro/wim/wan_link_actions.py [new file with mode: 0644]
RO/osm_ro/wim/wim_thread.py [new file with mode: 0644]
RO/osm_ro/wim/wimconn_odl.py [new file with mode: 0644]
RO/requirements.txt [new file with mode: 0644]
RO/setup.py [new file with mode: 0755]
RO/stdeb.cfg [new file with mode: 0644]
RO/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml [new file with mode: 0644]
RO/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml [new file with mode: 0644]
RO/test/RO_tests/empy_volume/scenario_additional_disk_empty_volume.yaml [new file with mode: 0644]
RO/test/RO_tests/empy_volume/vnfd_additional_disk_empty_volume.yaml [new file with mode: 0644]
RO/test/RO_tests/floating_ip/scenario_floating_ip.yaml [new file with mode: 0644]
RO/test/RO_tests/floating_ip/vnfd_floating_ip.yaml [new file with mode: 0644]
RO/test/RO_tests/image_based_volume/scenario_additional_disk_based_image.yaml [new file with mode: 0644]
RO/test/RO_tests/image_based_volume/vnfd_additional_disk_based_image.yaml [new file with mode: 0644]
RO/test/RO_tests/no_port_security/scenario_vnf_no_port_security.yaml [new file with mode: 0644]
RO/test/RO_tests/no_port_security/vnfd_no_port_security.yaml [new file with mode: 0644]
RO/test/RO_tests/passthrough/scenario_p2p_passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/passthrough/vnfd_1passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_passthrough/scenario_pmp_passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_passthrough/vnfd_1passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_sriov/scenario_pmp_sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_sriov/vnfd_1sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_sriov_passthrough/scenario_pmp_sriov_passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/pmp_sriov_passthrough/vnfd_1sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_2_vnf/scenario_simple_2_vnf.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_2_vnf/vnfd_linux.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_cloud_init/scenario_simple-cloud-init.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_cloud_init/vnfd_linux-cloud-init.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_count3/scenario_linux_count3.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_count3/vnfd_count3.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_linux/scenario_simple_linux.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_linux/vnfd_linux.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_multi_vnfc/scenario_multi_vnfc.yaml [new file with mode: 0644]
RO/test/RO_tests/simple_multi_vnfc/vnfd_linux_2VMs_v02.yaml [new file with mode: 0644]
RO/test/RO_tests/sr_iov/scenario_p2p_sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/sr_iov/vnfd_1sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/sriov_passthrough/scenario_p2p_sriov_passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/sriov_passthrough/vnfd_1passthrough.yaml [new file with mode: 0644]
RO/test/RO_tests/sriov_passthrough/vnfd_1sriov.yaml [new file with mode: 0644]
RO/test/RO_tests/v3_2vdu_set_ip_mac/scenario_2vdu_set_ip_mac.yaml [new file with mode: 0644]
RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac.yaml [new file with mode: 0644]
RO/test/RO_tests/v3_2vdu_set_ip_mac/vnfd_2vdu_set_ip_mac2.yaml [new file with mode: 0644]
RO/test/basictest.sh [new file with mode: 0755]
RO/test/test-multivim.sh [new file with mode: 0755]
RO/test/test_RO.py [new file with mode: 0755]
RO/test/test_on_container.sh [new file with mode: 0755]
RO/test/test_openmanocli.sh [new file with mode: 0755]
RO/test/test_openmanoclient.py [new file with mode: 0755]
RO/test/test_osconnector.py [new file with mode: 0755]
RO/test/test_vimconn.sh [new file with mode: 0755]
RO/tox.ini [new file with mode: 0644]
charms/.gitignore [new file with mode: 0644]
charms/README.md [new file with mode: 0644]
charms/layers/openmano/README.md [new file with mode: 0644]
charms/layers/openmano/config.yaml [new file with mode: 0644]
charms/layers/openmano/icon.svg [new file with mode: 0644]
charms/layers/openmano/layer.yaml [new file with mode: 0644]
charms/layers/openmano/metadata.yaml [new file with mode: 0644]
charms/layers/openmano/reactive/layer_openmano.py [new file with mode: 0644]
charms/layers/openmano/scripts/create-datacenter.sh [new file with mode: 0755]
charms/layers/openmano/scripts/create-tenant.sh [new file with mode: 0755]
charms/layers/openmano/scripts/init_mano_db.sh [new file with mode: 0755]
charms/layers/openmano/templates/openmanod.cfg [new file with mode: 0644]
charms/layers/openmano/tests/00-setup [new file with mode: 0755]
charms/layers/openmano/tests/10-deploy [new file with mode: 0755]
deprecated/vmwarerecli.py [new file with mode: 0755]
docker/Dockerfile-fromdeb [new file with mode: 0644]
docker/docker-compose-3c.yml [new file with mode: 0644]
docker/docker-compose.yaml [new file with mode: 0644]
docker/tests.dockerfile [new file with mode: 0644]
docker/tests.yml [new file with mode: 0644]
instance-scenarios/examples/instance-creation-complex2.yaml [new file with mode: 0644]
instance-scenarios/examples/instance-creation-complex4.yaml [new file with mode: 0644]
scenarios/examples/complex.yaml [new file with mode: 0644]
scenarios/examples/complex2.yaml [new file with mode: 0644]
scenarios/examples/complex3.yaml [new file with mode: 0644]
scenarios/examples/complex4.yaml [new file with mode: 0644]
scenarios/examples/complex5.yaml [new file with mode: 0644]
scenarios/examples/scenario_vnf_additional_disk_based_image.yaml [new file with mode: 0644]
scenarios/examples/scenario_vnf_additional_disk_empty_volume.yaml [new file with mode: 0644]
scenarios/examples/scenario_vnf_floating_ip.yaml [new file with mode: 0644]
scenarios/examples/scenario_vnf_no_additional_devices.yaml [new file with mode: 0644]
scenarios/examples/scenario_vnf_no_port_security.yaml [new file with mode: 0644]
scenarios/examples/simple-cloud-init.yaml [new file with mode: 0644]
scenarios/examples/simple.yaml [new file with mode: 0644]
scenarios/examples/v3_2linux_sriov.yaml [new file with mode: 0644]
scenarios/examples/v3_3vdu_2vnf_nsd.yaml [new file with mode: 0644]
scenarios/examples/v3_3vnf_2vdu_1vnffg_nsd.yaml [new file with mode: 0644]
scenarios/scenario-template.yaml [new file with mode: 0644]
scenarios/scenario-template2.yaml [new file with mode: 0644]
sdn/sdn_port_mapping.yaml [new file with mode: 0644]
test-docker/Dockerfile-devops [new file with mode: 0644]
test-docker/test-gen-devops.sh [new file with mode: 0755]
test-docker/test-gen-local.sh [new file with mode: 0755]
vnfs/examples/dataplaneVNF1.yaml [new file with mode: 0644]
vnfs/examples/dataplaneVNF2.yaml [new file with mode: 0644]
vnfs/examples/dataplaneVNF3.yaml [new file with mode: 0644]
vnfs/examples/dataplaneVNF4.yaml [new file with mode: 0644]
vnfs/examples/dataplaneVNF_2VMs.yaml [new file with mode: 0644]
vnfs/examples/dataplaneVNF_2VMs_v02.yaml [new file with mode: 0644]
vnfs/examples/linux-cloud-init.yaml [new file with mode: 0644]
vnfs/examples/linux.yaml [new file with mode: 0644]
vnfs/examples/linux_2VMs_v02.yaml [new file with mode: 0644]
vnfs/examples/v3_2vdu_vnfd.yaml [new file with mode: 0644]
vnfs/examples/v3_3vdu_vnfd.yaml [new file with mode: 0644]
vnfs/examples/v3_linux_sriov.yaml [new file with mode: 0644]
vnfs/examples/vnf_additional_disk_based_image.yaml [new file with mode: 0644]
vnfs/examples/vnf_additional_disk_empty_volume.yaml [new file with mode: 0644]
vnfs/examples/vnf_floating_ip.yaml [new file with mode: 0644]
vnfs/examples/vnf_no_additional_devices.yaml [new file with mode: 0644]
vnfs/examples/vnf_no_port_security.yaml [new file with mode: 0644]
vnfs/vnf-template-2vm.yaml [new file with mode: 0644]
vnfs/vnf-template.yaml [new file with mode: 0644]

diff --git a/RO-client/Makefile b/RO-client/Makefile
new file mode 100644 (file)
index 0000000..e689ad6
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright 2018 Telefonica S.A.
+#
+# 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.
+
+all: clean package
+
+clean:
+       rm -rf dist deb_dist osm_roclient-*.tar.gz osm_roclient.egg-info .eggs
+
+package:
+       python3 setup.py --command-packages=stdeb.command sdist_dsc
+       cp debian/python3-osm-roclient.postinst deb_dist/osm-roclient*/debian/
+       cd deb_dist/osm-roclient*/ && dpkg-buildpackage -rfakeroot -uc -us
+
diff --git a/RO-client/README.rst b/RO-client/README.rst
new file mode 100644 (file)
index 0000000..9b60216
--- /dev/null
@@ -0,0 +1,20 @@
+ Copyright 2018 Telefonica S.A.
+ 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.
+
+============
+osm-roclient
+============
+
+osm-roclient is a client for interact with osm-ro server
+
diff --git a/RO-client/debian/python3-osm-roclient.postinst b/RO-client/debian/python3-osm-roclient.postinst
new file mode 100755 (executable)
index 0000000..1814b31
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+##
+# 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.
+##
+
+
+#configure arg-autocomplete for RO-client
+[ -z "$SUDO_USER" ] && SUDO_USER="$USER"
+su $SUDO_USER -c 'activate-global-python-argcomplete3 --user'
+if ! su  $SUDO_USER -c 'grep -q bash_completion.d/python-argcomplete.sh ${HOME}/.bashrc'
+then
+    echo "    inserting .bash_completion.d/python-argcomplete.sh execution at .bashrc"
+    su $SUDO_USER -c 'echo ". ${HOME}/.bash_completion.d/python-argcomplete.sh" >> ~/.bashrc'
+fi
+
diff --git a/RO-client/osm_roclient/roclient.py b/RO-client/osm_roclient/roclient.py
new file mode 100755 (executable)
index 0000000..b2eb3ff
--- /dev/null
@@ -0,0 +1,2520 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# PYTHON_ARGCOMPLETE_OK
+
+##
+# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+"""
+openmano client used to interact with openmano-server (openmanod)
+"""
+__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
+__date__ = "$09-oct-2014 09:09:48$"
+__version__ = "0.5.0"
+version_date = "2019-010-04"
+
+from argcomplete.completers import FilesCompleter
+import os
+import argparse
+import argcomplete
+import requests
+import json
+import yaml
+import logging
+#from jsonschema import validate as js_v, exceptions as js_e
+
+
+class ArgumentParserError(Exception):
+    pass
+
+
+class OpenmanoCLIError(Exception):
+    pass
+
+
+class ThrowingArgumentParser(argparse.ArgumentParser):
+    def error(self, message):
+        print("Error: {}".format(message))
+        print()
+        self.print_usage()
+        #self.print_help()
+        print()
+        print("Type 'openmano -h' for help")
+        raise ArgumentParserError
+
+
+def config(args):
+    print("OPENMANO_HOST: {}".format(mano_host))
+    print("OPENMANO_PORT: {}".format(mano_port))
+    if args.n:
+        logger.debug("resolving tenant and datacenter names")
+        mano_tenant_id = "None"
+        mano_tenant_name = "None"
+        mano_datacenter_id = "None"
+        mano_datacenter_name = "None"
+        # WIM additions
+        logger.debug("resolving WIM names")
+        mano_wim_id = "None"
+        mano_wim_name = "None"
+        try:
+            mano_tenant_id = _get_item_uuid("tenants", mano_tenant)
+            URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, mano_tenant_id)
+            mano_response = requests.get(URLrequest)
+            logger.debug("openmano response: %s", mano_response.text )
+            content = mano_response.json()
+            mano_tenant_name = content["tenant"]["name"]
+            URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, mano_tenant_id,
+                                                                          mano_datacenter)
+            mano_response = requests.get(URLrequest)
+            logger.debug("openmano response: %s", mano_response.text)
+            content = mano_response.json()
+            if "error" not in content:
+                mano_datacenter_id = content["datacenter"]["uuid"]
+                mano_datacenter_name = content["datacenter"]["name"]
+
+            # WIM
+            URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(
+            mano_host, mano_port, mano_tenant_id, mano_wim)
+            mano_response = requests.get(URLrequest)
+            logger.debug("openmano response: %s", mano_response.text)
+            content = mano_response.json()
+            if "error" not in content:
+                mano_wim_id = content["wim"]["uuid"]
+                mano_wim_name = content["wim"]["name"]
+
+        except OpenmanoCLIError:
+            pass
+        print( "OPENMANO_TENANT: {}".format(mano_tenant))
+        print( "    Id: {}".format(mano_tenant_id))
+        print( "    Name: {}".format(mano_tenant_name))
+        print( "OPENMANO_DATACENTER: {}".format(mano_datacenter))
+        print( "    Id: {}".format(mano_datacenter_id))
+        print( "    Name: {}".format(mano_datacenter_name))
+        # WIM
+        print( "OPENMANO_WIM: {}".format( (mano_wim)))
+        print( "    Id: {}".format(mano_wim_id))
+        print( "    Name: {}".format(mano_wim_name))
+
+    else:
+        print("OPENMANO_TENANT: {}".format(mano_tenant))
+        print("OPENMANO_DATACENTER: {}".format(mano_datacenter))
+        # WIM
+        print("OPENMANO_WIM: {}".format(mano_wim))
+
+def _print_verbose(mano_response, verbose_level=0):
+    content = mano_response.json()
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    if type(content)!=dict or len(content)!=1:
+        # print("Non expected format output")
+        print(str(content))
+        return result
+
+    val = next(iter(content.values()))
+    if type(val)==str:
+        print(val)
+        return result
+    elif type(val) == list:
+        content_list = val
+    elif type(val)==dict:
+        content_list = [val]
+    else:
+        # print("Non expected dict/list format output"
+        print(str(content))
+        return result
+
+    # print(content_list
+    if verbose_level==None:
+        verbose_level=0
+    if verbose_level >= 3:
+        print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+        return result
+
+    if mano_response.status_code == 200:
+        uuid = None
+        for content in content_list:
+            if "uuid" in content:
+                uuid = content['uuid']
+            elif "id" in content:
+                uuid = content['id']
+            elif "vim_id" in content:
+                uuid = content['vim_id']
+            name = content.get('name');
+            if not uuid:
+                uuid = ""
+            if not name:
+                name = ""
+            myoutput = "{:38} {:20}".format(uuid, name)
+            if content.get("status"):
+                myoutput += " {:20}".format(content['status'])
+            elif "enabled" in content and not content["enabled"]:
+                myoutput += " enabled=False".ljust(20)
+            if verbose_level >=1:
+                if content.get('created_at'):
+                    myoutput += " {:20}".format(content['created_at'])
+                if content.get('sdn_attached_ports'):
+                    #myoutput += " " + str(content['sdn_attached_ports']).ljust(20)
+                    myoutput += "\nsdn_attached_ports:\n" + yaml.safe_dump(content['sdn_attached_ports'], indent=4, default_flow_style=False)
+                if verbose_level >=2:
+                    new_line='\n'
+                    if content.get('type'):
+                        myoutput += new_line + "  Type: {:29}".format(content['type'])
+                        new_line=''
+                    if content.get('description'):
+                        myoutput += new_line + "  Description: {:20}".format(content['description'])
+            print(myoutput)
+    else:
+        print(content['error']['description'])
+    return result
+
+def parser_json_yaml(file_name):
+    try:
+        with open(file_name, "r") as f:
+            text = f.read()
+    except Exception as e:
+        return (False, str(e))
+
+    #Read and parse file
+    if file_name[-5:]=='.yaml' or file_name[-4:]=='.yml' or (file_name[-5:]!='.json' and '\t' not in text):
+        try:
+            config = yaml.load(text, Loader=yaml.SafeLoader)
+        except yaml.YAMLError as exc:
+            error_pos = ""
+            if hasattr(exc, 'problem_mark'):
+                mark = exc.problem_mark
+                error_pos = " at line:{} column:{}".format(mark.line+1, mark.column+1)
+            return (False, "Error loading file '"+file_name+"' yaml format error" + error_pos)
+    else: #json
+        try:
+            config = json.loads(text)
+        except Exception as e:
+            return (False, "Error loading file '"+file_name+"' json format error " + str(e) )
+    return True, config
+
+def _load_file_or_yaml(content):
+    '''
+    'content' can be or a yaml/json file or a text containing a yaml/json text format
+    This function autodetect, trying to load and parse the file,
+    if fails trying to parse the 'content' text
+    Returns the dictionary once parsed, or print an error and finish the program
+    '''
+    #Check config file exists
+    if os.path.isfile(content):
+        r,payload = parser_json_yaml(content)
+        if not r:
+            print(payload)
+            exit(-1)
+    elif "{" in content or ":" in content:
+        try:
+            payload = yaml.load(content)
+        except yaml.YAMLError as exc:
+            error_pos = ""
+            if hasattr(exc, 'problem_mark'):
+                mark = exc.problem_mark
+                error_pos = " at position: ({}:{})".format(mark.line+1, mark.column+1)
+            print("Error loading yaml/json text"+error_pos)
+            exit (-1)
+    else:
+        print("'{}' is neither a valid file nor a yaml/json content".format(content))
+        exit(-1)
+    return payload
+
+def _get_item_uuid(item, item_name_id, tenant=None):
+    if tenant:
+        URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, tenant, item)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}".format(mano_host, mano_port, item)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    content = mano_response.json()
+    # print(content
+    found = 0
+    for i in content[item]:
+        if i["uuid"] == item_name_id:
+            return item_name_id
+        if i["name"] == item_name_id:
+            uuid = i["uuid"]
+            found += 1
+        if item_name_id.startswith("osm_id=") and i.get("osm_id") == item_name_id[7:]:
+            uuid = i["uuid"]
+            found += 1
+    if found == 0:
+        raise OpenmanoCLIError("No {} found with name/uuid '{}'".format(item[:-1], item_name_id))
+    elif found > 1:
+        raise OpenmanoCLIError("{} {} found with name '{}'. uuid must be used".format(found, item, item_name_id))
+    return uuid
+#
+# def check_valid_uuid(uuid):
+#     id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
+#     try:
+#         js_v(uuid, id_schema)
+#         return True
+#     except js_e.ValidationError:
+#         return False
+
+def _get_tenant(tenant_name_id = None):
+    if not tenant_name_id:
+        tenant_name_id = mano_tenant
+        if not mano_tenant:
+            raise OpenmanoCLIError("'OPENMANO_TENANT' environment variable is not set")
+    return _get_item_uuid("tenants", tenant_name_id)
+
+def _get_datacenter(datacenter_name_id = None, tenant = "any"):
+    if not datacenter_name_id:
+        datacenter_name_id = mano_datacenter
+        if not datacenter_name_id:
+            raise OpenmanoCLIError("neither 'OPENMANO_DATACENTER' environment variable is set nor --datacenter option is used")
+    return _get_item_uuid("datacenters", datacenter_name_id, tenant)
+
+# WIM
+def _get_wim(wim_name_id = None, tenant = "any"):
+    if not wim_name_id:
+        wim_name_id = mano_wim
+        if not wim_name_id:
+            raise OpenmanoCLIError("neither 'OPENMANO_WIM' environment variable is set nor --wim option is used")
+    return _get_item_uuid("wims", wim_name_id, tenant)
+
+def vnf_create(args):
+    # print("vnf-create", args)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    tenant = _get_tenant()
+    myvnf = _load_file_or_yaml(args.file)
+
+    api_version = ""
+    if "vnfd:vnfd-catalog" in myvnf or "vnfd-catalog" in myvnf:
+        api_version = "/v3"
+        token = "vnfd"
+        vnfd_catalog = myvnf.get("vnfd:vnfd-catalog")
+        if not vnfd_catalog:
+            vnfd_catalog = myvnf.get("vnfd-catalog")
+        vnfds = vnfd_catalog.get("vnfd:vnfd")
+        if not vnfds:
+            vnfds = vnfd_catalog.get("vnfd")
+        vnfd = vnfds[0]
+        vdu_list = vnfd.get("vdu")
+
+    else:  # old API
+        api_version = ""
+        token = "vnfs"
+        vnfd = myvnf['vnf']
+        vdu_list = vnfd.get("VNFC")
+
+    if args.name or args.description or args.image_path or args.image_name or args.image_checksum:
+        # TODO, change this for API v3
+        # print(args.name
+        try:
+            if args.name:
+                vnfd['name'] = args.name
+            if args.description:
+                vnfd['description'] = args.description
+            if vdu_list:
+                if args.image_path:
+                    index = 0
+                    for image_path_ in args.image_path.split(","):
+                        # print("image-path", image_path_)
+                        if api_version == "/v3":
+                            if vdu_list[index].get("image"):
+                                vdu_list[index]['image'] = image_path_
+                                if "image-checksum" in vdu_list[index]:
+                                    del vdu_list[index]["image-checksum"]
+                            else:  # image name in volumes
+                                vdu_list[index]["volumes"][0]["image"] = image_path_
+                                if "image-checksum" in vdu_list[index]["volumes"][0]:
+                                    del vdu_list[index]["volumes"][0]["image-checksum"]
+                        else:
+                            vdu_list[index]['VNFC image'] = image_path_
+                            if "image name" in vdu_list[index]:
+                                del vdu_list[index]["image name"]
+                            if "image checksum" in vdu_list[index]:
+                                del vdu_list[index]["image checksum"]
+                        index += 1
+                if args.image_name:  # image name precedes if both are supplied
+                    index = 0
+                    for image_name_ in args.image_name.split(","):
+                        if api_version == "/v3":
+                            if vdu_list[index].get("image"):
+                                vdu_list[index]['image'] = image_name_
+                                if "image-checksum" in vdu_list[index]:
+                                    del vdu_list[index]["image-checksum"]
+                                if vdu_list[index].get("alternative-images"):
+                                    for a_image in vdu_list[index]["alternative-images"]:
+                                        a_image['image'] = image_name_
+                                        if "image-checksum" in a_image:
+                                            del a_image["image-checksum"]
+                            else:  # image name in volumes
+                                vdu_list[index]["volumes"][0]["image"] = image_name_
+                                if "image-checksum" in vdu_list[index]["volumes"][0]:
+                                    del vdu_list[index]["volumes"][0]["image-checksum"]
+                        else:
+                            vdu_list[index]['image name'] = image_name_
+                            if "VNFC image" in vdu_list[index]:
+                                del vdu_list[index]["VNFC image"]
+                        index += 1
+                if args.image_checksum:
+                    index = 0
+                    for image_checksum_ in args.image_checksum.split(","):
+                        if api_version == "/v3":
+                            if vdu_list[index].get("image"):
+                                vdu_list[index]['image-checksum'] = image_checksum_
+                                if vdu_list[index].get("alternative-images"):
+                                    for a_image in vdu_list[index]["alternative-images"]:
+                                        a_image['image-checksum'] = image_checksum_
+                            else:  # image name in volumes
+                                vdu_list[index]["volumes"][0]["image-checksum"] = image_checksum_
+                        else:
+                            vdu_list[index]['image checksum'] = image_checksum_
+                        index += 1
+        except (KeyError, TypeError) as e:
+            if str(e) == 'vnf':           error_pos= "missing field 'vnf'"
+            elif str(e) == 'name':        error_pos= "missing field  'vnf':'name'"
+            elif str(e) == 'description': error_pos= "missing field  'vnf':'description'"
+            elif str(e) == 'VNFC':        error_pos= "missing field  'vnf':'VNFC'"
+            elif str(e) == str(index):    error_pos= "field  'vnf':'VNFC' must be an array"
+            elif str(e) == 'VNFC image':  error_pos= "missing field 'vnf':'VNFC'['VNFC image']"
+            elif str(e) == 'image name':  error_pos= "missing field 'vnf':'VNFC'['image name']"
+            elif str(e) == 'image checksum':  error_pos= "missing field 'vnf':'VNFC'['image checksum']"
+            else:                       error_pos="wrong format"
+            print("Wrong VNF descriptor: " + error_pos)
+            return -1
+    payload_req = json.dumps(myvnf)
+
+    # print(payload_req
+
+    URLrequest = "http://{}:{}/openmano{}/{}/{token}".format(mano_host, mano_port, api_version, tenant, token=token)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+
+    return _print_verbose(mano_response, args.verbose)
+
+def vnf_list(args):
+    # print("vnf-list",args
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    if args.name:
+        toshow = _get_item_uuid("vnfs", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/vnfs".format(mano_host, mano_port, tenant)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4)
+    if args.verbose==None:
+        args.verbose=0
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        if not args.name:
+            if args.verbose >= 3:
+                print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            if len(content['vnfs']) == 0:
+                print("No VNFs were found.")
+                return 404   # HTTP_Not_Found
+            for vnf in content['vnfs']:
+                myoutput = "{:38} {:20}".format(vnf['uuid'], vnf['name'])
+                if vnf.get('osm_id') or args.verbose >= 1:
+                    myoutput += " osm_id={:20}".format(vnf.get('osm_id'))
+                if args.verbose >= 1:
+                    myoutput += " {}".format(vnf['created_at'])
+                print(myoutput)
+                if args.verbose >= 2:
+                    print("  Description: {}".format(vnf['description']))
+                    # print("  VNF descriptor file: {}".format(vnf['path']))
+        else:
+            if args.verbose:
+                print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            vnf = content['vnf']
+            print("{:38} {:20} osm_id={:20} {:20}".format(vnf['uuid'], vnf['name'], vnf.get('osm_id'),
+                                                          vnf['created_at']), end=" ")
+            print("  Description: {}".format(vnf['description']))
+            # print(" VNF descriptor file: {}".format(vnf['path']))
+            print("  VMs:")
+            for vm in vnf['VNFC']:
+                print("    {:20} osm_id={:20} {}".format(vm['name'], vm.get('osm_id'), vm['description']))
+            if len(vnf['nets']) > 0:
+                print("  Internal nets:")
+                for net in vnf['nets']:
+                    print("    {:20} {}".format(net['name'], net['description']))
+            if len(vnf['external-connections']) > 0:
+                print("  External interfaces:")
+                for interface in vnf['external-connections']:
+                    print("    {:20} {:20} {:20} {:14}".format(
+                        interface['external_name'], interface['vm_name'],
+                        interface['internal_name'],
+                        interface.get('vpci') if interface.get('vpci') else ""))
+    else:
+        print(content['error']['description'])
+        if args.verbose:
+            print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+    return result
+
+def vnf_delete(args):
+    # print("vnf-delete",args
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    todelete = _get_item_uuid("vnfs", args.name, tenant=tenant)
+    if not args.force:
+        r = input("Delete VNF {} (y/N)? ".format(todelete))
+        if  not (len(r)>0  and r[0].lower()=="y"):
+            return 0
+    URLrequest = "http://{}:{}/openmano/{}/vnfs/{}".format(mano_host, mano_port, tenant, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+def scenario_create(args):
+    # print("scenario-create",args
+    tenant = _get_tenant()
+    headers_req = {'content-type': 'application/yaml'}
+    myscenario = _load_file_or_yaml(args.file)
+    if "nsd:nsd-catalog" in myscenario or "nsd-catalog" in myscenario:
+        api_version = "/v3"
+        token = "nsd"
+        nsd_catalog = myscenario.get("nsd:nsd-catalog")
+        if not nsd_catalog:
+            nsd_catalog = myscenario.get("nsd-catalog")
+        nsds = nsd_catalog.get("nsd:nsd")
+        if not nsds:
+            nsds = nsd_catalog.get("nsd")
+        nsd = nsds[0]
+    else:  # API<v3
+        api_version = ""
+        token = "scenarios"
+        if "scenario" in myscenario:
+            nsd = myscenario["scenario"]
+        else:
+            nsd = myscenario
+    # TODO modify for API v3
+    if args.name:
+        nsd['name'] = args.name
+    if args.description:
+        nsd['description'] = args.description
+    payload_req = yaml.safe_dump(myscenario, explicit_start=True, indent=4, default_flow_style=False, tags=False,
+                                 allow_unicode=True)
+
+    # print(payload_req
+    URLrequest = "http://{host}:{port}/openmano{api}/{tenant}/{token}".format(
+        host=mano_host, port=mano_port, api=api_version, tenant=tenant, token=token)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    return _print_verbose(mano_response, args.verbose)
+
+def scenario_list(args):
+    # print("scenario-list",args
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    if args.name:
+        toshow = _get_item_uuid("scenarios", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/scenarios".format(mano_host, mano_port, tenant)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4)
+    if args.verbose==None:
+        args.verbose=0
+
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        if not args.name:
+            if args.verbose >= 3:
+                print( yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            if len(content['scenarios']) == 0:
+                print( "No scenarios were found.")
+                return 404 #HTTP_Not_Found
+            for scenario in content['scenarios']:
+                myoutput = "{:38} {:20}".format(scenario['uuid'], scenario['name'])
+                if scenario.get('osm_id') or args.verbose >= 1:
+                    myoutput += " osm_id={:20}".format(scenario.get('osm_id'))
+                if args.verbose >= 1:
+                    myoutput += " {}".format(scenario['created_at'])
+                print(myoutput)
+                if args.verbose >=2:
+                    print("  Description: {}".format(scenario['description']))
+        else:
+            if args.verbose:
+                print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            scenario = content['scenario']
+            print("{:38} {:20} osm_id={:20} {:20}".format(scenario['uuid'], scenario['name'], scenario.get('osm_id'),
+                                                          scenario['created_at']), end=" ")
+            print("  Description: {}".format(scenario['description']))
+            print("  VNFs:")
+            for vnf in scenario['vnfs']:
+                print("    {:38} {:20} vnf_index={} {}".format(vnf['vnf_id'], vnf['name'], vnf.get("member_vnf_index"),
+                                                                vnf['description']))
+            if len(scenario['nets']) > 0:
+                print("  nets:")
+                for net in scenario['nets']:
+                    description = net['description']
+                    if not description:   # if description does not exist, description is "-". Valid for external and internal nets.
+                        description = '-'
+                    vim_id = ""
+                    if net.get('vim_id'):
+                        vim_id = " vim_id=" + net["vim_id"]
+                    external = ""
+                    if net["external"]:
+                        external = " external"
+                    print("    {:20} {:38} {:30}{}{}".format(net['name'], net['uuid'], description, vim_id, external))
+    else:
+        print(content['error']['description'])
+        if args.verbose:
+            print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+    return result
+
+def scenario_delete(args):
+    # print("scenario-delete",args
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    todelete = _get_item_uuid("scenarios", args.name, tenant=tenant)
+    if not args.force:
+        r = input("Delete scenario {} (y/N)? ".format(args.name))
+        if  not (len(r)>0  and r[0].lower()=="y"):
+            return 0
+    URLrequest = "http://{}:{}/openmano/{}/scenarios/{}".format(mano_host, mano_port, tenant, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4)
+    if mano_response.status_code == 200:
+        print( content['result'])
+    else:
+        print( content['error']['description'])
+    return result
+
+def scenario_deploy(args):
+    print("This command is deprecated, use 'openmano instance-scenario-create --scenario {} --name {}' instead!!!".format(args.scenario, args.name))
+    print()
+    args.file = None
+    args.netmap_use = None
+    args.netmap_create = None
+    args.keypair = None
+    args.keypair_auto = None
+    return instance_create(args)
+
+#     # print("scenario-deploy",args
+#     headers_req = {'content-type': 'application/json'}
+#     action = {}
+#     actionCmd="start"
+#     if args.nostart:
+#         actionCmd="reserve"
+#     action[actionCmd] = {}
+#     action[actionCmd]["instance_name"] = args.name
+#     if args.datacenter != None:
+#         action[actionCmd]["datacenter"] = args.datacenter
+#     elif mano_datacenter != None:
+#         action[actionCmd]["datacenter"] = mano_datacenter
+#
+#     if args.description:
+#         action[actionCmd]["description"] = args.description
+#     payload_req = json.dumps(action, indent=4)
+#     # print(payload_req
+#
+#     URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, mano_tenant, args.scenario)
+#     logger.debug("openmano request: %s", payload_req)
+#     mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+#     logger.debug("openmano response: %s", mano_response.text )
+#     if args.verbose==None:
+#         args.verbose=0
+#
+#     result = 0 if mano_response.status_code==200 else mano_response.status_code
+#     content = mano_response.json()
+#     # print(json.dumps(content, indent=4))
+#     if args.verbose >= 3:
+#         print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+#         return result
+#
+#     if mano_response.status_code == 200:
+#         myoutput = "{} {}".format(content['uuid'].ljust(38),content['name'].ljust(20))
+#         if args.verbose >=1:
+#             myoutput = "{} {}".format(myoutput, content['created_at'].ljust(20))
+#         if args.verbose >=2:
+#             myoutput = "{} {} {}".format(myoutput, content['description'].ljust(30))
+#         print(myoutput)
+#         print("")
+#         print("To check the status, run the following command:")
+#         print("openmano instance-scenario-list <instance_id>"
+#     else:
+#         print(content['error']['description'])
+#     return result
+
+def scenario_verify(args):
+    # print("scenario-verify",args)
+    tenant = _get_tenant()
+    headers_req = {'content-type': 'application/json'}
+    action = {}
+    action["verify"] = {}
+    action["verify"]["instance_name"] = "scen-verify-return5"
+    payload_req = json.dumps(action, indent=4)
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/scenarios/{}/action".format(mano_host, mano_port, tenant, args.scenario)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+def instance_create(args):
+    tenant = _get_tenant()
+    headers_req = {'content-type': 'application/yaml'}
+    myInstance={"instance": {}, "schema_version": "0.1"}
+    if args.file:
+        instance_dict = _load_file_or_yaml(args.file)
+        if "instance" not in instance_dict:
+            myInstance = {"instance": instance_dict, "schema_version": "0.1"}
+        else:
+            myInstance = instance_dict
+    if args.name:
+        myInstance["instance"]['name'] = args.name
+    if args.description:
+        myInstance["instance"]['description'] = args.description
+    if args.nostart:
+        myInstance["instance"]['action'] = "reserve"
+    #datacenter
+    datacenter = myInstance["instance"].get("datacenter")
+    if args.datacenter != None:
+        datacenter = args.datacenter
+    myInstance["instance"]["datacenter"] = _get_datacenter(datacenter, tenant)
+    #scenario
+    scenario = myInstance["instance"].get("scenario")
+    if args.scenario != None:
+        scenario = args.scenario
+    if not scenario:
+        print("you must provide a scenario in the file descriptor or with --scenario")
+        return -1
+    if isinstance(scenario, str):
+        myInstance["instance"]["scenario"] = _get_item_uuid("scenarios", scenario, tenant)
+    if args.netmap_use:
+        if "networks" not in myInstance["instance"]:
+            myInstance["instance"]["networks"] = {}
+        for net in args.netmap_use:
+            net_comma_list = net.split(",")
+            for net_comma in net_comma_list:
+                net_tuple = net_comma.split("=")
+                if len(net_tuple) != 2:
+                    print("error at netmap-use. Expected net-scenario=net-datacenter. ({})?".format(net_comma))
+                    return
+                net_scenario   = net_tuple[0].strip()
+                net_datacenter = net_tuple[1].strip()
+                if net_scenario not in myInstance["instance"]["networks"]:
+                    myInstance["instance"]["networks"][net_scenario] = {}
+                if "sites" not in myInstance["instance"]["networks"][net_scenario]:
+                    myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
+                myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-use"] = net_datacenter
+    if args.netmap_create:
+        if "networks" not in myInstance["instance"]:
+            myInstance["instance"]["networks"] = {}
+        for net in args.netmap_create:
+            net_comma_list = net.split(",")
+            for net_comma in net_comma_list:
+                net_tuple = net_comma.split("=")
+                if len(net_tuple) == 1:
+                    net_scenario   = net_tuple[0].strip()
+                    net_datacenter = None
+                elif len(net_tuple) == 2:
+                    net_scenario   = net_tuple[0].strip()
+                    net_datacenter = net_tuple[1].strip()
+                else:
+                    print("error at netmap-create. Expected net-scenario=net-datacenter or net-scenario. ({})?".format(
+                        net_comma))
+                    return
+                if net_scenario not in myInstance["instance"]["networks"]:
+                    myInstance["instance"]["networks"][net_scenario] = {}
+                if "sites" not in myInstance["instance"]["networks"][net_scenario]:
+                    myInstance["instance"]["networks"][net_scenario]["sites"] = [ {} ]
+                myInstance["instance"]["networks"][net_scenario]["sites"][0]["netmap-create"] = net_datacenter
+    if args.keypair:
+        if "cloud-config" not in myInstance["instance"]:
+            myInstance["instance"]["cloud-config"] = {}
+        cloud_config = myInstance["instance"]["cloud-config"]
+        for key in args.keypair:
+            index = key.find(":")
+            if index<0:
+                if "key-pairs" not in cloud_config:
+                    cloud_config["key-pairs"] = []
+                cloud_config["key-pairs"].append(key)
+            else:
+                user = key[:index]
+                key_ = key[index+1:]
+                key_list = key_.split(",")
+                if "users" not in cloud_config:
+                    cloud_config["users"] = []
+                cloud_config["users"].append({"name": user, "key-pairs": key_list  })
+    if args.keypair_auto:
+        try:
+            keys=[]
+            home = os.getenv("HOME")
+            user = os.getenv("USER")
+            files = os.listdir(home+'/.ssh')
+            for file in files:
+                if file[-4:] == ".pub":
+                    with open(home+'/.ssh/'+file, 'r') as f:
+                        keys.append(f.read())
+            if not keys:
+                print("Cannot obtain any public ssh key from '{}'. Try not using --keymap-auto".format(home+'/.ssh'))
+                return 1
+        except Exception as e:
+            print("Cannot obtain any public ssh key. Error '{}'. Try not using --keymap-auto".format(str(e)))
+            return 1
+
+        if "cloud-config" not in myInstance["instance"]:
+            myInstance["instance"]["cloud-config"] = {}
+        cloud_config = myInstance["instance"]["cloud-config"]
+        if "key-pairs" not in cloud_config:
+            cloud_config["key-pairs"] = []
+        if user:
+            if "users" not in cloud_config:
+                cloud_config["users"] = []
+            cloud_config["users"].append({"name": user, "key-pairs": keys })
+
+    payload_req = yaml.safe_dump(myInstance, explicit_start=True, indent=4, default_flow_style=False, tags=False,
+                                 allow_unicode=True)
+    logger.debug("openmano request: %s", payload_req)
+    URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant)
+    mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose==None:
+        args.verbose=0
+
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if args.verbose >= 3:
+        print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+        return result
+
+    if mano_response.status_code == 200:
+        myoutput = "{:38} {:20}".format(content['uuid'], content['name'])
+        if args.verbose >=1:
+            myoutput = "{} {:20}".format(myoutput, content['created_at'])
+        if args.verbose >=2:
+            myoutput = "{} {:30}".format(myoutput, content['description'])
+        print(myoutput)
+    else:
+        print(content['error']['description'])
+    return result
+
+def instance_scenario_list(args):
+    # print("instance-scenario-list",args)
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    if args.name:
+        toshow = _get_item_uuid("instances", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/instances".format(mano_host, mano_port, tenant)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4)
+    if args.verbose==None:
+        args.verbose=0
+
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        if not args.name:
+            if args.verbose >= 3:
+                print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            if len(content['instances']) == 0:
+                print("No scenario instances were found.")
+                return result
+            for instance in content['instances']:
+                myoutput = "{:38} {:20}".format(instance['uuid'], instance['name'])
+                if args.verbose >=1:
+                    myoutput = "{} {:20}".format(myoutput, instance['created_at'])
+                print(myoutput)
+                if args.verbose >=2:
+                    print("Description: {}".format(instance['description']))
+        else:
+            if args.verbose:
+                print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+                return result
+            instance = content
+            print("{:38} {:20} {:20}".format(instance['uuid'],instance['name'],instance['created_at']))
+            print("Description: {}".format(instance['description']))
+            print("Template scenario id: {}".format(instance['scenario_id']))
+            print("Template scenario name: {}".format(instance['scenario_name']))
+            print("---------------------------------------")
+            print("VNF instances: {}".format(len(instance['vnfs'])))
+            for vnf in instance['vnfs']:
+                # print("    {} {} Template vnf name: {} Template vnf id: {}".format(vnf['uuid'].ljust(38), vnf['name'].ljust(20), vnf['vnf_name'].ljust(20), vnf['vnf_id'].ljust(38))
+                print("    {:38} {:20} Template vnf id: {:38}".format(vnf['uuid'], vnf['vnf_name'], vnf['vnf_id']))
+            if len(instance['nets'])>0:
+                print("---------------------------------------")
+                print("Internal nets:")
+                for net in instance['nets']:
+                    if net['created']:
+                        print("    {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
+                print("---------------------------------------")
+                print("External nets:")
+                for net in instance['nets']:
+                    if not net['created']:
+                        print("    {:38} {:12} VIM ID: {}".format(net['uuid'], net['status'], net['vim_net_id']))
+            print("---------------------------------------")
+            print("VM instances:")
+            for vnf in instance['vnfs']:
+                for vm in vnf['vms']:
+                    print("    {:38} {:20} {:20} {:12} VIM ID: {}".format(vm['uuid'], vnf['vnf_name'], vm['name'],
+                                                                          vm['status'], vm['vim_vm_id']))
+    else:
+        print(content['error']['description'])
+        if args.verbose:
+            print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+    return result
+
+def instance_scenario_status(args):
+    print("instance-scenario-status")
+    return 0
+
+def instance_scenario_delete(args):
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    todelete = _get_item_uuid("instances", args.name, tenant=tenant)
+    # print("instance-scenario-delete",args)
+    if not args.force:
+        r = input("Delete scenario instance {} (y/N)? ".format(args.name))
+        if  not (len(r)>0  and r[0].lower()=="y"):
+            return
+    URLrequest = "http://{}:{}/openmano/{}/instances/{}".format(mano_host, mano_port, tenant, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+def get_action(args):
+    if not args.all:
+        tenant = _get_tenant()
+    else:
+        tenant = "any"
+    if not args.instance:
+        instance_id = "any"
+    else:
+        instance_id =args.instance
+    action_id = ""
+    if args.id:
+        action_id = "/" + args.id
+    URLrequest = "http://{}:{}/openmano/{}/instances/{}/action{}".format(mano_host, mano_port, tenant, instance_id,
+                                                                         action_id)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose == None:
+        args.verbose = 0
+    if args.id != None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+def instance_scenario_action(args):
+    # print("instance-scenario-action", args)
+    tenant = _get_tenant()
+    toact = _get_item_uuid("instances", args.name, tenant=tenant)
+    action={}
+    action[ args.action ] = yaml.safe_load(args.param)
+    if args.vnf:
+        action["vnfs"] = args.vnf
+    if args.vm:
+        action["vms"] = args.vm
+
+    headers_req = {'content-type': 'application/json'}
+    payload_req = json.dumps(action, indent=4)
+    URLrequest = "http://{}:{}/openmano/{}/instances/{}/action".format(mano_host, mano_port, tenant, toact)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        if args.verbose:
+            print(yaml.safe_dump(content, indent=4, default_flow_style=False))
+            return result
+        if "instance_action_id" in content:
+            print("instance_action_id={}".format(content["instance_action_id"]))
+        else:
+            for uuid,c in content.items():
+                print("{:38} {:20} {:20}".format(uuid, c.get('name'), c.get('description')))
+    else:
+        print(content['error']['description'])
+    return result
+
+
+def instance_vnf_list(args):
+    print("instance-vnf-list")
+    return 0
+
+def instance_vnf_status(args):
+    print("instance-vnf-status")
+    return 0
+
+def tenant_create(args):
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    tenant_dict={"name": args.name}
+    if args.description!=None:
+        tenant_dict["description"] = args.description
+    payload_req = json.dumps( {"tenant": tenant_dict })
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    return _print_verbose(mano_response, args.verbose)
+
+def tenant_list(args):
+    # print("tenant-list",args)
+    if args.name:
+        toshow = _get_item_uuid("tenants", args.name)
+        URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/tenants".format(mano_host, mano_port)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose==None:
+        args.verbose=0
+    if args.name!=None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+def tenant_delete(args):
+    # print("tenant-delete",args)
+    todelete = _get_item_uuid("tenants", args.name)
+    if not args.force:
+        r = input("Delete tenant {} (y/N)? ".format(args.name))
+        if  not (len(r)>0  and r[0].lower()=="y"):
+            return 0
+    URLrequest = "http://{}:{}/openmano/tenants/{}".format(mano_host, mano_port, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+def datacenter_attach(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    datacenter_dict={}
+    if args.vim_tenant_id != None:
+        datacenter_dict['vim_tenant'] = args.vim_tenant_id
+    if args.vim_tenant_name != None:
+        datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
+    if args.user != None:
+        datacenter_dict['vim_username'] = args.user
+    if args.password != None:
+        datacenter_dict['vim_password'] = args.password
+    if args.config!=None:
+        datacenter_dict["config"] = _load_file_or_yaml(args.config)
+
+    payload_req = json.dumps( {"datacenter": datacenter_dict })
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = _print_verbose(mano_response, args.verbose)
+    #provide addional information if error
+    if mano_response.status_code != 200:
+        content = mano_response.json()
+        if "already in use for  'name'" in content['error']['description'] and \
+                "to database vim_tenants table" in content['error']['description']:
+            print("Try to specify a different name with --vim-tenant-name")
+    return result
+
+
+def datacenter_edit_vim_tenant(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    if not (args.vim_tenant_id or args.vim_tenant_name or args.user or args.password or args.config):
+        raise OpenmanoCLIError("Error. At least one parameter must be updated.")
+
+    datacenter_dict = {}
+    if args.vim_tenant_id != None:
+        datacenter_dict['vim_tenant'] = args.vim_tenant_id
+    if args.vim_tenant_name != None:
+        datacenter_dict['vim_tenant_name'] = args.vim_tenant_name
+    if args.user != None:
+        datacenter_dict['vim_username'] = args.user
+    if args.password != None:
+        datacenter_dict['vim_password'] = args.password
+    if args.config != None:
+        datacenter_dict["config"] = _load_file_or_yaml(args.config)
+    payload_req = json.dumps({"datacenter": datacenter_dict})
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+
+    return result
+
+def datacenter_detach(args):
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, datacenter)
+    mano_response = requests.delete(URLrequest, headers=headers_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+def datacenter_create(args):
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    datacenter_dict={"name": args.name, "vim_url": args.url}
+    if args.description!=None:
+        datacenter_dict["description"] = args.description
+    if args.type!=None:
+        datacenter_dict["type"] = args.type
+    if args.url!=None:
+        datacenter_dict["vim_url_admin"] = args.url_admin
+    if args.config!=None:
+        datacenter_dict["config"] = _load_file_or_yaml(args.config)
+    if args.sdn_controller!=None:
+        tenant = _get_tenant()
+        sdn_controller = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
+        if not 'config' in datacenter_dict:
+            datacenter_dict['config'] = {}
+        datacenter_dict['config']['sdn-controller'] = sdn_controller
+    payload_req = json.dumps( {"datacenter": datacenter_dict })
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/datacenters".format(mano_host, mano_port)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    return _print_verbose(mano_response, args.verbose)
+
+def datacenter_delete(args):
+    # print("datacenter-delete",args)
+    todelete = _get_item_uuid("datacenters", args.name, "any")
+    if not args.force:
+        r = input("Delete datacenter {} (y/N)? ".format(args.name))
+        if  not (len(r)>0  and r[0].lower()=="y"):
+            return 0
+    URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    result = 0 if mano_response.status_code==200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+
+def datacenter_list(args):
+    # print("datacenter-list",args)
+    tenant='any' if args.all else _get_tenant()
+
+    if args.name:
+        toshow = _get_item_uuid("datacenters", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/datacenters/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/datacenters".format(mano_host, mano_port, tenant)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose==None:
+        args.verbose=0
+    if args.name!=None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+
+def datacenter_sdn_port_mapping_set(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    if not args.file:
+        raise OpenmanoCLIError(
+            "No yaml/json has been provided specifying the SDN port mapping")
+    sdn_port_mapping = _load_file_or_yaml(args.file)
+    payload_req = json.dumps({"sdn_port_mapping": sdn_port_mapping})
+
+    # read
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    port_mapping = mano_response.json()
+    if mano_response.status_code != 200:
+        str(mano_response.json())
+        raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
+    if len(port_mapping["sdn_port_mapping"]["ports_mapping"]) > 0:
+        if not args.force:
+            r = input("Datacenter {} already contains a port mapping. Overwrite? (y/N)? ".format(datacenter))
+            if not (len(r) > 0 and r[0].lower() == "y"):
+                return 0
+
+        # clear
+        URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
+        mano_response = requests.delete(URLrequest)
+        logger.debug("openmano response: %s", mano_response.text)
+        if mano_response.status_code != 200:
+            return _print_verbose(mano_response, args.verbose)
+
+    # set
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    return _print_verbose(mano_response, args.verbose)
+
+
+def datacenter_sdn_port_mapping_list(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name, tenant)
+
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+
+    return _print_verbose(mano_response, 4)
+
+
+def datacenter_sdn_port_mapping_clear(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.name, tenant)
+
+    if not args.force:
+        r = input("Clean SDN port mapping for datacenter {} (y/N)? ".format(datacenter))
+        if not (len(r) > 0 and r[0].lower() == "y"):
+            return 0
+
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/sdn_mapping".format(mano_host, mano_port, tenant, datacenter)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+
+    return _print_verbose(mano_response, args.verbose)
+
+
+def sdn_controller_create(args):
+    tenant = _get_tenant()
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    error_msg=[]
+    if not args.ip: error_msg.append("'ip'")
+    if not args.port: error_msg.append("'port'")
+    if not args.dpid: error_msg.append("'dpid'")
+    if not args.type: error_msg.append("'type'")
+    if error_msg:
+        raise OpenmanoCLIError("The following arguments are required: " + ",".join(error_msg))
+
+    controller_dict = {}
+    controller_dict['name'] = args.name
+    controller_dict['ip'] = args.ip
+    controller_dict['port'] = int(args.port)
+    controller_dict['dpid'] = args.dpid
+    controller_dict['type'] = args.type
+    if args.description != None:
+        controller_dict['description'] = args.description
+    if args.user != None:
+        controller_dict['user'] = args.user
+    if args.password != None:
+        controller_dict['password'] = args.password
+
+    payload_req = json.dumps({"sdn_controller": controller_dict})
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    return result
+
+
+def sdn_controller_edit(args):
+    tenant = _get_tenant()
+    controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    controller_dict = {}
+    if args.new_name:
+        controller_dict['name'] = args.new_name
+    if args.ip:
+        controller_dict['ip'] = args.ip
+    if args.port:
+        controller_dict['port'] = int(args.port)
+    if args.dpid:
+        controller_dict['dpid'] = args.dpid
+    if args.type:
+        controller_dict['type'] = args.type
+    if args.description:
+        controller_dict['description'] = args.description
+    if args.user:
+        controller_dict['user'] = args.user
+    if args.password:
+        controller_dict['password'] = args.password
+
+    if not controller_dict:
+        raise OpenmanoCLIError("At least one parameter must be edited")
+
+    if not args.force:
+        r = input("Update SDN controller {} (y/N)? ".format(args.name))
+        if not (len(r) > 0 and r[0].lower() == "y"):
+            return 0
+
+    payload_req = json.dumps({"sdn_controller": controller_dict})
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    return result
+
+
+def sdn_controller_list(args):
+    tenant = _get_tenant()
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    if args.name:
+        toshow = _get_item_uuid("sdn_controllers", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/sdn_controllers".format(mano_host, mano_port, tenant)
+    # print(URLrequest)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose==None:
+        args.verbose=0
+    if args.name!=None:
+        args.verbose += 1
+
+    # json.dumps(mano_response.json(), indent=4)
+    return _print_verbose(mano_response, args.verbose)
+
+
+def sdn_controller_delete(args):
+    tenant = _get_tenant()
+    controller_uuid = _get_item_uuid("sdn_controllers", args.name, tenant)
+
+    if not args.force:
+        r = input("Delete SDN controller {} (y/N)? ".format(args.name))
+        if not (len(r) > 0 and r[0].lower() == "y"):
+            return 0
+
+    URLrequest = "http://{}:{}/openmano/{}/sdn_controllers/{}".format(mano_host, mano_port, tenant, controller_uuid)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    return _print_verbose(mano_response, args.verbose)
+
+def vim_action(args):
+    # print("datacenter-net-action",args)
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.datacenter, tenant)
+    if args.verbose==None:
+        args.verbose=0
+    if args.action=="list":
+        URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item)
+        if args.name!=None:
+            args.verbose += 1
+            URLrequest += "/" + args.name
+        mano_response = requests.get(URLrequest)
+        logger.debug("openmano response: %s", mano_response.text )
+        return _print_verbose(mano_response, args.verbose)
+    elif args.action=="delete":
+        URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s/{}".format(mano_host, mano_port, tenant, datacenter, args.item, args.name)
+        mano_response = requests.delete(URLrequest)
+        logger.debug("openmano response: %s", mano_response.text )
+        result = 0 if mano_response.status_code==200 else mano_response.status_code
+        content = mano_response.json()
+        # print(json.dumps(content, indent=4))
+        if mano_response.status_code == 200:
+            print(content['result'])
+        else:
+            print(content['error']['description'])
+        return result
+    elif args.action=="create":
+        headers_req = {'content-type': 'application/yaml'}
+        if args.file:
+            create_dict = _load_file_or_yaml(args.file)
+            if args.item not in create_dict:
+                create_dict = {args.item: create_dict}
+        else:
+            create_dict = {args.item:{}}
+        if args.name:
+            create_dict[args.item]['name'] = args.name
+        #if args.description:
+        #    create_dict[args.item]['description'] = args.description
+        if args.item=="network":
+            if args.bind_net:
+                create_dict[args.item]['bind_net'] = args.bind_net
+            if args.type:
+                create_dict[args.item]['type'] = args.type
+            if args.shared:
+                create_dict[args.item]['shared'] = args.shared
+        if "name" not in create_dict[args.item]:
+            print("You must provide a name in the descriptor file or with the --name option")
+            return
+        payload_req = yaml.safe_dump(create_dict, explicit_start=True, indent=4, default_flow_style=False, tags=False,
+                                     allow_unicode=True)
+        logger.debug("openmano request: %s", payload_req)
+        URLrequest = "http://{}:{}/openmano/{}/vim/{}/{}s".format(mano_host, mano_port, tenant, datacenter, args.item)
+        mano_response = requests.post(URLrequest, headers = headers_req, data=payload_req)
+        logger.debug("openmano response: %s", mano_response.text )
+        if args.verbose==None:
+            args.verbose=0
+        return _print_verbose(mano_response, args.verbose)
+
+
+def _get_items(item, item_name_id=None, datacenter=None, tenant=None):
+    URLrequest = "http://{}:{}/openmano".format(mano_host, mano_port)
+    if tenant:
+        URLrequest += "/" + tenant
+    if datacenter:
+        URLrequest += "/vim/" + datacenter
+    if item:
+        URLrequest += "/" + item +"s"
+    if item_name_id:
+        URLrequest += "/" + item_name_id
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text )
+
+    return mano_response
+
+
+def vim_net_sdn_attach(args):
+    #Verify the network exists in the vim
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.datacenter, tenant)
+    result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
+    content = yaml.load(result.content)
+    if 'networks' in content:
+        raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
+    if 'error' in content:
+        raise OpenmanoCLIError(yaml.safe_dump(content))
+    network_uuid = content['network']['id']
+
+    #Make call to attach the dataplane port to the SND network associated to the vim network
+    headers_req = {'content-type': 'application/yaml'}
+    payload_req = {'port': args.port}
+    if args.vlan:
+        payload_req['vlan'] = int(args.vlan)
+    if args.mac:
+        payload_req['mac'] = args.mac
+
+    URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/attach".format(mano_host, mano_port, tenant, datacenter, network_uuid)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=json.dumps(payload_req))
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    return result
+
+
+def vim_net_sdn_detach(args):
+    if not args.all and not args.id:
+        print("--all or --id must be used")
+        return 1
+
+    # Verify the network exists in the vim
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.datacenter, tenant)
+    result = _get_items('network', item_name_id=args.vim_net, datacenter=datacenter, tenant=tenant)
+    content = yaml.load(result.content)
+    if 'networks' in content:
+        raise OpenmanoCLIError('More than one network in the vim named ' + args.vim_net + '. Use uuid instead')
+    if 'error' in content:
+        raise OpenmanoCLIError(yaml.safe_dump(content))
+    network_uuid = content['network']['id']
+
+    if not args.force:
+        r = input("Confirm action' (y/N)? ")
+        if len(r) == 0 or r[0].lower() != "y":
+            return 0
+
+    if args.id:
+        URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach/{}".format(
+            mano_host, mano_port, tenant, datacenter, network_uuid, args.id)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/vim/{}/network/{}/detach".format(
+            mano_host, mano_port, tenant, datacenter, network_uuid)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    return result
+
+
+def datacenter_net_action(args):
+    if args.action == "net-update":
+        print("This command is deprecated, use 'openmano datacenter-netmap-delete --all' and 'openmano"
+              " datacenter-netmap-import' instead!!!")
+        print()
+        args.action = "netmap-delete"
+        args.netmap = None
+        args.all = True
+        r = datacenter_netmap_action(args)
+        if r == 0:
+            args.force = True
+            args.action = "netmap-import"
+            r = datacenter_netmap_action(args)
+        return r
+
+    if args.action == "net-edit":
+        args.netmap = args.net
+        args.name = None
+    elif args.action == "net-list":
+        args.netmap = None
+    elif args.action == "net-delete":
+        args.netmap = args.net
+        args.all = False
+
+    args.action = "netmap" + args.action[3:]
+    args.vim_name=None
+    args.vim_id=None
+    print("This command is deprecated, use 'openmano datacenter-{}' instead!!!".format(args.action))
+    print()
+    return datacenter_netmap_action(args)
+
+def datacenter_netmap_action(args):
+    tenant = _get_tenant()
+    datacenter = _get_datacenter(args.datacenter, tenant)
+    # print("datacenter_netmap_action",args)
+    payload_req = None
+    if args.verbose==None:
+        args.verbose=0
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/{}/datacenters/{}/netmaps".format(mano_host, mano_port, tenant, datacenter)
+
+    if args.action=="netmap-list":
+        if args.netmap:
+            URLrequest += "/" + args.netmap
+            args.verbose += 1
+        mano_response = requests.get(URLrequest)
+
+    elif args.action=="netmap-delete":
+        if args.netmap and args.all:
+            print("you can not use a netmap name and the option --all at the same time")
+            return 1
+        if args.netmap:
+            force_text= "Delete default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter)
+            URLrequest += "/" + args.netmap
+        elif args.all:
+            force_text="Delete all default netmaps from datacenter '{}' (y/N)? ".format(datacenter)
+        else:
+            print("you must specify a netmap name or the option --all")
+            return 1
+        if not args.force:
+            r = input(force_text)
+            if  len(r)>0  and r[0].lower()=="y":
+                pass
+            else:
+                return 0
+        mano_response = requests.delete(URLrequest, headers=headers_req)
+    elif args.action=="netmap-import":
+        if not args.force:
+            r = input("Create all the available networks from datacenter '{}' as default netmaps (y/N)? ".format(datacenter))
+            if  len(r)>0  and r[0].lower()=="y":
+                pass
+            else:
+                return 0
+        URLrequest += "/upload"
+        mano_response = requests.post(URLrequest, headers=headers_req)
+    elif args.action=="netmap-edit" or args.action=="netmap-create":
+        if args.file:
+            payload = _load_file_or_yaml(args.file)
+        else:
+            payload = {}
+        if "netmap" not in payload:
+            payload = {"netmap": payload}
+        if args.name:
+            payload["netmap"]["name"] = args.name
+        if args.vim_id:
+            payload["netmap"]["vim_id"] = args.vim_id
+        if args.action=="netmap-create" and args.vim_name:
+            payload["netmap"]["vim_name"] = args.vim_name
+        payload_req = json.dumps(payload)
+        logger.debug("openmano request: %s", payload_req)
+
+        if args.action=="netmap-edit" and not args.force:
+            if len(payload["netmap"]) == 0:
+                print("You must supply some parameter to edit")
+                return 1
+            r = input("Edit default netmap '{}' from datacenter '{}' (y/N)? ".format(args.netmap, datacenter))
+            if  len(r)>0  and r[0].lower()=="y":
+                pass
+            else:
+                return 0
+            URLrequest += "/" + args.netmap
+            mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+        else: #netmap-create
+            if "vim_name" not in payload["netmap"] and "vim_id" not in payload["netmap"]:
+                print("You must supply either --vim-id or --vim-name option; or include one of them in the file"
+                      " descriptor")
+                return 1
+            mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+
+    logger.debug("openmano response: %s", mano_response.text )
+    return _print_verbose(mano_response, args.verbose)
+
+
+def element_edit(args):
+    element = _get_item_uuid(args.element, args.name)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/{}/{}".format(mano_host, mano_port, args.element, element)
+    payload=_load_file_or_yaml(args.file)
+    if args.element[:-1] not in payload:
+        payload = {args.element[:-1]: payload }
+    payload_req = json.dumps(payload)
+
+    # print(payload_req)
+    if not args.force or (args.name==None and args.filer==None):
+        r = input(" Edit " + args.element[:-1] + " " + args.name + " (y/N)? ")
+        if  len(r)>0  and r[0].lower()=="y":
+            pass
+        else:
+            return 0
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text )
+    if args.verbose==None:
+        args.verbose=0
+    if args.name!=None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+
+def datacenter_edit(args):
+    tenant = _get_tenant()
+    element = _get_item_uuid('datacenters', args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/datacenters/{}".format(mano_host, mano_port, element)
+
+    has_arguments = False
+    if args.file != None:
+        has_arguments = True
+        payload = _load_file_or_yaml(args.file)
+    else:
+        payload = {}
+
+    if args.sdn_controller != None:
+        has_arguments = True
+        if not 'config' in payload:
+            payload['config'] = {}
+        if not 'sdn-controller' in payload['config']:
+            payload['config']['sdn-controller'] = {}
+        if args.sdn_controller == 'null':
+            payload['config']['sdn-controller'] = None
+        else:
+            payload['config']['sdn-controller'] = _get_item_uuid("sdn_controllers", args.sdn_controller, tenant)
+
+    if not has_arguments:
+        raise OpenmanoCLIError("At least one argument must be provided to modify the datacenter")
+
+    if 'datacenter' not in payload:
+        payload = {'datacenter': payload}
+    payload_req = json.dumps(payload)
+
+    # print(payload_req)
+    if not args.force or (args.name == None and args.filer == None):
+        r = input(" Edit datacenter " + args.name + " (y/N)? ")
+        if len(r) > 0 and r[0].lower() == "y":
+            pass
+        else:
+            return 0
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    if args.verbose == None:
+        args.verbose = 0
+    if args.name != None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+
+# WIM
+def wim_account_create(args):
+    tenant = _get_tenant()
+    wim = _get_wim(args.name)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    wim_dict = {}
+    if args.account_name is not None:
+        wim_dict['name'] = args.account_name
+    if args.user is not None:
+        wim_dict['user'] = args.user
+    if args.password is not None:
+        wim_dict['password'] = args.password
+    if args.config is not None:
+        wim_dict["config"] = _load_file_or_yaml(args.config)
+
+    payload_req = json.dumps({"wim_account": wim_dict})
+
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    # provide addional information if error
+    if mano_response.status_code != 200:
+        content = mano_response.json()
+        if "already in use for  'name'" in content['error']['description'] and \
+                "to database wim_tenants table" in content['error']['description']:
+            print("Try to specify a different name with --wim-tenant-name")
+    return result
+
+
+def wim_account_delete(args):
+    if args.all:
+        tenant = "any"
+    else:
+        tenant = _get_tenant()
+    wim = _get_wim(args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
+    mano_response = requests.delete(URLrequest, headers=headers_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    result = 0 if mano_response.status_code == 200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+
+def wim_account_edit(args):
+    tenant = _get_tenant()
+    wim = _get_wim(args.name)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    wim_dict = {}
+    if not args.account_name:
+        wim_dict['name'] = args.vim_tenant_name
+    if not args.user:
+        wim_dict['user'] = args.user
+    if not args.password:
+        wim_dict['password'] = args.password
+    if not args.config:
+        wim_dict["config"] = _load_file_or_yaml(args.config)
+
+    payload_req = json.dumps({"wim_account": wim_dict})
+
+    # print(payload_req)
+
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, wim)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = _print_verbose(mano_response, args.verbose)
+    # provide addional information if error
+    if mano_response.status_code != 200:
+        content = mano_response.json()
+        if "already in use for  'name'" in content['error']['description'] and \
+                "to database wim_tenants table" in content['error']['description']:
+            print("Try to specify a different name with --wim-tenant-name")
+    return result
+
+def wim_create(args):
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    wim_dict = {"name": args.name, "wim_url": args.url}
+    if args.description != None:
+        wim_dict["description"] = args.description
+    if args.type != None:
+        wim_dict["type"] = args.type
+    if args.config != None:
+        wim_dict["config"] = _load_file_or_yaml(args.config)
+
+    payload_req = json.dumps({"wim": wim_dict})
+
+    URLrequest = "http://{}:{}/openmano/wims".format(mano_host, mano_port)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    return _print_verbose(mano_response, args.verbose)
+
+
+def wim_edit(args):
+    tenant = _get_tenant()
+    element = _get_item_uuid('wims', args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, element)
+
+    has_arguments = False
+    if args.file != None:
+        has_arguments = True
+        payload = _load_file_or_yaml(args.file)
+    else:
+        payload = {}
+
+    if not has_arguments:
+        raise OpenmanoCLIError("At least one argument must be provided to modify the wim")
+
+    if 'wim' not in payload:
+        payload = {'wim': payload}
+    payload_req = json.dumps(payload)
+
+    # print(payload_req)
+    if not args.force or (args.name == None and args.filer == None):
+        r = input(" Edit wim " + args.name + " (y/N)? ")
+        if len(r) > 0 and r[0].lower() == "y":
+            pass
+        else:
+            return 0
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.put(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    if args.verbose == None:
+        args.verbose = 0
+    if args.name != None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+
+def wim_delete(args):
+    # print("wim-delete",args)
+    todelete = _get_item_uuid("wims", args.name, "any")
+    if not args.force:
+        r = input("Delete wim {} (y/N)? ".format(args.name))
+        if not (len(r) > 0 and r[0].lower() == "y"):
+            return 0
+    URLrequest = "http://{}:{}/openmano/wims/{}".format(mano_host, mano_port, todelete)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    result = 0 if mano_response.status_code == 200 else mano_response.status_code
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4)
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+
+def wim_list(args):
+    # print("wim-list",args)
+    tenant = 'any' if args.all else _get_tenant()
+
+    if args.name:
+        toshow = _get_item_uuid("wims", args.name, tenant)
+        URLrequest = "http://{}:{}/openmano/{}/wims/{}".format(mano_host, mano_port, tenant, toshow)
+    else:
+        URLrequest = "http://{}:{}/openmano/{}/wims".format(mano_host, mano_port, tenant)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    if args.verbose == None:
+        args.verbose = 0
+    if args.name != None:
+        args.verbose += 1
+    return _print_verbose(mano_response, args.verbose)
+
+
+def wim_port_mapping_set(args):
+    tenant = _get_tenant()
+    wim = _get_wim(args.name, tenant)
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+
+    if not args.file:
+        raise OpenmanoCLIError(
+            "No yaml/json has been provided specifying the WIM port mapping")
+    wim_port_mapping = _load_file_or_yaml(args.file)
+
+    payload_req = json.dumps({"wim_port_mapping": wim_port_mapping})
+
+    # read
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    port_mapping = mano_response.json()
+
+    if mano_response.status_code != 200:
+        str(mano_response.json())
+        raise OpenmanoCLIError("openmano client error: {}".format(port_mapping['error']['description']))
+    # TODO: check this if statement
+    if len(port_mapping["wim_port_mapping"]) > 0:
+        if not args.force:
+            r = input("WIM {} already contains a port mapping. Overwrite? (y/N)? ".format(wim))
+            if not (len(r) > 0 and r[0].lower() == "y"):
+                return 0
+
+        # clear
+        URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
+        mano_response = requests.delete(URLrequest)
+        logger.debug("openmano response: %s", mano_response.text)
+        if mano_response.status_code != 200:
+            return _print_verbose(mano_response, args.verbose)
+
+    # set
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
+    logger.debug("openmano request: %s", payload_req)
+    mano_response = requests.post(URLrequest, headers=headers_req, data=payload_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    return _print_verbose(mano_response, 4)
+
+
+def wim_port_mapping_list(args):
+    tenant = _get_tenant()
+    wim = _get_wim(args.name, tenant)
+
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
+    mano_response = requests.get(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+
+    return _print_verbose(mano_response, 4)
+
+
+def wim_port_mapping_clear(args):
+    tenant = _get_tenant()
+    wim = _get_wim(args.name, tenant)
+
+    if not args.force:
+        r = input("Clear WIM port mapping for wim {} (y/N)? ".format(wim))
+        if not (len(r) > 0 and r[0].lower() == "y"):
+            return 0
+
+    URLrequest = "http://{}:{}/openmano/{}/wims/{}/port_mapping".format(mano_host, mano_port, tenant, wim)
+    mano_response = requests.delete(URLrequest)
+    logger.debug("openmano response: %s", mano_response.text)
+    content = mano_response.json()
+    # print(json.dumps(content, indent=4))
+    result = 0 if mano_response.status_code == 200 else mano_response.status_code
+    if mano_response.status_code == 200:
+        print(content['result'])
+    else:
+        print(content['error']['description'])
+    return result
+
+
+def version(args):
+    headers_req = {'Accept': 'application/json', 'content-type': 'application/json'}
+    URLrequest = "http://{}:{}/openmano/version".format(mano_host, mano_port)
+
+    mano_response = requests.get(URLrequest, headers=headers_req)
+    logger.debug("openmano response: %s", mano_response.text)
+    print(mano_response.text)
+
+
+def main():
+    global mano_host
+    global mano_port
+    global mano_tenant
+    global logger
+    mano_tenant = os.getenv('OPENMANO_TENANT', None)
+    mano_host = os.getenv('OPENMANO_HOST',"localhost")
+    mano_port = os.getenv('OPENMANO_PORT',"9090")
+    mano_datacenter = os.getenv('OPENMANO_DATACENTER',None)
+    # WIM env variable for default WIM
+    mano_wim = os.getenv('OPENMANO_WIM', None)
+
+    main_parser = ThrowingArgumentParser(description='User program to interact with OPENMANO-SERVER (openmanod)')
+    main_parser.add_argument('--version', action='version', help="get version of this client",
+                            version='%(prog)s client version ' + __version__ +
+                                    " (Note: use '%(prog)s version' to get server version)")
+
+    subparsers = main_parser.add_subparsers(help='commands')
+
+    parent_parser = argparse.ArgumentParser(add_help=False)
+    parent_parser.add_argument('--verbose', '-v', action='count', help="increase verbosity level. Use several times")
+    parent_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
+
+    config_parser = subparsers.add_parser('config', parents=[parent_parser], help="prints configuration values")
+    config_parser.add_argument("-n", action="store_true", help="resolves tenant and datacenter names")
+    config_parser.set_defaults(func=config)
+
+    version_parser = subparsers.add_parser('version', parents=[parent_parser], help="get server version")
+    version_parser.set_defaults(func=version)
+
+    vnf_create_parser = subparsers.add_parser('vnf-create', parents=[parent_parser], help="adds a vnf into the catalogue")
+    vnf_create_parser.add_argument("file", action="store", help="location of the JSON file describing the VNF").completer = FilesCompleter
+    vnf_create_parser.add_argument("--name", action="store", help="name of the VNF (if it exists in the VNF descriptor, it is overwritten)")
+    vnf_create_parser.add_argument("--description", action="store", help="description of the VNF (if it exists in the VNF descriptor, it is overwritten)")
+    vnf_create_parser.add_argument("--image-path", action="store",  help="change image path locations (overwritten)")
+    vnf_create_parser.add_argument("--image-name", action="store",  help="change image name (overwritten)")
+    vnf_create_parser.add_argument("--image-checksum", action="store",  help="change image checksum (overwritten)")
+    vnf_create_parser.set_defaults(func=vnf_create)
+
+    vnf_list_parser = subparsers.add_parser('vnf-list', parents=[parent_parser], help="lists information about a vnf")
+    vnf_list_parser.add_argument("name", nargs='?', help="name of the VNF")
+    vnf_list_parser.add_argument("-a", "--all", action="store_true", help="shows all vnfs, not only the owned or public ones")
+    #vnf_list_parser.add_argument('--descriptor', help="prints the VNF descriptor", action="store_true")
+    vnf_list_parser.set_defaults(func=vnf_list)
+
+    vnf_delete_parser = subparsers.add_parser('vnf-delete', parents=[parent_parser], help="deletes a vnf from the catalogue")
+    vnf_delete_parser.add_argument("name", action="store", help="name or uuid of the VNF to be deleted")
+    vnf_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    vnf_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
+    vnf_delete_parser.set_defaults(func=vnf_delete)
+
+    scenario_create_parser = subparsers.add_parser('scenario-create', parents=[parent_parser], help="adds a scenario into the OPENMANO DB")
+    scenario_create_parser.add_argument("file", action="store", help="location of the YAML file describing the scenario").completer = FilesCompleter
+    scenario_create_parser.add_argument("--name", action="store", help="name of the scenario (if it exists in the YAML scenario, it is overwritten)")
+    scenario_create_parser.add_argument("--description", action="store", help="description of the scenario (if it exists in the YAML scenario, it is overwritten)")
+    scenario_create_parser.set_defaults(func=scenario_create)
+
+    scenario_list_parser = subparsers.add_parser('scenario-list', parents=[parent_parser], help="lists information about a scenario")
+    scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario")
+    #scenario_list_parser.add_argument('--descriptor', help="prints the scenario descriptor", action="store_true")
+    scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all scenarios, not only the owned or public ones")
+    scenario_list_parser.set_defaults(func=scenario_list)
+
+    scenario_delete_parser = subparsers.add_parser('scenario-delete', parents=[parent_parser], help="deletes a scenario from the OPENMANO DB")
+    scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario to be deleted")
+    scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
+    scenario_delete_parser.set_defaults(func=scenario_delete)
+
+    scenario_deploy_parser = subparsers.add_parser('scenario-deploy', parents=[parent_parser], help="deploys a scenario")
+    scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be deployed")
+    scenario_deploy_parser.add_argument("name", action="store", help="name of the instance")
+    scenario_deploy_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
+    scenario_deploy_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
+    scenario_deploy_parser.add_argument("--description", action="store", help="description of the instance")
+    scenario_deploy_parser.set_defaults(func=scenario_deploy)
+
+    scenario_deploy_parser = subparsers.add_parser('scenario-verify', help="verifies if a scenario can be deployed (deploys it and deletes it)")
+    scenario_deploy_parser.add_argument("scenario", action="store", help="name or uuid of the scenario to be verified")
+    scenario_deploy_parser.add_argument('--debug', '-d', action='store_true', help="show debug information")
+    scenario_deploy_parser.set_defaults(func=scenario_verify)
+
+    instance_scenario_create_parser = subparsers.add_parser('instance-scenario-create', parents=[parent_parser], help="deploys a scenario")
+    instance_scenario_create_parser.add_argument("file", nargs='?', help="descriptor of the instance. Must be a file or yaml/json text")
+    instance_scenario_create_parser.add_argument("--scenario", action="store", help="name or uuid of the scenario to be deployed")
+    instance_scenario_create_parser.add_argument("--name", action="store", help="name of the instance")
+    instance_scenario_create_parser.add_argument("--nostart", action="store_true", help="does not start the vms, just reserve resources")
+    instance_scenario_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter. Needed if several datacenters are available")
+    instance_scenario_create_parser.add_argument("--netmap-use", action="append", type=str, dest="netmap_use", help="indicates a datacenter network to map a scenario network 'scenario-network=datacenter-network'. Can be used several times")
+    instance_scenario_create_parser.add_argument("--netmap-create", action="append", type=str, dest="netmap_create", help="the scenario network must be created at datacenter 'scenario-network[=datacenter-network-name]' . Can be used several times")
+    instance_scenario_create_parser.add_argument("--keypair", action="append", type=str, dest="keypair", help="public key for ssh access. Format '[user:]key1[,key2...]'. Can be used several times")
+    instance_scenario_create_parser.add_argument("--keypair-auto", action="store_true", dest="keypair_auto", help="Inject the user ssh-keys found at $HOME/.ssh directory")
+    instance_scenario_create_parser.add_argument("--description", action="store", help="description of the instance")
+    instance_scenario_create_parser.set_defaults(func=instance_create)
+
+    instance_scenario_list_parser = subparsers.add_parser('instance-scenario-list', parents=[parent_parser], help="lists information about a scenario instance")
+    instance_scenario_list_parser.add_argument("name", nargs='?', help="name of the scenario instance")
+    instance_scenario_list_parser.add_argument("-a", "--all", action="store_true", help="shows all instance-scenarios, not only the owned")
+    instance_scenario_list_parser.set_defaults(func=instance_scenario_list)
+
+    instance_scenario_delete_parser = subparsers.add_parser('instance-scenario-delete', parents=[parent_parser], help="deletes a scenario instance (and deletes all VM and net instances in VIM)")
+    instance_scenario_delete_parser.add_argument("name", action="store", help="name or uuid of the scenario instance to be deleted")
+    instance_scenario_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    instance_scenario_delete_parser.add_argument("-a", "--all", action="store_true", help="allow delete not owned or privated one")
+    instance_scenario_delete_parser.set_defaults(func=instance_scenario_delete)
+
+    instance_scenario_action_parser = subparsers.add_parser('instance-scenario-action', parents=[parent_parser], help="invoke an action over part or the whole scenario instance")
+    instance_scenario_action_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
+    instance_scenario_action_parser.add_argument("action", action="store", type=str, \
+            choices=["start","pause","resume","shutoff","shutdown","forceOff","rebuild","reboot", "console", "add_public_key","vdu-scaling"],\
+            help="action to send")
+    instance_scenario_action_parser.add_argument("param", nargs='?', help="addional param of the action. e.g. console: novnc; reboot: type; vdu-scaling: '[{vdu-id: xxx, type: create|delete, count: 1}]'")
+    instance_scenario_action_parser.add_argument("--vnf", action="append", help="VNF to act on (can use several entries)")
+    instance_scenario_action_parser.add_argument("--vm", action="append", help="VM to act on (can use several entries)")
+    instance_scenario_action_parser.set_defaults(func=instance_scenario_action)
+
+    action_parser = subparsers.add_parser('action-list', parents=[parent_parser], help="get action over an instance status")
+    action_parser.add_argument("id", nargs='?', action="store", help="action id")
+    action_parser.add_argument("--instance", action="store", help="fitler by this instance_id")
+    action_parser.add_argument("--all", action="store", help="Not filter by tenant")
+    action_parser.set_defaults(func=get_action)
+
+    #instance_scenario_status_parser = subparsers.add_parser('instance-scenario-status', help="show the status of a scenario instance")
+    #instance_scenario_status_parser.add_argument("name", action="store", help="name or uuid of the scenario instance")
+    #instance_scenario_status_parser.set_defaults(func=instance_scenario_status)
+
+    tenant_create_parser = subparsers.add_parser('tenant-create', parents=[parent_parser], help="creates a new tenant")
+    tenant_create_parser.add_argument("name", action="store", help="name for the tenant")
+    tenant_create_parser.add_argument("--description", action="store", help="description of the tenant")
+    tenant_create_parser.set_defaults(func=tenant_create)
+
+    tenant_delete_parser = subparsers.add_parser('tenant-delete', parents=[parent_parser], help="deletes a tenant from the catalogue")
+    tenant_delete_parser.add_argument("name", action="store", help="name or uuid of the tenant to be deleted")
+    tenant_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    tenant_delete_parser.set_defaults(func=tenant_delete)
+
+    tenant_list_parser = subparsers.add_parser('tenant-list', parents=[parent_parser], help="lists information about a tenant")
+    tenant_list_parser.add_argument("name", nargs='?', help="name or uuid of the tenant")
+    tenant_list_parser.set_defaults(func=tenant_list)
+
+    element_edit_parser = subparsers.add_parser('tenant-edit', parents=[parent_parser], help="edits one tenant")
+    element_edit_parser.add_argument("name", help="name or uuid of the tenant")
+    element_edit_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
+    element_edit_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
+    element_edit_parser.set_defaults(func=element_edit, element='tenants')
+
+    datacenter_create_parser = subparsers.add_parser('datacenter-create', parents=[parent_parser], help="creates a new datacenter")
+    datacenter_create_parser.add_argument("name", action="store", help="name for the datacenter")
+    datacenter_create_parser.add_argument("url", action="store", help="url for the datacenter")
+    datacenter_create_parser.add_argument("--url_admin", action="store", help="url for administration for the datacenter")
+    datacenter_create_parser.add_argument("--type", action="store", help="datacenter type: openstack or openvim (default)")
+    datacenter_create_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
+    datacenter_create_parser.add_argument("--description", action="store", help="description of the datacenter")
+    datacenter_create_parser.add_argument("--sdn-controller", action="store", help="Name or uuid of the SDN controller to be used", dest='sdn_controller')
+    datacenter_create_parser.set_defaults(func=datacenter_create)
+
+    datacenter_delete_parser = subparsers.add_parser('datacenter-delete', parents=[parent_parser], help="deletes a datacenter from the catalogue")
+    datacenter_delete_parser.add_argument("name", action="store", help="name or uuid of the datacenter to be deleted")
+    datacenter_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    datacenter_delete_parser.set_defaults(func=datacenter_delete)
+
+    datacenter_edit_parser = subparsers.add_parser('datacenter-edit', parents=[parent_parser], help="Edit datacenter")
+    datacenter_edit_parser.add_argument("name", help="name or uuid of the datacenter")
+    datacenter_edit_parser.add_argument("--file", help="json/yaml text or file with the changes").completer = FilesCompleter
+    datacenter_edit_parser.add_argument("--sdn-controller", action="store",
+                                          help="Name or uuid of the SDN controller to be used. Specify 'null' to clear entry", dest='sdn_controller')
+    datacenter_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
+    datacenter_edit_parser.set_defaults(func=datacenter_edit)
+
+    datacenter_list_parser = subparsers.add_parser('datacenter-list', parents=[parent_parser], help="lists information about a datacenter")
+    datacenter_list_parser.add_argument("name", nargs='?', help="name or uuid of the datacenter")
+    datacenter_list_parser.add_argument("-a", "--all", action="store_true", help="shows all datacenters, not only datacenters attached to tenant")
+    datacenter_list_parser.set_defaults(func=datacenter_list)
+
+    datacenter_attach_parser = subparsers.add_parser('datacenter-attach', parents=[parent_parser], help="associates a datacenter to the operating tenant")
+    datacenter_attach_parser.add_argument("name", help="name or uuid of the datacenter")
+    datacenter_attach_parser.add_argument('--vim-tenant-id', action='store', help="specify a datacenter tenant to use. A new one is created by default")
+    datacenter_attach_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
+    datacenter_attach_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
+    datacenter_attach_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
+    datacenter_attach_parser.add_argument("--config", action="store", help="aditional configuration in json/yaml format")
+    datacenter_attach_parser.set_defaults(func=datacenter_attach)
+
+    datacenter_edit_vim_tenant_parser = subparsers.add_parser('datacenter-edit-vim-tenant', parents=[parent_parser],
+                                                     help="Edit the association of a datacenter to the operating tenant")
+    datacenter_edit_vim_tenant_parser.add_argument("name", help="name or uuid of the datacenter")
+    datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-id', action='store',
+                                          help="specify a datacenter tenant to use. A new one is created by default")
+    datacenter_edit_vim_tenant_parser.add_argument('--vim-tenant-name', action='store', help="specify a datacenter tenant name.")
+    datacenter_edit_vim_tenant_parser.add_argument("--user", action="store", help="user credentials for the datacenter")
+    datacenter_edit_vim_tenant_parser.add_argument("--password", action="store", help="password credentials for the datacenter")
+    datacenter_edit_vim_tenant_parser.add_argument("--config", action="store",
+                                          help="aditional configuration in json/yaml format")
+    datacenter_edit_vim_tenant_parser.set_defaults(func=datacenter_edit_vim_tenant)
+
+    datacenter_detach_parser = subparsers.add_parser('datacenter-detach', parents=[parent_parser], help="removes the association between a datacenter and the operating tenant")
+    datacenter_detach_parser.add_argument("name", help="name or uuid of the datacenter")
+    datacenter_detach_parser.add_argument("-a", "--all", action="store_true", help="removes all associations from this datacenter")
+    datacenter_detach_parser.set_defaults(func=datacenter_detach)
+
+    #=======================datacenter_sdn_port_mapping_xxx section=======================
+    #datacenter_sdn_port_mapping_set
+    datacenter_sdn_port_mapping_set_parser = subparsers.add_parser('datacenter-sdn-port-mapping-set',
+                                                                   parents=[parent_parser],
+                                                                   help="Load a file with the mapping of physical ports "
+                                                                        "and the ports of the dataplaneswitch controlled "
+                                                                        "by a datacenter")
+    datacenter_sdn_port_mapping_set_parser.add_argument("name", action="store", help="specifies the datacenter")
+    datacenter_sdn_port_mapping_set_parser.add_argument("file",
+                                                        help="json/yaml text or file with the port mapping").completer = FilesCompleter
+    datacenter_sdn_port_mapping_set_parser.add_argument("-f", "--force", action="store_true",
+                                                          help="forces overwriting without asking")
+    datacenter_sdn_port_mapping_set_parser.set_defaults(func=datacenter_sdn_port_mapping_set)
+
+    #datacenter_sdn_port_mapping_list
+    datacenter_sdn_port_mapping_list_parser = subparsers.add_parser('datacenter-sdn-port-mapping-list',
+                                                                    parents=[parent_parser],
+                                                                    help="Show the SDN port mapping in a datacenter")
+    datacenter_sdn_port_mapping_list_parser.add_argument("name", action="store", help="specifies the datacenter")
+    datacenter_sdn_port_mapping_list_parser.set_defaults(func=datacenter_sdn_port_mapping_list)
+
+    # datacenter_sdn_port_mapping_clear
+    datacenter_sdn_port_mapping_clear_parser = subparsers.add_parser('datacenter-sdn-port-mapping-clear',
+                                                                    parents=[parent_parser],
+                                                                    help="Clean the the SDN port mapping in a datacenter")
+    datacenter_sdn_port_mapping_clear_parser.add_argument("name", action="store",
+                                                         help="specifies the datacenter")
+    datacenter_sdn_port_mapping_clear_parser.add_argument("-f", "--force", action="store_true",
+                                              help="forces clearing without asking")
+    datacenter_sdn_port_mapping_clear_parser.set_defaults(func=datacenter_sdn_port_mapping_clear)
+    # =======================
+
+    # =======================sdn_controller_xxx section=======================
+    # sdn_controller_create
+    sdn_controller_create_parser = subparsers.add_parser('sdn-controller-create', parents=[parent_parser],
+                                                        help="Creates an SDN controller entity within RO")
+    sdn_controller_create_parser.add_argument("name", help="name of the SDN controller")
+    sdn_controller_create_parser.add_argument("--description", action="store", help="description of the SDN controller")
+    sdn_controller_create_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
+    sdn_controller_create_parser.add_argument("--port", action="store", help="Port of the SDN controller")
+    sdn_controller_create_parser.add_argument("--dpid", action="store",
+                                             help="DPID of the dataplane switch controlled by this SDN controller")
+    sdn_controller_create_parser.add_argument("--type", action="store",
+                                             help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
+    sdn_controller_create_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
+    sdn_controller_create_parser.add_argument("--passwd", action="store", dest='password',
+                                             help="password credentials for the SDN controller")
+    sdn_controller_create_parser.set_defaults(func=sdn_controller_create)
+
+    # sdn_controller_edit
+    sdn_controller_edit_parser = subparsers.add_parser('sdn-controller-edit', parents=[parent_parser],
+                                                        help="Update one or more options of a SDN controller")
+    sdn_controller_edit_parser.add_argument("name", help="name or uuid of the SDN controller", )
+    sdn_controller_edit_parser.add_argument("--name", action="store", help="Update the name of the SDN controller",
+                                              dest='new_name')
+    sdn_controller_edit_parser.add_argument("--description", action="store", help="description of the SDN controller")
+    sdn_controller_edit_parser.add_argument("--ip", action="store", help="IP of the SDN controller")
+    sdn_controller_edit_parser.add_argument("--port", action="store", help="Port of the SDN controller")
+    sdn_controller_edit_parser.add_argument("--dpid", action="store",
+                                             help="DPID of the dataplane switch controlled by this SDN controller")
+    sdn_controller_edit_parser.add_argument("--type", action="store",
+                                             help="Specify the SDN controller type. Valid types are 'opendaylight' and 'floodlight'")
+    sdn_controller_edit_parser.add_argument("--user", action="store", help="user credentials for the SDN controller")
+    sdn_controller_edit_parser.add_argument("--password", action="store",
+                                             help="password credentials for the SDN controller", dest='password')
+    sdn_controller_edit_parser.add_argument("-f", "--force", action="store_true", help="do not prompt for confirmation")
+    #TODO: include option --file
+    sdn_controller_edit_parser.set_defaults(func=sdn_controller_edit)
+
+    #sdn_controller_list
+    sdn_controller_list_parser = subparsers.add_parser('sdn-controller-list',
+                                                                    parents=[parent_parser],
+                                                                    help="List the SDN controllers")
+    sdn_controller_list_parser.add_argument("name", nargs='?', help="name or uuid of the SDN controller")
+    sdn_controller_list_parser.set_defaults(func=sdn_controller_list)
+
+    # sdn_controller_delete
+    sdn_controller_delete_parser = subparsers.add_parser('sdn-controller-delete',
+                                                                    parents=[parent_parser],
+                                                                    help="Delete the the SDN controller")
+    sdn_controller_delete_parser.add_argument("name", help="name or uuid of the SDN controller")
+    sdn_controller_delete_parser.add_argument("-f", "--force", action="store_true", help="forces deletion without asking")
+    sdn_controller_delete_parser.set_defaults(func=sdn_controller_delete)
+    # =======================
+
+    # WIM ======================= WIM section==================
+
+    # WIM create
+    wim_create_parser = subparsers.add_parser('wim-create',
+                                              parents=[parent_parser], help="creates a new wim")
+    wim_create_parser.add_argument("name", action="store",
+                                   help="name for the wim")
+    wim_create_parser.add_argument("url", action="store",
+                                   help="url for the wim")
+    wim_create_parser.add_argument("--type", action="store",
+                                   help="wim type: ietfl2vpn, dynpac, ...")
+    wim_create_parser.add_argument("--config", action="store",
+                                   help="additional configuration in json/yaml format")
+    wim_create_parser.add_argument("--description", action="store",
+                                   help="description of the wim")
+    wim_create_parser.set_defaults(func=wim_create)
+
+    # WIM delete
+    wim_delete_parser = subparsers.add_parser('wim-delete',
+                                              parents=[parent_parser], help="deletes a wim from the catalogue")
+    wim_delete_parser.add_argument("name", action="store",
+                                   help="name or uuid of the wim to be deleted")
+    wim_delete_parser.add_argument("-f", "--force", action="store_true",
+                                   help="forces deletion without asking")
+    wim_delete_parser.set_defaults(func=wim_delete)
+
+    # WIM edit
+    wim_edit_parser = subparsers.add_parser('wim-edit',
+                                            parents=[parent_parser], help="edits a wim")
+    wim_edit_parser.add_argument("name", help="name or uuid of the wim")
+    wim_edit_parser.add_argument("--file",
+                                 help="json/yaml text or file with the changes")\
+                                .completer = FilesCompleter
+    wim_edit_parser.add_argument("-f", "--force", action="store_true",
+                                 help="do not prompt for confirmation")
+    wim_edit_parser.set_defaults(func=wim_edit)
+
+    # WIM list
+    wim_list_parser = subparsers.add_parser('wim-list',
+                                            parents=[parent_parser],
+                                            help="lists information about registered wims")
+    wim_list_parser.add_argument("name", nargs='?',
+                                 help="name or uuid of the wim")
+    wim_list_parser.add_argument("-a", "--all", action="store_true",
+                                 help="shows all wims, not only wims attached to tenant")
+    wim_list_parser.set_defaults(func=wim_list)
+
+    # WIM account create
+    wim_attach_parser = subparsers.add_parser('wim-account-create', parents=
+    [parent_parser], help="associates a wim account to the operating tenant")
+    wim_attach_parser.add_argument("name", help="name or uuid of the wim")
+    wim_attach_parser.add_argument('--account-name', action='store',
+                                   help="specify a name for the wim account.")
+    wim_attach_parser.add_argument("--user", action="store",
+                                   help="user credentials for the wim account")
+    wim_attach_parser.add_argument("--password", action="store",
+                                   help="password credentials for the wim account")
+    wim_attach_parser.add_argument("--config", action="store",
+                                   help="additional configuration in json/yaml format")
+    wim_attach_parser.set_defaults(func=wim_account_create)
+
+    # WIM account delete
+    wim_detach_parser = subparsers.add_parser('wim-account-delete',
+                                        parents=[parent_parser],
+                                        help="removes the association "
+                                                "between a wim account and the operating tenant")
+    wim_detach_parser.add_argument("name", help="name or uuid of the wim")
+    wim_detach_parser.add_argument("-a", "--all", action="store_true",
+                                   help="removes all associations from this wim")
+    wim_detach_parser.add_argument("-f", "--force", action="store_true",
+                                   help="forces delete without asking")
+    wim_detach_parser.set_defaults(func=wim_account_delete)
+
+    # WIM account edit
+    wim_attach_edit_parser = subparsers.add_parser('wim-account-edit', parents=
+    [parent_parser], help="modifies the association of a wim account to the operating tenant")
+    wim_attach_edit_parser.add_argument("name", help="name or uuid of the wim")
+    wim_attach_edit_parser.add_argument('--account-name', action='store',
+                                   help="specify a name for the wim account.")
+    wim_attach_edit_parser.add_argument("--user", action="store",
+                                   help="user credentials for the wim account")
+    wim_attach_edit_parser.add_argument("--password", action="store",
+                                   help="password credentials for the wim account")
+    wim_attach_edit_parser.add_argument("--config", action="store",
+                                   help="additional configuration in json/yaml format")
+    wim_attach_edit_parser.set_defaults(func=wim_account_edit)
+
+    # WIM port mapping set
+    wim_port_mapping_set_parser = subparsers.add_parser('wim-port-mapping-set',
+                                                        parents=[parent_parser],
+                                                        help="Load a file with the mappings "
+                                                                "of ports of a WAN switch that is "
+                                                                "connected to a PoP and the ports "
+                                                                "of the switch controlled by the PoP")
+    wim_port_mapping_set_parser.add_argument("name", action="store",
+                                             help="specifies the wim")
+    wim_port_mapping_set_parser.add_argument("file",
+                                             help="json/yaml text or file with the wim port mapping")\
+        .completer = FilesCompleter
+    wim_port_mapping_set_parser.add_argument("-f", "--force",
+                                             action="store_true", help="forces overwriting without asking")
+    wim_port_mapping_set_parser.set_defaults(func=wim_port_mapping_set)
+
+    # WIM port mapping list
+    wim_port_mapping_list_parser = subparsers.add_parser('wim-port-mapping-list',
+            parents=[parent_parser], help="Show the port mappings for a wim")
+    wim_port_mapping_list_parser.add_argument("name", action="store",
+                                              help="specifies the wim")
+    wim_port_mapping_list_parser.set_defaults(func=wim_port_mapping_list)
+
+    # WIM port mapping clear
+    wim_port_mapping_clear_parser = subparsers.add_parser('wim-port-mapping-clear',
+            parents=[parent_parser], help="Clean the port mapping in a wim")
+    wim_port_mapping_clear_parser.add_argument("name", action="store",
+                                               help="specifies the wim")
+    wim_port_mapping_clear_parser.add_argument("-f", "--force",
+                                               action="store_true",
+                                               help="forces clearing without asking")
+    wim_port_mapping_clear_parser.set_defaults(func=wim_port_mapping_clear)
+
+    # =======================================================
+
+    action_dict={'net-update': 'retrieves external networks from datacenter',
+                 'net-edit': 'edits an external network',
+                 'net-delete': 'deletes an external network',
+                 'net-list': 'lists external networks from a datacenter'
+                 }
+    for item in action_dict:
+        datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
+        datacenter_action_parser.add_argument("datacenter", help="name or uuid of the datacenter")
+        if item=='net-edit' or item=='net-delete':
+            datacenter_action_parser.add_argument("net", help="name or uuid of the datacenter net")
+        if item=='net-edit':
+            datacenter_action_parser.add_argument("file", help="json/yaml text or file with the changes").completer = FilesCompleter
+        if item!='net-list':
+            datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
+        datacenter_action_parser.set_defaults(func=datacenter_net_action, action=item)
+
+
+    action_dict={'netmap-import': 'create network senario netmap base on the datacenter networks',
+                 'netmap-create': 'create a new network senario netmap',
+                 'netmap-edit':   'edit name of a network senario netmap',
+                 'netmap-delete': 'deletes a network scenario netmap (--all for clearing all)',
+                 'netmap-list':   'list/show network scenario netmaps'
+                 }
+    for item in action_dict:
+        datacenter_action_parser = subparsers.add_parser('datacenter-'+item, parents=[parent_parser], help=action_dict[item])
+        datacenter_action_parser.add_argument("--datacenter", help="name or uuid of the datacenter")
+        #if item=='net-add':
+        #    datacenter_action_parser.add_argument("net", help="name of the network")
+        if item=='netmap-delete':
+            datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to delete")
+            datacenter_action_parser.add_argument("--all", action="store_true", help="delete all netmap of this datacenter")
+            datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
+        if item=='netmap-edit':
+            datacenter_action_parser.add_argument("netmap", help="name or uuid of the datacenter netmap do edit")
+            datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file with the changes").completer = FilesCompleter
+            datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap")
+            datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
+            datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
+        if item=='netmap-list':
+            datacenter_action_parser.add_argument("netmap", nargs='?',help="name or uuid of the datacenter netmap to show")
+        if item=='netmap-create':
+            datacenter_action_parser.add_argument("file", nargs='?', help="json/yaml text or file descriptor with the changes").completer = FilesCompleter
+            datacenter_action_parser.add_argument("--name", action='store', help="name to assign to the datacenter netmap, by default same as vim-name")
+            datacenter_action_parser.add_argument('--vim-id', action='store', help="specify vim network uuid")
+            datacenter_action_parser.add_argument('--vim-name', action='store', help="specify vim network name")
+        if item=='netmap-import':
+            datacenter_action_parser.add_argument("-f","--force", action="store_true", help="do not prompt for confirmation")
+        datacenter_action_parser.set_defaults(func=datacenter_netmap_action, action=item)
+
+    # =======================vim_net_sdn_xxx section=======================
+    # vim_net_sdn_attach
+    vim_net_sdn_attach_parser = subparsers.add_parser('vim-net-sdn-attach',
+                                                      parents=[parent_parser],
+                                                      help="Specify the port to access to an external network using SDN")
+    vim_net_sdn_attach_parser.add_argument("vim_net", action="store",
+                                                help="Name/id of the network in the vim that will be used to connect to the external network")
+    vim_net_sdn_attach_parser.add_argument("port", action="store", help="Specifies the port in the dataplane switch to access to the external network")
+    vim_net_sdn_attach_parser.add_argument("--vlan", action="store", help="Specifies the vlan (if any) to use in the defined port")
+    vim_net_sdn_attach_parser.add_argument("--mac", action="store", help="Specifies the MAC (if known) of the physical device that will be reachable by this external port")
+    vim_net_sdn_attach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+    vim_net_sdn_attach_parser.set_defaults(func=vim_net_sdn_attach)
+
+    # vim_net_sdn_detach
+    vim_net_sdn_detach_parser = subparsers.add_parser('vim-net-sdn-detach',
+                                                           parents=[parent_parser],
+                                                           help="Remove the port information to access to an external network using SDN")
+
+    vim_net_sdn_detach_parser.add_argument("vim_net", action="store", help="Name/id of the vim network")
+    vim_net_sdn_detach_parser.add_argument("--id", action="store",help="Specify the uuid of the external ports from this network to be detached")
+    vim_net_sdn_detach_parser.add_argument("--all", action="store_true", help="Detach all external ports from this network")
+    vim_net_sdn_detach_parser.add_argument("-f", "--force", action="store_true", help="forces clearing without asking")
+    vim_net_sdn_detach_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+    vim_net_sdn_detach_parser.set_defaults(func=vim_net_sdn_detach)
+    # =======================
+
+    for item in ("network", "tenant", "image"):
+        if item=="network":
+            command_name = 'vim-net'
+        else:
+            command_name = 'vim-'+item
+        vim_item_list_parser = subparsers.add_parser(command_name + '-list', parents=[parent_parser], help="list the vim " + item + "s")
+        vim_item_list_parser.add_argument("name", nargs='?', help="name or uuid of the " + item + "s")
+        vim_item_list_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+        vim_item_list_parser.set_defaults(func=vim_action, item=item, action="list")
+
+        vim_item_del_parser = subparsers.add_parser(command_name + '-delete', parents=[parent_parser], help="list the vim " + item + "s")
+        vim_item_del_parser.add_argument("name", help="name or uuid of the " + item + "s")
+        vim_item_del_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+        vim_item_del_parser.set_defaults(func=vim_action, item=item, action="delete")
+
+        if item == "network" or item == "tenant":
+            vim_item_create_parser = subparsers.add_parser(command_name + '-create', parents=[parent_parser], help="create a "+item+" at vim")
+            vim_item_create_parser.add_argument("file", nargs='?', help="descriptor of the {}. Must be a file or yaml/json text".format(item)).completer = FilesCompleter
+            vim_item_create_parser.add_argument("--name", action="store", help="name of the {}".format(item))
+            vim_item_create_parser.add_argument("--datacenter", action="store", help="specifies the datacenter")
+            if item=="network":
+                vim_item_create_parser.add_argument("--type", action="store", help="type of network, data, ptp, bridge")
+                vim_item_create_parser.add_argument("--shared", action="store_true", help="Private or shared")
+                vim_item_create_parser.add_argument("--bind-net", action="store", help="For openvim datacenter type, net to be bind to, for vlan type, use sufix ':<vlan_tag>'")
+            else:
+                vim_item_create_parser.add_argument("--description", action="store", help="description of the {}".format(item))
+            vim_item_create_parser.set_defaults(func=vim_action, item=item, action="create")
+
+    argcomplete.autocomplete(main_parser)
+
+    try:
+        args = main_parser.parse_args()
+        #logging info
+        level = logging.CRITICAL
+        streamformat = "%(asctime)s %(name)s %(levelname)s: %(message)s"
+        if "debug" in args and args.debug:
+            level = logging.DEBUG
+        logging.basicConfig(format=streamformat, level= level)
+        logger = logging.getLogger('mano')
+        logger.setLevel(level)
+        # print("#TODO py3", args)
+        result = args.func(args)
+        if result == None:
+            result = 0
+        #for some reason it fails if call exit inside try instance. Need to call exit at the end !?
+    except (requests.exceptions.ConnectionError):
+        print("Connection error: not possible to contact OPENMANO-SERVER (openmanod)")
+        result = -2
+    except (KeyboardInterrupt):
+        print('Exiting openmano')
+        result = -3
+    except (SystemExit, ArgumentParserError):
+        result = -4
+    except (AttributeError):
+        print("Type '--help' for more information")
+        result = -4
+    except OpenmanoCLIError as e:
+        # print("#TODO py3", e)
+        print(e)
+        result = -5
+
+    # print(result)
+    exit(result)
+
+
+if __name__ == '__main__':
+    main()
+
diff --git a/RO-client/requirements.txt b/RO-client/requirements.txt
new file mode 100644 (file)
index 0000000..fd9682c
--- /dev/null
@@ -0,0 +1,17 @@
+##
+# 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.
+##
+
+argcomplete
+requests==2.*
+PyYAML
diff --git a/RO-client/setup.py b/RO-client/setup.py
new file mode 100644 (file)
index 0000000..d1748cd
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright 2018 Telefonica S.A.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from setuptools import setup
+
+_name = "osm_roclient"
+# version is at first line of osm_roclient/html_public/version
+here = os.path.abspath(os.path.dirname(__file__))
+with open(os.path.join(here, 'README.rst')) as readme_file:
+    README = readme_file.read()
+
+setup(
+    name=_name,
+    description='OSM ro client',
+    long_description=README,
+    version_command=('git describe --match v* --tags --long --dirty', 'pep440-git-full'),
+    # version=VERSION,
+    # python_requires='>3.5.0',
+    author='ETSI OSM',
+    author_email='alfonso.tiernosepulveda@telefonica.com',
+    maintainer='Alfonso Tierno',
+    maintainer_email='alfonso.tiernosepulveda@telefonica.com',
+    url='https://osm.etsi.org/gitweb/?p=osm/LCM.git;a=summary',
+    license='Apache 2.0',
+
+    packages=[_name],
+    include_package_data=True,
+    # data_files=[('/etc/osm/', ['osm_roclient/lcm.cfg']),
+    #             ('/etc/systemd/system/', ['osm_roclient/osm-lcm.service']),
+    #             ],
+    install_requires=[
+        'PyYAML',
+        'requests==2.*',
+        'argcomplete',
+    ],
+    setup_requires=['setuptools-version-command'],
+    entry_points={
+        "console_scripts": [
+            "openmano=osm_roclient.roclient:main"
+        ]
+    },
+)
diff --git a/RO-client/stdeb.cfg b/RO-client/stdeb.cfg
new file mode 100644 (file)
index 0000000..94477fb
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+[DEFAULT]
+X-Python3-Version : >= 3.5
+Maintainer: Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>
+Depends3: python3-argcomplete, python3-requests, python3-yaml
diff --git a/RO-client/tox.ini b/RO-client/tox.ini
new file mode 100644 (file)
index 0000000..a131fea
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright 2018 Telefonica S.A.
+#
+# 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.
+
+[tox]
+envlist = flake8
+toxworkdir={toxinidir}/../.tox
+
+[testenv]
+basepython = python3
+install_command = python3 -m pip install -r requirements.txt -U {opts} {packages}
+
+[testenv:flake8]
+basepython = python3
+deps = flake8
+commands = flake8 osm_roclient --max-line-length 120 \
+    --exclude .svn,CVS,.gz,.git,__pycache__,.tox,local,temp --ignore W291,W293,E226,W504
+
+[testenv:unittest]
+basepython = python3
+commands = python3 -m unittest osm_roclient.tests
+
+[testenv:build]
+basepython = python3
+deps = stdeb
+       setuptools-version-command
+commands = python3 setup.py --command-packages=stdeb.command bdist_deb
+
diff --git a/RO/MANIFEST.in b/RO/MANIFEST.in
new file mode 100644 (file)
index 0000000..7251d31
--- /dev/null
@@ -0,0 +1,21 @@
+##
+# 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.
+##
+
+#include MANIFEST.in
+#include requirements.txt
+include README.rst
+include requirements.txt
+include README.rst
+recursive-include osm_ro *
+
diff --git a/RO/Makefile b/RO/Makefile
new file mode 100644 (file)
index 0000000..437ce0e
--- /dev/null
@@ -0,0 +1,123 @@
+# Copyright 2018 Telefonica S.A.
+#
+# 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.
+
+.PHONY: all test clean
+
+SHELL := /bin/bash
+
+BRANCH ?= master
+
+all:  clean package
+
+clean:
+       rm -rf dist deb_dist osm_ro-*.tar.gz osm_ro.egg-info .eggs
+       find osm_ro -name '*.pyc' -delete
+       find osm_ro -name '*.pyo' -delete
+
+package:
+#      apt-get install -y python-stdeb
+       python3 setup.py --command-packages=stdeb.command sdist_dsc
+       cp debian/python3-osm-ro.postinst deb_dist/osm-ro*/debian/
+       # cd deb_dist/osm-nbi*/debian && echo "cryptography python3-cryptography (>= 1.9)" > py3dist-overrides
+       cd deb_dist/osm-ro*/ && dpkg-buildpackage -rfakeroot -uc -us
+       # mkdir -p .build
+       # cp build/deb_dist/python-*.deb .build/
+
+clean_build:
+       rm -rf build
+       find osm_ro -name '*.pyc' -delete
+       find osm_ro -name '*.pyo' -delete
+
+prepare:
+#      ip install --user --upgrade setuptools
+       mkdir -p build/
+#      VER1=$(shell git describe | sed -e 's/^v//' |cut -d- -f1); \
+#      VER2=$(shell git describe | cut -d- -f2); \
+#      VER3=$(shell git describe | cut -d- -f3); \
+#      echo "$$VER1.dev$$VER2+$$VER3" > build/RO_VERSION
+       cp tox.ini build/
+       cp MANIFEST.in build/
+       cp requirements.txt build/
+       cp README.rst build/
+       cp setup.py build/
+       cp stdeb.cfg build/
+       cp -r osm_ro build/
+       cp openmano build/
+       cp openmanod build/
+       cp -r vnfs build/osm_ro
+       cp -r scenarios build/osm_ro
+       cp -r instance-scenarios build/osm_ro
+       cp -r scripts build/osm_ro
+       cp -r database_utils build/osm_ro
+       cp LICENSE build/osm_ro
+
+connectors: prepare
+       # python-novaclient is required for that
+       rm -f build/osm_ro/openmanolinkervimconn.py
+       cd build/osm_ro; for i in `ls vimconn_*.py |sed "s/\.py//"` ; do echo "import $$i" >> openmanolinkervimconn.py; done
+       python build/osm_ro/openmanolinkervimconn.py 2>&1
+       rm -f build/osm_ro/openmanolinkervimconn.py
+
+build: connectors prepare
+       python -m py_compile build/osm_ro/*.py
+#      cd build && tox -e flake8
+
+lib-openvim:
+       $(shell git clone https://osm.etsi.org/gerrit/osm/openvim)
+       LIB_BRANCH=$(shell git -C openvim branch -a|grep -oP 'remotes/origin/\K$(BRANCH)'); \
+       [ -z "$$LIB_BRANCH" ] && LIB_BRANCH='master'; \
+       echo "BRANCH: $(BRANCH)"; \
+       echo "LIB_OPENVIM_BRANCH: $$LIB_BRANCH"; \
+       git -C openvim checkout $$LIB_BRANCH
+       make -C openvim clean lite
+
+osm-im:
+       $(shell git clone https://osm.etsi.org/gerrit/osm/IM)
+       make -C IM clean all
+
+snap:
+       echo "Nothing to be done yet"
+
+install: lib-openvim osm-im
+       dpkg -i IM/deb_dist/python-osm-im*.deb
+       dpkg -i openvim/.build/python-lib-osm-openvim*.deb
+       dpkg -i .build/python-osm-ro*.deb
+       cd .. && \
+       OSMLIBOVIM_PATH=`python -c 'import lib_osm_openvim; print lib_osm_openvim.__path__[0]'` || FATAL "lib-osm-openvim was not properly installed" && \
+       OSMRO_PATH=`python -c 'import osm_ro; print osm_ro.__path__[0]'` || FATAL "osm-ro was not properly installed" && \
+       USER=root DEBIAN_FRONTEND=noninteractive $$OSMRO_PATH/database_utils/install-db-server.sh --updatedb || FATAL "osm-ro db installation failed" && \
+       USER=root DEBIAN_FRONTEND=noninteractive $$OSMLIBOVIM_PATH/database_utils/install-db-server.sh -u mano -p manopw -d mano_vim_db --updatedb || FATAL "lib-osm-openvim db installation failed"
+       service osm-ro restart
+
+develop: prepare
+#      pip install -r requirements.txt
+       cd build && ./setup.py develop
+
+test:
+       . ./test/basictest.sh -f --insert-bashrc --install-openvim --init-openvim
+       . ./test/basictest.sh -f reset add-openvim
+       ./test/test_RO.py deploy -n mgmt -t osm -i cirros034 -d local-openvim --timeout=30 --failfast
+       ./test/test_RO.py vim  -t osm  -d local-openvim --timeout=30 --failfast
+
+build-docker-from-source:
+       docker build -t osm/openmano -f docker/Dockerfile-local .
+
+run-docker:
+       docker-compose -f docker/openmano-compose.yml up
+
+stop-docker:
+       docker-compose -f docker/openmano-compose.yml down
+
+
diff --git a/RO/README.rst b/RO/README.rst
new file mode 100644 (file)
index 0000000..44a4fc4
--- /dev/null
@@ -0,0 +1,22 @@
+ Copyright 2018 Telefonica S.A.
+ 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.
+
+===========
+osm-ro
+===========
+
+osm-ro is the Resource Orchestrator for OSM, dealing with resource operations
+against different VIMs such as Openstack, VMware's vCloud Director, openvim
+and AWS.
+
diff --git a/RO/debian/python3-osm-ro.postinst b/RO/debian/python3-osm-ro.postinst
new file mode 100755 (executable)
index 0000000..877a496
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+##
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: OSM_TECH@list.etsi.org
+##
+
+echo "POST INSTALL OSM-RO"
+# Ensure a proper version of cryptography, needed by paramiko
+python3 -m pip install "cryptography>=2.5" -U
diff --git a/RO/osm_ro/__init__.py b/RO/osm_ro/__init__.py
new file mode 100644 (file)
index 0000000..7284a2b
--- /dev/null
@@ -0,0 +1,13 @@
+##
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+##
diff --git a/RO/osm_ro/console_proxy_thread.py b/RO/osm_ro/console_proxy_thread.py
new file mode 100644 (file)
index 0000000..0c44899
--- /dev/null
@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+'''
+Implement like a proxy for TCP/IP in a separated thread.
+It creates two sockets to bypass the TCP/IP packets among the fix console 
+server specified at class construction (console_host, console_port)
+and a client that connect against the (host, port) specified also at construction
+
+                ---------------------           -------------------------------
+                |       OPENMANO     |          |         VIM                  |
+client 1  ----> | ConsoleProxyThread | ------>  |  Console server              |
+client 2  ----> |  (host, port)      | ------>  |(console_host, console_server)|
+   ...           --------------------            ------------------------------
+'''
+__author__="Alfonso Tierno"
+__date__ ="$19-nov-2015 09:07:15$"
+
+import socket
+import select
+import threading
+import logging
+
+
+class ConsoleProxyException(Exception):
+    '''raise when an exception has found''' 
+class ConsoleProxyExceptionPortUsed(ConsoleProxyException):
+    '''raise when the port is used''' 
+
+class ConsoleProxyThread(threading.Thread):
+    buffer_size = 4096
+    check_finish = 1 #frequency to check if requested to end in seconds
+
+    def __init__(self, host, port, console_host, console_port, log_level=None):
+        try:
+            threading.Thread.__init__(self)
+            self.console_host = console_host
+            self.console_port = console_port
+            self.host = host
+            self.port = port
+            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            self.server.bind((host, port))
+            self.server.listen(200)
+            #TODO timeout in a lock section can be used to autoterminate the thread
+            #when inactivity and timeout<time : set timeout=0 and terminate
+            #from outside, close class when timeout==0; set timeout=time+120 when adding a new console on this thread
+            #set self.timeout = time.time() + 120 at init
+            self.name = "ConsoleProxy " + console_host + ":" + str(console_port)
+            self.input_list = [self.server]
+            self.channel = {}
+            self.terminate = False #put at True from outside to force termination
+            self.logger = logging.getLogger('openmano.console')
+            if log_level:
+                self.logger.setLevel( getattr(logging, log_level) )
+
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            if e is socket.error and e.errno==98:
+                raise ConsoleProxyExceptionPortUsed("socket.error " + str(e))
+            raise ConsoleProxyException(type(e).__name__ + ": "+  (str(e) if len(e.args)==0 else str(e.args[0])) )
+        
+    def run(self):
+        while True:
+            try:
+                inputready, _, _ = select.select(self.input_list, [], [], self.check_finish)
+            except select.error as e:
+                self.logger.error("Exception on select %s: %s", type(e).__name__, str(e) )
+                self.on_terminate()
+
+            if self.terminate:
+                self.on_terminate()
+                self.logger.debug("Terminate because commanded")
+                break
+            
+            for sock in inputready:
+                if sock == self.server:
+                    self.on_accept()
+                else:
+                    self.on_recv(sock)
+                    
+    def on_terminate(self):
+        while self.input_list:
+            if self.input_list[0] is self.server:
+                self.server.close()
+                del self.input_list[0]
+            else:
+                self.on_close(self.input_list[0], "Terminating thread")
+
+    def on_accept(self):
+        #accept
+        try:
+            clientsock, clientaddr = self.server.accept()
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            self.logger.error("Exception on_accept %s: %s", type(e).__name__, str(e) )
+            return False
+        #print self.name, ": Accept new client ", clientaddr
+
+        #connect
+        try:
+            forward = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            forward.connect((self.console_host, self.console_port))
+            name = "{}:{} => ({}:{} => {}:{}) => {}:{}".format(
+                *clientsock.getpeername(), *clientsock.getsockname(), *forward.getsockname(), *forward.getpeername() )
+            self.logger.warning("new connection " + name)
+                
+            self.input_list.append(clientsock)
+            self.input_list.append(forward)
+            info = { "name": name,
+                    "clientsock" : clientsock,
+                    "serversock" : forward
+                    }
+            self.channel[clientsock] = info
+            self.channel[forward] = info
+            return True
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            self.logger.error("Exception on_connect to server %s:%d; %s: %s  Close client side %s",
+                self.console_host, self.console_port, type(e).__name__, str(e), str(clientaddr) )
+            clientsock.close()
+            return False
+
+    def on_close(self, sock, cause):
+        if sock not in self.channel:
+            return  #can happen if there is data ready to received at both sides and the channel has been deleted. QUITE IMPROBABLE but just in case
+        info = self.channel[sock]
+        # debug info
+        sockname = "client" if sock is info["clientsock"] else "server"
+        self.logger.warning("del connection %s %s at %s side", info["name"], str(cause), str(sockname))
+        # close sockets
+        try:
+            # close the connection with client
+            info["clientsock"].close()  # equivalent to do self.s.close()
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            self.logger.error("Exception on_close client socket %s: %s", type(e).__name__, str(e))
+        try:
+            # close the connection with remote server
+            info["serversock"].close()
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            self.logger.error("Exception on_close server socket %s: %s", type(e).__name__, str(e) )
+        
+        # remove objects from input_list
+        self.input_list.remove(info["clientsock"])
+        self.input_list.remove(info["serversock"])
+        # delete both objects from channel dict
+        del self.channel[info["clientsock"]]
+        del self.channel[info["serversock"]]
+
+    def on_recv(self, sock):
+        if sock not in self.channel:
+            return  # can happen if there is data ready to received at both sides and the channel has been deleted. QUITE IMPROBABLE but just in case
+        info = self.channel[sock]
+        peersock = info["serversock"] if sock is info["clientsock"] else info["clientsock"]
+        try:
+            data = sock.recv(self.buffer_size)
+            if len(data) == 0:
+                self.on_close(sock, "peer closed")
+            else:
+                # print self.data
+                sock = peersock
+                peersock.send(data)
+        except (socket.error, socket.herror, socket.gaierror, socket.timeout) as e:
+            # print(self.name, ": Exception {}: {}".format(type(e).__name__, e))
+            self.on_close(sock, "Exception {}: {}".format(type(e).__name__, e))
+
+        
+
+    #def start_timeout(self):
+    #    self.timeout = time.time() + 120
+        
diff --git a/RO/osm_ro/database_utils/dump_db.sh b/RO/osm_ro/database_utils/dump_db.sh
new file mode 100755 (executable)
index 0000000..89c83f0
--- /dev/null
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+##
+# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+
+LICENSE_HEAD='/**
+* Copyright 2017 Telefonica Investigacion y Desarrollo, S.A.U.
+* This file is part of openmano
+* All Rights Reserved.
+*
+* 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.
+*
+* For those usages not covered by the Apache License, Version 2.0 please
+* contact with: nfvlabs@tid.es
+**/
+'
+
+DBUSER="mano"
+DBPASS=""
+DBHOST="localhost"
+DBPORT="3306"
+DBNAME="mano_db"
+# Detect paths
+MYSQL=$(which mysql)
+AWK=$(which awk)
+GREP=$(which grep)
+DIRNAME=`dirname $(readlink -f $0)`
+function usage(){
+    echo -e "Usage: $0 OPTIONS"
+    echo -e "  Dumps openmano database content"
+    echo -e "  OPTIONS"
+    echo -e "     -u USER  database user. '$DBUSER' by default. Prompts if DB access fails"
+    echo -e "     -p PASS  database password. 'No password' by default. Prompts if DB access fails"
+    echo -e "     -P PORT  database port. '$DBPORT' by default"
+    echo -e "     -h HOST  database host. '$DBHOST' by default"
+    echo -e "     -d NAME  database name. '$DBNAME' by default.  Prompts if DB access fails"
+    echo -e "     --help   shows this help"
+}
+
+while getopts ":u:p:P:h:-:" o; do
+    case "${o}" in
+        u)
+            DBUSER="$OPTARG"
+            ;;
+        p)
+            DBPASS="$OPTARG"
+            ;;
+        P)
+            DBPORT="$OPTARG"
+            ;;
+        d)
+            DBNAME="$OPTARG"
+            ;;
+        h)
+            DBHOST="$OPTARG"
+            ;;
+        -)
+            [ "${OPTARG}" == "help" ] && usage && exit 0
+            echo "Invalid option: --$OPTARG" >&2 && usage  >&2
+            exit 1
+            ;;
+        \?)
+            echo "Invalid option: -$OPTARG" >&2 && usage  >&2
+            exit 1
+            ;;
+        :)
+            echo "Option -$OPTARG requires an argument." >&2 && usage  >&2
+            exit 1
+            ;;
+        *)
+            usage >&2
+            exit -1
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+#check and ask for database user password
+DBUSER_="-u$DBUSER"
+DBPASS_=""
+[ -n "$DBPASS" ] && DBPASS_="-p$DBPASS"
+DBHOST_="-h$DBHOST"
+DBPORT_="-P$DBPORT"
+while !  echo ";" | mysql $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ $DBNAME >/dev/null 2>&1
+do
+        [ -n "$logintry" ] &&  echo -e "\nInvalid database credentials!!!. Try again (Ctrl+c to abort)"
+        [ -z "$logintry" ] &&  echo -e "\nProvide database name and credentials"
+        read -e -p "mysql database name($DBNAME): " KK
+        [ -n "$KK" ] && DBNAME="$KK"
+        read -e -p "mysql user($DBUSER): " KK
+        [ -n "$KK" ] && DBUSER="$KK" && DBUSER_="-u$DBUSER"
+        read -e -s -p "mysql password: " DBPASS
+        [ -n "$DBPASS" ] && DBPASS_="-p$DBPASS"
+        [ -z "$DBPASS" ] && DBPASS_=""
+        logintry="yes"
+        echo
+done
+
+#echo structure, including the content of schema_version
+echo "$LICENSE_HEAD" > ${DIRNAME}/${DBNAME}_structure.sql
+mysqldump $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ --no-data --add-drop-table --add-drop-database --routines --databases $DBNAME >> ${DIRNAME}/${DBNAME}_structure.sql
+echo -e "\n\n\n\n" >> ${DIRNAME}/${DBNAME}_structure.sql
+mysqldump $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ --no-create-info $DBNAME --tables schema_version 2>/dev/null  >> ${DIRNAME}/${DBNAME}_structure.sql
+echo "    ${DIRNAME}/${DBNAME}_structure.sql"
+
+#echo only data
+echo "$LICENSE_HEAD" > ${DIRNAME}/${DBNAME}_data.sql #copy my own header
+mysqldump $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ --no-create-info $DBNAME >> ${DIRNAME}/${DBNAME}_data.sql
+echo "    ${DIRNAME}/${DBNAME}_data.sql"
+
+#echo all
+echo "$LICENSE_HEAD" > ${DIRNAME}/${DBNAME}_all.sql #copy my own header
+mysqldump $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ --add-drop-table --add-drop-database --routines --databases $DBNAME >> ${DIRNAME}/${DBNAME}_all.sql
+echo "    ${DIRNAME}/${DBNAME}_all.sql"
+
diff --git a/RO/osm_ro/database_utils/init_mano_db.sh b/RO/osm_ro/database_utils/init_mano_db.sh
new file mode 100755 (executable)
index 0000000..147ea38
--- /dev/null
@@ -0,0 +1,170 @@
+#!/bin/bash
+
+##
+# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+DBUSER="mano"
+DBPASS=""
+DEFAULT_DBPASS="manopw"
+DBHOST=""
+DBPORT="3306"
+DBNAME="mano_db"
+QUIET_MODE=""
+CREATEDB=""
+
+# Detect paths
+MYSQL=$(which mysql)
+AWK=$(which awk)
+GREP=$(which grep)
+DIRNAME=`dirname $(readlink -f $0)`
+
+function usage(){
+    echo -e "Usage: $0 OPTIONS [version]"
+    echo -e "  Inits openmano database; deletes previous one and loads from ${DBNAME}_structure.sql"\
+    echo -e "   and data from host_ranking.sql, nets.sql, of_ports_pci_correspondece*.sql"
+            "If [version]  is not provided, it is upgraded to the last version"
+    echo -e "  OPTIONS"
+    echo -e "     -u USER  database user. '$DBUSER' by default. Prompts if DB access fails"
+    echo -e "     -p PASS  database password. If missing it tries without and '$DEFAULT_DBPASS' password before prompting"
+    echo -e "     -P PORT  database port. '$DBPORT' by default"
+    echo -e "     -h HOST  database host. 'localhost' by default"
+    echo -e "     -d NAME  database name. '$DBNAME' by default.  Prompts if DB access fails"
+    echo -e "     -q --quiet: Do not prompt for credentials and exit if cannot access to database"
+    echo -e "     --createdb   forces the deletion and creation of the database"
+    echo -e "     --help   shows this help"
+}
+
+while getopts ":u:p:P:h:d:q-:" o; do
+    case "${o}" in
+        u)
+            DBUSER="$OPTARG"
+            ;;
+        p)
+            DBPASS="$OPTARG"
+            ;;
+        P)
+            DBPORT="$OPTARG"
+            ;;
+        d)
+            DBNAME="$OPTARG"
+            ;;
+        h)
+            DBHOST="$OPTARG"
+            ;;
+        q)
+            export QUIET_MODE="-q"
+            ;;
+        -)
+            [ "${OPTARG}" == "help" ] && usage && exit 0
+            [ "${OPTARG}" == "quiet" ] && export QUIET_MODE="-q" && continue
+            [ "${OPTARG}" == "createdb" ] && export CREATEDB=yes && continue
+            echo "Invalid option: '--$OPTARG'. Type --help for more information" >&2
+            exit 1
+            ;;
+        \?)
+            echo "Invalid option: '-$OPTARG'. Type --help for more information" >&2
+            exit 1
+            ;;
+        :)
+            echo "Option '-$OPTARG' requires an argument. Type --help for more information" >&2
+            exit 1
+            ;;
+        *)
+            usage >&2
+            exit 1
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+DB_VERSION=$1
+
+if [ -n "$DB_VERSION" ] ; then
+    # check it is a number and an allowed one
+    [ "$DB_VERSION" -eq "$DB_VERSION" ] 2>/dev/null || 
+        ! echo "parameter 'version' requires a integer value" >&2 || exit 1
+fi
+
+# Creating temporary file
+TEMPFILE="$(mktemp -q --tmpdir "initdb.XXXXXX")"
+trap 'rm -f "$TEMPFILE"' EXIT
+chmod 0600 "$TEMPFILE"
+DEF_EXTRA_FILE_PARAM="--defaults-extra-file=$TEMPFILE"
+echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE"
+
+if [ -n "${CREATEDB}" ] ; then
+    FIRST_TRY="yes"
+    while ! DB_ERROR=`mysqladmin "$DEF_EXTRA_FILE_PARAM" -s status 2>&1 >/dev/null` ; do
+        # if password is not provided, try silently with $DEFAULT_DBPASS before exit or prompt for credentials
+        [[ -n "$FIRST_TRY" ]] && [[ -z "$DBPASS" ]] && DBPASS="$DEFAULT_DBPASS" &&
+            echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE" &&
+            continue
+        echo "$DB_ERROR"
+        [[ -n "$QUIET_MODE" ]] && echo -e "Invalid admin database credentials!!!" >&2 && exit 1
+        echo -e "Provide database credentials (Ctrl+c to abort):"
+        read -e -p "    mysql user($DBUSER): " KK
+        [ -n "$KK" ] && DBUSER="$KK"
+        read -e -s -p "    mysql password: " DBPASS
+        echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE"
+        FIRST_TRY=""
+        echo
+    done
+    # echo "    deleting previous database ${DBNAME} if it exists"
+    mysqladmin $DEF_EXTRA_FILE_PARAM DROP "${DBNAME}" -f && echo "Previous database deleted"
+    echo "    creating database ${DBNAME}"
+    mysqladmin $DEF_EXTRA_FILE_PARAM create "${DBNAME}" || exit 1
+fi
+
+# Check and ask for database user password
+FIRST_TRY="yes"
+while ! DB_ERROR=`mysql "$DEF_EXTRA_FILE_PARAM" $DBNAME -e "quit" 2>&1 >/dev/null`
+do
+    # if password is not provided, try silently with $DEFAULT_DBPASS before exit or prompt for credentials
+    [[ -n "$FIRST_TRY" ]] && [[ -z "$DBPASS" ]] && DBPASS="$DEFAULT_DBPASS" &&
+        echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE" &&
+        continue
+    echo "$DB_ERROR"
+    [[ -n "$QUIET_MODE" ]] && echo -e "Invalid database credentials!!!" >&2 && exit 1
+    echo -e "Provide database name and credentials (Ctrl+c to abort):"
+    read -e -p "    mysql database name($DBNAME): " KK
+    [ -n "$KK" ] && DBNAME="$KK"
+    read -e -p "    mysql user($DBUSER): " KK
+    [ -n "$KK" ] && DBUSER="$KK"
+    read -e -s -p "    mysql password: " DBPASS
+    echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE"
+    FIRST_TRY=""
+    echo
+done
+
+DBCMD="mysql $DEF_EXTRA_FILE_PARAM $DBNAME"
+DBUSER_="" && [ -n "$DBUSER" ] && DBUSER_="-u$DBUSER"
+DBPASS_="" && [ -n "$DBPASS" ] && DBPASS_="-p$DBPASS"
+DBHOST_="" && [ -n "$DBHOST" ] && DBHOST_="-h$DBHOST"
+DBPORT_="-P$DBPORT"
+
+echo "    loading ${DIRNAME}/mano_db_structure.sql"
+sed -e "s/{{mano_db}}/$DBNAME/" ${DIRNAME}/mano_db_structure.sql | mysql $DEF_EXTRA_FILE_PARAM ||
+    ! echo "ERROR at init $DBNAME" || exit 1
+
+echo "    migrage database version"
+# echo "${DIRNAME}/migrate_mano_db.sh $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ -d$DBNAME $QUIET_MODE $DB_VERSION"
+${DIRNAME}/migrate_mano_db.sh $DBHOST_ $DBPORT_ $DBUSER_ $DBPASS_ -d$DBNAME $QUIET_MODE $DB_VERSION
+
diff --git a/RO/osm_ro/database_utils/install-db-server.sh b/RO/osm_ro/database_utils/install-db-server.sh
new file mode 100755 (executable)
index 0000000..8ef780c
--- /dev/null
@@ -0,0 +1,313 @@
+#!/usr/bin/env bash
+
+##
+# Copyright Telefonica Investigacion y Desarrollo, S.A.U.
+# All Rights Reserved.
+#
+# 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.
+##
+
+DB_NAME='mano_db'
+DB_ADMIN_USER="root"
+DB_USER="mano"
+DB_PASS="manopw"
+DB_ADMIN_PASSWD=""
+DB_PORT="3306"
+DB_HOST=""
+DB_HOST_PARAM=""
+QUIET_MODE=""
+FORCEDB=""
+UPDATEDB=""
+NO_PACKAGES=""
+UNINSTALL=""
+
+
+function usage(){
+    echo -e "usage: sudo $0 [OPTIONS]"
+    echo -e "Install openmano database server and the needed packages"
+    echo -e "  OPTIONS"
+    echo -e "     -U USER:    database admin user. '$DB_ADMIN_USER' by default. Prompts if needed"
+    echo -e "     -P PASS:    database admin password to be used or installed. Prompts if needed"
+    echo -e "     -d: database name, '$DB_NAME' by default"
+    echo -e "     -u: database user, '$DB_USER' by default"
+    echo -e "     -p: database pass, '$DB_PASS' by default"
+    echo -e "     -H: HOST  database host. 'localhost' by default"
+    echo -e "     -T: PORT  database port. '$DB_PORT' by default"
+    echo -e "     -q --quiet: install in unattended mode"
+    echo -e "     -h --help:  show this help"
+    echo -e "     --forcedb:  if database exists, it is dropped and a new one is created"
+    echo -e "     --updatedb: if database exists, it preserves the content and it is updated to the needed version"
+    echo -e "     --no-install-packages: use this option to skip updating and installing the requires packages. This avoid wasting time if you are sure requires packages are present e.g. because of a previous installation"
+    echo -e "     --unistall: delete database"
+}
+
+function ask_user(){
+    # ask to the user and parse a response among 'y', 'yes', 'n' or 'no'. Case insensitive
+    # Params: $1 text to ask;   $2 Action by default, can be 'y' for yes, 'n' for no, other or empty for not allowed
+    # Return: true(0) if user type 'yes'; false (1) if user type 'no'
+    read -e -p "$1" USER_CONFIRMATION
+    while true ; do
+        [ -z "$USER_CONFIRMATION" ] && [ "$2" == 'y' ] && return 0
+        [ -z "$USER_CONFIRMATION" ] && [ "$2" == 'n' ] && return 1
+        [ "${USER_CONFIRMATION,,}" == "yes" ] || [ "${USER_CONFIRMATION,,}" == "y" ] && return 0
+        [ "${USER_CONFIRMATION,,}" == "no" ]  || [ "${USER_CONFIRMATION,,}" == "n" ] && return 1
+        read -e -p "Please type 'yes' or 'no': " USER_CONFIRMATION
+    done
+}
+
+function install_packages(){
+    [ -x /usr/bin/apt-get ] && apt-get install -y $*
+    [ -x /usr/bin/yum ]     && yum install     -y $*   
+    
+    #check properly installed
+    for PACKAGE in $*
+    do
+        PACKAGE_INSTALLED="no"
+        [ -x /usr/bin/apt-get ] && dpkg -l $PACKAGE            &>> /dev/null && PACKAGE_INSTALLED="yes"
+        [ -x /usr/bin/yum ]     && yum list installed $PACKAGE &>> /dev/null && PACKAGE_INSTALLED="yes" 
+        if [ "$PACKAGE_INSTALLED" = "no" ]
+        then
+            echo "failed to install package '$PACKAGE'. Revise network connectivity and try again" >&2
+            exit 1
+       fi
+    done
+}
+
+function _install_mysql_package(){
+    echo '
+    #################################################################
+    #####               INSTALL REQUIRED PACKAGES               #####
+    #################################################################'
+    [ "$_DISTRO" == "Ubuntu" ] && ! install_packages "mysql-server" && exit 1
+    [ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ] && ! install_packages "mariadb mariadb-server" && exit 1
+
+    if [[ "$_DISTRO" == "Ubuntu" ]]
+    then
+        #start services. By default CentOS does not start services
+        service mysql start >> /dev/null
+        # try to set admin password, ignore if fails
+        [[ -n $DBPASSWD ]] && mysqladmin -u $DB_ADMIN_USER -s password $DB_ADMIN_PASSWD
+    fi
+
+    if [ "$_DISTRO" == "CentOS" -o "$_DISTRO" == "Red" ]
+    then
+        #start services. By default CentOS does not start services
+        service mariadb start
+        service httpd   start
+        systemctl enable mariadb
+        systemctl enable httpd
+        ask_user "Do you want to configure mariadb (recommended if not done before) (Y/n)? " y &&
+            mysql_secure_installation
+
+        ask_user "Do you want to set firewall to grant web access port 80,443  (Y/n)? " y &&
+            firewall-cmd --permanent --zone=public --add-service=http &&
+            firewall-cmd --permanent --zone=public --add-service=https &&
+            firewall-cmd --reload
+    fi
+}
+
+function _create_db(){
+    echo '
+    #################################################################
+    #####        CREATE AND INIT DATABASE                       #####
+    #################################################################'
+    echo "mysqladmin --defaults-extra-file="$TEMPFILE" -s create ${DB_NAME}"
+    mysqladmin --defaults-extra-file="$TEMPFILE" -s create ${DB_NAME} \
+        || ! echo "Error creating ${DB_NAME} database" >&2 \
+        || exit 1
+    echo "CREATE USER $DB_USER@'localhost' IDENTIFIED BY '$DB_PASS';"   | mysql --defaults-extra-file="$TEMPFILE" -s 2>/dev/null \
+        || echo "Warning: User '$DB_USER' cannot be created at database. Probably exist" >&2
+    echo "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '$DB_USER'@'localhost';" | mysql --defaults-extra-file="$TEMPFILE" -s \
+        || ! echo "Error: Granting privileges to user '$DB_USER' at database" >&2 \
+        || exit 1
+    echo " Database '${DB_NAME}' created, user '$DB_USER' password '$DB_PASS'"
+    DIRNAME=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
+    ${DIRNAME}/init_mano_db.sh -u"$DB_USER" -p"$DB_PASS" -d"$DB_NAME" -P"$DB_PORT" $DB_HOST_PARAM \
+        || ! echo "Error initializing database '$DB_NAME'" >&2 \
+        || exit 1
+}
+
+function _delete_db(){
+   mysqladmin --defaults-extra-file="$TEMPFILE" -s drop "${DB_NAME}" $DBDELETEPARAM \
+       || ! echo "Error: Could not delete '${DB_NAME}' database" >&2 \
+       || exit 1
+}
+
+function _update_db(){
+    echo '
+    #################################################################
+    #####        UPDATE DATABASE                                #####
+    #################################################################'
+    echo "CREATE USER $DB_USER@'localhost' IDENTIFIED BY '$DB_PASS';" | mysql --defaults-extra-file="$TEMPFILE" -s 2>/dev/null \
+        || echo "Warning: User '$DB_USER' cannot be created at database. Probably exist" >&2
+    echo "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '$DB_USER'@'localhost';" | mysql --defaults-extra-file="$TEMPFILE" -s \
+        || ! echo "Error: Granting privileges to user '$DB_USER' at database" >&2 \
+        || exit 1
+    echo " Granted privileges to user '$DB_USER' password '$DB_PASS' to existing database '${DB_NAME}'"
+    DIRNAME=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
+    ${DIRNAME}/migrate_mano_db.sh -u"$DB_USER" -p"$DB_PASS" -d"$DB_NAME" -P"$DB_PORT" $DB_HOST_PARAM \
+        || ! echo "Error updating database '$DB_NAME'" >&2 \
+        || exit 1
+}
+
+function _uninstall_db(){
+echo '
+    #################################################################
+    #####        DELETE DATABASE                                #####
+    #################################################################'
+    DBDELETEPARAM=""
+    [[ -n $QUIET_MODE ]] && DBDELETEPARAM="-f"
+    _delete_db
+}
+
+function db_exists(){  # (db_name, credential_file)
+    # check credentials
+    mysqlshow --defaults-extra-file="$2" >/dev/null  || exit 1
+    if mysqlshow --defaults-extra-file="$2" | grep -v Wildcard | grep -w -q $1
+    then
+        # echo " DB $1 exists"
+        return 0
+    fi
+    # echo " DB $1 does not exist"
+    return 1
+}
+
+while getopts ":U:P:d:u:p:H:T:hiq-:" o; do
+    case "${o}" in
+        U)
+            export DB_ADMIN_USER="$OPTARG"
+            ;;
+        P)
+            export DB_ADMIN_PASSWD="$OPTARG"
+            ;;
+        d)
+            export DB_NAME="$OPTARG"
+            ;;
+        u)
+            export DB_USER="$OPTARG"
+            ;;
+        p)
+            export DB_PASS="$OPTARG"
+            ;;
+        H)
+            export DB_HOST="$OPTARG"
+            export DB_HOST_PARAM="-h$DB_HOST"
+            ;;
+        T)
+            export DB_PORT="$OPTARG"
+            ;;
+        q)
+            export QUIET_MODE=yes
+            export DEBIAN_FRONTEND=noninteractive
+            ;;
+        h)
+            usage && exit 0
+            ;;
+        -)
+            [ "${OPTARG}" == "help" ] && usage && exit 0
+            [ "${OPTARG}" == "forcedb" ] && FORCEDB="y" && continue
+            [ "${OPTARG}" == "updatedb" ] && UPDATEDB="y" && continue
+            [ "${OPTARG}" == "quiet" ] && export QUIET_MODE=yes && export DEBIAN_FRONTEND=noninteractive && continue
+            [ "${OPTARG}" == "no-install-packages" ] && export NO_PACKAGES=yes && continue
+            [ "${OPTARG}" == "uninstall" ] &&  UNINSTALL="y" && continue
+            echo -e "Invalid option: '--$OPTARG'\nTry $0 --help for more information" >&2
+            exit 1
+            ;;
+        \?)
+            echo -e "Invalid option: '-$OPTARG'\nTry $0 --help for more information" >&2
+            exit 1
+            ;;
+        :)
+            echo -e "Option '-$OPTARG' requires an argument\nTry $0 --help for more information" >&2
+            exit 1
+            ;;
+        *)
+            usage >&2
+            exit 1
+            ;;
+    esac
+done
+if [ -n "$FORCEDB" ] && [ -n "$UPDATEDB" ] ; then
+    echo "Error: options --forcedb and --updatedb are mutually exclusive" >&2
+    exit 1
+fi
+
+# Discover Linux distribution
+# try redhat type
+[ -f /etc/redhat-release ] && _DISTRO=$(cat /etc/redhat-release 2>/dev/null | cut  -d" " -f1)
+# if not assuming ubuntu type
+[ -f /etc/redhat-release ] || _DISTRO=$(lsb_release -is  2>/dev/null)
+
+if [[ -z "$NO_PACKAGES" ]]
+then
+    [ "$USER" != "root" ] && echo "Needed root privileges" >&2 && exit 1
+    _install_mysql_package || exit 1
+fi
+
+# Creating temporary file for MYSQL installation and initialization"
+TEMPFILE="$(mktemp -q --tmpdir "installdb.XXXXXX")"
+trap 'rm -f "$TEMPFILE"' EXIT
+chmod 0600 "$TEMPFILE"
+echo -e "[client]\n user='${DB_ADMIN_USER}'\n password='$DB_ADMIN_PASSWD'\n host='$DB_HOST'\n port='$DB_PORT'" > "$TEMPFILE"
+
+#check and ask for database user password. Must be done after database installation
+if [[ -z $QUIET_MODE ]]
+then
+    echo -e "\nCheking database connection and ask for credentials"
+    # echo "mysqladmin --defaults-extra-file=$TEMPFILE -s status >/dev/null"
+    while ! mysqladmin --defaults-extra-file="$TEMPFILE" -s status >/dev/null
+    do
+        [ -n "$logintry" ] &&  echo -e "\nInvalid database credentials!!!. Try again (Ctrl+c to abort)"
+        [ -z "$logintry" ] &&  echo -e "\nProvide database credentials"
+        read -e -p "database admin user? ($DB_ADMIN_USER) " DBUSER_
+        [ -n "$DBUSER_" ] && DB_ADMIN_USER=$DBUSER_
+        read -e -s -p "database admin password? (Enter for not using password) " DBPASSWD_
+        [ -n "$DBPASSWD_" ] && DB_ADMIN_PASSWD="$DBPASSWD_"
+        [ -z "$DBPASSWD_" ] && DB_ADMIN_PASSWD=""
+        echo -e "[client]\n user='${DB_ADMIN_USER}'\n password='$DB_ADMIN_PASSWD'\n host='$DB_HOST'\n port='$DB_PORT'" > "$TEMPFILE"
+        logintry="yes"
+    done
+fi
+
+if [[ ! -z "$UNINSTALL" ]]
+then
+    _uninstall_db
+    exit
+fi
+
+# Create or update database
+if db_exists $DB_NAME $TEMPFILE ; then
+    if [[ -n $FORCEDB ]] ; then
+        # DBDELETEPARAM=""
+        # [[ -n $QUIET_MODE ]] && DBDELETEPARAM="-f"
+        DBDELETEPARAM="-f"
+        _delete_db
+        _create_db
+    elif [[ -n $UPDATEDB ]] ; then
+        _update_db
+    elif [[ -z $QUIET_MODE ]] ; then
+        echo "database '$DB_NAME' exist. Reinstall it?"
+        if ask_user "Type 'y' to drop and reinstall existing database (content will be lost), Type 'n' to update existing database (y/N)? " n ; then
+            _delete_db
+            _create_db
+        else
+            _update_db
+        fi
+    else
+        echo "Database '$DB_NAME' exists. Use option '--forcedb' to force the deletion of the existing one, or '--updatedb' to use existing one and update it"
+        exit 1
+    fi
+else
+    _create_db
+fi
+
diff --git a/RO/osm_ro/database_utils/mano_db_structure.sql b/RO/osm_ro/database_utils/mano_db_structure.sql
new file mode 100644 (file)
index 0000000..be3720f
--- /dev/null
@@ -0,0 +1,1257 @@
+/**
+* Copyright 2017 Telefonica Investigacion y Desarrollo, S.A.U.
+* This file is part of openmano
+* All Rights Reserved.
+*
+* 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.
+*
+* For those usages not covered by the Apache License, Version 2.0 please
+* contact with: nfvlabs@tid.es
+**/
+
+-- MySQL dump 10.13  Distrib 5.7.30, for Linux (x86_64)
+--
+-- Host: localhost    Database: {{mano_db}}
+-- ------------------------------------------------------
+-- Server version      5.7.27
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Current Database: `{{mano_db}}`
+--
+
+/*!40000 DROP DATABASE IF EXISTS `{{mano_db}}`*/;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{{mano_db}}` /*!40100 DEFAULT CHARACTER SET utf8 */;
+
+USE `{{mano_db}}`;
+
+--
+-- Table structure for table `datacenter_nets`
+--
+
+DROP TABLE IF EXISTS `datacenter_nets`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `datacenter_nets` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `vim_net_id` varchar(300) NOT NULL,
+  `datacenter_id` varchar(36) NOT NULL,
+  `type` enum('bridge','data','ptp') NOT NULL DEFAULT 'data' COMMENT 'Type of network',
+  `multipoint` enum('true','false') NOT NULL DEFAULT 'true',
+  `shared` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'If can be shared with serveral scenarios',
+  `description` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `name_datacenter_id` (`name`,`datacenter_id`),
+  KEY `FK_datacenter_nets_datacenters` (`datacenter_id`),
+  CONSTRAINT `FK_datacenter_nets_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contain the external nets of a datacenter';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `datacenter_tenants`
+--
+
+DROP TABLE IF EXISTS `datacenter_tenants`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `datacenter_tenants` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) DEFAULT NULL,
+  `datacenter_id` varchar(36) NOT NULL COMMENT 'Datacenter of this tenant',
+  `vim_tenant_name` varchar(256) DEFAULT NULL,
+  `vim_tenant_id` varchar(256) DEFAULT NULL COMMENT 'Tenant ID at VIM',
+  `created` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'Indicates if this tenant has been created by openmano, or it existed on VIM',
+  `user` varchar(64) DEFAULT NULL,
+  `passwd` varchar(64) DEFAULT NULL,
+  `config` varchar(4000) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_vim_tenants_datacenters` (`datacenter_id`),
+  CONSTRAINT `FK_vim_tenants_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Scenarios defined by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `datacenters`
+--
+
+DROP TABLE IF EXISTS `datacenters`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `datacenters` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `type` varchar(36) NOT NULL DEFAULT 'openvim',
+  `vim_url` varchar(150) NOT NULL COMMENT 'URL of the VIM for the REST API',
+  `vim_url_admin` varchar(150) DEFAULT NULL,
+  `config` varchar(4000) DEFAULT NULL COMMENT 'extra config information in json',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Datacenters managed by the NFVO.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `datacenters_flavors`
+--
+
+DROP TABLE IF EXISTS `datacenters_flavors`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `datacenters_flavors` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `flavor_id` varchar(36) NOT NULL,
+  `datacenter_vim_id` varchar(36) NOT NULL,
+  `vim_id` varchar(300) NOT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `vim_info` text,
+  `created` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'Indicates if it has been created by openmano, or already existed',
+  `extended` varchar(2000) DEFAULT NULL COMMENT 'Extra description json format of additional devices',
+  PRIMARY KEY (`id`),
+  KEY `FK__flavors` (`flavor_id`),
+  KEY `FK_datacenters_flavors_datacenter_tenants` (`datacenter_vim_id`),
+  CONSTRAINT `FK__flavors` FOREIGN KEY (`flavor_id`) REFERENCES `flavors` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_datacenters_flavors_datacenter_tenants` FOREIGN KEY (`datacenter_vim_id`) REFERENCES `datacenter_tenants` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `datacenters_images`
+--
+
+DROP TABLE IF EXISTS `datacenters_images`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `datacenters_images` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `image_id` varchar(36) NOT NULL,
+  `datacenter_vim_id` varchar(36) NOT NULL,
+  `vim_id` varchar(300) NOT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `vim_info` text,
+  `created` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'Indicates if it has been created by openmano, or already existed',
+  PRIMARY KEY (`id`),
+  KEY `FK__images` (`image_id`),
+  KEY `FK_datacenters_images_datacenter_tenants` (`datacenter_vim_id`),
+  CONSTRAINT `FK__images` FOREIGN KEY (`image_id`) REFERENCES `images` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_datacenters_images_datacenter_tenants` FOREIGN KEY (`datacenter_vim_id`) REFERENCES `datacenter_tenants` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `flavors`
+--
+
+DROP TABLE IF EXISTS `flavors`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `flavors` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `disk` smallint(5) unsigned DEFAULT NULL,
+  `ram` mediumint(7) unsigned DEFAULT NULL,
+  `vcpus` smallint(5) unsigned DEFAULT NULL,
+  `extended` varchar(2000) DEFAULT NULL COMMENT 'Extra description json format of needed resources and pining, orginized in sets per numa',
+  PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `images`
+--
+
+DROP TABLE IF EXISTS `images`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `images` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `universal_name` varchar(255) DEFAULT NULL,
+  `checksum` varchar(32) DEFAULT NULL,
+  `location` varchar(200) DEFAULT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `metadata` varchar(2000) DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `location` (`location`),
+  UNIQUE KEY `universal_name_checksum` (`universal_name`,`checksum`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_actions`
+--
+
+DROP TABLE IF EXISTS `instance_actions`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_actions` (
+  `uuid` varchar(36) NOT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `instance_id` varchar(36) DEFAULT NULL,
+  `description` varchar(64) DEFAULT NULL COMMENT 'CREATE, DELETE, SCALE OUT/IN, ...',
+  `number_tasks` smallint(6) NOT NULL DEFAULT '1',
+  `number_done` smallint(6) NOT NULL DEFAULT '0',
+  `number_failed` smallint(6) NOT NULL DEFAULT '0',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_actions_tenants` (`tenant_id`),
+  CONSTRAINT `FK_actions_tenant` FOREIGN KEY (`tenant_id`) REFERENCES `nfvo_tenants` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contains client actions over instances';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_classifications`
+--
+
+DROP TABLE IF EXISTS `instance_classifications`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_classifications` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_scenario_id` varchar(36) NOT NULL,
+  `vim_classification_id` varchar(300) DEFAULT NULL,
+  `sce_classifier_match_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) DEFAULT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_classifications_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_classifications_sce_classifier_matches` (`sce_classifier_match_id`),
+  KEY `FK_instance_classifications_datacenters` (`datacenter_id`),
+  KEY `FK_instance_classifications_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_classifications_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_classifications_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_classifications_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_classifications_sce_classifier_matches` FOREIGN KEY (`sce_classifier_match_id`) REFERENCES `sce_classifier_matches` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_interfaces`
+--
+
+DROP TABLE IF EXISTS `instance_interfaces`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_interfaces` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_vm_id` varchar(36) NOT NULL,
+  `instance_net_id` varchar(36) NOT NULL,
+  `instance_wim_net_id` varchar(36) DEFAULT NULL,
+  `interface_id` varchar(36) DEFAULT NULL,
+  `vim_interface_id` varchar(300) DEFAULT NULL,
+  `mac_address` varchar(32) DEFAULT NULL,
+  `ip_address` varchar(64) DEFAULT NULL,
+  `vim_info` text,
+  `type` enum('internal','external') NOT NULL COMMENT 'Indicates if this interface is external to a vnf, or internal',
+  `model` varchar(12) DEFAULT NULL,
+  `floating_ip` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Indicates if a floating_ip must be associated to this interface',
+  `port_security` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Indicates if port security must be enabled or disabled. By default it is enabled',
+  `sdn_port_id` varchar(36) DEFAULT NULL COMMENT 'Port id in ovim',
+  `compute_node` varchar(100) DEFAULT NULL COMMENT 'Compute node id used to specify the SDN port mapping',
+  `pci` varchar(50) DEFAULT NULL COMMENT 'PCI of the  physical port in the host',
+  `vlan` smallint(5) unsigned DEFAULT NULL COMMENT 'VLAN tag used by the port',
+  `created_at` double DEFAULT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_vms` (`instance_vm_id`),
+  KEY `FK_instance_nets` (`instance_net_id`),
+  KEY `FK_instance_ids` (`interface_id`),
+  CONSTRAINT `FK_instance_ids` FOREIGN KEY (`interface_id`) REFERENCES `interfaces` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_nets` FOREIGN KEY (`instance_net_id`) REFERENCES `instance_nets` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_vms` FOREIGN KEY (`instance_vm_id`) REFERENCES `instance_vms` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Table with all running associattion among VM instances and net instances';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_nets`
+--
+
+DROP TABLE IF EXISTS `instance_nets`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_nets` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `vim_net_id` varchar(300) DEFAULT NULL,
+  `vim_name` varchar(255) DEFAULT NULL,
+  `instance_scenario_id` varchar(36) DEFAULT NULL,
+  `sce_net_id` varchar(36) DEFAULT NULL,
+  `net_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) NOT NULL,
+  `status` enum('ACTIVE','INACTIVE','DOWN','BUILD','ERROR','VIM_ERROR','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `multipoint` enum('true','false') NOT NULL DEFAULT 'true',
+  `created` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'Created or already exists at VIM',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `sdn_net_id` varchar(36) DEFAULT NULL COMMENT 'Network id in ovim',
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_nets_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_nets_sce_nets` (`sce_net_id`),
+  KEY `FK_instance_nets_nets` (`net_id`),
+  KEY `FK_instance_nets_datacenters` (`datacenter_id`),
+  KEY `FK_instance_nets_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_nets_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_nets_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_nets_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_nets_nets` FOREIGN KEY (`net_id`) REFERENCES `nets` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_nets_sce_nets` FOREIGN KEY (`sce_net_id`) REFERENCES `sce_nets` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Instances of networks';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_scenarios`
+--
+
+DROP TABLE IF EXISTS `instance_scenarios`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_scenarios` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `scenario_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) NOT NULL,
+  `datacenter_tenant_id` varchar(36) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `cloud_config` mediumtext,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_scenarios_nfvo_tenants` (`tenant_id`),
+  KEY `FK_instance_scenarios_vim_tenants` (`datacenter_tenant_id`),
+  KEY `FK_instance_scenarios_datacenters` (`datacenter_id`),
+  KEY `FK_instance_scenarios_scenarios` (`scenario_id`),
+  CONSTRAINT `FK_instance_scenarios_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_scenarios_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_scenarios_nfvo_tenants` FOREIGN KEY (`tenant_id`) REFERENCES `nfvo_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_scenarios_scenarios` FOREIGN KEY (`scenario_id`) REFERENCES `scenarios` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Instances of scenarios defined by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_sfis`
+--
+
+DROP TABLE IF EXISTS `instance_sfis`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_sfis` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_scenario_id` varchar(36) NOT NULL,
+  `vim_sfi_id` varchar(300) DEFAULT NULL,
+  `sce_rsp_hop_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) DEFAULT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_sfis_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_sfis_sce_rsp_hops` (`sce_rsp_hop_id`),
+  KEY `FK_instance_sfis_datacenters` (`datacenter_id`),
+  KEY `FK_instance_sfis_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_sfis_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_sfis_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_sfis_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_sfis_sce_rsp_hops` FOREIGN KEY (`sce_rsp_hop_id`) REFERENCES `sce_rsp_hops` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_sfps`
+--
+
+DROP TABLE IF EXISTS `instance_sfps`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_sfps` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_scenario_id` varchar(36) NOT NULL,
+  `vim_sfp_id` varchar(300) DEFAULT NULL,
+  `sce_rsp_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) DEFAULT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_sfps_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_sfps_sce_rsps` (`sce_rsp_id`),
+  KEY `FK_instance_sfps_datacenters` (`datacenter_id`),
+  KEY `FK_instance_sfps_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_sfps_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_sfps_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_sfps_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_sfps_sce_rsps` FOREIGN KEY (`sce_rsp_id`) REFERENCES `sce_rsps` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_sfs`
+--
+
+DROP TABLE IF EXISTS `instance_sfs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_sfs` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_scenario_id` varchar(36) NOT NULL,
+  `vim_sf_id` varchar(300) DEFAULT NULL,
+  `sce_rsp_hop_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) DEFAULT NULL,
+  `status` enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_sfs_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_sfs_sce_rsp_hops` (`sce_rsp_hop_id`),
+  KEY `FK_instance_sfs_datacenters` (`datacenter_id`),
+  KEY `FK_instance_sfs_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_sfs_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_sfs_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_sfs_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_sfs_sce_rsp_hops` FOREIGN KEY (`sce_rsp_hop_id`) REFERENCES `sce_rsp_hops` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_vms`
+--
+
+DROP TABLE IF EXISTS `instance_vms`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_vms` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_vnf_id` varchar(36) NOT NULL,
+  `vim_vm_id` varchar(300) DEFAULT NULL,
+  `vm_id` varchar(36) DEFAULT NULL,
+  `vim_name` varchar(255) DEFAULT NULL,
+  `status` enum('ACTIVE:NoMgmtIP','ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `vim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_vms_vms` (`vm_id`),
+  KEY `FK_instance_vms_instance_vnfs` (`instance_vnf_id`),
+  CONSTRAINT `FK_instance_vms_instance_vnfs` FOREIGN KEY (`instance_vnf_id`) REFERENCES `instance_vnfs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_vms_vms` FOREIGN KEY (`vm_id`) REFERENCES `vms` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Instances of VMs as part of VNF instances';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_vnfs`
+--
+
+DROP TABLE IF EXISTS `instance_vnfs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_vnfs` (
+  `uuid` varchar(36) NOT NULL,
+  `instance_scenario_id` varchar(36) NOT NULL,
+  `vnf_id` varchar(36) NOT NULL,
+  `sce_vnf_id` varchar(36) DEFAULT NULL,
+  `datacenter_id` varchar(36) DEFAULT NULL,
+  `datacenter_tenant_id` varchar(36) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_vnfs_vnfs` (`vnf_id`),
+  KEY `FK_instance_vnfs_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_vnfs_sce_vnfs` (`sce_vnf_id`),
+  KEY `FK_instance_vnfs_datacenters` (`datacenter_id`),
+  KEY `FK_instance_vnfs_datacenter_tenants` (`datacenter_tenant_id`),
+  CONSTRAINT `FK_instance_vnfs_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_instance_vnfs_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_instance_vnfs_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_vnfs_sce_vnfs` FOREIGN KEY (`sce_vnf_id`) REFERENCES `sce_vnfs` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_vnfs_vnfs` FOREIGN KEY (`vnf_id`) REFERENCES `vnfs` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Instances of VNFs as part of a scenario';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `instance_wim_nets`
+--
+
+DROP TABLE IF EXISTS `instance_wim_nets`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `instance_wim_nets` (
+  `uuid` varchar(36) NOT NULL,
+  `wim_internal_id` varchar(300) DEFAULT NULL COMMENT 'Internal ID used by the WIM to refer to the network',
+  `instance_scenario_id` varchar(36) DEFAULT NULL,
+  `sce_net_id` varchar(36) DEFAULT NULL,
+  `wim_id` varchar(36) DEFAULT NULL,
+  `wim_account_id` varchar(36) NOT NULL,
+  `status` enum('ACTIVE','INACTIVE','DOWN','BUILD','ERROR','WIM_ERROR','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `wim_info` text,
+  `related` varchar(36) DEFAULT NULL,
+  `multipoint` enum('true','false') NOT NULL DEFAULT 'false',
+  `created` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'Created or already exists at WIM',
+  `sdn` enum('true','false') NOT NULL DEFAULT 'false',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_instance_wim_nets_instance_scenarios` (`instance_scenario_id`),
+  KEY `FK_instance_wim_nets_sce_nets` (`sce_net_id`),
+  KEY `FK_instance_wim_nets_wims` (`wim_id`),
+  KEY `FK_instance_wim_nets_wim_accounts` (`wim_account_id`),
+  CONSTRAINT `FK_instance_wim_nets_instance_scenarios` FOREIGN KEY (`instance_scenario_id`) REFERENCES `instance_scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_wim_nets_sce_nets` FOREIGN KEY (`sce_net_id`) REFERENCES `sce_nets` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE,
+  CONSTRAINT `FK_instance_wim_nets_wim_accounts` FOREIGN KEY (`wim_account_id`) REFERENCES `wim_accounts` (`uuid`),
+  CONSTRAINT `FK_instance_wim_nets_wims` FOREIGN KEY (`wim_id`) REFERENCES `wims` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Instances of wim networks';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `interfaces`
+--
+
+DROP TABLE IF EXISTS `interfaces`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `interfaces` (
+  `uuid` varchar(36) NOT NULL,
+  `internal_name` varchar(255) NOT NULL,
+  `external_name` varchar(255) DEFAULT NULL,
+  `vm_id` varchar(36) NOT NULL,
+  `net_id` varchar(36) DEFAULT NULL,
+  `type` enum('mgmt','bridge','data') NOT NULL DEFAULT 'data' COMMENT 'Type of network',
+  `vpci` char(12) DEFAULT NULL,
+  `bw` mediumint(8) unsigned DEFAULT NULL COMMENT 'BW expressed in Mbits/s. Maybe this field is not necessary.',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `model` varchar(12) DEFAULT NULL,
+  `mac` char(18) DEFAULT NULL,
+  `ip_address` varchar(64) DEFAULT NULL,
+  `floating_ip` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Indicates if a floating_ip must be associated to this interface',
+  `port_security` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Indicates if port security must be enabled or disabled. By default it is enabled',
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `internal_name_vm_id` (`internal_name`,`vm_id`),
+  KEY `FK_interfaces_vms` (`vm_id`),
+  KEY `FK_interfaces_nets` (`net_id`),
+  CONSTRAINT `FK_interfaces_nets` FOREIGN KEY (`net_id`) REFERENCES `nets` (`uuid`) ON DELETE CASCADE,
+  CONSTRAINT `FK_interfaces_vms` FOREIGN KEY (`vm_id`) REFERENCES `vms` (`uuid`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='VM interfaces';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `ip_profiles`
+--
+
+DROP TABLE IF EXISTS `ip_profiles`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ip_profiles` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `net_id` varchar(36) DEFAULT NULL,
+  `sce_net_id` varchar(36) DEFAULT NULL,
+  `instance_net_id` varchar(36) DEFAULT NULL,
+  `ip_version` enum('IPv4','IPv6') NOT NULL DEFAULT 'IPv4',
+  `subnet_address` varchar(64) DEFAULT NULL,
+  `gateway_address` varchar(64) DEFAULT NULL,
+  `dns_address` varchar(255) DEFAULT NULL COMMENT 'dns ip list separated by semicolon',
+  `dhcp_enabled` enum('true','false') NOT NULL DEFAULT 'true',
+  `dhcp_start_address` varchar(64) DEFAULT NULL,
+  `dhcp_count` int(11) DEFAULT NULL,
+  `security_group` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  KEY `FK_ipprofiles_nets` (`net_id`),
+  KEY `FK_ipprofiles_scenets` (`sce_net_id`),
+  KEY `FK_ipprofiles_instancenets` (`instance_net_id`),
+  CONSTRAINT `FK_ipprofiles_instancenets` FOREIGN KEY (`instance_net_id`) REFERENCES `instance_nets` (`uuid`) ON DELETE CASCADE,
+  CONSTRAINT `FK_ipprofiles_nets` FOREIGN KEY (`net_id`) REFERENCES `nets` (`uuid`) ON DELETE CASCADE,
+  CONSTRAINT `FK_ipprofiles_scenets` FOREIGN KEY (`sce_net_id`) REFERENCES `sce_nets` (`uuid`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Table containing the IP parameters of a network, either a net, a sce_net or and instance_net.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `logs`
+--
+
+DROP TABLE IF EXISTS `logs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `logs` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `nfvo_tenant_id` varchar(36) DEFAULT NULL,
+  `related` varchar(36) NOT NULL COMMENT 'Relevant element for the log',
+  `uuid` varchar(36) DEFAULT NULL COMMENT 'Uuid of vnf, scenario, etc. that log relates to',
+  `level` enum('panic','error','info','debug','verbose') NOT NULL,
+  `description` varchar(200) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `nets`
+--
+
+DROP TABLE IF EXISTS `nets`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `nets` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `vnf_id` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `type` enum('bridge','data','ptp') NOT NULL DEFAULT 'data' COMMENT 'Type of network',
+  `multipoint` enum('true','false') NOT NULL DEFAULT 'false',
+  `description` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `vnf_id_name` (`vnf_id`,`name`),
+  CONSTRAINT `FK_nets_vnfs` FOREIGN KEY (`vnf_id`) REFERENCES `vnfs` (`uuid`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Networks in a VNF definition. These are only the internal networks among VMs of the same VNF.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `nfvo_tenants`
+--
+
+DROP TABLE IF EXISTS `nfvo_tenants`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `nfvo_tenants` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `encrypted_RO_priv_key` varchar(2000) DEFAULT NULL,
+  `RO_pub_key` varchar(510) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `name` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Scenarios defined by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_classifier_matches`
+--
+
+DROP TABLE IF EXISTS `sce_classifier_matches`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_classifier_matches` (
+  `uuid` varchar(36) NOT NULL,
+  `ip_proto` varchar(2) NOT NULL,
+  `source_ip` varchar(16) NOT NULL,
+  `destination_ip` varchar(16) NOT NULL,
+  `source_port` varchar(5) NOT NULL,
+  `destination_port` varchar(5) NOT NULL,
+  `sce_classifier_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_classifiers_classifier_match` (`sce_classifier_id`),
+  CONSTRAINT `FK_sce_classifiers_classifier_match` FOREIGN KEY (`sce_classifier_id`) REFERENCES `sce_classifiers` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_classifiers`
+--
+
+DROP TABLE IF EXISTS `sce_classifiers`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_classifiers` (
+  `uuid` varchar(36) NOT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `sce_vnffg_id` varchar(36) NOT NULL,
+  `sce_rsp_id` varchar(36) NOT NULL,
+  `sce_vnf_id` varchar(36) NOT NULL,
+  `interface_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_sce_vnffgs_classifier` (`sce_vnffg_id`),
+  KEY `FK_sce_rsps_classifier` (`sce_rsp_id`),
+  KEY `FK_sce_vnfs_classifier` (`sce_vnf_id`),
+  KEY `FK_interfaces_classifier` (`interface_id`),
+  CONSTRAINT `FK_interfaces_classifier` FOREIGN KEY (`interface_id`) REFERENCES `interfaces` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_rsps_classifier` FOREIGN KEY (`sce_rsp_id`) REFERENCES `sce_rsps` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_vnffgs_classifier` FOREIGN KEY (`sce_vnffg_id`) REFERENCES `sce_vnffgs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_vnfs_classifier` FOREIGN KEY (`sce_vnf_id`) REFERENCES `sce_vnfs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_interfaces`
+--
+
+DROP TABLE IF EXISTS `sce_interfaces`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_interfaces` (
+  `uuid` varchar(36) NOT NULL,
+  `sce_vnf_id` varchar(36) NOT NULL,
+  `sce_net_id` varchar(36) DEFAULT NULL,
+  `interface_id` varchar(36) DEFAULT NULL,
+  `ip_address` varchar(64) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_sce_interfaces_sce_vnfs` (`sce_vnf_id`),
+  KEY `FK_sce_interfaces_sce_nets` (`sce_net_id`),
+  KEY `FK_sce_interfaces_interfaces` (`interface_id`),
+  CONSTRAINT `FK_sce_interfaces_interfaces` FOREIGN KEY (`interface_id`) REFERENCES `interfaces` (`uuid`),
+  CONSTRAINT `FK_sce_interfaces_sce_nets` FOREIGN KEY (`sce_net_id`) REFERENCES `sce_nets` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_interfaces_sce_vnfs` FOREIGN KEY (`sce_vnf_id`) REFERENCES `sce_vnfs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='VNF interfaces in a scenario definition.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_nets`
+--
+
+DROP TABLE IF EXISTS `sce_nets`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_nets` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `scenario_id` varchar(36) DEFAULT NULL COMMENT 'NULL if net is matched to several scenarios',
+  `type` enum('bridge','data','ptp') NOT NULL DEFAULT 'data' COMMENT 'Type of network',
+  `multipoint` enum('true','false') NOT NULL DEFAULT 'true',
+  `external` enum('true','false') NOT NULL DEFAULT 'false' COMMENT 'If external, net is already present at VIM',
+  `description` varchar(255) DEFAULT NULL,
+  `vim_network_name` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `graph` varchar(2000) DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_sce_nets_scenarios` (`scenario_id`),
+  CONSTRAINT `FK_sce_nets_scenarios` FOREIGN KEY (`scenario_id`) REFERENCES `scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Networks in a scenario definition. It only considers networks among VNFs. Networks among internal VMs are only considered in tble ''nets''.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_rsp_hops`
+--
+
+DROP TABLE IF EXISTS `sce_rsp_hops`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_rsp_hops` (
+  `uuid` varchar(36) NOT NULL,
+  `if_order` int(11) NOT NULL DEFAULT '0',
+  `ingress_interface_id` varchar(36) NOT NULL,
+  `egress_interface_id` varchar(36) NOT NULL,
+  `sce_vnf_id` varchar(36) NOT NULL,
+  `sce_rsp_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_interfaces_rsp_hop` (`ingress_interface_id`),
+  KEY `FK_sce_vnfs_rsp_hop` (`sce_vnf_id`),
+  KEY `FK_sce_rsps_rsp_hop` (`sce_rsp_id`),
+  KEY `FK_interfaces_rsp_hop_egress` (`egress_interface_id`),
+  CONSTRAINT `FK_interfaces_rsp_hop_egress` FOREIGN KEY (`egress_interface_id`) REFERENCES `interfaces` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_interfaces_rsp_hop_ingress` FOREIGN KEY (`ingress_interface_id`) REFERENCES `interfaces` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_rsps_rsp_hop` FOREIGN KEY (`sce_rsp_id`) REFERENCES `sce_rsps` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_vnfs_rsp_hop` FOREIGN KEY (`sce_vnf_id`) REFERENCES `sce_vnfs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_rsps`
+--
+
+DROP TABLE IF EXISTS `sce_rsps`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_rsps` (
+  `uuid` varchar(36) NOT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `sce_vnffg_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_sce_vnffgs_rsp` (`sce_vnffg_id`),
+  CONSTRAINT `FK_sce_vnffgs_rsp` FOREIGN KEY (`sce_vnffg_id`) REFERENCES `sce_vnffgs` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_vnffgs`
+--
+
+DROP TABLE IF EXISTS `sce_vnffgs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_vnffgs` (
+  `uuid` varchar(36) NOT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `vendor` varchar(255) DEFAULT NULL,
+  `scenario_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_scenarios_sce_vnffg` (`scenario_id`),
+  KEY `FK_scenarios_vnffg` (`tenant_id`),
+  CONSTRAINT `FK_scenarios_vnffg` FOREIGN KEY (`tenant_id`) REFERENCES `scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `sce_vnfs`
+--
+
+DROP TABLE IF EXISTS `sce_vnfs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sce_vnfs` (
+  `uuid` varchar(36) NOT NULL,
+  `member_vnf_index` varchar(255) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `scenario_id` varchar(36) NOT NULL,
+  `vnf_id` varchar(36) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `graph` varchar(2000) DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `name_scenario_id` (`name`,`scenario_id`),
+  KEY `FK_sce_vnfs_scenarios` (`scenario_id`),
+  KEY `FK_sce_vnfs_vnfs` (`vnf_id`),
+  CONSTRAINT `FK_sce_vnfs_scenarios` FOREIGN KEY (`scenario_id`) REFERENCES `scenarios` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_sce_vnfs_vnfs` FOREIGN KEY (`vnf_id`) REFERENCES `vnfs` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='VNFs in scenario definitions. This table also contains the Physical Network Functions and the external elements such as MAN, Core, etc.\r\n';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `scenarios`
+--
+
+DROP TABLE IF EXISTS `scenarios`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `scenarios` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `short_name` varchar(255) DEFAULT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `vendor` varchar(255) DEFAULT NULL,
+  `public` enum('true','false') NOT NULL DEFAULT 'false',
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `descriptor` text COMMENT 'Original text descriptor used for create the scenario',
+  `cloud_config` mediumtext,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `osm_id_tenant_id` (`osm_id`,`tenant_id`),
+  KEY `FK_scenarios_nfvo_tenants` (`tenant_id`),
+  CONSTRAINT `FK_scenarios_nfvo_tenants` FOREIGN KEY (`tenant_id`) REFERENCES `nfvo_tenants` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Scenarios defined by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `schema_version`
+--
+
+DROP TABLE IF EXISTS `schema_version`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `schema_version` (
+  `version_int` int(11) NOT NULL COMMENT 'version as a number. Must not contain gaps',
+  `version` varchar(20) NOT NULL COMMENT 'version as a text',
+  `openmano_ver` varchar(20) NOT NULL COMMENT 'openmano version',
+  `comments` varchar(2000) DEFAULT NULL COMMENT 'changes to database',
+  `date` date DEFAULT NULL,
+  PRIMARY KEY (`version_int`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='database schema control version';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tenants_datacenters`
+--
+
+DROP TABLE IF EXISTS `tenants_datacenters`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `tenants_datacenters` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `nfvo_tenant_id` varchar(36) NOT NULL,
+  `datacenter_id` varchar(36) NOT NULL,
+  `datacenter_tenant_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `datacenter_nfvo_tenant` (`datacenter_id`,`nfvo_tenant_id`),
+  KEY `FK_nfvo_tenants_datacenters` (`datacenter_id`),
+  KEY `FK_nfvo_tenants_vim_tenants` (`datacenter_tenant_id`),
+  KEY `FK_tenants_datacenters_nfvo_tenants` (`nfvo_tenant_id`),
+  CONSTRAINT `FK_tenants_datacenters_datacenter_tenants` FOREIGN KEY (`datacenter_tenant_id`) REFERENCES `datacenter_tenants` (`uuid`),
+  CONSTRAINT `FK_tenants_datacenters_datacenters` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`),
+  CONSTRAINT `FK_tenants_datacenters_nfvo_tenants` FOREIGN KEY (`nfvo_tenant_id`) REFERENCES `nfvo_tenants` (`uuid`)
+) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Scenarios defined by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `uuids`
+--
+
+DROP TABLE IF EXISTS `uuids`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `uuids` (
+  `uuid` varchar(36) NOT NULL,
+  `root_uuid` varchar(36) DEFAULT NULL COMMENT 'Some related UUIDs can be grouped by this field, so that they can be deleted at once',
+  `created_at` double NOT NULL,
+  `used_at` varchar(36) DEFAULT NULL COMMENT 'Table that uses this UUID',
+  PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Table with all unique IDs used to avoid UUID repetitions among different elements';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `vim_wim_actions`
+--
+
+DROP TABLE IF EXISTS `vim_wim_actions`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `vim_wim_actions` (
+  `instance_action_id` varchar(36) NOT NULL,
+  `task_index` int(6) NOT NULL,
+  `worker` varchar(64) DEFAULT NULL,
+  `related` varchar(36) DEFAULT NULL,
+  `datacenter_vim_id` varchar(36) DEFAULT NULL,
+  `vim_id` varchar(300) DEFAULT NULL,
+  `wim_account_id` varchar(36) DEFAULT NULL,
+  `wim_internal_id` varchar(64) DEFAULT NULL,
+  `action` varchar(36) NOT NULL COMMENT 'CREATE,DELETE,START,STOP...',
+  `item` enum('datacenters_flavors','datacenter_images','instance_nets','instance_vms','instance_interfaces','instance_sfis','instance_sfs','instance_classifications','instance_sfps','instance_wim_nets') NOT NULL COMMENT 'table where the item is stored',
+  `item_id` varchar(36) DEFAULT NULL COMMENT 'uuid of the entry in the table',
+  `status` enum('SCHEDULED','BUILD','DONE','FAILED','SUPERSEDED','FINISHED') NOT NULL DEFAULT 'SCHEDULED',
+  `extra` text COMMENT 'json with params:, depends_on: for the task',
+  `error_msg` varchar(1024) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`task_index`,`instance_action_id`),
+  KEY `FK_actions_instance_actions` (`instance_action_id`),
+  KEY `FK_actions_vims` (`datacenter_vim_id`),
+  KEY `item_type_id` (`item`,`item_id`),
+  KEY `FK_actions_wims` (`wim_account_id`),
+  CONSTRAINT `FK_actions_instance_actions` FOREIGN KEY (`instance_action_id`) REFERENCES `instance_actions` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_actions_vims` FOREIGN KEY (`datacenter_vim_id`) REFERENCES `datacenter_tenants` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_actions_wims` FOREIGN KEY (`wim_account_id`) REFERENCES `wim_accounts` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Table with the individual VIM actions.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `vms`
+--
+
+DROP TABLE IF EXISTS `vms`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `vms` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `pdu_type` varchar(255) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `vnf_id` varchar(36) NOT NULL,
+  `count` smallint(6) NOT NULL DEFAULT '1',
+  `flavor_id` varchar(36) NOT NULL COMMENT 'Link to flavor table',
+  `image_id` varchar(36) DEFAULT NULL COMMENT 'Link to image table',
+  `image_list` text COMMENT 'Alternative images',
+  `image_path` varchar(100) DEFAULT NULL COMMENT 'Path where the image of the VM is located',
+  `boot_data` text,
+  `description` varchar(255) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `availability_zone` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `name_vnf_id` (`name`,`vnf_id`),
+  KEY `FK_vms_vnfs` (`vnf_id`),
+  KEY `FK_vms_images` (`image_id`),
+  KEY `FK_vms_flavors` (`flavor_id`),
+  CONSTRAINT `FK_vms_flavors` FOREIGN KEY (`flavor_id`) REFERENCES `flavors` (`uuid`),
+  CONSTRAINT `FK_vms_images` FOREIGN KEY (`image_id`) REFERENCES `images` (`uuid`),
+  CONSTRAINT `FK_vms_vnfs` FOREIGN KEY (`vnf_id`) REFERENCES `vnfs` (`uuid`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='VM definitions. It contains the set of VMs used by the VNF definitions.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `vnfs`
+--
+
+DROP TABLE IF EXISTS `vnfs`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `vnfs` (
+  `uuid` varchar(36) NOT NULL,
+  `osm_id` varchar(255) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `short_name` varchar(255) DEFAULT NULL,
+  `tenant_id` varchar(36) DEFAULT NULL,
+  `physical` enum('true','false') NOT NULL DEFAULT 'false',
+  `public` enum('true','false') NOT NULL DEFAULT 'false',
+  `description` varchar(255) DEFAULT NULL,
+  `vendor` varchar(255) DEFAULT NULL,
+  `mgmt_access` varchar(2000) DEFAULT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  `class` varchar(36) DEFAULT 'MISC',
+  `descriptor` text COMMENT 'Original text descriptor used for create the VNF',
+  PRIMARY KEY (`uuid`),
+  UNIQUE KEY `osm_id_tenant_id` (`osm_id`,`tenant_id`),
+  KEY `FK_vnfs_nfvo_tenants` (`tenant_id`),
+  CONSTRAINT `FK_vnfs_nfvo_tenants` FOREIGN KEY (`tenant_id`) REFERENCES `nfvo_tenants` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='VNF definitions. This is the catalogue of VNFs. It also includes Physical Network Functions or Physical Elements.\r\n';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `wim_accounts`
+--
+
+DROP TABLE IF EXISTS `wim_accounts`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `wim_accounts` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) DEFAULT NULL,
+  `wim_id` varchar(36) NOT NULL,
+  `sdn` enum('true','false') NOT NULL DEFAULT 'false',
+  `user` varchar(64) DEFAULT NULL,
+  `password` varchar(64) DEFAULT NULL,
+  `config` text,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`),
+  KEY `FK_wim_accounts_wims` (`wim_id`),
+  CONSTRAINT `FK_wim_accounts_wims` FOREIGN KEY (`wim_id`) REFERENCES `wims` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='WIM accounts by the user';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `wim_nfvo_tenants`
+--
+
+DROP TABLE IF EXISTS `wim_nfvo_tenants`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `wim_nfvo_tenants` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `nfvo_tenant_id` varchar(36) NOT NULL,
+  `wim_id` varchar(36) NOT NULL,
+  `wim_account_id` varchar(36) NOT NULL,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `wim_nfvo_tenant` (`wim_id`,`nfvo_tenant_id`),
+  KEY `FK_wims_nfvo_tenants` (`wim_id`),
+  KEY `FK_wim_accounts_nfvo_tenants` (`wim_account_id`),
+  KEY `FK_nfvo_tenants_wim_accounts` (`nfvo_tenant_id`),
+  CONSTRAINT `FK_nfvo_tenants_wim_accounts` FOREIGN KEY (`nfvo_tenant_id`) REFERENCES `nfvo_tenants` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_wim_accounts_nfvo_tenants` FOREIGN KEY (`wim_account_id`) REFERENCES `wim_accounts` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_wims_nfvo_tenants` FOREIGN KEY (`wim_id`) REFERENCES `wims` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='WIM accounts mapping to NFVO tenants';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `wim_port_mappings`
+--
+
+DROP TABLE IF EXISTS `wim_port_mappings`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `wim_port_mappings` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `wim_id` varchar(36) NOT NULL,
+  `datacenter_id` varchar(36) NOT NULL,
+  `device_id` varchar(64) DEFAULT NULL,
+  `device_interface_id` varchar(64) DEFAULT NULL,
+  `service_endpoint_id` varchar(256) NOT NULL,
+  `switch_dpid` varchar(64) DEFAULT NULL,
+  `switch_port` varchar(64) DEFAULT NULL,
+  `service_mapping_info` text,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `unique_wim_port_mapping` (`wim_id`,`service_endpoint_id`),
+  KEY `FK_wims_wim_physical_connections` (`wim_id`),
+  KEY `FK_datacenters_wim_port_mappings` (`datacenter_id`),
+  CONSTRAINT `FK_datacenters_wim_port_mappings` FOREIGN KEY (`datacenter_id`) REFERENCES `datacenters` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `FK_wims_wim_port_mappings` FOREIGN KEY (`wim_id`) REFERENCES `wims` (`uuid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='WIM port mappings managed by the WIM.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `wims`
+--
+
+DROP TABLE IF EXISTS `wims`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `wims` (
+  `uuid` varchar(36) NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` varchar(255) DEFAULT NULL,
+  `type` varchar(36) NOT NULL DEFAULT 'odl',
+  `wim_url` varchar(150) NOT NULL,
+  `config` text,
+  `created_at` double NOT NULL,
+  `modified_at` double DEFAULT NULL,
+  PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='WIMs managed by the NFVO.';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping routines for database 'mano_db'
+--
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2020-07-15 22:32:14
+
+
+
+
+
+-- MySQL dump 10.13  Distrib 5.7.30, for Linux (x86_64)
+--
+-- Host: localhost    Database: {{mano_db}}
+-- ------------------------------------------------------
+-- Server version      5.7.27
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Dumping data for table `schema_version`
+--
+
+LOCK TABLES `schema_version` WRITE;
+/*!40000 ALTER TABLE `schema_version` DISABLE KEYS */;
+INSERT INTO `schema_version` VALUES
+(0,'0.0','0.0.0','Database in init process','2015-05-08'),
+(1,'0.1','0.2.2','insert schema_version','2015-05-08'),
+(2,'0.2','0.2.5','new tables images,flavors','2015-07-13'),
+(3,'0.3','0.3.3','alter vim_tenant tables','2015-07-28'),
+(4,'0.4','0.3.5','enlarge graph field at sce_vnfs/nets','2015-10-20'),
+(5,'0.5','0.4.1','Add mac address for bridge interfaces','2015-12-14'),
+(6,'0.6','0.4.2','Adding VIM status info','2015-12-22'),
+(7,'0.7','0.4.3','Changing created_at time at database','2016-01-25'),
+(8,'0.8','0.4.32','Enlarging name at database','2016-02-01'),
+(9,'0.9','0.4.33','Add ACTIVE:NoMgmtIP to instance_vms table','2016-02-05'),
+(10,'0.10','0.4.36','tenant management of vnfs,scenarios','2016-03-08'),
+(11,'0.11','0.4.43','remove unique name at scenarios,instance_scenarios','2016-07-18'),
+(12,'0.12','0.4.46','create ip_profiles table, with foreign keys to all nets tables, and add ip_address column to interfaces and sce_interfaces','2016-08-29'),
+(13,'0.13','0.4.47','insert cloud-config at scenarios,instance_scenarios','2016-08-30'),
+(14,'0.14','0.4.57','remove unique index vim_net_id, instance_scenario_id','2016-09-26'),
+(15,'0.15','0.4.59','add columns universal_name and checksum at table images, add unique index universal_name_checksum, and change location to allow NULL; change column image_path in table vms to allow NULL','2016-09-27'),
+(16,'0.16','0.5.2','enlarge vim_tenant_name and id. New config at datacenter_tenants','2016-10-11'),
+(17,'0.17','0.5.3','Extra description json format of additional devices in datacenter_flavors','2016-12-20'),
+(18,'0.18','0.5.4','Add columns \'floating_ip\' and \'port_security\' at tables \'interfaces\' and \'instance_interfaces\'','2017-01-09'),
+(19,'0.19','0.5.5','Extra Boot-data content at VNFC (vms)','2017-01-11'),
+(20,'0.20','0.5.9','Added columns to store dataplane connectivity info','2017-03-13'),
+(21,'0.21','0.5.15','Edit instance_nets to allow instance_scenario_id=None and enlarge column dns_address at table ip_profiles','2017-06-02'),
+(22,'0.22','0.5.16','Changed type of ram in flavors from SMALLINT to MEDIUMINT','2017-06-02'),
+(23,'0.23','0.5.20','Changed type of ram in flavors from SMALLINT to MEDIUMINT','2017-08-29'),
+(24,'0.24','0.5.21','Added vnfd fields','2017-08-29'),
+(25,'0.25','0.5.22','Added osm_id to vnfs,scenarios','2017-09-01'),
+(26,'0.26','0.5.23','Several changes','2017-09-09'),
+(27,'0.27','0.5.25','Added encrypted_RO_priv_key,RO_pub_key to table nfvo_tenants','2017-09-29'),
+(28,'0.28','0.5.28','Adding VNFFG-related tables','2017-11-20'),
+(29,'0.29','0.5.59','Change member_vnf_index to str accordingly to the model','2018-04-11'),
+(30,'0.30','0.5.60','Add image_list to vms','2018-04-24'),
+(31,'0.31','0.5.61','Add vim_network_name to sce_nets','2018-05-03'),
+(32,'0.32','0.5.70','Add vim_name to instance vms','2018-06-28'),
+(33,'0.33','0.5.82','Add pdu information to vms','2018-11-13'),
+(34,'0.34','0.6.00','Added WIM tables','2018-09-10'),
+(35,'0.35','0.6.02','Adding ingress and egress ports for RSPs','2018-12-11'),
+(36,'0.36','0.6.03','Allow vm without image_id for PDUs','2018-12-19'),
+(37,'0.37','0.6.09','Adding the enum tags for SFC','2019-02-07'),
+(38,'0.38','0.6.11','Adding related to vim_wim_actions','2019-03-07'),
+(39,'0.39','0.6.20','Enlarge vim_id to 300 at all places','2019-05-23'),
+(40,'0.40','6.0.4','Chagnes to SDN ','2019-10-23'),
+(41,'0.41','8.0.0','Removing unique name for wims/wim_accounts','2020-07-16');
+/*!40000 ALTER TABLE `schema_version` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2020-07-15 22:32:14
diff --git a/RO/osm_ro/database_utils/migrate_mano_db.sh b/RO/osm_ro/database_utils/migrate_mano_db.sh
new file mode 100755 (executable)
index 0000000..12f4566
--- /dev/null
@@ -0,0 +1,1660 @@
+#!/bin/bash
+
+##
+# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+#
+#Upgrade/Downgrade openmano database preserving the content
+#
+DBUTILS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+DBUSER="mano"
+DBPASS=""
+DEFAULT_DBPASS="manopw"
+DBHOST=""
+DBPORT="3306"
+DBNAME="mano_db"
+QUIET_MODE=""
+BACKUP_DIR=""
+BACKUP_FILE=""
+# TODO update it with the last database version
+LAST_DB_VERSION=42
+
+# Detect paths
+MYSQL=$(which mysql)
+AWK=$(which awk)
+GREP=$(which grep)
+
+function usage(){
+    echo -e "Usage: $0 OPTIONS [version]"
+    echo -e "  Upgrades/Downgrades openmano database preserving the content."\
+            "If [version]  is not provided, it is upgraded to the last version"
+    echo -e "  OPTIONS"
+    echo -e "     -u USER  database user. '$DBUSER' by default. Prompts if DB access fails"
+    echo -e "     -p PASS  database password. If missing it tries without and '$DEFAULT_DBPASS' password before prompting"
+    echo -e "     -P PORT  database port. '$DBPORT' by default"
+    echo -e "     -h HOST  database host. 'localhost' by default"
+    echo -e "     -d NAME  database name. '$DBNAME' by default.  Prompts if DB access fails"
+    echo -e "     -b DIR   backup folder where to create rollback backup file"
+    echo -e "     -q --quiet: Do not prompt for credentials and exit if cannot access to database"
+    echo -e "     --help   shows this help"
+}
+
+while getopts ":u:p:b:P:h:d:q-:" o; do
+    case "${o}" in
+        u)
+            DBUSER="$OPTARG"
+            ;;
+        p)
+            DBPASS="$OPTARG"
+            ;;
+        P)
+            DBPORT="$OPTARG"
+            ;;
+        d)
+            DBNAME="$OPTARG"
+            ;;
+        h)
+            DBHOST="$OPTARG"
+            ;;
+        b)
+            BACKUP_DIR="$OPTARG"
+            ;;
+        q)
+            export QUIET_MODE=yes
+            ;;
+        -)
+            [ "${OPTARG}" == "help" ] && usage && exit 0
+            [ "${OPTARG}" == "quiet" ] && export QUIET_MODE=yes && continue
+            echo "Invalid option: '--$OPTARG'. Type --help for more information" >&2
+            exit 1
+            ;;
+        \?)
+            echo "Invalid option: '-$OPTARG'. Type --help for more information" >&2
+            exit 1
+            ;;
+        :)
+            echo "Option '-$OPTARG' requires an argument. Type --help for more information" >&2
+            exit 1
+            ;;
+        *)
+            usage >&2
+            exit 1
+            ;;
+    esac
+done
+shift $((OPTIND-1))
+
+DB_VERSION=$1
+
+if [ -n "$DB_VERSION" ] ; then
+    # check it is a number and an allowed one
+    [ "$DB_VERSION" -eq "$DB_VERSION" ] 2>/dev/null || 
+        ! echo "parameter 'version' requires a integer value" >&2 || exit 1
+    if [ "$DB_VERSION" -lt 0 ] || [ "$DB_VERSION" -gt "$LAST_DB_VERSION" ] ; then
+        echo "parameter 'version' requires a valid database version between '0' and '$LAST_DB_VERSION'"\
+             "If you need an upper version, get a newer version of this script '$0'" >&2
+        exit 1
+    fi
+else
+    DB_VERSION="$LAST_DB_VERSION"
+fi
+
+# Creating temporary file
+TEMPFILE="$(mktemp -q --tmpdir "migratemanodb.XXXXXX")"
+trap 'rm -f "$TEMPFILE"' EXIT
+chmod 0600 "$TEMPFILE"
+DEF_EXTRA_FILE_PARAM="--defaults-extra-file=$TEMPFILE"
+echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE"
+
+# Check and ask for database user password
+FIRST_TRY="yes"
+while ! DB_ERROR=`mysql "$DEF_EXTRA_FILE_PARAM" $DBNAME -e "quit" 2>&1 >/dev/null`
+do
+    # if password is not provided, try silently with $DEFAULT_DBPASS before exit or prompt for credentials
+    [[ -n "$FIRST_TRY" ]] && [[ -z "$DBPASS" ]] && DBPASS="$DEFAULT_DBPASS" &&
+        echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE" &&
+        continue
+    echo "$DB_ERROR"
+    [[ -n "$QUIET_MODE" ]] && echo -e "Invalid database credentials!!!" >&2 && exit 1
+    echo -e "Provide database name and credentials (Ctrl+c to abort):"
+    read -e -p "    mysql database name($DBNAME): " KK
+    [ -n "$KK" ] && DBNAME="$KK"
+    read -e -p "    mysql user($DBUSER): " KK
+    [ -n "$KK" ] && DBUSER="$KK"
+    read -e -s -p "    mysql password: " DBPASS
+    echo -e "[client]\n user='${DBUSER}'\n password='$DBPASS'\n host='$DBHOST'\n port='$DBPORT'" > "$TEMPFILE"
+    FIRST_TRY=""
+    echo
+done
+
+DBCMD="mysql $DEF_EXTRA_FILE_PARAM $DBNAME"
+#echo DBCMD $DBCMD
+
+#check that the database seems a openmano database
+if ! echo -e "show create table vnfs;\nshow create table scenarios" | $DBCMD >/dev/null 2>&1
+then
+    echo "    database $DBNAME does not seem to be an openmano database" >&2
+    exit 1;
+fi
+
+#GET DATABASE TARGET VERSION
+#DB_VERSION=0
+#[ $OPENMANO_VER_NUM -ge 2002 ] && DB_VERSION=1   #0.2.2 =>  1
+#[ $OPENMANO_VER_NUM -ge 2005 ] && DB_VERSION=2   #0.2.5 =>  2
+#[ $OPENMANO_VER_NUM -ge 3003 ] && DB_VERSION=3   #0.3.3 =>  3
+#[ $OPENMANO_VER_NUM -ge 3005 ] && DB_VERSION=4   #0.3.5 =>  4
+#[ $OPENMANO_VER_NUM -ge 4001 ] && DB_VERSION=5   #0.4.1 =>  5
+#[ $OPENMANO_VER_NUM -ge 4002 ] && DB_VERSION=6   #0.4.2 =>  6
+#[ $OPENMANO_VER_NUM -ge 4003 ] && DB_VERSION=7   #0.4.3 =>  7
+#[ $OPENMANO_VER_NUM -ge 4032 ] && DB_VERSION=8   #0.4.32=>  8
+#[ $OPENMANO_VER_NUM -ge 4033 ] && DB_VERSION=9   #0.4.33=>  9
+#[ $OPENMANO_VER_NUM -ge 4036 ] && DB_VERSION=10  #0.4.36=>  10
+#[ $OPENMANO_VER_NUM -ge 4043 ] && DB_VERSION=11  #0.4.43=>  11
+#[ $OPENMANO_VER_NUM -ge 4046 ] && DB_VERSION=12  #0.4.46=>  12
+#[ $OPENMANO_VER_NUM -ge 4047 ] && DB_VERSION=13  #0.4.47=>  13
+#[ $OPENMANO_VER_NUM -ge 4057 ] && DB_VERSION=14  #0.4.57=>  14
+#[ $OPENMANO_VER_NUM -ge 4059 ] && DB_VERSION=15  #0.4.59=>  15
+#[ $OPENMANO_VER_NUM -ge 5002 ] && DB_VERSION=16  #0.5.2 =>  16
+#[ $OPENMANO_VER_NUM -ge 5003 ] && DB_VERSION=17  #0.5.3 =>  17
+#[ $OPENMANO_VER_NUM -ge 5004 ] && DB_VERSION=18  #0.5.4 =>  18
+#[ $OPENMANO_VER_NUM -ge 5005 ] && DB_VERSION=19  #0.5.5 =>  19
+#[ $OPENMANO_VER_NUM -ge 5009 ] && DB_VERSION=20  #0.5.9 =>  20
+#[ $OPENMANO_VER_NUM -ge 5015 ] && DB_VERSION=21  #0.5.15 =>  21
+#[ $OPENMANO_VER_NUM -ge 5016 ] && DB_VERSION=22  #0.5.16 =>  22
+#[ $OPENMANO_VER_NUM -ge 5020 ] && DB_VERSION=23  #0.5.20 =>  23
+#[ $OPENMANO_VER_NUM -ge 5021 ] && DB_VERSION=24  #0.5.21 =>  24
+#[ $OPENMANO_VER_NUM -ge 5022 ] && DB_VERSION=25  #0.5.22 =>  25
+#[ $OPENMANO_VER_NUM -ge 5024 ] && DB_VERSION=26  #0.5.24 =>  26
+#[ $OPENMANO_VER_NUM -ge 5025 ] && DB_VERSION=27  #0.5.25 =>  27
+#[ $OPENMANO_VER_NUM -ge 5052 ] && DB_VERSION=28  #0.5.52 =>  28
+#[ $OPENMANO_VER_NUM -ge 5059 ] && DB_VERSION=29  #0.5.59 =>  29
+#[ $OPENMANO_VER_NUM -ge 5060 ] && DB_VERSION=30  #0.5.60 =>  30
+#[ $OPENMANO_VER_NUM -ge 5061 ] && DB_VERSION=31  #0.5.61 =>  31
+#[ $OPENMANO_VER_NUM -ge 5070 ] && DB_VERSION=32  #0.5.70 =>  32
+#[ $OPENMANO_VER_NUM -ge 5082 ] && DB_VERSION=33  #0.5.82 =>  33
+#[ $OPENMANO_VER_NUM -ge 6000 ] && DB_VERSION=34  #0.6.00 =>  34
+#[ $OPENMANO_VER_NUM -ge 6001 ] && DB_VERSION=35  #0.6.01 =>  35
+#[ $OPENMANO_VER_NUM -ge 6003 ] && DB_VERSION=36  #0.6.03 =>  36
+#[ $OPENMANO_VER_NUM -ge 6009 ] && DB_VERSION=37  #0.6.09 =>  37
+#[ $OPENMANO_VER_NUM -ge 6011 ] && DB_VERSION=38  #0.6.11 =>  38
+#[ $OPENMANO_VER_NUM -ge 6020 ] && DB_VERSION=39  #0.6.20 =>  39
+#[ $OPENMANO_VER_NUM -ge 6000004 ] && DB_VERSION=40  #6.0.4 =>  40
+#[ $OPENMANO_VER_NUM -ge 8000000 ] && DB_VERSION=41  #8.0.0 =>  41
+#[ $OPENMANO_VER_NUM -ge 8000002 ] && DB_VERSION=42  #8.0.2 =>  42
+# TODO ... put next versions here
+
+function upgrade_to_1(){
+    # echo "    upgrade database from version 0.0 to version 0.1"
+    echo "      CREATE TABLE \`schema_version\`"
+    sql "CREATE TABLE \`schema_version\` (
+       \`version_int\` INT NOT NULL COMMENT 'version as a number. Must not contain gaps',
+       \`version\` VARCHAR(20) NOT NULL COMMENT 'version as a text',
+       \`openmano_ver\` VARCHAR(20) NOT NULL COMMENT 'openmano version',
+       \`comments\` VARCHAR(2000) NULL COMMENT 'changes to database',
+       \`date\` DATE NULL,
+       PRIMARY KEY (\`version_int\`)
+       )
+       COMMENT='database schema control version'
+       COLLATE='utf8_general_ci'
+       ENGINE=InnoDB;"
+    sql "INSERT INTO \`schema_version\` (\`version_int\`, \`version\`, \`openmano_ver\`, \`comments\`, \`date\`)
+        VALUES (1, '0.1', '0.2.2', 'insert schema_version', '2015-05-08');"
+}
+function downgrade_from_1(){
+    # echo "    downgrade database from version 0.1 to version 0.0"
+    echo "      DROP TABLE IF EXISTS \`schema_version\`"
+    sql "DROP TABLE IF EXISTS \`schema_version\`;"
+}
+function upgrade_to_2(){
+    # echo "    upgrade database from version 0.1 to version 0.2"
+    echo "      Add columns user/passwd to table 'vim_tenants'"
+    sql "ALTER TABLE vim_tenants ADD COLUMN user VARCHAR(36) NULL COMMENT 'Credentials for vim' AFTER created,
+       ADD COLUMN passwd VARCHAR(50) NULL COMMENT 'Credentials for vim' AFTER user;"
+    echo "      Add table 'images' and 'datacenters_images'"
+    sql "CREATE TABLE images (
+       uuid VARCHAR(36) NOT NULL,
+       name VARCHAR(50) NOT NULL,
+       location VARCHAR(200) NOT NULL,
+       description VARCHAR(100) NULL,
+       metadata VARCHAR(400) NULL,
+       PRIMARY KEY (uuid),
+       UNIQUE INDEX location (location)  )
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    sql "CREATE TABLE datacenters_images (
+       id INT NOT NULL AUTO_INCREMENT,
+       image_id VARCHAR(36) NOT NULL,
+       datacenter_id VARCHAR(36) NOT NULL,
+       vim_id VARCHAR(36) NOT NULL,
+       PRIMARY KEY (id),
+       CONSTRAINT FK__images FOREIGN KEY (image_id) REFERENCES images (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+       CONSTRAINT FK__datacenters_i FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid) ON UPDATE CASCADE ON DELETE CASCADE  )
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      migrate data from table 'vms' into 'images'"
+    sql "INSERT INTO images (uuid, name, location) SELECT DISTINCT vim_image_id, vim_image_id, image_path FROM vms;"
+    sql "INSERT INTO datacenters_images (image_id, datacenter_id, vim_id)
+          SELECT DISTINCT vim_image_id, datacenters.uuid, vim_image_id FROM vms JOIN datacenters;"
+    echo "      Add table 'flavors' and 'datacenter_flavors'"
+    sql "CREATE TABLE flavors (
+       uuid VARCHAR(36) NOT NULL,
+       name VARCHAR(50) NOT NULL,
+       description VARCHAR(100) NULL,
+       disk SMALLINT(5) UNSIGNED NULL DEFAULT NULL,
+       ram SMALLINT(5) UNSIGNED NULL DEFAULT NULL,
+       vcpus SMALLINT(5) UNSIGNED NULL DEFAULT NULL,
+       extended VARCHAR(2000) NULL DEFAULT NULL COMMENT 'Extra description json format of needed resources and pining, orginized in sets per numa',
+       PRIMARY KEY (uuid)  )
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    sql "CREATE TABLE datacenters_flavors (
+       id INT NOT NULL AUTO_INCREMENT,
+       flavor_id VARCHAR(36) NOT NULL,
+       datacenter_id VARCHAR(36) NOT NULL,
+       vim_id VARCHAR(36) NOT NULL,
+       PRIMARY KEY (id),
+       CONSTRAINT FK__flavors FOREIGN KEY (flavor_id) REFERENCES flavors (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+       CONSTRAINT FK__datacenters_f FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid) ON UPDATE CASCADE ON DELETE CASCADE  )
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      migrate data from table 'vms' into 'flavors'"
+    sql "INSERT INTO flavors (uuid, name) SELECT DISTINCT vim_flavor_id, vim_flavor_id FROM vms;"
+    sql "INSERT INTO datacenters_flavors (flavor_id, datacenter_id, vim_id)
+          SELECT DISTINCT vim_flavor_id, datacenters.uuid, vim_flavor_id FROM vms JOIN datacenters;"
+    sql "ALTER TABLE vms ALTER vim_flavor_id DROP DEFAULT, ALTER vim_image_id DROP DEFAULT;
+          ALTER TABLE vms CHANGE COLUMN vim_flavor_id flavor_id VARCHAR(36) NOT NULL COMMENT 'Link to flavor table' AFTER vnf_id,
+          CHANGE COLUMN vim_image_id image_id VARCHAR(36) NOT NULL COMMENT 'Link to image table' AFTER flavor_id, 
+          ADD CONSTRAINT FK_vms_images  FOREIGN KEY (image_id) REFERENCES  images (uuid),
+          ADD CONSTRAINT FK_vms_flavors FOREIGN KEY (flavor_id) REFERENCES flavors (uuid);"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (2, '0.2', '0.2.5', 'new tables images,flavors', '2015-07-13');"
+
+}   
+     
+function downgrade_from_2(){
+    # echo "    downgrade database from version 0.2 to version 0.1"
+    echo "       migrate back data from 'datacenters_images' 'datacenters_flavors' into 'vms'"
+    sql "ALTER TABLE vms ALTER image_id DROP DEFAULT, ALTER flavor_id DROP DEFAULT;
+          ALTER TABLE vms CHANGE COLUMN flavor_id vim_flavor_id VARCHAR(36) NOT NULL COMMENT 'Flavor ID in the VIM DB' AFTER vnf_id,
+          CHANGE COLUMN image_id vim_image_id VARCHAR(36) NOT NULL COMMENT 'Image ID in the VIM DB' AFTER vim_flavor_id,
+          DROP FOREIGN KEY FK_vms_flavors, DROP INDEX FK_vms_flavors,
+          DROP FOREIGN KEY FK_vms_images, DROP INDEX FK_vms_images;"
+#    echo "UPDATE v SET v.vim_image_id=di.vim_id
+#          FROM  vms as v INNER JOIN images as i ON v.vim_image_id=i.uuid 
+#          INNER JOIN datacenters_images as di ON i.uuid=di.image_id;"
+    echo "      Delete columns 'user/passwd' from 'vim_tenants'"
+    sql "ALTER TABLE vim_tenants DROP COLUMN user, DROP COLUMN passwd; "
+    echo "        delete tables 'datacenter_images', 'images'"
+    sql "DROP TABLE IF EXISTS \`datacenters_images\`;"
+    sql "DROP TABLE IF EXISTS \`images\`;"
+    echo "        delete tables 'datacenter_flavors', 'flavors'"
+    sql "DROP TABLE IF EXISTS \`datacenters_flavors\`;"
+    sql "DROP TABLE IF EXISTS \`flavors\`;"
+    sql "DELETE FROM schema_version WHERE version_int='2';"
+}
+
+function upgrade_to_3(){
+    # echo "    upgrade database from version 0.2 to version 0.3"
+    echo "      Change table 'logs', 'uuids"
+    sql "ALTER TABLE logs CHANGE COLUMN related related VARCHAR(36) NOT NULL COMMENT 'Relevant element for the log' AFTER nfvo_tenant_id;"
+    sql "ALTER TABLE uuids CHANGE COLUMN used_at used_at VARCHAR(36) NULL DEFAULT NULL COMMENT 'Table that uses this UUID' AFTER created_at;"
+    echo "      Add column created to table 'datacenters_images' and 'datacenters_flavors'"
+    for table in datacenters_images datacenters_flavors
+    do
+        sql "ALTER TABLE $table ADD COLUMN created ENUM('true','false') NOT NULL DEFAULT 'false' 
+            COMMENT 'Indicates if it has been created by openmano, or already existed' AFTER vim_id;"
+    done
+    sql "ALTER TABLE images CHANGE COLUMN metadata metadata VARCHAR(2000) NULL DEFAULT NULL AFTER description;"
+    echo "      Allow null to column 'vim_interface_id' in 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(36) NULL DEFAULT NULL COMMENT 'vim identity for that interface' AFTER interface_id; "
+    echo "      Add column config to table 'datacenters'"
+    sql "ALTER TABLE datacenters ADD COLUMN config VARCHAR(4000) NULL DEFAULT NULL COMMENT 'extra config information in json' AFTER vim_url_admin;
+       "
+    echo "      Add column datacenter_id to table 'vim_tenants'"
+    sql "ALTER TABLE vim_tenants ADD COLUMN datacenter_id VARCHAR(36) NULL COMMENT 'Datacenter of this tenant' AFTER uuid,
+       DROP INDEX name, DROP INDEX vim_tenant_id;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN name vim_tenant_name VARCHAR(36) NULL DEFAULT NULL COMMENT 'tenant name at VIM' AFTER datacenter_id,
+       CHANGE COLUMN vim_tenant_id vim_tenant_id VARCHAR(36) NULL DEFAULT NULL COMMENT 'Tenant ID at VIM' AFTER vim_tenant_name;"
+    echo "UPDATE vim_tenants as vt LEFT JOIN tenants_datacenters as td ON vt.uuid=td.vim_tenant_id
+       SET vt.datacenter_id=td.datacenter_id;"
+    sql "DELETE FROM vim_tenants WHERE datacenter_id is NULL;"
+    sql "ALTER TABLE vim_tenants ALTER datacenter_id DROP DEFAULT;
+       ALTER TABLE vim_tenants
+       CHANGE COLUMN datacenter_id datacenter_id VARCHAR(36) NOT NULL COMMENT 'Datacenter of this tenant' AFTER uuid;"
+    sql "ALTER TABLE vim_tenants ADD CONSTRAINT FK_vim_tenants_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid)
+       ON UPDATE CASCADE ON DELETE CASCADE;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (3, '0.3', '0.3.3', 'alter vim_tenant tables', '2015-07-28');"
+}
+
+
+function downgrade_from_3(){
+    # echo "    downgrade database from version 0.3 to version 0.2"
+    echo "      Change back table 'logs', 'uuids'"
+    sql "ALTER TABLE logs CHANGE COLUMN related related ENUM('nfvo_tenants','datacenters','vim_tenants','tenants_datacenters','vnfs','vms','interfaces','nets','scenarios','sce_vnfs','sce_interfaces','sce_nets','instance_scenarios','instance_vnfs','instance_vms','instance_nets','instance_interfaces') NOT NULL COMMENT 'Relevant element for the log' AFTER nfvo_tenant_id;"
+    sql "ALTER TABLE uuids CHANGE COLUMN used_at used_at ENUM('nfvo_tenants','datacenters','vim_tenants','vnfs','vms','interfaces','nets','scenarios','sce_vnfs','sce_interfaces','sce_nets','instance_scenarios','instance_vnfs','instance_vms','instance_nets','instance_interfaces') NULL DEFAULT NULL COMMENT 'Table that uses this UUID' AFTER created_at;"
+    echo "      Delete column created from table 'datacenters_images' and 'datacenters_flavors'"
+    for table in datacenters_images datacenters_flavors
+    do
+        sql "ALTER TABLE $table DROP COLUMN created;"
+    done
+    sql "ALTER TABLE images CHANGE COLUMN metadata metadata VARCHAR(400) NULL DEFAULT NULL AFTER description;"
+    echo "      Deny back null to column 'vim_interface_id' in 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(36) NOT NULL COMMENT 'vim identity for that interface' AFTER interface_id; "
+    echo "       Delete column config to table 'datacenters'"
+    sql "ALTER TABLE datacenters DROP COLUMN config;"
+    echo "       Delete column datacenter_id to table 'vim_tenants'"
+    sql "ALTER TABLE vim_tenants DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_vim_tenants_datacenters;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name name VARCHAR(36) NULL DEFAULT NULL COMMENT '' AFTER uuid"
+    sql "ALTER TABLE vim_tenants ALTER name DROP DEFAULT;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN name name VARCHAR(36) NOT NULL AFTER uuid" || ! echo "Warning changing column name at vim_tenants!"
+    sql "ALTER TABLE vim_tenants ADD UNIQUE INDEX name (name);" || ! echo "Warning add unique index name at vim_tenants!"
+    sql "ALTER TABLE vim_tenants ALTER vim_tenant_id DROP DEFAULT;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_id vim_tenant_id VARCHAR(36) NOT NULL COMMENT 'Tenant ID in the VIM DB' AFTER name;" ||
+        ! echo "Warning changing column vim_tenant_id at vim_tenants!"
+    sql "ALTER TABLE vim_tenants ADD UNIQUE INDEX vim_tenant_id (vim_tenant_id);" ||
+        ! echo "Warning add unique index vim_tenant_id at vim_tenants!"
+    sql "DELETE FROM schema_version WHERE version_int='3';"
+}
+
+function upgrade_to_4(){
+    # echo "    upgrade database from version 0.3 to version 0.4"
+    echo "      Enlarge graph field at tables 'sce_vnfs', 'sce_nets'"
+    for table in sce_vnfs sce_nets
+    do
+        sql "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;"
+    done
+    sql "ALTER TABLE datacenters CHANGE COLUMN type type VARCHAR(36) NOT NULL DEFAULT 'openvim' AFTER description;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (4, '0.4', '0.3.5', 'enlarge graph field at sce_vnfs/nets', '2015-10-20');"
+}
+
+function downgrade_from_4(){
+    # echo "    downgrade database from version 0.4 to version 0.3"
+    echo "      Shorten back graph field at tables 'sce_vnfs', 'sce_nets'"
+    for table in sce_vnfs sce_nets
+    do
+        sql "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;"
+    done
+    sql "ALTER TABLE datacenters CHANGE COLUMN type type ENUM('openvim','openstack') NOT NULL DEFAULT 'openvim' AFTER description;"
+    sql "DELETE FROM schema_version WHERE version_int='4';"
+}
+
+function upgrade_to_5(){
+    # echo "    upgrade database from version 0.4 to version 0.5"
+    echo "      Add 'mac' field for bridge interfaces in table 'interfaces'"
+    sql "ALTER TABLE interfaces ADD COLUMN mac CHAR(18) NULL DEFAULT NULL AFTER model;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (5, '0.5', '0.4.1', 'Add mac address for bridge interfaces', '2015-12-14');"
+}
+function downgrade_from_5(){
+    # echo "    downgrade database from version 0.5 to version 0.4"
+    echo "      Remove 'mac' field for bridge interfaces in table 'interfaces'"
+    sql "ALTER TABLE interfaces DROP COLUMN mac;"
+    sql "DELETE FROM schema_version WHERE version_int='5';"
+}
+
+function upgrade_to_6(){
+    # echo "    upgrade database from version 0.5 to version 0.6"
+    echo "      Add 'descriptor' field text to 'vnfd', 'scenarios'"
+    sql "ALTER TABLE vnfs ADD COLUMN descriptor TEXT NULL DEFAULT NULL COMMENT 'Original text descriptor used for create the VNF' AFTER class;"
+    sql "ALTER TABLE scenarios ADD COLUMN descriptor TEXT NULL DEFAULT NULL COMMENT 'Original text descriptor used for create the scenario' AFTER modified_at;"
+    echo "      Add 'last_error', 'vim_info' to 'instance_vms', 'instance_nets'"
+    sql "ALTER TABLE instance_vms  ADD COLUMN error_msg VARCHAR(1024) NULL DEFAULT NULL AFTER status;"
+    sql "ALTER TABLE instance_vms  ADD COLUMN vim_info TEXT NULL DEFAULT NULL AFTER error_msg;"
+    sql "ALTER TABLE instance_vms  CHANGE COLUMN status status ENUM('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD' AFTER vim_vm_id;"
+    sql "ALTER TABLE instance_nets ADD COLUMN error_msg VARCHAR(1024) NULL DEFAULT NULL AFTER status;"
+    sql "ALTER TABLE instance_nets ADD COLUMN vim_info TEXT NULL DEFAULT NULL AFTER error_msg;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN status status ENUM('ACTIVE','DOWN','BUILD','ERROR','VIM_ERROR','INACTIVE','DELETED') NOT NULL DEFAULT 'BUILD' AFTER instance_scenario_id;"
+    echo "      Add 'mac_address', 'ip_address', 'vim_info' to 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces ADD COLUMN mac_address VARCHAR(32) NULL DEFAULT NULL AFTER vim_interface_id, ADD COLUMN ip_address VARCHAR(64) NULL DEFAULT NULL AFTER mac_address, ADD COLUMN vim_info TEXT NULL DEFAULT NULL AFTER ip_address;"
+    echo "      Add 'sce_vnf_id','datacenter_id','vim_tenant_id' field to 'instance_vnfs'"
+    sql "ALTER TABLE instance_vnfs ADD COLUMN sce_vnf_id VARCHAR(36) NULL DEFAULT NULL AFTER vnf_id, ADD CONSTRAINT FK_instance_vnfs_sce_vnfs FOREIGN KEY (sce_vnf_id) REFERENCES sce_vnfs (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+    sql "ALTER TABLE instance_vnfs ADD COLUMN vim_tenant_id VARCHAR(36) NULL DEFAULT NULL AFTER sce_vnf_id, ADD CONSTRAINT FK_instance_vnfs_vim_tenants FOREIGN KEY (vim_tenant_id) REFERENCES vim_tenants (uuid) ON UPDATE RESTRICT ON DELETE RESTRICT;"
+    sql "ALTER TABLE instance_vnfs ADD COLUMN datacenter_id VARCHAR(36) NULL DEFAULT NULL AFTER vim_tenant_id, ADD CONSTRAINT FK_instance_vnfs_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid) ON UPDATE RESTRICT ON DELETE RESTRICT;"
+    echo "      Add 'sce_net_id','net_id','datacenter_id','vim_tenant_id' field to 'instance_nets'"
+    sql "ALTER TABLE instance_nets ADD COLUMN sce_net_id VARCHAR(36) NULL DEFAULT NULL AFTER instance_scenario_id, ADD CONSTRAINT FK_instance_nets_sce_nets FOREIGN KEY (sce_net_id) REFERENCES sce_nets (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+    sql "ALTER TABLE instance_nets ADD COLUMN net_id VARCHAR(36) NULL DEFAULT NULL AFTER sce_net_id, ADD CONSTRAINT FK_instance_nets_nets FOREIGN KEY (net_id) REFERENCES nets (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+    sql "ALTER TABLE instance_nets ADD COLUMN vim_tenant_id VARCHAR(36) NULL DEFAULT NULL AFTER net_id, ADD CONSTRAINT FK_instance_nets_vim_tenants FOREIGN KEY (vim_tenant_id) REFERENCES vim_tenants (uuid) ON UPDATE RESTRICT ON DELETE RESTRICT;"
+    sql "ALTER TABLE instance_nets ADD COLUMN datacenter_id VARCHAR(36) NULL DEFAULT NULL AFTER vim_tenant_id, ADD CONSTRAINT FK_instance_nets_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid) ON UPDATE RESTRICT ON DELETE RESTRICT;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (6, '0.6', '0.4.2', 'Adding VIM status info', '2015-12-22');"
+}
+function downgrade_from_6(){
+    # echo "    downgrade database from version 0.6 to version 0.5"
+    echo "      Remove 'descriptor' field from 'vnfd', 'scenarios' tables"
+    sql "ALTER TABLE vnfs      DROP COLUMN descriptor;"
+    sql "ALTER TABLE scenarios DROP COLUMN descriptor;"
+    echo "      Remove 'last_error', 'vim_info' from 'instance_vms', 'instance_nets'"
+    sql "ALTER TABLE instance_vms  DROP COLUMN error_msg, DROP COLUMN vim_info;"
+    sql "ALTER TABLE instance_vms  CHANGE COLUMN status status ENUM('ACTIVE','PAUSED','INACTIVE','CREATING','ERROR','DELETING') NOT NULL DEFAULT 'CREATING' AFTER vim_vm_id;"
+    sql "ALTER TABLE instance_nets DROP COLUMN error_msg, DROP COLUMN vim_info;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN status status ENUM('ACTIVE','DOWN','BUILD','ERROR') NOT NULL DEFAULT 'BUILD' AFTER instance_scenario_id;"
+    echo "      Remove 'mac_address', 'ip_address', 'vim_info' from 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN mac_address, DROP COLUMN ip_address, DROP COLUMN vim_info;"
+    echo "      Remove 'sce_vnf_id','datacenter_id','vim_tenant_id' field from 'instance_vnfs'"
+    sql "ALTER TABLE instance_vnfs DROP COLUMN sce_vnf_id, DROP FOREIGN KEY FK_instance_vnfs_sce_vnfs;"
+    sql "ALTER TABLE instance_vnfs DROP COLUMN vim_tenant_id, DROP FOREIGN KEY FK_instance_vnfs_vim_tenants;"
+    sql "ALTER TABLE instance_vnfs DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_instance_vnfs_datacenters;"
+    echo "      Remove 'sce_net_id','net_id','datacenter_id','vim_tenant_id' field from 'instance_nets'"
+    sql "ALTER TABLE instance_nets DROP COLUMN sce_net_id, DROP FOREIGN KEY FK_instance_nets_sce_nets;"
+    sql "ALTER TABLE instance_nets DROP COLUMN net_id, DROP FOREIGN KEY FK_instance_nets_nets;"
+    sql "ALTER TABLE instance_nets DROP COLUMN vim_tenant_id, DROP FOREIGN KEY FK_instance_nets_vim_tenants;"
+    sql "ALTER TABLE instance_nets DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_instance_nets_datacenters;"
+    sql "DELETE FROM schema_version WHERE version_int='6';"
+}
+
+function upgrade_to_7(){
+    # echo "    upgrade database from version 0.6 to version 0.7"
+    echo "      Change created_at, modified_at from timestamp to unix float at all database"
+    for table in datacenters datacenter_nets instance_nets instance_scenarios instance_vms instance_vnfs interfaces nets nfvo_tenants scenarios sce_interfaces sce_nets sce_vnfs tenants_datacenters vim_tenants vms vnfs uuids
+    do
+         echo -en "        $table               \r"
+         sql "ALTER TABLE $table ADD COLUMN created_at_ DOUBLE NOT NULL after created_at;"
+         echo "UPDATE $table SET created_at_=unix_timestamp(created_at);"
+         sql "ALTER TABLE $table DROP COLUMN created_at, CHANGE COLUMN created_at_ created_at DOUBLE NOT NULL;"
+         [[ $table == uuids ]] || sql "ALTER TABLE $table CHANGE COLUMN modified_at modified_at DOUBLE NULL DEFAULT NULL;"
+    done
+    
+    echo "      Add 'descriptor' field text to 'vnfd', 'scenarios'"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (7, '0.7', '0.4.3', 'Changing created_at time at database', '2016-01-25');"
+}
+function downgrade_from_7(){
+    # echo "    downgrade database from version 0.7 to version 0.6"
+    echo "      Change back created_at, modified_at from unix float to timestamp at all database"
+    for table in datacenters datacenter_nets instance_nets instance_scenarios instance_vms instance_vnfs interfaces nets nfvo_tenants scenarios sce_interfaces sce_nets sce_vnfs tenants_datacenters vim_tenants vms vnfs uuids
+    do
+         echo -en "        $table               \r"
+         sql "ALTER TABLE $table ADD COLUMN created_at_ TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP after created_at;"
+         echo "UPDATE $table SET created_at_=from_unixtime(created_at);"
+         sql "ALTER TABLE $table DROP COLUMN created_at, CHANGE COLUMN created_at_ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;"
+         [[ $table == uuids ]] || sql "ALTER TABLE $table CHANGE COLUMN modified_at modified_at TIMESTAMP NULL DEFAULT NULL;"
+    done
+    echo "      Remove 'descriptor' field from 'vnfd', 'scenarios' tables"
+    sql "DELETE FROM schema_version WHERE version_int='7';"
+}
+
+function upgrade_to_8(){
+    # echo "    upgrade database from version 0.7 to version 0.8"
+    echo "      Change enalarge name, description to 255 at all database"
+    for table in datacenters datacenter_nets flavors images instance_scenarios nets nfvo_tenants scenarios sce_nets sce_vnfs vms vnfs
+    do
+         echo -en "        $table               \r"
+         sql "ALTER TABLE $table CHANGE COLUMN name name VARCHAR(255) NOT NULL;"
+         sql "ALTER TABLE $table CHANGE COLUMN description description VARCHAR(255) NULL DEFAULT NULL;"
+    done
+    echo -en "        interfaces           \r"
+    sql "ALTER TABLE interfaces CHANGE COLUMN internal_name internal_name VARCHAR(255) NOT NULL, CHANGE COLUMN external_name external_name VARCHAR(255) NULL DEFAULT NULL;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(64) NULL DEFAULT NULL;"
+    echo -en "        vim_tenants          \r"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN user user VARCHAR(64) NULL DEFAULT NULL, CHANGE COLUMN passwd passwd VARCHAR(64) NULL DEFAULT NULL;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (8, '0.8', '0.4.32', 'Enlarging name at database', '2016-02-01');"
+}
+function downgrade_from_8(){
+    # echo "    downgrade database from version 0.8 to version 0.7"
+    echo "      Change back name,description to shorter length at all database"
+    for table in datacenters datacenter_nets flavors images instance_scenarios nets nfvo_tenants scenarios sce_nets sce_vnfs vms vnfs
+    do
+         name_length=50
+         [[ $table == flavors ]] || [[ $table == images ]] || name_length=36 
+         echo -en "        $table               \r"
+         sql "ALTER TABLE $table CHANGE COLUMN name name VARCHAR($name_length) NOT NULL;"
+         sql "ALTER TABLE $table CHANGE COLUMN description description VARCHAR(100) NULL DEFAULT NULL;"
+    done
+    echo -en "        interfaces           \r"
+    sql "ALTER TABLE interfaces CHANGE COLUMN internal_name internal_name VARCHAR(25) NOT NULL, CHANGE COLUMN external_name external_name VARCHAR(25) NULL DEFAULT NULL;"
+    echo -en "        vim_tenants          \r"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(36) NULL DEFAULT NULL;"
+    sql "ALTER TABLE vim_tenants CHANGE COLUMN user user VARCHAR(36) NULL DEFAULT NULL, CHANGE COLUMN passwd passwd VARCHAR(50) NULL DEFAULT NULL;"
+    sql "DELETE FROM schema_version WHERE version_int='8';"
+}
+function upgrade_to_9(){
+    # echo "    upgrade database from version 0.8 to version 0.9"
+    echo "      Add more status to 'instance_vms'"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE:NoMgmtIP','ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (9, '0.9', '0.4.33', 'Add ACTIVE:NoMgmtIP to instance_vms table', '2016-02-05');"
+}
+function downgrade_from_9(){
+    # echo "    downgrade database from version 0.9 to version 0.8"
+    echo "      Add more status to 'instance_vms'"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD';"
+    sql "DELETE FROM schema_version WHERE version_int='9';"
+}
+function upgrade_to_10(){
+    # echo "    upgrade database from version 0.9 to version 0.10"
+    echo "      add tenant to 'vnfs'"
+    sql "ALTER TABLE vnfs ADD COLUMN tenant_id VARCHAR(36) NULL DEFAULT NULL AFTER name, ADD CONSTRAINT FK_vnfs_nfvo_tenants FOREIGN KEY (tenant_id) REFERENCES nfvo_tenants (uuid) ON UPDATE CASCADE ON DELETE SET NULL, CHANGE COLUMN public public ENUM('true','false') NOT NULL DEFAULT 'false' AFTER physical, DROP INDEX name, DROP INDEX path, DROP COLUMN path;"
+    sql "ALTER TABLE scenarios DROP FOREIGN KEY FK_scenarios_nfvo_tenants;"
+    sql "ALTER TABLE scenarios CHANGE COLUMN nfvo_tenant_id tenant_id VARCHAR(36) NULL DEFAULT NULL after name, ADD CONSTRAINT FK_scenarios_nfvo_tenants FOREIGN KEY (tenant_id) REFERENCES nfvo_tenants (uuid);"
+    sql "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_nfvo_tenants;"
+    sql "ALTER TABLE instance_scenarios CHANGE COLUMN nfvo_tenant_id tenant_id VARCHAR(36) NULL DEFAULT NULL after name, ADD CONSTRAINT FK_instance_scenarios_nfvo_tenants FOREIGN KEY (tenant_id) REFERENCES nfvo_tenants (uuid);"
+    echo "      rename 'vim_tenants' table to 'datacenter_tenants'"
+    echo "RENAME TABLE vim_tenants TO datacenter_tenants;"
+    for table in tenants_datacenters instance_scenarios instance_vnfs instance_nets
+    do
+        NULL="NOT NULL"
+        [[ $table == instance_vnfs ]] && NULL="NULL DEFAULT NULL"
+        sql "ALTER TABLE ${table} DROP FOREIGN KEY FK_${table}_vim_tenants;"
+        sql "ALTER TABLE ${table} ALTER vim_tenant_id DROP DEFAULT;"
+        sql "ALTER TABLE ${table} CHANGE COLUMN vim_tenant_id datacenter_tenant_id VARCHAR(36)  ${NULL} AFTER datacenter_id, ADD CONSTRAINT FK_${table}_datacenter_tenants FOREIGN KEY (datacenter_tenant_id) REFERENCES datacenter_tenants (uuid); "
+    done    
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (10, '0.10', '0.4.36', 'tenant management of vnfs,scenarios', '2016-03-08');"
+}
+
+function downgrade_from_10(){
+    # echo "    downgrade database from version 0.10 to version 0.9"
+    echo "      remove tenant from 'vnfs'"
+    sql "ALTER TABLE vnfs DROP COLUMN tenant_id, DROP FOREIGN KEY FK_vnfs_nfvo_tenants, ADD UNIQUE INDEX name (name), ADD COLUMN path VARCHAR(100) NULL DEFAULT NULL COMMENT 'Path where the YAML descriptor of the VNF can be found. NULL if it is a physical network function.' AFTER name, ADD UNIQUE INDEX path (path), CHANGE COLUMN public public ENUM('true','false') NOT NULL DEFAULT 'true' AFTER physical;"
+    sql "ALTER TABLE scenarios DROP FOREIGN KEY FK_scenarios_nfvo_tenants;"
+    sql "ALTER TABLE scenarios CHANGE COLUMN tenant_id nfvo_tenant_id VARCHAR(36) NULL DEFAULT NULL after name, ADD CONSTRAINT FK_scenarios_nfvo_tenants FOREIGN KEY (nfvo_tenant_id) REFERENCES nfvo_tenants (uuid);"
+    sql "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_nfvo_tenants;"
+    sql "ALTER TABLE instance_scenarios CHANGE COLUMN tenant_id nfvo_tenant_id VARCHAR(36) NULL DEFAULT NULL after name, ADD CONSTRAINT FK_instance_scenarios_nfvo_tenants FOREIGN KEY (nfvo_tenant_id) REFERENCES nfvo_tenants (uuid);"
+    echo "      rename back 'datacenter_tenants' table to 'vim_tenants'"
+    echo "RENAME TABLE datacenter_tenants TO vim_tenants;"
+    for table in tenants_datacenters instance_scenarios instance_vnfs instance_nets
+    do
+        sql "ALTER TABLE ${table} DROP FOREIGN KEY FK_${table}_datacenter_tenants;"
+        NULL="NOT NULL"
+        [[ $table == instance_vnfs ]] && NULL="NULL DEFAULT NULL"
+        sql "ALTER TABLE ${table} ALTER datacenter_tenant_id DROP DEFAULT;"
+        sql "ALTER TABLE ${table} CHANGE COLUMN datacenter_tenant_id vim_tenant_id VARCHAR(36) $NULL AFTER datacenter_id, ADD CONSTRAINT FK_${table}_vim_tenants FOREIGN KEY (vim_tenant_id) REFERENCES vim_tenants (uuid); "
+    done    
+    sql "DELETE FROM schema_version WHERE version_int='10';"
+}
+
+function upgrade_to_11(){
+    # echo "    upgrade database from version 0.10 to version 0.11"
+    echo "      remove unique name at 'scenarios', 'instance_scenarios'"
+    sql "ALTER TABLE scenarios DROP INDEX name;"
+    sql "ALTER TABLE instance_scenarios DROP INDEX name;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (11, '0.11', '0.4.43', 'remove unique name at scenarios,instance_scenarios', '2016-07-18');"
+}
+function downgrade_from_11(){
+    # echo "    downgrade database from version 0.11 to version 0.10"
+    echo "      add unique name at 'scenarios', 'instance_scenarios'"
+    sql "ALTER TABLE scenarios ADD UNIQUE INDEX name (name);"
+    sql "ALTER TABLE instance_scenarios ADD UNIQUE INDEX name (name);"
+    sql "DELETE FROM schema_version WHERE version_int='11';"
+}
+
+function upgrade_to_12(){
+    # echo "    upgrade database from version 0.11 to version 0.12"
+    echo "      create ip_profiles table, with foreign keys to all nets tables, and add ip_address column to 'interfaces' and 'sce_interfaces'"
+    sql "CREATE TABLE IF NOT EXISTS ip_profiles (
+       id INT(11) NOT NULL AUTO_INCREMENT,
+       net_id VARCHAR(36) NULL DEFAULT NULL,
+       sce_net_id VARCHAR(36) NULL DEFAULT NULL,
+       instance_net_id VARCHAR(36) NULL DEFAULT NULL,
+       ip_version ENUM('IPv4','IPv6') NOT NULL DEFAULT 'IPv4',
+       subnet_address VARCHAR(64) NULL DEFAULT NULL,
+       gateway_address VARCHAR(64) NULL DEFAULT NULL,
+       dns_address VARCHAR(64) NULL DEFAULT NULL,
+       dhcp_enabled ENUM('true','false') NOT NULL DEFAULT 'true',
+       dhcp_start_address VARCHAR(64) NULL DEFAULT NULL,
+       dhcp_count INT(11) NULL DEFAULT NULL,
+       PRIMARY KEY (id),
+       CONSTRAINT FK_ipprofiles_nets FOREIGN KEY (net_id) REFERENCES nets (uuid) ON DELETE CASCADE,
+       CONSTRAINT FK_ipprofiles_scenets FOREIGN KEY (sce_net_id) REFERENCES sce_nets (uuid) ON DELETE CASCADE,
+       CONSTRAINT FK_ipprofiles_instancenets FOREIGN KEY (instance_net_id) REFERENCES instance_nets (uuid) ON DELETE CASCADE  )
+        COMMENT='Table containing the IP parameters of a network, either a net, a sce_net or and instance_net.'
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    sql "ALTER TABLE interfaces ADD COLUMN ip_address VARCHAR(64) NULL DEFAULT NULL AFTER mac;"
+    sql "ALTER TABLE sce_interfaces ADD COLUMN ip_address VARCHAR(64) NULL DEFAULT NULL AFTER interface_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (12, '0.12', '0.4.46', 'create ip_profiles table, with foreign keys to all nets tables, and add ip_address column to interfaces and sce_interfaces', '2016-08-29');"
+}
+function downgrade_from_12(){
+    # echo "    downgrade database from version 0.12 to version 0.11"
+    echo "      delete ip_profiles table, and remove ip_address column in 'interfaces' and 'sce_interfaces'"
+    sql "DROP TABLE IF EXISTS ip_profiles;"
+    sql "ALTER TABLE interfaces DROP COLUMN ip_address;"
+    sql "ALTER TABLE sce_interfaces DROP COLUMN ip_address;"
+    sql "DELETE FROM schema_version WHERE version_int='12';"
+}
+
+function upgrade_to_13(){
+    # echo "    upgrade database from version 0.12 to version 0.13"
+    echo "      add cloud_config at 'scenarios', 'instance_scenarios'"
+    sql "ALTER TABLE scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER descriptor;"
+    sql "ALTER TABLE instance_scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER modified_at;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (13, '0.13', '0.4.47', 'insert cloud-config at scenarios,instance_scenarios', '2016-08-30');"
+}
+function downgrade_from_13(){
+    # echo "    downgrade database from version 0.13 to version 0.12"
+    echo "      remove cloud_config at 'scenarios', 'instance_scenarios'"
+    sql "ALTER TABLE scenarios DROP COLUMN cloud_config;"
+    sql "ALTER TABLE instance_scenarios DROP COLUMN cloud_config;"
+    sql "DELETE FROM schema_version WHERE version_int='13';"
+}
+
+function upgrade_to_14(){
+    # echo "    upgrade database from version 0.13 to version 0.14"
+    echo "      remove unique index vim_net_id, instance_scenario_id at table 'instance_nets'"
+    sql "ALTER TABLE instance_nets DROP INDEX vim_net_id_instance_scenario_id;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN external created ENUM('true','false') NOT NULL DEFAULT 'false' COMMENT 'Created or already exists at VIM' AFTER multipoint;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (14, '0.14', '0.4.57', 'remove unique index vim_net_id, instance_scenario_id', '2016-09-26');"
+}
+function downgrade_from_14(){
+    # echo "    downgrade database from version 0.14 to version 0.13"
+    echo "      remove cloud_config at 'scenarios', 'instance_scenarios'"
+    sql "ALTER TABLE instance_nets ADD UNIQUE INDEX vim_net_id_instance_scenario_id (vim_net_id, instance_scenario_id);"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN created external ENUM('true','false') NOT NULL DEFAULT 'false' COMMENT 'If external, means that it already exists at VIM' AFTER multipoint;"
+    sql "DELETE FROM schema_version WHERE version_int='14';"
+}
+
+function upgrade_to_15(){
+    # echo "    upgrade database from version 0.14 to version 0.15"
+    echo "      add columns 'universal_name' and 'checksum' at table 'images', add unique index universal_name_checksum, and change location to allow NULL; change column 'image_path' in table 'vms' to allow NULL"
+    sql "ALTER TABLE images ADD COLUMN checksum VARCHAR(32) NULL DEFAULT NULL AFTER name;"
+    sql "ALTER TABLE images ALTER location DROP DEFAULT;"
+    sql "ALTER TABLE images ADD COLUMN universal_name VARCHAR(255) NULL AFTER name, CHANGE COLUMN location location VARCHAR(200) NULL AFTER checksum, ADD UNIQUE INDEX universal_name_checksum (universal_name, checksum);"
+    sql "ALTER TABLE vms ALTER image_path DROP DEFAULT;"
+    sql "ALTER TABLE vms CHANGE COLUMN image_path image_path VARCHAR(100) NULL COMMENT 'Path where the image of the VM is located' AFTER image_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (15, '0.15', '0.4.59', 'add columns universal_name and checksum at table images, add unique index universal_name_checksum, and change location to allow NULL; change column image_path in table vms to allow NULL', '2016-09-27');"
+}
+function downgrade_from_15(){
+    # echo "    downgrade database from version 0.15 to version 0.14"
+    echo "      remove columns 'universal_name' and 'checksum' from table 'images', remove index universal_name_checksum, change location NOT NULL; change column 'image_path' in table 'vms' to NOT NULL"
+    sql "ALTER TABLE images DROP INDEX universal_name_checksum;"
+    sql "ALTER TABLE images ALTER location DROP DEFAULT;"
+    sql "ALTER TABLE images CHANGE COLUMN location location VARCHAR(200) NOT NULL AFTER checksum;"
+    sql "ALTER TABLE images DROP COLUMN universal_name;"
+    sql "ALTER TABLE images DROP COLUMN checksum;"
+    sql "ALTER TABLE vms ALTER image_path DROP DEFAULT;"
+    sql "ALTER TABLE vms CHANGE COLUMN image_path image_path VARCHAR(100) NOT NULL COMMENT 'Path where the image of the VM is located' AFTER image_id;"
+    sql "DELETE FROM schema_version WHERE version_int='15';"
+}
+
+function upgrade_to_16(){
+    # echo "    upgrade database from version 0.15 to version 0.16"
+    echo "      add column 'config' at table 'datacenter_tenants', enlarge 'vim_tenant_name/id'"
+    sql "ALTER TABLE datacenter_tenants ADD COLUMN config VARCHAR(4000) NULL DEFAULT NULL AFTER passwd;"
+    sql "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(256) NULL DEFAULT NULL AFTER datacenter_id;"
+    sql "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_id vim_tenant_id VARCHAR(256) NULL DEFAULT NULL COMMENT 'Tenant ID at VIM' AFTER vim_tenant_name;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (16, '0.16', '0.5.2', 'enlarge vim_tenant_name and id. New config at datacenter_tenants', '2016-10-11');"
+}
+function downgrade_from_16(){
+    # echo "    downgrade database from version 0.16 to version 0.15"
+    echo "      remove column 'config' at table 'datacenter_tenants', restoring lenght 'vim_tenant_name/id'"
+    sql "ALTER TABLE datacenter_tenants DROP COLUMN config;"
+    sql "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(64) NULL DEFAULT NULL AFTER datacenter_id;"
+    sql "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_id vim_tenant_id VARCHAR(36) NULL DEFAULT NULL COMMENT 'Tenant ID at VIM' AFTER vim_tenant_name;"
+    sql "DELETE FROM schema_version WHERE version_int='16';"
+}
+
+function upgrade_to_17(){
+    # echo "    upgrade database from version 0.16 to version 0.17"
+    echo "      add column 'extended' at table 'datacenter_flavors'"
+    sql "ALTER TABLE datacenters_flavors ADD extended varchar(2000) NULL COMMENT 'Extra description json format of additional devices';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (17, '0.17', '0.5.3', 'Extra description json format of additional devices in datacenter_flavors', '2016-12-20');"
+}
+function downgrade_from_17(){
+    # echo "    downgrade database from version 0.17 to version 0.16"
+    echo "      remove column 'extended' from table 'datacenter_flavors'"
+    sql "ALTER TABLE datacenters_flavors DROP COLUMN extended;"
+    sql "DELETE FROM schema_version WHERE version_int='17';"
+}
+
+function upgrade_to_18(){
+    # echo "    upgrade database from version 0.17 to version 0.18"
+    echo "      add columns 'floating_ip' and 'port_security' at tables 'interfaces' and 'instance_interfaces'"
+    sql "ALTER TABLE interfaces ADD floating_ip BOOL DEFAULT 0 NOT NULL COMMENT 'Indicates if a floating_ip must be associated to this interface';"
+    sql "ALTER TABLE interfaces ADD port_security BOOL DEFAULT 1 NOT NULL COMMENT 'Indicates if port security must be enabled or disabled. By default it is enabled';"
+    sql "ALTER TABLE instance_interfaces ADD floating_ip BOOL DEFAULT 0 NOT NULL COMMENT 'Indicates if a floating_ip must be associated to this interface';"
+    sql "ALTER TABLE instance_interfaces ADD port_security BOOL DEFAULT 1 NOT NULL COMMENT 'Indicates if port security must be enabled or disabled. By default it is enabled';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (18, '0.18', '0.5.4', 'Add columns \'floating_ip\' and \'port_security\' at tables \'interfaces\' and \'instance_interfaces\'', '2017-01-09');"
+}
+function downgrade_from_18(){
+    # echo "    downgrade database from version 0.18 to version 0.17"
+    echo "      remove columns 'floating_ip' and 'port_security' from tables 'interfaces' and 'instance_interfaces'"
+    sql "ALTER TABLE interfaces DROP COLUMN floating_ip;"
+    sql "ALTER TABLE interfaces DROP COLUMN port_security;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN floating_ip;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN port_security;"
+    sql "DELETE FROM schema_version WHERE version_int='18';"
+}
+
+function upgrade_to_19(){
+    # echo "    upgrade database from version 0.18 to version 0.19"
+    echo "      add column 'boot_data' at table 'vms'"
+    sql "ALTER TABLE vms ADD COLUMN boot_data TEXT NULL DEFAULT NULL AFTER image_path;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (19, '0.19', '0.5.5', 'Extra Boot-data content at VNFC (vms)', '2017-01-11');"
+}
+function downgrade_from_19(){
+    # echo "    downgrade database from version 0.19 to version 0.18"
+    echo "      remove column 'boot_data' from table 'vms'"
+    sql "ALTER TABLE vms DROP COLUMN boot_data;"
+    sql "DELETE FROM schema_version WHERE version_int='19';"
+}
+
+function upgrade_to_20(){
+    # echo "    upgrade database from version 0.19 to version 0.20"
+    echo "      add column 'sdn_net_id' at table 'instance_nets' and columns 'sdn_port_id', 'compute_node', 'pci' and 'vlan' to table 'instance_interfaces'"
+    sql "ALTER TABLE instance_nets ADD sdn_net_id varchar(36) DEFAULT NULL NULL COMMENT 'Network id in ovim';"
+    sql "ALTER TABLE instance_interfaces ADD sdn_port_id varchar(36) DEFAULT NULL NULL COMMENT 'Port id in ovim';"
+    sql "ALTER TABLE instance_interfaces ADD compute_node varchar(100) DEFAULT NULL NULL COMMENT 'Compute node id used to specify the SDN port mapping';"
+    sql "ALTER TABLE instance_interfaces ADD pci varchar(12) DEFAULT NULL NULL COMMENT 'PCI of the physical port in the host';"
+    sql "ALTER TABLE instance_interfaces ADD vlan SMALLINT UNSIGNED DEFAULT NULL NULL COMMENT 'VLAN tag used by the port';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (20, '0.20', '0.5.9', 'Added columns to store dataplane connectivity info', '2017-03-13');"
+}
+function downgrade_from_20(){
+    # echo "    downgrade database from version 0.20 to version 0.19"
+    echo "      remove column 'sdn_net_id' at table 'instance_nets' and columns 'sdn_port_id', 'compute_node', 'pci' and 'vlan' to table 'instance_interfaces'"
+    sql "ALTER TABLE instance_nets DROP COLUMN sdn_net_id;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN vlan;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN pci;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN compute_node;"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN sdn_port_id;"
+    sql "DELETE FROM schema_version WHERE version_int='20';"
+}
+
+function upgrade_to_21(){
+    # echo "    upgrade database from version 0.20 to version 0.21"
+    echo "      edit 'instance_nets' to allow instance_scenario_id=None"
+    sql "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NULL;"
+    echo "      enlarge column 'dns_address' at table 'ip_profiles'"
+    sql "ALTER TABLE ip_profiles MODIFY dns_address varchar(255) DEFAULT NULL NULL "\
+         "comment 'dns ip list separated by semicolon';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (21, '0.21', '0.5.15', 'Edit instance_nets to allow instance_scenario_id=None and enlarge column dns_address at table ip_profiles', '2017-06-02');"
+}
+function downgrade_from_21(){
+    # echo "    downgrade database from version 0.21 to version 0.20"
+    echo "      edit 'instance_nets' to disallow instance_scenario_id=None"
+    #Delete all lines with a instance_scenario_id=NULL in order to disable this option
+    sql "DELETE FROM instance_nets WHERE instance_scenario_id IS NULL;"
+    sql "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NOT NULL;"
+    echo "      shorten column 'dns_address' at table 'ip_profiles'"
+    sql "ALTER TABLE ip_profiles MODIFY dns_address varchar(64) DEFAULT NULL NULL;"
+    sql "DELETE FROM schema_version WHERE version_int='21';"
+}
+
+function upgrade_to_22(){
+    # echo "    upgrade database from version 0.21 to version 0.22"
+    echo "      Changed type of ram in 'flavors' from SMALLINT to MEDIUMINT"
+    sql "ALTER TABLE flavors CHANGE COLUMN ram ram MEDIUMINT(7) UNSIGNED NULL DEFAULT NULL AFTER disk;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (22, '0.22', '0.5.16', 'Changed type of ram in flavors from SMALLINT to MEDIUMINT', '2017-06-02');"
+}
+function downgrade_from_22(){
+    # echo "    downgrade database from version 0.22 to version 0.21"
+    echo "      Changed type of ram in 'flavors' from MEDIUMINT to SMALLINT"
+    sql "ALTER TABLE flavors CHANGE COLUMN ram ram SMALLINT(5) UNSIGNED NULL DEFAULT NULL AFTER disk;"
+    sql "DELETE FROM schema_version WHERE version_int='22';"
+}
+
+function upgrade_to_23(){
+    # echo "    upgrade database from version 0.22 to version 0.23"
+    echo "      add column 'availability_zone' at table 'vms'"
+    sql "ALTER TABLE vms ADD COLUMN availability_zone VARCHAR(255) NULL AFTER modified_at;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (23, '0.23', '0.5.20',"\
+        "'Changed type of ram in flavors from SMALLINT to MEDIUMINT', '2017-08-29');"
+}
+function downgrade_from_23(){
+    # echo "    downgrade database from version 0.23 to version 0.22"
+    echo "      remove column 'availability_zone' from table 'vms'"
+    sql "ALTER TABLE vms DROP COLUMN availability_zone;"
+    sql "DELETE FROM schema_version WHERE version_int='23';"
+}
+
+function upgrade_to_24(){
+    # echo "    upgrade database from version 0.23 to version 0.24"
+    echo "      Add 'count' to table 'vms'"
+
+    sql "ALTER TABLE vms ADD COLUMN count SMALLINT NOT NULL DEFAULT '1' AFTER vnf_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (24, '0.24', '0.5.21', 'Added vnfd fields', '2017-08-29');"
+}
+function downgrade_from_24(){
+    # echo "    downgrade database from version 0.24 to version 0.23"
+    echo "      Remove 'count' from table 'vms'"
+    sql "ALTER TABLE vms DROP COLUMN count;"
+    sql "DELETE FROM schema_version WHERE version_int='24';"
+}
+function upgrade_to_25(){
+    # echo "    upgrade database from version 0.24 to version 0.25"
+    echo "      Add 'osm_id','short_name','vendor' to tables 'vnfs', 'scenarios'"
+    for table in vnfs scenarios; do
+        sql "ALTER TABLE $table ADD COLUMN osm_id VARCHAR(255) NULL AFTER uuid, "\
+             "ADD UNIQUE INDEX osm_id_tenant_id (osm_id, tenant_id), "\
+             "ADD COLUMN short_name VARCHAR(255) NULL AFTER name, "\
+             "ADD COLUMN vendor VARCHAR(255) NULL AFTER description;"
+    done
+    sql "ALTER TABLE vnfs ADD COLUMN mgmt_access VARCHAR(2000) NULL AFTER vendor;"
+    sql "ALTER TABLE vms ADD COLUMN osm_id VARCHAR(255) NULL AFTER uuid;"
+    sql "ALTER TABLE sce_vnfs ADD COLUMN member_vnf_index SMALLINT(6) NULL DEFAULT NULL AFTER uuid;"
+    echo "      Add 'security_group' to table 'ip_profiles'"
+    sql "ALTER TABLE ip_profiles ADD COLUMN security_group VARCHAR(255) NULL DEFAULT NULL AFTER dhcp_count;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (25, '0.25', '0.5.22', 'Added osm_id to vnfs,scenarios', '2017-09-01');"
+}
+function downgrade_from_25(){
+    # echo "    downgrade database from version 0.25 to version 0.24"
+    echo "      Remove 'osm_id','short_name','vendor' from tables 'vnfs', 'scenarios'"
+    for table in vnfs scenarios; do
+        sql "ALTER TABLE $table DROP INDEX  osm_id_tenant_id, DROP COLUMN osm_id, "\
+             "DROP COLUMN short_name, DROP COLUMN vendor;"
+    done
+    sql "ALTER TABLE vnfs DROP COLUMN mgmt_access;"
+    sql "ALTER TABLE vms DROP COLUMN osm_id;"
+    sql "ALTER TABLE sce_vnfs DROP COLUMN member_vnf_index;"
+    echo "      Remove 'security_group' from table 'ip_profiles'"
+    sql "ALTER TABLE ip_profiles DROP COLUMN security_group;"
+
+    sql "DELETE FROM schema_version WHERE version_int='25';"
+}
+
+function upgrade_to_26(){
+    echo "      Add name to table datacenter_tenants"
+    sql "ALTER TABLE datacenter_tenants ADD COLUMN name VARCHAR(255) NULL AFTER uuid;"
+    sql "UPDATE datacenter_tenants as dt join datacenters as d on dt.datacenter_id = d.uuid set dt.name=d.name;"
+    echo "      Add 'SCHEDULED' to 'status' at tables 'instance_nets', 'instance_vms'"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE:NoMgmtIP','ACTIVE','INACTIVE','BUILD',"\
+         "'ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') "\
+         "NOT NULL DEFAULT 'BUILD';"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN status status ENUM('ACTIVE','INACTIVE','DOWN','BUILD','ERROR',"\
+         "'VIM_ERROR','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD';"
+    echo "      Enlarge pci at instance_interfaces to allow extended pci for SDN por mapping"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN pci pci VARCHAR(50) NULL DEFAULT NULL COMMENT 'PCI of the "\
+        "physical port in the host' AFTER compute_node;"
+
+    for t in flavor image; do
+        echo "      Change 'datacenters_${t}s' to point to datacenter_tenant, add status, vim_info"
+        sql "ALTER TABLE datacenters_${t}s ADD COLUMN datacenter_vim_id VARCHAR(36) NULL DEFAULT NULL AFTER "\
+            "datacenter_id, ADD COLUMN status ENUM('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','DELETED',"\
+            "'SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD' AFTER vim_id, ADD COLUMN vim_info "\
+            "TEXT NULL AFTER status;"
+        sql "UPDATE datacenters_${t}s as df left join datacenter_tenants as dt on dt.datacenter_id=df.datacenter_id "\
+            "set df.datacenter_vim_id=dt.uuid;"
+        sql "DELETE FROM datacenters_${t}s WHERE datacenter_vim_id is NULL;"
+        sql "ALTER TABLE datacenters_${t}s CHANGE COLUMN datacenter_vim_id datacenter_vim_id VARCHAR(36) NOT NULL;"
+        sql "ALTER TABLE datacenters_${t}s ADD CONSTRAINT FK_datacenters_${t}s_datacenter_tenants FOREIGN KEY "\
+            "(datacenter_vim_id) REFERENCES datacenter_tenants (uuid) ON UPDATE CASCADE ON DELETE CASCADE;"
+        sql "ALTER TABLE datacenters_${t}s DROP FOREIGN KEY FK__datacenters_${t:0:1};"
+        sql "ALTER TABLE datacenters_${t}s DROP COLUMN datacenter_id;"
+       done
+
+    echo "      Decoupling 'instance_interfaces' from scenarios/vnfs to allow scale actions"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(128) NULL DEFAULT NULL;"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN interface_id interface_id VARCHAR(36) NULL DEFAULT NULL;"
+       sql "ALTER TABLE instance_interfaces DROP FOREIGN KEY FK_instance_ids"
+       sql "ALTER TABLE instance_interfaces ADD CONSTRAINT FK_instance_ids FOREIGN KEY (interface_id) "\
+           "REFERENCES interfaces (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+
+    echo "      Decoupling 'instance_vms' from scenarios/vnfs to allow scale actions"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vim_vm_id vim_vm_id VARCHAR(128) NULL DEFAULT NULL;"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vm_id vm_id VARCHAR(36) NULL DEFAULT NULL;"
+       sql "ALTER TABLE instance_vms DROP FOREIGN KEY FK_instance_vms_vms;"
+       sql "ALTER TABLE instance_vms ADD CONSTRAINT FK_instance_vms_vms FOREIGN KEY (vm_id) "\
+           "REFERENCES vms (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+
+    echo "      Decoupling 'instance_nets' from scenarios/vnfs to allow scale actions"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(128) NULL DEFAULT NULL;"
+
+    echo "      Decoupling 'instance_scenarios' from scenarios"
+    sql "ALTER TABLE instance_scenarios CHANGE COLUMN scenario_id scenario_id VARCHAR(36) NULL DEFAULT NULL;"
+       sql "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_scenarios;"
+       sql "ALTER TABLE instance_scenarios ADD CONSTRAINT FK_instance_scenarios_scenarios FOREIGN KEY (scenario_id) "\
+           "REFERENCES scenarios (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"
+
+    echo "      Create table instance_actions, vim_actions"
+    sql "CREATE TABLE IF NOT EXISTS instance_actions (
+           uuid VARCHAR(36) NOT NULL,
+           tenant_id VARCHAR(36) NULL DEFAULT NULL,
+           instance_id VARCHAR(36) NULL DEFAULT NULL,
+           description VARCHAR(64) NULL DEFAULT NULL COMMENT 'CREATE, DELETE, SCALE OUT/IN, ...',
+           number_tasks SMALLINT(6) NOT NULL DEFAULT '1',
+           number_done SMALLINT(6) NOT NULL DEFAULT '0',
+           number_failed SMALLINT(6) NOT NULL DEFAULT '0',
+           created_at DOUBLE NOT NULL,
+           modified_at DOUBLE NULL DEFAULT NULL,
+           PRIMARY KEY (uuid),
+        INDEX FK_actions_tenants (tenant_id),
+       CONSTRAINT FK_actions_tenant FOREIGN KEY (tenant_id) REFERENCES nfvo_tenants (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+               COMMENT='Contains client actions over instances'
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"  
+
+    sql "CREATE TABLE IF NOT EXISTS vim_actions (
+           instance_action_id VARCHAR(36) NOT NULL,
+           task_index INT(6) NOT NULL,
+           datacenter_vim_id VARCHAR(36) NOT NULL,
+           vim_id VARCHAR(64) NULL DEFAULT NULL,
+           action VARCHAR(36) NOT NULL COMMENT 'CREATE,DELETE,START,STOP...',
+           item ENUM('datacenters_flavors','datacenter_images','instance_nets','instance_vms','instance_interfaces') NOT NULL COMMENT 'table where the item is stored',
+           item_id VARCHAR(36) NULL DEFAULT NULL COMMENT 'uuid of the entry in the table',
+           status ENUM('SCHEDULED', 'BUILD', 'DONE', 'FAILED', 'SUPERSEDED') NOT NULL DEFAULT 'SCHEDULED',
+           extra TEXT NULL DEFAULT NULL COMMENT 'json with params:, depends_on: for the task',
+           error_msg VARCHAR(1024) NULL DEFAULT NULL,
+           created_at DOUBLE NOT NULL,
+           modified_at DOUBLE NULL DEFAULT NULL,
+           PRIMARY KEY (task_index, instance_action_id),
+        INDEX FK_actions_instance_actions (instance_action_id),
+       CONSTRAINT FK_actions_instance_actions FOREIGN KEY (instance_action_id) REFERENCES instance_actions (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        INDEX FK_actions_vims (datacenter_vim_id),
+       CONSTRAINT FK_actions_vims FOREIGN KEY (datacenter_vim_id) REFERENCES datacenter_tenants (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COMMENT='Table with the individual VIM actions.'
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"  
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (26, '0.26', '0.5.23', 'Several changes', '2017-09-09');"
+}
+function downgrade_from_26(){
+    echo "      Remove name from table datacenter_tenants"
+    sql "ALTER TABLE datacenter_tenants DROP COLUMN name;"
+    echo "      Remove 'SCHEDULED' from the 'status' at tables 'instance_nets', 'instance_vms'"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE:NoMgmtIP','ACTIVE','INACTIVE','BUILD',"\
+         "'ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD';"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN status status ENUM('ACTIVE','DOWN','BUILD','ERROR','VIM_ERROR',"\
+         "'INACTIVE','DELETED') NOT NULL DEFAULT 'BUILD';"
+    echo "      Shorten back pci at instance_interfaces to allow extended pci for SDN por mapping"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN pci pci VARCHAR(12) NULL DEFAULT NULL COMMENT 'PCI of the "\
+        "physical port in the host' AFTER compute_node;"
+
+    for t in flavor image; do
+        echo "      Restore back 'datacenters_${t}s'"
+        sql "ALTER TABLE datacenters_${t}s ADD COLUMN datacenter_id VARCHAR(36) NULL DEFAULT NULL AFTER "\
+            "${t}_id, DROP COLUMN status, DROP COLUMN vim_info ;"
+        sql "UPDATE datacenters_${t}s as df left join datacenter_tenants as dt on dt.uuid=df.datacenter_vim_id set "\
+            "df.datacenter_id=dt.datacenter_id;"
+        sql "ALTER TABLE datacenters_${t}s CHANGE COLUMN datacenter_id datacenter_id VARCHAR(36) NOT NULL;"
+        sql "ALTER TABLE datacenters_${t}s ADD CONSTRAINT FK__datacenters_${t:0:1} FOREIGN KEY "\
+            "(datacenter_id) REFERENCES datacenters (uuid), DROP FOREIGN KEY FK_datacenters_${t}s_datacenter_tenants, "\
+            "DROP COLUMN datacenter_vim_id;"
+    done
+
+    echo "      Restore back 'instance_interfaces' coupling to scenarios/vnfs"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(36) NULL DEFAULT NULL;"
+       sql "ALTER TABLE instance_interfaces DROP FOREIGN KEY FK_instance_ids"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN interface_id interface_id VARCHAR(36) NOT NULL;"
+       sql "ALTER TABLE instance_interfaces ADD CONSTRAINT FK_instance_ids FOREIGN KEY (interface_id) "\
+           "REFERENCES interfaces (uuid);"
+
+    echo "      Restore back 'instance_vms' coupling to scenarios/vnfs"
+    echo "      Decoupling 'instance vms' from scenarios/vnfs to allow scale actions"
+    sql "UPDATE instance_vms SET vim_vm_id='' WHERE vim_vm_id is NULL;"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vim_vm_id vim_vm_id VARCHAR(36) NOT NULL;"
+       sql "ALTER TABLE instance_vms DROP FOREIGN KEY FK_instance_vms_vms;"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vm_id vm_id VARCHAR(36) NOT NULL;"
+       sql "ALTER TABLE instance_vms ADD CONSTRAINT FK_instance_vms_vms FOREIGN KEY (vm_id) "\
+           "REFERENCES vms (uuid);"
+
+    echo "      Restore back 'instance_nets' coupling to scenarios/vnfs"
+    sql "UPDATE instance_nets SET vim_net_id='' WHERE vim_net_id is NULL;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(36) NOT NULL;"
+
+    echo "      Restore back  'instance_scenarios' coupling to scenarios"
+       sql "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_scenarios;"
+    sql "ALTER TABLE instance_scenarios CHANGE COLUMN scenario_id scenario_id VARCHAR(36) NOT NULL;"
+       sql "ALTER TABLE instance_scenarios ADD CONSTRAINT FK_instance_scenarios_scenarios FOREIGN KEY (scenario_id) "\
+           "REFERENCES scenarios (uuid);"
+
+    echo "      Delete table instance_actions"
+    sql "DROP TABLE IF EXISTS vim_actions"
+    sql "DROP TABLE IF EXISTS instance_actions"
+    sql "DELETE FROM schema_version WHERE version_int='26';"
+}
+
+function upgrade_to_27(){
+    echo "      Added 'encrypted_RO_priv_key','RO_pub_key' to table 'nfvo_tenants'"
+    sql "ALTER TABLE nfvo_tenants ADD COLUMN encrypted_RO_priv_key VARCHAR(2000) NULL AFTER description;"
+    sql "ALTER TABLE nfvo_tenants ADD COLUMN RO_pub_key VARCHAR(510) NULL AFTER encrypted_RO_priv_key;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (27, '0.27', '0.5.25', 'Added encrypted_RO_priv_key,RO_pub_key to table nfvo_tenants', '2017-09-29');"
+}
+function downgrade_from_27(){
+    echo "      Remove 'encrypted_RO_priv_key','RO_pub_key' from table 'nfvo_tenants'"
+    sql "ALTER TABLE nfvo_tenants DROP COLUMN encrypted_RO_priv_key;"
+    sql "ALTER TABLE nfvo_tenants DROP COLUMN RO_pub_key;"
+    sql "DELETE FROM schema_version WHERE version_int='27';"
+}
+function upgrade_to_28(){
+    echo "      [Adding necessary tables for VNFFG]"
+    echo "      Adding sce_vnffgs"
+    sql "CREATE TABLE IF NOT EXISTS sce_vnffgs (
+            uuid VARCHAR(36) NOT NULL,
+            tenant_id VARCHAR(36) NULL DEFAULT NULL,
+            name VARCHAR(255) NOT NULL,
+            description VARCHAR(255) NULL DEFAULT NULL,
+            vendor VARCHAR(255) NULL DEFAULT NULL,
+            scenario_id VARCHAR(36) NOT NULL,
+            created_at DOUBLE NOT NULL,
+            modified_at DOUBLE NULL DEFAULT NULL,
+        PRIMARY KEY (uuid),
+        INDEX FK_scenarios_sce_vnffg (scenario_id),
+        CONSTRAINT FK_scenarios_vnffg FOREIGN KEY (tenant_id) REFERENCES scenarios (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      Adding sce_rsps"
+    sql "CREATE TABLE IF NOT EXISTS sce_rsps (
+            uuid VARCHAR(36) NOT NULL,
+            tenant_id VARCHAR(36) NULL DEFAULT NULL,
+            name VARCHAR(255) NOT NULL,
+            sce_vnffg_id VARCHAR(36) NOT NULL,
+            created_at DOUBLE NOT NULL,
+            modified_at DOUBLE NULL DEFAULT NULL,
+        PRIMARY KEY (uuid),
+        INDEX FK_sce_vnffgs_rsp (sce_vnffg_id),
+        CONSTRAINT FK_sce_vnffgs_rsp FOREIGN KEY (sce_vnffg_id) REFERENCES sce_vnffgs (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      Adding sce_rsp_hops"
+    sql "CREATE TABLE IF NOT EXISTS sce_rsp_hops (
+            uuid VARCHAR(36) NOT NULL,
+            if_order INT DEFAULT 0 NOT NULL,
+            interface_id VARCHAR(36) NOT NULL,
+            sce_vnf_id VARCHAR(36) NOT NULL,
+            sce_rsp_id VARCHAR(36) NOT NULL,
+            created_at DOUBLE NOT NULL,
+            modified_at DOUBLE NULL DEFAULT NULL,
+        PRIMARY KEY (uuid),
+        INDEX FK_interfaces_rsp_hop (interface_id),
+        INDEX FK_sce_vnfs_rsp_hop (sce_vnf_id),
+        INDEX FK_sce_rsps_rsp_hop (sce_rsp_id),
+        CONSTRAINT FK_interfaces_rsp_hop FOREIGN KEY (interface_id) REFERENCES interfaces (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        CONSTRAINT FK_sce_vnfs_rsp_hop FOREIGN KEY (sce_vnf_id) REFERENCES sce_vnfs (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        CONSTRAINT FK_sce_rsps_rsp_hop FOREIGN KEY (sce_rsp_id) REFERENCES sce_rsps (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      Adding sce_classifiers"
+    sql "CREATE TABLE IF NOT EXISTS sce_classifiers (
+            uuid VARCHAR(36) NOT NULL,
+            tenant_id VARCHAR(36) NULL DEFAULT NULL,
+            name VARCHAR(255) NOT NULL,
+            sce_vnffg_id VARCHAR(36) NOT NULL,
+            sce_rsp_id VARCHAR(36) NOT NULL,
+            sce_vnf_id VARCHAR(36) NOT NULL,
+            interface_id VARCHAR(36) NOT NULL,
+            created_at DOUBLE NOT NULL,
+            modified_at DOUBLE NULL DEFAULT NULL,
+        PRIMARY KEY (uuid),
+        INDEX FK_sce_vnffgs_classifier (sce_vnffg_id),
+        INDEX FK_sce_rsps_classifier (sce_rsp_id),
+        INDEX FK_sce_vnfs_classifier (sce_vnf_id),
+        INDEX FK_interfaces_classifier (interface_id),
+        CONSTRAINT FK_sce_vnffgs_classifier FOREIGN KEY (sce_vnffg_id) REFERENCES sce_vnffgs (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        CONSTRAINT FK_sce_rsps_classifier FOREIGN KEY (sce_rsp_id) REFERENCES sce_rsps (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        CONSTRAINT FK_sce_vnfs_classifier FOREIGN KEY (sce_vnf_id) REFERENCES sce_vnfs (uuid) ON UPDATE CASCADE ON DELETE CASCADE,
+        CONSTRAINT FK_interfaces_classifier FOREIGN KEY (interface_id) REFERENCES interfaces (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+    echo "      Adding sce_classifier_matches"
+    sql "CREATE TABLE IF NOT EXISTS sce_classifier_matches (
+            uuid VARCHAR(36) NOT NULL,
+            ip_proto VARCHAR(2) NOT NULL,
+            source_ip VARCHAR(16) NOT NULL,
+            destination_ip VARCHAR(16) NOT NULL,
+            source_port VARCHAR(5) NOT NULL,
+            destination_port VARCHAR(5) NOT NULL,
+            sce_classifier_id VARCHAR(36) NOT NULL,
+            created_at DOUBLE NOT NULL,
+            modified_at DOUBLE NULL DEFAULT NULL,
+        PRIMARY KEY (uuid),
+        INDEX FK_classifiers_classifier_match (sce_classifier_id),
+        CONSTRAINT FK_sce_classifiers_classifier_match FOREIGN KEY (sce_classifier_id) REFERENCES sce_classifiers (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+        COLLATE='utf8_general_ci'
+        ENGINE=InnoDB;"
+
+    echo "      [Adding necessary tables for VNFFG-SFC instance mapping]"
+    echo "      Adding instance_sfis"
+    sql "CREATE TABLE IF NOT EXISTS instance_sfis (
+          uuid varchar(36) NOT NULL,
+          instance_scenario_id varchar(36) NOT NULL,
+          vim_sfi_id varchar(36) DEFAULT NULL,
+          sce_rsp_hop_id varchar(36) DEFAULT NULL,
+          datacenter_id varchar(36) DEFAULT NULL,
+          datacenter_tenant_id varchar(36) DEFAULT NULL,
+          status enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+          error_msg varchar(1024) DEFAULT NULL,
+          vim_info text,
+          created_at double NOT NULL,
+          modified_at double DEFAULT NULL,
+          PRIMARY KEY (uuid),
+      KEY FK_instance_sfis_instance_scenarios (instance_scenario_id),
+      KEY FK_instance_sfis_sce_rsp_hops (sce_rsp_hop_id),
+      KEY FK_instance_sfis_datacenters (datacenter_id),
+      KEY FK_instance_sfis_datacenter_tenants (datacenter_tenant_id),
+      CONSTRAINT FK_instance_sfis_datacenter_tenants FOREIGN KEY (datacenter_tenant_id) REFERENCES datacenter_tenants (uuid),
+      CONSTRAINT FK_instance_sfis_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid),
+      CONSTRAINT FK_instance_sfis_instance_scenarios FOREIGN KEY (instance_scenario_id) REFERENCES instance_scenarios (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
+      CONSTRAINT FK_instance_sfis_sce_rsp_hops FOREIGN KEY (sce_rsp_hop_id) REFERENCES sce_rsp_hops (uuid) ON DELETE SET NULL ON UPDATE CASCADE)
+      COLLATE='utf8_general_ci'
+      ENGINE=InnoDB;"
+    echo "      Adding instance_sfs"
+    sql "CREATE TABLE IF NOT EXISTS instance_sfs (
+          uuid varchar(36) NOT NULL,
+          instance_scenario_id varchar(36) NOT NULL,
+          vim_sf_id varchar(36) DEFAULT NULL,
+          sce_rsp_hop_id varchar(36) DEFAULT NULL,
+          datacenter_id varchar(36) DEFAULT NULL,
+          datacenter_tenant_id varchar(36) DEFAULT NULL,
+          status enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+          error_msg varchar(1024) DEFAULT NULL,
+          vim_info text,
+          created_at double NOT NULL,
+          modified_at double DEFAULT NULL,
+      PRIMARY KEY (uuid),
+      KEY FK_instance_sfs_instance_scenarios (instance_scenario_id),
+      KEY FK_instance_sfs_sce_rsp_hops (sce_rsp_hop_id),
+      KEY FK_instance_sfs_datacenters (datacenter_id),
+      KEY FK_instance_sfs_datacenter_tenants (datacenter_tenant_id),
+      CONSTRAINT FK_instance_sfs_datacenter_tenants FOREIGN KEY (datacenter_tenant_id) REFERENCES datacenter_tenants (uuid),
+      CONSTRAINT FK_instance_sfs_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid),
+      CONSTRAINT FK_instance_sfs_instance_scenarios FOREIGN KEY (instance_scenario_id) REFERENCES instance_scenarios (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
+      CONSTRAINT FK_instance_sfs_sce_rsp_hops FOREIGN KEY (sce_rsp_hop_id) REFERENCES sce_rsp_hops (uuid) ON DELETE SET NULL ON UPDATE CASCADE)
+      COLLATE='utf8_general_ci'
+      ENGINE=InnoDB;"
+    echo "      Adding instance_classifications"
+    sql "CREATE TABLE IF NOT EXISTS instance_classifications (
+          uuid varchar(36) NOT NULL,
+          instance_scenario_id varchar(36) NOT NULL,
+          vim_classification_id varchar(36) DEFAULT NULL,
+          sce_classifier_match_id varchar(36) DEFAULT NULL,
+          datacenter_id varchar(36) DEFAULT NULL,
+          datacenter_tenant_id varchar(36) DEFAULT NULL,
+          status enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+          error_msg varchar(1024) DEFAULT NULL,
+          vim_info text,
+          created_at double NOT NULL,
+          modified_at double DEFAULT NULL,
+      PRIMARY KEY (uuid),
+      KEY FK_instance_classifications_instance_scenarios (instance_scenario_id),
+      KEY FK_instance_classifications_sce_classifier_matches (sce_classifier_match_id),
+      KEY FK_instance_classifications_datacenters (datacenter_id),
+      KEY FK_instance_classifications_datacenter_tenants (datacenter_tenant_id),
+      CONSTRAINT FK_instance_classifications_datacenter_tenants FOREIGN KEY (datacenter_tenant_id) REFERENCES datacenter_tenants (uuid),
+      CONSTRAINT FK_instance_classifications_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid),
+      CONSTRAINT FK_instance_classifications_instance_scenarios FOREIGN KEY (instance_scenario_id) REFERENCES instance_scenarios (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
+      CONSTRAINT FK_instance_classifications_sce_classifier_matches FOREIGN KEY (sce_classifier_match_id) REFERENCES sce_classifier_matches (uuid) ON DELETE SET NULL ON UPDATE CASCADE)
+      COLLATE='utf8_general_ci'
+      ENGINE=InnoDB;"
+    echo "      Adding instance_sfps"
+    sql "CREATE TABLE IF NOT EXISTS instance_sfps (
+          uuid varchar(36) NOT NULL,
+          instance_scenario_id varchar(36) NOT NULL,
+          vim_sfp_id varchar(36) DEFAULT NULL,
+          sce_rsp_id varchar(36) DEFAULT NULL,
+          datacenter_id varchar(36) DEFAULT NULL,
+          datacenter_tenant_id varchar(36) DEFAULT NULL,
+          status enum('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED','SCHEDULED_CREATION','SCHEDULED_DELETION') NOT NULL DEFAULT 'BUILD',
+          error_msg varchar(1024) DEFAULT NULL,
+          vim_info text,
+          created_at double NOT NULL,
+          modified_at double DEFAULT NULL,
+      PRIMARY KEY (uuid),
+      KEY FK_instance_sfps_instance_scenarios (instance_scenario_id),
+      KEY FK_instance_sfps_sce_rsps (sce_rsp_id),
+      KEY FK_instance_sfps_datacenters (datacenter_id),
+      KEY FK_instance_sfps_datacenter_tenants (datacenter_tenant_id),
+      CONSTRAINT FK_instance_sfps_datacenter_tenants FOREIGN KEY (datacenter_tenant_id) REFERENCES datacenter_tenants (uuid),
+      CONSTRAINT FK_instance_sfps_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid),
+      CONSTRAINT FK_instance_sfps_instance_scenarios FOREIGN KEY (instance_scenario_id) REFERENCES instance_scenarios (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
+      CONSTRAINT FK_instance_sfps_sce_rsps FOREIGN KEY (sce_rsp_id) REFERENCES sce_rsps (uuid) ON DELETE SET NULL ON UPDATE CASCADE)
+      COLLATE='utf8_general_ci'
+      ENGINE=InnoDB;"
+
+
+    echo "      [Altering vim_actions table]"
+    sql "ALTER TABLE vim_actions MODIFY COLUMN item ENUM('datacenters_flavors','datacenter_images','instance_nets','instance_vms','instance_interfaces','instance_sfis','instance_sfs','instance_classifications','instance_sfps') NOT NULL COMMENT 'table where the item is stored'"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (28, '0.28', '0.5.28', 'Adding VNFFG-related tables', '2017-11-20');"
+}
+function downgrade_from_28(){
+    echo "      [Undo adding the VNFFG tables]"
+    echo "      Dropping instance_sfps"
+    sql "DROP TABLE IF EXISTS instance_sfps;"
+    echo "      Dropping sce_classifications"
+    sql "DROP TABLE IF EXISTS instance_classifications;"
+    echo "      Dropping instance_sfs"
+    sql "DROP TABLE IF EXISTS instance_sfs;"
+    echo "      Dropping instance_sfis"
+    sql "DROP TABLE IF EXISTS instance_sfis;"
+    echo "      Dropping sce_classifier_matches"
+    echo "      [Undo adding the VNFFG-SFC instance mapping tables]"
+    sql "DROP TABLE IF EXISTS sce_classifier_matches;"
+    echo "      Dropping sce_classifiers"
+    sql "DROP TABLE IF EXISTS sce_classifiers;"
+    echo "      Dropping sce_rsp_hops"
+    sql "DROP TABLE IF EXISTS sce_rsp_hops;"
+    echo "      Dropping sce_rsps"
+    sql "DROP TABLE IF EXISTS sce_rsps;"
+    echo "      Dropping sce_vnffgs"
+    sql "DROP TABLE IF EXISTS sce_vnffgs;"
+    echo "      [Altering vim_actions table]"
+    sql "ALTER TABLE vim_actions MODIFY COLUMN item ENUM('datacenters_flavors','datacenter_images','instance_nets','instance_vms','instance_interfaces') NOT NULL COMMENT 'table where the item is stored'"
+    sql "DELETE FROM schema_version WHERE version_int='28';"
+}
+function upgrade_to_29(){
+    echo "      Change 'member_vnf_index' from int to str at 'sce_vnfs'"
+    sql "ALTER TABLE sce_vnfs CHANGE COLUMN member_vnf_index member_vnf_index VARCHAR(255) NULL DEFAULT NULL AFTER uuid;"
+    echo "      Add osm_id to 'nets's and 'sce_nets'"
+    sql "ALTER TABLE nets ADD COLUMN osm_id VARCHAR(255) NULL AFTER uuid;"
+    sql "ALTER TABLE sce_nets ADD COLUMN osm_id VARCHAR(255) NULL AFTER uuid;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (29, '0.29', '0.5.59', 'Change member_vnf_index to str accordingly to the model', '2018-04-11');"
+}
+function downgrade_from_29(){
+    echo "      Change back 'member_vnf_index' from str to int at 'sce_vnfs'"
+    sql "ALTER TABLE sce_vnfs CHANGE COLUMN member_vnf_index member_vnf_index SMALLINT NULL DEFAULT NULL AFTER uuid;"
+    echo "      Remove osm_id from 'nets's and 'sce_nets'"
+    sql "ALTER TABLE nets DROP COLUMN osm_id;"
+    sql "ALTER TABLE sce_nets DROP COLUMN osm_id;"
+    sql "DELETE FROM schema_version WHERE version_int='29';"
+}
+function upgrade_to_30(){
+    echo "      Add 'image_list' at 'vms' to allocate alternative images"
+    sql "ALTER TABLE vms ADD COLUMN image_list TEXT NULL COMMENT 'Alternative images' AFTER image_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (30, '0.30', '0.5.60', 'Add image_list to vms', '2018-04-24');"
+}
+function downgrade_from_30(){
+    echo "      Remove back 'image_list' from 'vms' to allocate alternative images"
+    sql "ALTER TABLE vms DROP COLUMN image_list;"
+    sql "DELETE FROM schema_version WHERE version_int='30';"
+}
+function upgrade_to_31(){
+    echo "      Add 'vim_network_name' at 'sce_nets'"
+    sql "ALTER TABLE sce_nets ADD COLUMN vim_network_name VARCHAR(255) NULL DEFAULT NULL AFTER description;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (31, '0.31', '0.5.61', 'Add vim_network_name to sce_nets', '2018-05-03');"
+}
+function downgrade_from_31(){
+    echo "      Remove back 'vim_network_name' from 'sce_nets'"
+    sql "ALTER TABLE sce_nets DROP COLUMN vim_network_name;"
+    sql "DELETE FROM schema_version WHERE version_int='31';"
+}
+function upgrade_to_32(){
+    echo "      Add 'vim_name' to 'instance_vms'"
+    sql "ALTER TABLE instance_vms ADD COLUMN vim_name VARCHAR(255) NULL DEFAULT NULL AFTER vim_vm_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (32, '0.32', '0.5.70', 'Add vim_name to instance vms', '2018-06-28');"
+}
+function downgrade_from_32(){
+    echo "      Remove back 'vim_name' from 'instance_vms'"
+    sql "ALTER TABLE instance_vms DROP COLUMN vim_name;"
+    sql "DELETE FROM schema_version WHERE version_int='32';"
+}
+
+function upgrade_to_33(){
+    echo "      Add PDU information to 'vms'"
+    sql "ALTER TABLE vms ADD COLUMN pdu_type VARCHAR(255) NULL DEFAULT NULL AFTER osm_id;"
+    sql "ALTER TABLE instance_nets ADD COLUMN vim_name VARCHAR(255) NULL DEFAULT NULL AFTER vim_net_id;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (33, '0.33', '0.5.82', 'Add pdu information to vms', '2018-11-13');"
+}
+function downgrade_from_33(){
+    echo "      Remove back PDU information from 'vms'"
+    sql "ALTER TABLE vms DROP COLUMN pdu_type;"
+    sql "ALTER TABLE instance_nets DROP COLUMN vim_name;"
+    sql "DELETE FROM schema_version WHERE version_int='33';"
+}
+function upgrade_to_X(){
+    echo "      change 'datacenter_nets'"
+    sql "ALTER TABLE datacenter_nets ADD COLUMN vim_tenant_id VARCHAR(36) NOT NULL AFTER datacenter_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id, vim_tenant_id);"
+}
+function downgrade_from_X(){
+    echo "      Change back 'datacenter_nets'"
+    sql "ALTER TABLE datacenter_nets DROP COLUMN vim_tenant_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id);"
+}
+function upgrade_to_34() {
+    echo "      Create databases required for WIM features"
+    script="$(find "${DBUTILS}/migrations/up" -iname "34*.sql" | tail -1)"
+    sql "source ${script}"
+}
+function downgrade_from_34() {
+    echo "      Drop databases required for WIM features"
+    script="$(find "${DBUTILS}/migrations/down" -iname "34*.sql" | tail -1)"
+    sql "source ${script}"
+}
+function upgrade_to_35(){
+    echo "      Create databases required for WIM features"
+    script="$(find "${DBUTILS}/migrations/up" -iname "35*.sql" | tail -1)"
+    sql "source ${script}"
+}
+function downgrade_from_35(){
+    echo "      Drop databases required for WIM features"
+    script="$(find "${DBUTILS}/migrations/down" -iname "35*.sql" | tail -1)"
+    sql "source ${script}"
+}
+function upgrade_to_36(){
+    echo "      Allow null for image_id at 'vms'"
+    sql "ALTER TABLE vms ALTER image_id DROP DEFAULT;"
+    sql "ALTER TABLE vms CHANGE COLUMN image_id image_id VARCHAR(36) NULL COMMENT 'Link to image table' AFTER " \
+        "flavor_id;"
+    echo "      Enlarge config at 'wims' and 'wim_accounts'"
+    sql "ALTER TABLE wims CHANGE COLUMN config config TEXT NULL DEFAULT NULL AFTER wim_url;"
+    sql "ALTER TABLE wim_accounts CHANGE COLUMN config config TEXT NULL DEFAULT NULL AFTER password;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) "\
+         "VALUES (36, '0.36', '0.6.03', 'Allow vm without image_id for PDUs', '2018-12-19');"
+}
+function downgrade_from_36(){
+    echo "      Force back not null for image_id at 'vms'"
+    sql "ALTER TABLE vms ALTER image_id DROP DEFAULT;"
+    sql "ALTER TABLE vms CHANGE COLUMN image_id image_id VARCHAR(36) NOT NULL COMMENT 'Link to image table' AFTER " \
+        "flavor_id;"
+    # For downgrade do not restore wims/wim_accounts config to varchar 4000
+    sql "DELETE FROM schema_version WHERE version_int='36';"
+}
+function upgrade_to_37(){
+    echo "      Adding the enum tags for SFC"
+    sql "ALTER TABLE vim_wim_actions " \
+        "MODIFY COLUMN item " \
+        "ENUM('datacenters_flavors','datacenter_images','instance_nets','instance_vms','instance_interfaces'," \
+            "'instance_sfis','instance_sfs','instance_classifications','instance_sfps','instance_wim_nets') " \
+        "NOT NULL COMMENT 'table where the item is stored';"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+         "VALUES (37, '0.37', '0.6.09', 'Adding the enum tags for SFC', '2019-02-07');"
+}
+function downgrade_from_37(){
+    echo "      Adding the enum tags for SFC isn't going to be reversed"
+    # It doesn't make sense to reverse to a bug state.
+    sql "DELETE FROM schema_version WHERE version_int='37';"
+}
+function upgrade_to_38(){
+    echo "      Change vim_wim_actions, add worker, related"
+    sql "ALTER TABLE vim_wim_actions ADD COLUMN worker VARCHAR(64) NULL AFTER task_index, " \
+           "ADD COLUMN related VARCHAR(36) NULL AFTER worker, " \
+           "CHANGE COLUMN status status ENUM('SCHEDULED','BUILD','DONE','FAILED','SUPERSEDED','FINISHED') " \
+           "NOT NULL DEFAULT 'SCHEDULED' AFTER item_id;"
+       sql "UPDATE vim_wim_actions set related=item_id;"
+       echo "      Change DONE to FINISHED when DELETE has been completed"
+       sql "UPDATE vim_wim_actions as v1 join vim_wim_actions as v2 on (v1.action='CREATE' or v1.action='FIND') and " \
+           "v2.action='DELETE' and (v2.status='SUPERSEDED' or v2.status='DONE') and v1.item_id=v2.item_id " \
+        "SET v1.status='FINISHED', v2.status='FINISHED';"
+    echo "      Add osm_id to instance_nets"
+    sql "ALTER TABLE instance_nets ADD COLUMN osm_id VARCHAR(255) NULL AFTER uuid;"
+    echo "      Add related to instance_xxxx"
+    for table in instance_classifications instance_nets instance_sfis instance_sfps instance_sfs \
+        instance_vms
+    do
+        sql "ALTER TABLE $table ADD COLUMN related VARCHAR(36) NULL AFTER vim_info;"
+       sql "UPDATE $table set related=uuid;"
+    done
+    sql "ALTER TABLE instance_wim_nets ADD COLUMN related VARCHAR(36) NULL AFTER wim_info;"
+       sql "UPDATE instance_wim_nets set related=uuid;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+        "VALUES (38, '0.38', '0.6.11', 'Adding related to vim_wim_actions', '2019-03-07');"
+
+}
+function downgrade_from_38(){
+    echo "      Change vim_wim_actions, delete worker, related"
+       sql "UPDATE vim_wim_actions SET status='DONE' WHERE status='FINISHED';"
+    sql "ALTER TABLE vim_wim_actions DROP COLUMN worker, DROP COLUMN related, " \
+           "CHANGE COLUMN status status ENUM('SCHEDULED','BUILD','DONE','FAILED','SUPERSEDED') " \
+           "NOT NULL DEFAULT 'SCHEDULED' AFTER item_id;"
+    echo "      Remove related from instance_xxxx"
+    for table in instance_classifications instance_nets instance_wim_nets instance_sfis instance_sfps instance_sfs \
+        instance_vms
+    do
+        sql "ALTER TABLE $table DROP COLUMN related;"
+    done
+    echo "      Remove osm_id from instance_nets"
+    sql "ALTER TABLE instance_nets DROP COLUMN osm_id;"
+    sql "DELETE FROM schema_version WHERE version_int='38';"
+}
+
+function upgrade_to_39(){
+    echo "      Enlarge vim_id to 300 at all places"
+    sql "ALTER TABLE datacenters_flavors CHANGE COLUMN vim_id vim_id VARCHAR(300) NOT NULL AFTER datacenter_vim_id;"
+    sql "ALTER TABLE datacenters_images CHANGE COLUMN vim_id vim_id VARCHAR(300) NOT NULL AFTER datacenter_vim_id;"
+    sql "ALTER TABLE datacenter_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(300) NOT NULL AFTER name;"
+    sql "ALTER TABLE instance_classifications CHANGE COLUMN vim_classification_id vim_classification_id VARCHAR(300)" \
+        " NULL DEFAULT NULL AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(300) NULL DEFAULT " \
+        " NULL AFTER interface_id;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER osm_id;"
+    sql "ALTER TABLE instance_sfis CHANGE COLUMN vim_sfi_id vim_sfi_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_sfps CHANGE COLUMN vim_sfp_id vim_sfp_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_sfs CHANGE COLUMN vim_sf_id vim_sf_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vim_vm_id vim_vm_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER instance_vnf_id, DROP INDEX vim_vm_id;"
+    sql "ALTER TABLE instance_wim_nets CHANGE COLUMN wim_internal_id wim_internal_id VARCHAR(300) NULL DEFAULT NULL" \
+        " COMMENT 'Internal ID used by the WIM to refer to the network' AFTER uuid;"
+    sql "ALTER TABLE vim_wim_actions CHANGE COLUMN vim_id vim_id VARCHAR(300) NULL DEFAULT NULL" \
+        " AFTER datacenter_vim_id;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+        "VALUES (39, '0.39', '0.6.20', 'Enlarge vim_id to 300 at all places', '2019-05-23');"
+}
+function downgrade_from_39(){
+    echo "      Set vim_id to original lenght at all places"
+    sql "ALTER TABLE datacenters_flavors CHANGE COLUMN vim_id vim_id VARCHAR(36) NOT NULL AFTER datacenter_vim_id;"
+    sql "ALTER TABLE datacenters_images CHANGE COLUMN vim_id vim_id VARCHAR(36) NOT NULL AFTER datacenter_vim_id;"
+    sql "ALTER TABLE datacenter_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(36) NOT NULL AFTER name;"
+    sql "ALTER TABLE instance_classifications CHANGE COLUMN vim_classification_id vim_classification_id VARCHAR(36)" \
+        " NULL DEFAULT NULL AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_interfaces CHANGE COLUMN vim_interface_id vim_interface_id VARCHAR(128) NULL DEFAULT " \
+        " NULL AFTER interface_id;"
+    sql "ALTER TABLE instance_nets CHANGE COLUMN vim_net_id vim_net_id VARCHAR(128) NULL DEFAULT NULL" \
+        " AFTER osm_id;"
+    sql "ALTER TABLE instance_sfis CHANGE COLUMN vim_sfi_id vim_sfi_id VARCHAR(36) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_sfps CHANGE COLUMN vim_sfp_id vim_sfp_id VARCHAR(36) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_sfs CHANGE COLUMN vim_sf_id vim_sf_id VARCHAR(36) NULL DEFAULT NULL" \
+        " AFTER instance_scenario_id;"
+    sql "ALTER TABLE instance_vms CHANGE COLUMN vim_vm_id vim_vm_id VARCHAR(36) NULL DEFAULT NULL" \
+        " AFTER instance_vnf_id, ADD UNIQUE INDEX vim_vm_id (vim_vm_id);"
+    sql "ALTER TABLE instance_wim_nets CHANGE COLUMN wim_internal_id wim_internal_id VARCHAR(128) NULL DEFAULT NULL" \
+        " COMMENT 'Internal ID used by the WIM to refer to the network' AFTER uuid;"
+    sql "ALTER TABLE vim_wim_actions CHANGE COLUMN vim_id vim_id VARCHAR(64) NULL DEFAULT NULL" \
+        " AFTER datacenter_vim_id;"
+
+    sql "DELETE FROM schema_version WHERE version_int='39';"
+}
+function upgrade_to_40(){
+    echo "      Adding instance_wim_net_id, created_at, modified_at at 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces ADD COLUMN instance_wim_net_id VARCHAR(36) NULL AFTER instance_net_id, " \
+        "ADD COLUMN model VARCHAR(12) NULL DEFAULT NULL AFTER type, " \
+        "ADD COLUMN created_at DOUBLE NULL DEFAULT NULL AFTER vlan, " \
+        "ADD COLUMN modified_at DOUBLE NULL DEFAULT NULL AFTER created_at;"
+    echo "      Adding sdn to 'instance_wim_nets'"
+    sql "ALTER TABLE instance_wim_nets ADD COLUMN sdn ENUM('true','false') NOT NULL DEFAULT 'false' AFTER created;"
+    echo "      Change from created to sdn at 'wim_accounts'"
+    sql "ALTER TABLE wim_accounts CHANGE COLUMN created sdn ENUM('true','false') NOT NULL DEFAULT 'false' AFTER wim_id;"
+    echo "      Remove unique_datacenter_port_mapping at 'wim_port_mappings'"
+    sql "ALTER TABLE wim_port_mappings DROP INDEX unique_datacenter_port_mapping;"
+    echo "      change 'wim_port_mappings' pop_x to device_x, adding switch_dpid, switch_port"
+    sql "ALTER TABLE wim_port_mappings ALTER pop_switch_dpid DROP DEFAULT, ALTER pop_switch_port DROP DEFAULT;"
+    sql "ALTER TABLE wim_port_mappings CHANGE COLUMN pop_switch_dpid device_id VARCHAR(64) NULL AFTER datacenter_id," \
+        " CHANGE COLUMN pop_switch_port device_interface_id VARCHAR(64) NULL AFTER device_id, " \
+        " CHANGE COLUMN wan_service_endpoint_id service_endpoint_id VARCHAR(256) NOT NULL AFTER device_interface_id, " \
+        " CHANGE COLUMN wan_service_mapping_info service_mapping_info TEXT NULL AFTER service_endpoint_id, " \
+        " ADD COLUMN switch_dpid VARCHAR(64) NULL AFTER service_endpoint_id," \
+        " ADD COLUMN switch_port VARCHAR(64) NULL AFTER switch_dpid;"
+    echo "      remove unique name to 'datacenters'"
+    sql "ALTER TABLE datacenters DROP INDEX name;"
+
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+        "VALUES (40, '0.40', '6.0.4', 'Chagnes to SDN ', '2019-10-23');"
+}
+function downgrade_from_40(){
+    echo "      Removing instance_wim_net_id, created_at, modified_at from 'instance_interfaces'"
+    sql "ALTER TABLE instance_interfaces DROP COLUMN instance_wim_net_id, DROP COLUMN created_at, " \
+        "DROP COLUMN modified_at, DROP COLUMN model;"
+    echo "      Removing sdn from 'instance_wim_nets'"
+    sql "ALTER TABLE instance_wim_nets DROP COLUMN sdn;"
+    echo "      Change back from sdn to created at 'wim_accounts'"
+    sql "ALTER TABLE wim_accounts CHANGE COLUMN sdn created ENUM('true','false') NOT NULL DEFAULT 'false' AFTER wim_id;"
+    echo "      Restore back unique_datacenter_port_mapping at 'wim_port_mappings'"
+    echo "      change 'wim_port_mappings' device_x to pop_x, remove switch_dpid, switch_port"
+    sql "ALTER TABLE wim_port_mappings ALTER device_id DROP DEFAULT, ALTER device_interface_id DROP DEFAULT;"
+    sql "ALTER TABLE wim_port_mappings CHANGE COLUMN device_id pop_switch_dpid VARCHAR(64) NOT NULL AFTER " \
+        "datacenter_id,        CHANGE COLUMN device_interface_id pop_switch_port VARCHAR(64) NOT NULL AFTER pop_switch_dpid," \
+        " CHANGE COLUMN service_endpoint_id wan_service_endpoint_id VARCHAR(256) NOT NULL AFTER pop_switch_port, " \
+        " CHANGE COLUMN service_mapping_info wan_service_mapping_info TEXT NULL AFTER wan_service_endpoint_id, " \
+             " DROP COLUMN switch_dpid, DROP COLUMN switch_port;"
+    sql "ALTER TABLE wim_port_mappings ADD UNIQUE INDEX unique_datacenter_port_mapping(datacenter_id, " \
+        "pop_switch_dpid, pop_switch_port);"
+    echo "      add unique name to 'datacenters'"
+    sql "ALTER TABLE datacenters ADD UNIQUE INDEX name (name);"
+    sql "DELETE FROM schema_version WHERE version_int='40';"
+}
+
+function upgrade_to_41(){
+    echo "      Removing unique name at 'wims' 'wim_accounts'"
+    sql "ALTER TABLE wims      DROP INDEX name;"
+    sql "ALTER TABLE wim_accounts      DROP INDEX wim_name;"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+        "VALUES (41, '0.41', '8.0.0', 'Removing unique name for wims/wim_accounts', '2020-07-16');"
+}
+function downgrade_from_41(){
+    echo "      Adding back unique name at 'wims' 'wim_accounts'"
+    sql "ALTER TABLE wims      ADD UNIQUE INDEX name (name);"
+    sql "ALTER TABLE wim_accounts      ADD UNIQUE INDEX wim_name (name);"
+    sql "DELETE FROM schema_version WHERE version_int='41';"
+}
+
+function upgrade_to_42(){
+    echo "      Adding 'port_security_disable_strategy' to 'interfaces'"
+    sql "ALTER TABLE interfaces    ADD COLUMN port_security_disable_strategy CHAR(25);"
+    sql "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) " \
+        "VALUES (42, '0.42', '8.0.2', 'Adding port_security_disable_strategy to interfaces', '2020-10-19');"
+}
+
+function downgrade_to_42(){
+    echo "      Removing 'port_security_disable_strategy' from 'interfaces'"
+    sql "ALTER TABLE interfaces     DROP port_security_disable_strategy;"
+    sql "DELETE FROM schema_version WHERE version_int='42';"
+}
+
+#TODO ... put functions here
+
+
+function del_schema_version_process()
+{
+    echo "DELETE FROM schema_version WHERE version_int='0';" | $DBCMD ||
+        ! echo "    ERROR writing on schema_version" >&2 || exit 1
+}
+
+function set_schema_version_process()
+{
+    echo "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES "\
+        "(0, '0.0', '0.0.0', 'migration from $DATABASE_VER_NUM to $DB_VERSION backup: $BACKUP_FILE',"\
+        "'$(date +%Y-%m-%d)');" | $DBCMD ||
+        ! echo  "    Cannot set database at migration process writing into schema_version" >&2 || exit 1
+
+}
+
+function rollback_db()
+{
+    if echo $DATABASE_PROCESS | grep -q init ; then   # Empty database. No backup needed
+        echo "    Aborted! Rollback database not needed" && exit 1
+    else   # migration a non empty database or Recovering a migration process
+        cat $BACKUP_FILE | mysql $DEF_EXTRA_FILE_PARAM && echo "    Aborted! Rollback database OK" &&
+            del_schema_version_process && rm -f "$BACKUP_FILE" && exit 1
+        echo "    Aborted! Rollback database FAIL" && exit 1
+    fi
+}
+
+function sql()    # send a sql command
+{
+    echo "$*" | $DBCMD || ! echo "    ERROR with command '$*'" || rollback_db
+    return 0
+}
+
+function migrate()
+{
+    #UPGRADE DATABASE step by step
+    while [ $DB_VERSION -gt $DATABASE_VER_NUM ]
+    do
+        echo "    upgrade database from version '$DATABASE_VER_NUM' to '$((DATABASE_VER_NUM+1))'"
+        DATABASE_VER_NUM=$((DATABASE_VER_NUM+1))
+        upgrade_to_${DATABASE_VER_NUM}
+        #FILE_="${DIRNAME}/upgrade_to_${DATABASE_VER_NUM}.sh"
+        #[ ! -x "$FILE_" ] && echo "Error, can not find script '$FILE_' to upgrade" >&2 && exit -1
+        #$FILE_ || exit -1  # if fail return
+    done
+
+    #DOWNGRADE DATABASE step by step
+    while [ $DB_VERSION -lt $DATABASE_VER_NUM ]
+    do
+        echo "    downgrade database from version '$DATABASE_VER_NUM' to '$((DATABASE_VER_NUM-1))'"
+        #FILE_="${DIRNAME}/downgrade_from_${DATABASE_VER_NUM}.sh"
+        #[ ! -x "$FILE_" ] && echo "Error, can not find script '$FILE_' to downgrade" >&2 && exit -1
+        #$FILE_ || exit -1  # if fail return
+        downgrade_from_${DATABASE_VER_NUM}
+        DATABASE_VER_NUM=$((DATABASE_VER_NUM-1))
+    done
+}
+
+
+# check if current database is ok
+function check_migration_needed()
+{
+    DATABASE_VER_NUM=`echo "select max(version_int) from schema_version;" | $DBCMD | tail -n+2` ||
+    ! echo "    ERROR cannot read from schema_version" || exit 1
+
+    if [[ -z "$DATABASE_VER_NUM" ]] || [[ "$DATABASE_VER_NUM" -lt 0 ]] || [[ "$DATABASE_VER_NUM" -gt 100 ]] ; then
+        echo "    Error can not get database version ($DATABASE_VER_NUM?)" >&2
+        exit 1
+    fi
+
+    [[ $DB_VERSION -eq $DATABASE_VER_NUM ]] && echo "    current database version '$DATABASE_VER_NUM' is ok" && return 1
+    [[ "$DATABASE_VER_NUM" -gt "$LAST_DB_VERSION" ]] &&
+        echo "Database has been upgraded with a newer version of this script. Use this version to downgrade" >&2 &&
+        exit 1
+    return 0
+}
+
+DATABASE_PROCESS=`echo "select comments from schema_version where version_int=0;" | $DBCMD | tail -n+2` ||
+    ! echo "    ERROR cannot read from schema_version" || exit 1
+if [[ -z "$DATABASE_PROCESS" ]] ; then  # migration a non empty database
+    check_migration_needed || exit 0
+    # Create a backup database content
+    [[ -n "$BACKUP_DIR" ]] && BACKUP_FILE=$(mktemp -q  "${BACKUP_DIR}/backupdb.XXXXXX.sql")
+    [[ -z "$BACKUP_DIR" ]] && BACKUP_FILE=$(mktemp -q --tmpdir "backupdb.XXXXXX.sql")
+    mysqldump $DEF_EXTRA_FILE_PARAM --add-drop-table --add-drop-database --routines --databases $DBNAME > $BACKUP_FILE ||
+        ! echo "Cannot create Backup file '$BACKUP_FILE'" >&2 || exit 1
+    echo "    Backup file '$BACKUP_FILE' created"
+    # Set schema version
+    set_schema_version_process
+    migrate
+    del_schema_version_process
+    rm -f "$BACKUP_FILE"
+elif echo $DATABASE_PROCESS | grep -q init ; then   # Empty database. No backup needed
+    echo "    Migrating an empty database"
+    if check_migration_needed ; then
+        migrate
+    fi
+    del_schema_version_process
+
+else  # Recover Migration process
+    BACKUP_FILE=${DATABASE_PROCESS##*backup: }
+    [[ -f "$BACKUP_FILE" ]] || ! echo "Previous migration process fail and cannot recover backup file '$BACKUP_FILE'" >&2 ||
+        exit 1
+    echo "    Previous migration was killed. Restoring database from rollback file'$BACKUP_FILE'"
+    cat $BACKUP_FILE | mysql $DEF_EXTRA_FILE_PARAM || ! echo "    Cannot load backup file '$BACKUP_FILE'" >&2 || exit 1
+    if check_migration_needed ; then
+        set_schema_version_process
+        migrate
+    fi
+    del_schema_version_process
+    rm -f "$BACKUP_FILE"
+fi
+exit 0
+
+#echo done
+
diff --git a/RO/osm_ro/database_utils/migrations/down/34_remove_wim_tables.sql b/RO/osm_ro/database_utils/migrations/down/34_remove_wim_tables.sql
new file mode 100644 (file)
index 0000000..7ab4bf7
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+* 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&nb