From: garciadeblas Date: Thu, 21 Sep 2017 16:12:58 +0000 (+0200) Subject: Merge branch 'master' into vnffg X-Git-Tag: v3.0.0~12^2~2 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=commitdiff_plain;h=a92a0eaaf370c626b442863f4127cd11fc64754c;hp=862a60ae93454d1cb15feb25efa31f493e2f46d3 Merge branch 'master' into vnffg Change-Id: I13e763560a923aa47a1626cdd6ff37c0c31a3aa9 Signed-off-by: garciadeblas --- diff --git a/Dockerfile b/Dockerfile index 254027cf..f901e9ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,17 @@ FROM ubuntu:16.04 RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install git build-essential apt-utils && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python python-dev python-all python-stdeb fakeroot pypi2deb && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-pip libmysqlclient-dev libssl-dev libffi-dev && \ - DEBIAN_FRONTEND=noninteractive pip install --upgrade pip && \ - DEBIAN_FRONTEND=noninteractive pip install --upgrade setuptools && \ - DEBIAN_FRONTEND=noninteractive apt-get -y install python-argcomplete python-boto python-bottle python-jsonschema python-logutils python-cinderclient python-glanceclient python-keystoneclient python-neutronclient python-novaclient python-openstackclient python-mysqldb + DEBIAN_FRONTEND=noninteractive apt-get -y install git make python python-pip debhelper && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install wget tox && \ + DEBIAN_FRONTEND=noninteractive pip install -U pip && \ + DEBIAN_FRONTEND=noninteractive pip install -U setuptools setuptools-version-command stdeb && \ + DEBIAN_FRONTEND=noninteractive pip install -U pyang pyangbind && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install python-yaml python-netaddr python-boto && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install software-properties-common && \ + DEBIAN_FRONTEND=noninteractive add-apt-repository -y cloud-archive:ocata && \ + DEBIAN_FRONTEND=noninteractive apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install python-novaclient python-keystoneclient python-glanceclient python-cinderclient python-neutronclient && \ + DEBIAN_FRONTEND=noninteractive pip install -U progressbar pyvmomi pyvcloud && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install python-argcomplete python-bottle python-cffi python-packaging python-paramiko python-pkgconfig libmysqlclient-dev libssl-dev libffi-dev python-mysqldb && \ + DEBIAN_FRONTEND=noninteractive apt-get -y install python-logutils python-openstackclient python-openstacksdk diff --git a/Jenkinsfile b/Jenkinsfile index bc6c2d0f..6eea999d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,6 +6,7 @@ properties([ string(defaultValue: env.GERRIT_PATCHSET_REVISION, description: '', name: 'GERRIT_PATCHSET_REVISION'), string(defaultValue: 'https://osm.etsi.org/gerrit', description: '', name: 'PROJECT_URL_PREFIX'), booleanParam(defaultValue: false, description: '', name: 'TEST_INSTALL'), + string(defaultValue: 'artifactory-osm', description: '', name: 'ARTIFACTORY_SERVER'), ]) ]) @@ -15,7 +16,7 @@ def devops_checkout() { } } -node { +node('docker') { checkout scm devops_checkout() @@ -26,5 +27,6 @@ node { params.GERRIT_BRANCH, params.GERRIT_REFSPEC, params.GERRIT_PATCHSET_REVISION, - params.TEST_INSTALL) + params.TEST_INSTALL, + params.ARTIFACTORY_SERVER) } diff --git a/MANIFEST.in b/MANIFEST.in index 48790d46..483b709e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,6 @@ #include MANIFEST.in #include requirements.txt include README.rst -include RO_VERSION include openmano include openmanod recursive-include osm_ro * diff --git a/Makefile b/Makefile index 41b265a7..d3128451 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,29 @@ +.PHONY: all test clean + SHELL := /bin/bash -all: package install -clean_deb: - rm -rf .build +BRANCH ?= master + +all: lib-openvim osm-im + $(MAKE) clean_build build + $(MAKE) clean_build package + +clean: clean_build + rm -rf .build openvim IM -clean: +clean_build: rm -rf build find osm_ro -name '*.pyc' -delete find osm_ro -name '*.pyo' -delete + prepare: - pip install --user --upgrade setuptools +# 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 +# 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/ @@ -28,6 +37,7 @@ prepare: 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 @@ -36,14 +46,25 @@ connectors: prepare python build/osm_ro/openmanolinkervimconn.py rm -f build/osm_ro/openmanolinkervimconn.py -build: clean connectors prepare +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 -pip: prepare - cd build && ./setup.py sdist +osm-im: + $(shell git clone https://osm.etsi.org/gerrit/osm/IM) + make -C IM clean all -package: clean clean_deb prepare - #apt-get install -y python-stdeb +package: prepare +# apt-get install -y python-stdeb cd build && python setup.py --command-packages=stdeb.command sdist_dsc --with-python2=True cd build && cp osm_ro/scripts/python-osm-ro.postinst deb_dist/osm-ro*/debian/ cd build/deb_dist/osm-ro* && dpkg-buildpackage -rfakeroot -uc -us @@ -54,17 +75,25 @@ snap: echo "Nothing to be done yet" install: - DEBIAN_FRONTEND=noninteractive apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y python-pip && \ - pip install --upgrade pip && \ - dpkg -i .build/*.deb + 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 +# pip install -r requirements.txt cd build && ./setup.py develop test: - ./test/basictest.sh --force --insert-bashrc --install-openvim --init-openvim + . ./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 . diff --git a/database_utils/migrate_mano_db.sh b/database_utils/migrate_mano_db.sh index 52d8cb1a..1e3e5b6c 100755 --- a/database_utils/migrate_mano_db.sh +++ b/database_utils/migrate_mano_db.sh @@ -33,7 +33,7 @@ DBPORT="3306" DBNAME="mano_db" QUIET_MODE="" #TODO update it with the last database version -LAST_DB_VERSION=22 +LAST_DB_VERSION=24 # Detect paths MYSQL=$(which mysql) @@ -147,7 +147,7 @@ DBCMD="mysql $DEF_EXTRA_FILE_PARAM $DBNAME" 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; + exit 1; fi if ! echo 'show create table schema_version;' | $DBCMD >/dev/null 2>&1 @@ -158,7 +158,7 @@ else DATABASE_VER_NUM=`echo "select max(version_int) from schema_version;" | $DBCMD | tail -n+2` DATABASE_VER=`echo "select version from schema_version where version_int='$DATABASE_VER_NUM';" | $DBCMD | tail -n+2` [ "$DATABASE_VER_NUM" -lt 0 -o "$DATABASE_VER_NUM" -gt 100 ] && - echo " Error can not get database version ($DATABASE_VER?)" >&2 && exit -1 + echo " Error can not get database version ($DATABASE_VER?)" >&2 && exit 1 #echo "_${DATABASE_VER_NUM}_${DATABASE_VER}" fi @@ -190,12 +190,14 @@ fi #[ $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 #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\`" - 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', @@ -205,22 +207,22 @@ function upgrade_to_1(){ ) COMMENT='database schema control version' COLLATE='utf8_general_ci' - ENGINE=InnoDB;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "INSERT INTO \`schema_version\` (\`version_int\`, \`version\`, \`openmano_ver\`, \`comments\`, \`date\`) - VALUES (1, '0.1', '0.2.2', 'insert schema_version', '2015-05-08');" | $DBCMD + 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 \`schema_version\`" - echo "DROP TABLE \`schema_version\`;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "DROP TABLE \`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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "CREATE TABLE images ( + sql "CREATE TABLE images ( uuid VARCHAR(36) NOT NULL, name VARCHAR(50) NOT NULL, location VARCHAR(200) NOT NULL, @@ -229,8 +231,8 @@ function upgrade_to_2(){ PRIMARY KEY (uuid), UNIQUE INDEX location (location) ) COLLATE='utf8_general_ci' - ENGINE=InnoDB;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "CREATE TABLE datacenters_images ( + 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, @@ -239,13 +241,13 @@ function upgrade_to_2(){ 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + ENGINE=InnoDB;" echo " migrate data from table 'vms' into 'images'" - echo "INSERT INTO images (uuid, name, location) SELECT DISTINCT vim_image_id, vim_image_id, image_path FROM vms;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "INSERT INTO datacenters_images (image_id, datacenter_id, vim_id) - SELECT DISTINCT vim_image_id, datacenters.uuid, vim_image_id FROM vms JOIN datacenters;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "CREATE TABLE flavors ( + sql "CREATE TABLE flavors ( uuid VARCHAR(36) NOT NULL, name VARCHAR(50) NOT NULL, description VARCHAR(100) NULL, @@ -255,8 +257,8 @@ function upgrade_to_2(){ 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "CREATE TABLE datacenters_flavors ( + 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, @@ -265,104 +267,104 @@ function upgrade_to_2(){ 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + ENGINE=InnoDB;" echo " migrate data from table 'vms' into 'flavors'" - echo "INSERT INTO flavors (uuid, name) SELECT DISTINCT vim_flavor_id, vim_flavor_id FROM vms;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "INSERT INTO datacenters_flavors (flavor_id, datacenter_id, vim_id) - SELECT DISTINCT vim_flavor_id, datacenters.uuid, vim_flavor_id FROM vms JOIN datacenters;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vms ALTER vim_flavor_id DROP DEFAULT, ALTER vim_image_id DROP DEFAULT; + 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); - " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE vms ALTER image_id DROP DEFAULT, ALTER flavor_id DROP DEFAULT; + 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; - " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 +# INNER JOIN datacenters_images as di ON i.uuid=di.image_id;" echo " Delete columns 'user/passwd' from 'vim_tenants'" - echo "ALTER TABLE vim_tenants DROP COLUMN user, DROP COLUMN passwd; " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE vim_tenants DROP COLUMN user, DROP COLUMN passwd; " echo " delete tables 'datacenter_images', 'images'" - echo "DROP TABLE \`datacenters_images\`;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DROP TABLE \`images\`;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "DROP TABLE \`datacenters_images\`;" + sql "DROP TABLE \`images\`;" echo " delete tables 'datacenter_flavors', 'flavors'" - echo "DROP TABLE \`datacenters_flavors\`;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DROP TABLE \`flavors\`;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='2';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "DROP TABLE \`datacenters_flavors\`;" + sql "DROP TABLE \`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" - echo "ALTER TABLE logs CHANGE COLUMN related related VARCHAR(36) NOT NULL COMMENT 'Relevant element for the log' AFTER nfvo_tenant_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE uuids CHANGE COLUMN used_at used_at VARCHAR(36) NULL DEFAULT NULL COMMENT 'Table that uses this UUID' AFTER created_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "ALTER TABLE images CHANGE COLUMN metadata metadata VARCHAR(2000) NULL DEFAULT NULL AFTER description;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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; " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenters ADD COLUMN config VARCHAR(4000) NULL DEFAULT NULL COMMENT 'extra config information in json' AFTER vim_url_admin; - " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM vim_tenants WHERE datacenter_id is NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants ALTER datacenter_id DROP DEFAULT; + 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants ADD CONSTRAINT FK_vim_tenants_datacenters FOREIGN KEY (datacenter_id) REFERENCES datacenters (uuid) - ON UPDATE CASCADE ON DELETE CASCADE;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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;" - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "ALTER TABLE $table DROP COLUMN created;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE $table DROP COLUMN created;" done - echo "ALTER TABLE images CHANGE COLUMN metadata metadata VARCHAR(400) NULL DEFAULT NULL AFTER description;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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; " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenters DROP COLUMN config;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE datacenters DROP COLUMN config;" echo " Delete column datacenter_id to table 'vim_tenants'" - echo "ALTER TABLE vim_tenants DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_vim_tenants_datacenters;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name name VARCHAR(36) NULL DEFAULT NULL COMMENT '' AFTER uuid"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants ALTER name DROP DEFAULT;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants CHANGE COLUMN name name VARCHAR(36) NOT NULL AFTER uuid"| $DBCMD || ! echo "Warning changing column name at vim_tenants!" - echo "ALTER TABLE vim_tenants ADD UNIQUE INDEX name (name);" | $DBCMD || ! echo "Warning add unique index name at vim_tenants!" - echo "ALTER TABLE vim_tenants ALTER vim_tenant_id DROP DEFAULT;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;"| $DBCMD || ! echo "Warning changing column vim_tenant_id at vim_tenants!" - echo "ALTER TABLE vim_tenants ADD UNIQUE INDEX vim_tenant_id (vim_tenant_id);" | $DBCMD || ! echo "Warning add unique index vim_tenant_id at vim_tenants!" - echo "DELETE FROM schema_version WHERE version_int='3';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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(){ @@ -370,10 +372,10 @@ function upgrade_to_4(){ echo " Enlarge graph field at tables 'sce_vnfs', 'sce_nets'" for table in sce_vnfs sce_nets do - echo "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;" done - echo "ALTER TABLE datacenters CHANGE COLUMN type type VARCHAR(36) NOT NULL DEFAULT 'openvim' AFTER description;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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(){ @@ -381,72 +383,72 @@ function downgrade_from_4(){ echo " Shorten back graph field at tables 'sce_vnfs', 'sce_nets'" for table in sce_vnfs sce_nets do - echo "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE $table CHANGE COLUMN graph graph VARCHAR(2000) NULL DEFAULT NULL AFTER modified_at;" done - echo "ALTER TABLE datacenters CHANGE COLUMN type type ENUM('openvim','openstack') NOT NULL DEFAULT 'openvim' AFTER description;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='4';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE interfaces ADD COLUMN mac CHAR(18) NULL DEFAULT NULL AFTER model;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE interfaces DROP COLUMN mac;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='5';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE vnfs ADD COLUMN descriptor TEXT NULL DEFAULT NULL COMMENT 'Original text descriptor used for create the VNF' AFTER class;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE scenarios ADD COLUMN descriptor TEXT NULL DEFAULT NULL COMMENT 'Original text descriptor used for create the scenario' AFTER modified_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_vms ADD COLUMN error_msg VARCHAR(1024) NULL DEFAULT NULL AFTER status;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_vms ADD COLUMN vim_info TEXT NULL DEFAULT NULL AFTER error_msg;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets ADD COLUMN error_msg VARCHAR(1024) NULL DEFAULT NULL AFTER status;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets ADD COLUMN vim_info TEXT NULL DEFAULT NULL AFTER error_msg;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE vnfs DROP COLUMN descriptor;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE scenarios DROP COLUMN descriptor;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_vms DROP COLUMN error_msg, DROP COLUMN vim_info;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE','PAUSED','INACTIVE','CREATING','ERROR','DELETING') NOT NULL DEFAULT 'CREATING' AFTER vim_vm_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets DROP COLUMN error_msg, DROP COLUMN vim_info;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets CHANGE COLUMN status status ENUM('ACTIVE','DOWN','BUILD','ERROR') NOT NULL DEFAULT 'BUILD' AFTER instance_scenario_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_interfaces DROP COLUMN mac_address, DROP COLUMN ip_address, DROP COLUMN vim_info;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_vnfs DROP COLUMN sce_vnf_id, DROP FOREIGN KEY FK_instance_vnfs_sce_vnfs;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_vnfs DROP COLUMN vim_tenant_id, DROP FOREIGN KEY FK_instance_vnfs_vim_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_vnfs DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_instance_vnfs_datacenters;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_nets DROP COLUMN sce_net_id, DROP FOREIGN KEY FK_instance_nets_sce_nets;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets DROP COLUMN net_id, DROP FOREIGN KEY FK_instance_nets_nets;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets DROP COLUMN vim_tenant_id, DROP FOREIGN KEY FK_instance_nets_vim_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets DROP COLUMN datacenter_id, DROP FOREIGN KEY FK_instance_nets_datacenters;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='6';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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(){ @@ -455,14 +457,14 @@ function upgrade_to_7(){ 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" - echo "ALTER TABLE $table ADD COLUMN created_at_ DOUBLE NOT NULL after created_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "UPDATE $table SET created_at_=unix_timestamp(created_at);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE $table DROP COLUMN created_at, CHANGE COLUMN created_at_ created_at DOUBLE NOT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - [[ $table == uuids ]] || echo "ALTER TABLE $table CHANGE COLUMN modified_at modified_at DOUBLE NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" @@ -470,13 +472,13 @@ function downgrade_from_7(){ 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" - echo "ALTER TABLE $table ADD COLUMN created_at_ TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP after created_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "UPDATE $table SET created_at_=from_unixtime(created_at);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE $table DROP COLUMN created_at, CHANGE COLUMN created_at_ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - [[ $table == uuids ]] || echo "ALTER TABLE $table CHANGE COLUMN modified_at modified_at TIMESTAMP NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "DELETE FROM schema_version WHERE version_int='7';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "DELETE FROM schema_version WHERE version_int='7';" } function upgrade_to_8(){ @@ -485,15 +487,15 @@ function upgrade_to_8(){ 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" - echo "ALTER TABLE $table CHANGE COLUMN name name VARCHAR(255) NOT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE $table CHANGE COLUMN description description VARCHAR(255) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE interfaces CHANGE COLUMN internal_name internal_name VARCHAR(255) NOT NULL, CHANGE COLUMN external_name external_name VARCHAR(255) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(64) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE vim_tenants CHANGE COLUMN user user VARCHAR(64) NULL DEFAULT NULL, CHANGE COLUMN passwd passwd VARCHAR(64) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" @@ -503,89 +505,89 @@ function downgrade_from_8(){ name_length=50 [[ $table == flavors ]] || [[ $table == images ]] || name_length=36 echo -en " $table \r" - echo "ALTER TABLE $table CHANGE COLUMN name name VARCHAR($name_length) NOT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE $table CHANGE COLUMN description description VARCHAR(100) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE interfaces CHANGE COLUMN internal_name internal_name VARCHAR(25) NOT NULL, CHANGE COLUMN external_name external_name VARCHAR(25) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE vim_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(36) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vim_tenants CHANGE COLUMN user user VARCHAR(36) NULL DEFAULT NULL, CHANGE COLUMN passwd passwd VARCHAR(50) NULL DEFAULT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='8';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE:NoMgmtIP','ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_vms CHANGE COLUMN status status ENUM('ACTIVE','INACTIVE','BUILD','ERROR','VIM_ERROR','PAUSED','SUSPENDED','DELETED') NOT NULL DEFAULT 'BUILD';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='9';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE scenarios DROP FOREIGN KEY FK_scenarios_nfvo_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_nfvo_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE ${table} DROP FOREIGN KEY FK_${table}_vim_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE ${table} ALTER vim_tenant_id DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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); " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE scenarios DROP FOREIGN KEY FK_scenarios_nfvo_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios DROP FOREIGN KEY FK_instance_scenarios_nfvo_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + echo "RENAME TABLE datacenter_tenants TO vim_tenants;" for table in tenants_datacenters instance_scenarios instance_vnfs instance_nets do - echo "ALTER TABLE ${table} DROP FOREIGN KEY FK_${table}_datacenter_tenants;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE ${table} DROP FOREIGN KEY FK_${table}_datacenter_tenants;" NULL="NOT NULL" [[ $table == instance_vnfs ]] && NULL="NULL DEFAULT NULL" - echo "ALTER TABLE ${table} ALTER datacenter_tenant_id DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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); " | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "DELETE FROM schema_version WHERE version_int='10';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE scenarios DROP INDEX name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios DROP INDEX name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE scenarios ADD UNIQUE INDEX name (name);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios ADD UNIQUE INDEX name (name);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='11';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "CREATE TABLE IF NOT EXISTS ip_profiles ( + 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, @@ -603,201 +605,248 @@ function upgrade_to_12(){ 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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE interfaces ADD COLUMN ip_address VARCHAR(64) NULL DEFAULT NULL AFTER mac;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE sce_interfaces ADD COLUMN ip_address VARCHAR(64) NULL DEFAULT NULL AFTER interface_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "DROP TABLE ip_profiles;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE interfaces DROP COLUMN ip_address;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE sce_interfaces DROP COLUMN ip_address;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='12';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "DROP TABLE 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'" - echo "ALTER TABLE scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER descriptor;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios ADD COLUMN cloud_config MEDIUMTEXT NULL DEFAULT NULL AFTER modified_at;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE scenarios DROP COLUMN cloud_config;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_scenarios DROP COLUMN cloud_config;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='13';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_nets DROP INDEX vim_net_id_instance_scenario_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets CHANGE COLUMN external created ENUM('true','false') NOT NULL DEFAULT 'false' COMMENT 'Created or already exists at VIM' AFTER multipoint;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_nets ADD UNIQUE INDEX vim_net_id_instance_scenario_id (vim_net_id, instance_scenario_id);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='14';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE images ADD COLUMN checksum VARCHAR(32) NULL DEFAULT NULL AFTER name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE images ALTER location DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vms ALTER image_path DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE images DROP INDEX universal_name_checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE images ALTER location DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE images CHANGE COLUMN location location VARCHAR(200) NOT NULL AFTER checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE images DROP COLUMN universal_name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE images DROP COLUMN checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE vms ALTER image_path DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='15';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenter_tenants ADD COLUMN config VARCHAR(4000) NULL DEFAULT NULL AFTER passwd;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(256) NULL DEFAULT NULL AFTER datacenter_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenter_tenants DROP COLUMN config;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE datacenter_tenants CHANGE COLUMN vim_tenant_name vim_tenant_name VARCHAR(64) NULL DEFAULT NULL AFTER datacenter_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='16';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenters_flavors ADD extended varchar(2000) NULL COMMENT 'Extra description json format of additional devices';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenters_flavors DROP COLUMN extended;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='17';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE interfaces ADD floating_ip BOOL DEFAULT 0 NOT NULL COMMENT 'Indicates if a floating_ip must be associated to this interface';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces ADD floating_ip BOOL DEFAULT 0 NOT NULL COMMENT 'Indicates if a floating_ip must be associated to this interface';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE interfaces DROP COLUMN floating_ip;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE interfaces DROP COLUMN port_security;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN floating_ip;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN port_security;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='18';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE vms ADD COLUMN boot_data TEXT NULL DEFAULT NULL AFTER image_path;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE vms DROP COLUMN boot_data;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='19';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_nets ADD sdn_net_id varchar(36) DEFAULT NULL NULL COMMENT 'Network id in ovim';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces ADD sdn_port_id varchar(36) DEFAULT NULL NULL COMMENT 'Port id in ovim';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces ADD compute_node varchar(100) DEFAULT NULL NULL COMMENT 'Compute node id used to specify the SDN port mapping';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces ADD pci varchar(12) DEFAULT NULL NULL COMMENT 'PCI of the physical port in the host';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces ADD vlan SMALLINT UNSIGNED DEFAULT NULL NULL COMMENT 'VLAN tag used by the port';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE instance_nets DROP COLUMN sdn_net_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN vlan;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN pci;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN compute_node;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_interfaces DROP COLUMN sdn_port_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='20';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NULL;" echo " enlarge column 'dns_address' at table 'ip_profiles'" - echo "ALTER TABLE ip_profiles MODIFY dns_address varchar(255) DEFAULT NULL NULL "\ - "comment 'dns ip list separated by semicolon';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 - echo "DELETE FROM instance_nets WHERE instance_scenario_id IS NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "ALTER TABLE instance_nets MODIFY COLUMN instance_scenario_id varchar(36) NOT NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE ip_profiles MODIFY dns_address varchar(64) DEFAULT NULL NULL;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='21';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE flavors CHANGE COLUMN ram ram MEDIUMINT(7) UNSIGNED NULL DEFAULT NULL AFTER disk;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "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');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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" - echo "ALTER TABLE flavors CHANGE COLUMN ram ram SMALLINT(5) UNSIGNED NULL DEFAULT NULL AFTER disk;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 - echo "DELETE FROM schema_version WHERE version_int='22';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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 mano_db.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 mano_db.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_X(){ echo " change 'datacenter_nets'" - echo "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);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + 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'" - echo "ALTER TABLE datacenter_nets DROP COLUMN vim_tenant_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1 + sql "ALTER TABLE datacenter_nets DROP COLUMN vim_tenant_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id);" } -#TODO ... put funtions here +#TODO ... put functions here # echo "db version = "${DATABASE_VER_NUM} -[ $DB_VERSION -eq $DATABASE_VER_NUM ] && echo " current database version '$DATABASE_VER_NUM' is ok" +[ $DB_VERSION -eq $DATABASE_VER_NUM ] && echo " current database version '$DATABASE_VER_NUM' is ok" && exit 0 + +# Create a backup database content +TEMPFILE2="$(mktemp -q --tmpdir "backupdb.XXXXXX.sql")" +trap 'rm -f "$TEMPFILE2"' EXIT +mysqldump $DEF_EXTRA_FILE_PARAM --add-drop-table --add-drop-database --routines --databases $DBNAME > $TEMPFILE2 + +function rollback_db() +{ + cat $TEMPFILE2 | mysql $DEF_EXTRA_FILE_PARAM && echo " Rollback database OK" || + echo " Rollback database FAIL" + exit 1 +} + +function sql() # send a sql command +{ + echo "$*" | $DBCMD || ! echo " ERROR. Aborted!" || rollback_db + return 0 +} + #UPGRADE DATABASE step by step while [ $DB_VERSION -gt $DATABASE_VER_NUM ] do diff --git a/devops-stages/stage-build.sh b/devops-stages/stage-build.sh index 85054995..25de71a7 100755 --- a/devops-stages/stage-build.sh +++ b/devops-stages/stage-build.sh @@ -1,2 +1,4 @@ #!/bin/sh -make package +make clean all BRANCH=master +#make install && \ +#make test diff --git a/openmanod b/openmanod index fbd8e2e2..94924bd7 100755 --- a/openmanod +++ b/openmanod @@ -48,13 +48,14 @@ import osm_ro __author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" __date__ = "$26-aug-2014 11:09:29$" -__version__ = "0.5.17-r526" -version_date = "Jul 2017" -database_version = 22 #expected database schema version +__version__ = "0.5.21-r531" +version_date = "Aug 2017" +database_version = 24 # expected database schema version global global_config global logger + class LoadConfigurationException(Exception): pass diff --git a/osm_ro/db_base.py b/osm_ro/db_base.py index 4a877213..26e4c002 100644 --- a/osm_ro/db_base.py +++ b/osm_ro/db_base.py @@ -336,7 +336,31 @@ class db_base(): self.logger.debug(cmd) self.cur.execute(cmd) return self.cur.rowcount - + + def _new_uuid(self, root_uuid=None, used_table=None, created_time=0): + """ + Generate a new uuid. It DOES NOT begin or end the transaction, so self.con.cursor must be created + :param root_uuid: master uuid of the transaction + :param used_table: the table this uuid is intended for + :param created_time: time of creation + :return: the created uuid + """ + + uuid = str(myUuid.uuid1()) + # defining root_uuid if not provided + if root_uuid is None: + root_uuid = uuid + if created_time: + created_at = created_time + else: + created_at = time.time() + # inserting new uuid + cmd = "INSERT INTO uuids (uuid, root_uuid, used_at, created_at) VALUES ('{:s}','{:s}','{:s}', {:f})".format( + uuid, root_uuid, used_table, created_at) + self.logger.debug(cmd) + self.cur.execute(cmd) + return uuid + def _new_row_internal(self, table, INSERT, add_uuid=False, root_uuid=None, created_time=0): ''' Add one row into a table. It DOES NOT begin or end the transaction, so self.con.cursor must be created Attribute diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py index a5599418..8b6a2e13 100644 --- a/osm_ro/nfvo.py +++ b/osm_ro/nfvo.py @@ -38,6 +38,7 @@ import console_proxy_thread as cli import vimconn import logging import collections +from uuid import uuid4 from db_base import db_base_Exception import nfvo_db @@ -334,7 +335,9 @@ def rollback(mydb, vims, rollback_list): if item["where"]=="vim": if item["vim_id"] not in vims: continue - vim=vims[ item["vim_id"] ] + if is_task_id(item["uuid"]): + continue + vim = vims[item["vim_id"]] try: if item["what"]=="image": vim.delete_image(item["uuid"]) @@ -392,12 +395,12 @@ def check_vnf_descriptor(vnf_descriptor, vnf_descriptor_version=1): name_dict[ interface["name"] ] = "overlay" vnfc_interfaces[ vnfc["name"] ] = name_dict # check bood-data info - if "boot-data" in vnfc: - # check that user-data is incompatible with users and config-files - if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"): - raise NfvoException( - "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'", - HTTP_Bad_Request) + # if "boot-data" in vnfc: + # # check that user-data is incompatible with users and config-files + # if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"): + # raise NfvoException( + # "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'", + # HTTP_Bad_Request) #check if the info in external_connections matches with the one in the vnfcs name_list=[] @@ -481,7 +484,7 @@ def check_vnf_descriptor(vnf_descriptor, vnf_descriptor_version=1): HTTP_Bad_Request) -def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vim=False, return_on_error = None): +def create_or_use_image(mydb, vims, image_dict, rollback_list, only_create_at_vim=False, return_on_error=None): #look if image exist if only_create_at_vim: image_mano_id = image_dict['uuid'] @@ -757,6 +760,7 @@ def new_vnf(mydb, tenant_id, vnf_descriptor): for vnfc in vnf_descriptor['vnf']['VNFC']: VNFCitem={} VNFCitem["name"] = vnfc['name'] + VNFCitem["availability_zone"] = vnfc.get('availability_zone') VNFCitem["description"] = vnfc.get("description", 'VM %s of the VNF %s' %(vnfc['name'],vnf_name)) #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"]) @@ -827,6 +831,7 @@ def new_vnf(mydb, tenant_id, vnf_descriptor): #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id) VNFCDict[vnfc['name']]["image_id"] = image_id VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image') + VNFCDict[vnfc['name']]["count"] = vnfc.get('count', 1) if vnfc.get("boot-data"): VNFCDict[vnfc['name']]["boot_data"] = yaml.safe_dump(vnfc["boot-data"], default_flow_style=True, width=256) @@ -962,6 +967,7 @@ def new_vnf_v02(mydb, tenant_id, vnf_descriptor): #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id) VNFCDict[vnfc['name']]["image_id"] = image_id VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image') + VNFCDict[vnfc['name']]["count"] = vnfc.get('count', 1) if vnfc.get("boot-data"): VNFCDict[vnfc['name']]["boot_data"] = yaml.safe_dump(vnfc["boot-data"], default_flow_style=True, width=256) @@ -1665,6 +1671,7 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc logger.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM") #For each vnf net, we create it and we add it to instanceNetlist. + for sce_vnf in scenarioDict['vnfs']: for net in sce_vnf['nets']: #print "Net name: %s. Description: %s" % (net["name"], net["description"]) @@ -1696,6 +1703,17 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict) i = 0 for sce_vnf in scenarioDict['vnfs']: + vnf_availability_zones = [] + for vm in sce_vnf['vms']: + vm_av = vm.get('availability_zone') + if vm_av and vm_av not in vnf_availability_zones: + vnf_availability_zones.append(vm_av) + + # check if there is enough availability zones available at vim level. + if myvims[datacenter_id].availability_zone and vnf_availability_zones: + if len(vnf_availability_zones) > len(myvims[datacenter_id].availability_zone): + raise NfvoException('No enough availability zones at VIM for this deployment', HTTP_Bad_Request) + for vm in sce_vnf['vms']: i += 1 myVMDict = {} @@ -1782,8 +1800,16 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False) #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False) #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>" - vm_id = myvim.new_vminstance(myVMDict['name'],myVMDict['description'],myVMDict.get('start', None), - myVMDict['imageRef'],myVMDict['flavorRef'],myVMDict['networks']) + + if 'availability_zone' in myVMDict: + av_index = vnf_availability_zones.index(myVMDict['availability_zone']) + else: + av_index = None + + vm_id = myvim.new_vminstance(myVMDict['name'], myVMDict['description'], myVMDict.get('start', None), + myVMDict['imageRef'], myVMDict['flavorRef'], myVMDict['networks'], + availability_zone_index=av_index, + availability_zone_list=vnf_availability_zones) #print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id) vm['vim_id'] = vm_id rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id}) @@ -1813,10 +1839,10 @@ def start_scenario(mydb, tenant_id, scenario_id, instance_scenario_name, instanc def unify_cloud_config(cloud_config_preserve, cloud_config): - ''' join the cloud config information into cloud_config_preserve. + """ join the cloud config information into cloud_config_preserve. In case of conflict cloud_config_preserve preserves - None is admited - ''' + None is allowed + """ if not cloud_config_preserve and not cloud_config: return None @@ -1866,10 +1892,19 @@ def unify_cloud_config(cloud_config_preserve, cloud_config): new_cloud_config["boot-data-drive"] = cloud_config_preserve["boot-data-drive"] # user-data - if cloud_config and cloud_config.get("user-data") != None: - new_cloud_config["user-data"] = cloud_config["user-data"] - if cloud_config_preserve and cloud_config_preserve.get("user-data") != None: - new_cloud_config["user-data"] = cloud_config_preserve["user-data"] + new_cloud_config["user-data"] = [] + if cloud_config and cloud_config.get("user-data"): + if isinstance(cloud_config["user-data"], list): + new_cloud_config["user-data"] += cloud_config["user-data"] + else: + new_cloud_config["user-data"].append(cloud_config["user-data"]) + if cloud_config_preserve and cloud_config_preserve.get("user-data"): + if isinstance(cloud_config_preserve["user-data"], list): + new_cloud_config["user-data"] += cloud_config_preserve["user-data"] + else: + new_cloud_config["user-data"].append(cloud_config_preserve["user-data"]) + if not new_cloud_config["user-data"]: + del new_cloud_config["user-data"] # config files new_cloud_config["config-files"] = [] @@ -1979,14 +2014,30 @@ def create_instance(mydb, tenant_id, instance_dict): #logger.debug(">>>>>>> InstanceDict:\n{}".format(yaml.safe_dump(instance_dict,default_flow_style=False, width=256))) #logger.debug(">>>>>>> ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256))) - scenarioDict['datacenter_id'] = default_datacenter_id + uuid_list = [] + instance_name = instance_dict["name"] + instance_uuid = str(uuid4()) + uuid_list.append(instance_uuid) + db_instance_scenario = { + "uuid": instance_uuid, + "name": instance_name, + "tenant_id": tenant_id, + "scenario_id": scenarioDict['uuid'], + "datacenter_id": default_datacenter_id, + # filled bellow 'datacenter_tenant_id' + "description": instance_dict.get("description"), + } + db_ip_profiles=[] + if scenarioDict.get("cloud-config"): + db_instance_scenario["cloud_config"] = yaml.safe_dump(scenarioDict["cloud-config"], + default_flow_style=True, width=256) + vnf_net2instance = {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id + sce_net2instance = {} auxNetDict = {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id auxNetDict['scenario'] = {} logger.debug("Creating instance from scenario-dict:\n%s", yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)) #TODO remove - instance_name = instance_dict["name"] - instance_description = instance_dict.get("description") try: # 0 check correct parameters for net_name, net_instance_desc in instance_dict.get("networks",{}).iteritems(): @@ -2070,12 +2121,12 @@ def create_instance(mydb, tenant_id, instance_dict): #logger.debug(">>>>>>>> Merged dictionary") logger.debug("Creating instance scenario-dict MERGED:\n%s", yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)) - # 1. Creating new nets (sce_nets) in the VIM" + db_instance_nets = [] for sce_net in scenarioDict['nets']: - sce_net["vim_id_sites"]={} - descriptor_net = instance_dict.get("networks",{}).get(sce_net["name"],{}) + descriptor_net = instance_dict.get("networks",{}).get(sce_net["name"],{}) net_name = descriptor_net.get("vim-network-name") + sce_net2instance[sce_net['uuid']] = {} auxNetDict['scenario'][sce_net['uuid']] = {} sites = descriptor_net.get("sites", [ {} ]) @@ -2140,7 +2191,7 @@ def create_instance(mydb, tenant_id, instance_dict): if not create_network: raise NfvoException("No candidate VIM network found for " + filter_text, HTTP_Bad_Request ) else: - sce_net["vim_id_sites"][datacenter_id] = vim_nets[0]['id'] + vim_id = vim_nets[0]['id'] auxNetDict['scenario'][sce_net['uuid']][datacenter_id] = vim_nets[0]['id'] create_network = False if create_network: @@ -2150,13 +2201,41 @@ def create_instance(mydb, tenant_id, instance_dict): instance_tasks[task_id] = task tasks_to_launch[myvim_thread_id].append(task) #network_id = vim.new_network(net_vim_name, net_type, sce_net.get('ip_profile',None)) - sce_net["vim_id_sites"][datacenter_id] = task_id + vim_id = task_id auxNetDict['scenario'][sce_net['uuid']][datacenter_id] = task_id rollbackList.append({'what':'network', 'where':'vim', 'vim_id':datacenter_id, 'uuid':task_id}) sce_net["created"] = True + # fill database content + net_uuid = str(uuid4()) + uuid_list.append(net_uuid) + sce_net2instance[sce_net['uuid']][datacenter_id] = net_uuid + db_net = { + "uuid": net_uuid, + 'vim_net_id': vim_id, + "instance_scenario_id": instance_uuid, + "sce_net_id": sce_net["uuid"], + "created": create_network, + 'datacenter_id': datacenter_id, + 'datacenter_tenant_id': myvim_thread_id, + 'status': 'BUILD' if create_network else "ACTIVE" + } + db_instance_nets.append(db_net) + if 'ip_profile' in sce_net: + db_ip_profile={ + 'instance_net_id': net_uuid, + 'ip_version': sce_net['ip_profile']['ip_version'], + 'subnet_address': sce_net['ip_profile']['subnet_address'], + 'gateway_address': sce_net['ip_profile']['gateway_address'], + 'dns_address': sce_net['ip_profile']['dns_address'], + 'dhcp_enabled': sce_net['ip_profile']['dhcp_enabled'], + 'dhcp_start_address': sce_net['ip_profile']['dhcp_start_address'], + 'dhcp_count': sce_net['ip_profile']['dhcp_count'], + } + db_ip_profiles.append(db_ip_profile) + # 2. Creating new nets (vnf internal nets) in the VIM" - #For each vnf net, we create it and we add it to instanceNetlist. + # For each vnf net, we create it and we add it to instanceNetlist. for sce_vnf in scenarioDict['vnfs']: for net in sce_vnf['nets']: if sce_vnf.get("datacenter"): @@ -2178,20 +2257,65 @@ def create_instance(mydb, tenant_id, instance_dict): instance_tasks[task_id] = task tasks_to_launch[myvim_thread_id].append(task) # network_id = vim.new_network(net_name, net_type, net.get('ip_profile',None)) - net['vim_id'] = task_id + vim_id = task_id + if sce_vnf['uuid'] not in vnf_net2instance: + vnf_net2instance[sce_vnf['uuid']] = {} + vnf_net2instance[sce_vnf['uuid']][net['uuid']] = task_id if sce_vnf['uuid'] not in auxNetDict: auxNetDict[sce_vnf['uuid']] = {} auxNetDict[sce_vnf['uuid']][net['uuid']] = task_id rollbackList.append({'what':'network','where':'vim','vim_id':datacenter_id,'uuid':task_id}) net["created"] = True - - #print "auxNetDict:" - #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False) + # fill database content + net_uuid = str(uuid4()) + uuid_list.append(net_uuid) + vnf_net2instance[sce_vnf['uuid']][net['uuid']] = net_uuid + db_net = { + "uuid": net_uuid, + 'vim_net_id': vim_id, + "instance_scenario_id": instance_uuid, + "net_id": net["uuid"], + "created": True, + 'datacenter_id': datacenter_id, + 'datacenter_tenant_id': myvim_thread_id, + } + db_instance_nets.append(db_net) + if 'ip_profile' in net: + db_ip_profile = { + 'instance_net_id': net_uuid, + 'ip_version': net['ip_profile']['ip_version'], + 'subnet_address': net['ip_profile']['subnet_address'], + 'gateway_address': net['ip_profile']['gateway_address'], + 'dns_address': net['ip_profile']['dns_address'], + 'dhcp_enabled': net['ip_profile']['dhcp_enabled'], + 'dhcp_start_address': net['ip_profile']['dhcp_start_address'], + 'dhcp_count': net['ip_profile']['dhcp_count'], + } + db_ip_profiles.append(db_ip_profile) + + #print "vnf_net2instance:" + #print yaml.safe_dump(vnf_net2instance, indent=4, default_flow_style=False) # 3. Creating new vm instances in the VIM + db_instance_vnfs = [] + db_instance_vms = [] + db_instance_interfaces = [] #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict) - for sce_vnf in scenarioDict['vnfs']: + sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name']) + #for sce_vnf in scenarioDict['vnfs']: + for sce_vnf in sce_vnf_list: + vnf_availability_zones = [] + for vm in sce_vnf['vms']: + vm_av = vm.get('availability_zone') + if vm_av and vm_av not in vnf_availability_zones: + vnf_availability_zones.append(vm_av) + + # check if there is enough availability zones available at vim level. + if myvims[datacenter_id].availability_zone and vnf_availability_zones: + if len(vnf_availability_zones) > len(myvims[datacenter_id].availability_zone): + raise NfvoException('No enough availability zones at VIM for this deployment', HTTP_Bad_Request) + if sce_vnf.get("datacenter"): vim = myvims[ sce_vnf["datacenter"] ] myvim_thread_id = myvim_threads_id[ sce_vnf["datacenter"] ] @@ -2200,12 +2324,24 @@ def create_instance(mydb, tenant_id, instance_dict): vim = myvims[ default_datacenter_id ] myvim_thread_id = myvim_threads_id[ default_datacenter_id ] datacenter_id = default_datacenter_id - sce_vnf["datacenter_id"] = datacenter_id + sce_vnf["datacenter_id"] = datacenter_id i = 0 + + vnf_uuid = str(uuid4()) + uuid_list.append(vnf_uuid) + db_instance_vnf = { + 'uuid': vnf_uuid, + 'instance_scenario_id': instance_uuid, + 'vnf_id': sce_vnf['vnf_id'], + 'sce_vnf_id': sce_vnf['uuid'], + 'datacenter_id': datacenter_id, + 'datacenter_tenant_id': myvim_thread_id, + } + db_instance_vnfs.append(db_instance_vnf) + for vm in sce_vnf['vms']: - i += 1 myVMDict = {} - myVMDict['name'] = "{}.{}.{}".format(instance_name,sce_vnf['name'],chr(96+i)) + myVMDict['name'] = "{}.{}.{}".format(instance_name[:64], sce_vnf['name'][:64], vm["name"][:64]) myVMDict['description'] = myVMDict['name'][0:99] # if not startvms: # myVMDict['start'] = "no" @@ -2238,9 +2374,11 @@ def create_instance(mydb, tenant_id, instance_dict): vm['vim_flavor_id'] = flavor_id myVMDict['imageRef'] = vm['vim_image_id'] myVMDict['flavorRef'] = vm['vim_flavor_id'] + myVMDict['availability_zone'] = vm.get('availability_zone') myVMDict['networks'] = [] task_depends = {} #TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true + db_vm_ifaces = [] for iface in vm['interfaces']: netDict = {} if iface['type']=="data": @@ -2287,48 +2425,114 @@ def create_instance(mydb, tenant_id, instance_dict): #print vnf_iface if vnf_iface['interface_id']==iface['uuid']: netDict['net_id'] = auxNetDict['scenario'][ vnf_iface['sce_net_id'] ][datacenter_id] + instance_net_id = sce_net2instance[ vnf_iface['sce_net_id'] ][datacenter_id] break else: netDict['net_id'] = auxNetDict[ sce_vnf['uuid'] ][ iface['net_id'] ] + instance_net_id = vnf_net2instance[ sce_vnf['uuid'] ][ iface['net_id'] ] if netDict.get('net_id') and is_task_id(netDict['net_id']): task_depends[netDict['net_id']] = instance_tasks[netDict['net_id']] #skip bridge ifaces not connected to any net #if 'net_id' not in netDict or netDict['net_id']==None: # continue myVMDict['networks'].append(netDict) - #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>" - #print myVMDict['name'] - #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False) - #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False) - #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>" + db_vm_iface={ + # "uuid" + # 'instance_vm_id': instance_vm_uuid, + "instance_net_id": instance_net_id, + 'interface_id': iface['uuid'], + # 'vim_interface_id': , + 'type': 'external' if iface['external_name'] is not None else 'internal', + 'ip_address': iface.get('ip_address'), + 'floating_ip': int(iface.get('floating-ip', False)), + 'port_security': int(iface.get('port-security', True)) + } + db_vm_ifaces.append(db_vm_iface) + # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>" + # print myVMDict['name'] + # print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False) + # print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False) + # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>" if vm.get("boot_data"): cloud_config_vm = unify_cloud_config(vm["boot_data"], cloud_config) else: cloud_config_vm = cloud_config - task = new_task("new-vm", (myVMDict['name'], myVMDict['description'], myVMDict.get('start', None), - myVMDict['imageRef'], myVMDict['flavorRef'], myVMDict['networks'], - cloud_config_vm, myVMDict['disks']), depends=task_depends) - instance_tasks[task["id"]] = task - tasks_to_launch[myvim_thread_id].append(task) - vm_id = task["id"] - vm['vim_id'] = vm_id - rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id}) - #put interface uuid back to scenario[vnfs][vms[[interfaces] - for net in myVMDict['networks']: - if "vim_id" in net: - for iface in vm['interfaces']: - if net["name"]==iface["internal_name"]: - iface["vim_id"]=net["vim_id"] - break + if myVMDict.get('availability_zone'): + av_index = vnf_availability_zones.index(myVMDict['availability_zone']) + else: + av_index = None + for vm_index in range(0, vm.get('count', 1)): + vm_index_name = "" + if vm.get('count', 1) > 1: + vm_index_name += "." + chr(97 + vm_index) + task = new_task("new-vm", (myVMDict['name']+vm_index_name, myVMDict['description'], + myVMDict.get('start', None), myVMDict['imageRef'], + myVMDict['flavorRef'], myVMDict['networks'], + cloud_config_vm, myVMDict['disks'], av_index, + vnf_availability_zones), depends=task_depends) + instance_tasks[task["id"]] = task + tasks_to_launch[myvim_thread_id].append(task) + vm_id = task["id"] + vm['vim_id'] = vm_id + rollbackList.append({'what':'vm','where':'vim','vim_id':datacenter_id,'uuid':vm_id}) + # put interface uuid back to scenario[vnfs][vms[[interfaces] + for net in myVMDict['networks']: + if "vim_id" in net: + for iface in vm['interfaces']: + if net["name"]==iface["internal_name"]: + iface["vim_id"]=net["vim_id"] + break + vm_uuid = str(uuid4()) + uuid_list.append(vm_uuid) + db_vm = { + "uuid": vm_uuid, + 'instance_vnf_id': vnf_uuid, + "vim_vm_id": vm_id, + "vm_id": vm["uuid"], + # "status": + } + db_instance_vms.append(db_vm) + for db_vm_iface in db_vm_ifaces: + iface_uuid = str(uuid4()) + uuid_list.append(iface_uuid) + db_vm_iface_instance = { + "uuid": iface_uuid, + "instance_vm_id": vm_uuid + } + db_vm_iface_instance.update(db_vm_iface) + if db_vm_iface_instance.get("ip_address"): # increment ip_address + ip = db_vm_iface_instance.get("ip_address") + i = ip.rfind(".") + if i > 0: + try: + i += 1 + ip = ip[i:] + str(int(ip[:i]) +1) + db_vm_iface_instance["ip_address"] = ip + except: + db_vm_iface_instance["ip_address"] = None + db_instance_interfaces.append(db_vm_iface_instance) + scenarioDict["datacenter2tenant"] = myvim_threads_id + + db_instance_scenario['datacenter_tenant_id'] = myvim_threads_id[default_datacenter_id] + db_instance_scenario['datacenter_id'] = default_datacenter_id + db_tables=[ + {"instance_scenarios": db_instance_scenario}, + {"instance_vnfs": db_instance_vnfs}, + {"instance_nets": db_instance_nets}, + {"ip_profiles": db_ip_profiles}, + {"instance_vms": db_instance_vms}, + {"instance_interfaces": db_instance_interfaces}, + ] + logger.debug("create_instance Deployment done scenarioDict: %s", - yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False) ) - instance_id = mydb.new_instance_scenario_as_a_whole(tenant_id,instance_name, instance_description, scenarioDict) + yaml.safe_dump(db_tables, indent=4, default_flow_style=False) ) + mydb.new_rows(db_tables, uuid_list) for myvim_thread_id,task_list in tasks_to_launch.items(): for task in task_list: vim_threads["running"][myvim_thread_id].insert_task(task) - global_instance_tasks[instance_id] = instance_tasks + global_instance_tasks[instance_uuid] = instance_tasks # Update database with those ended instance_tasks # for task in instance_tasks.values(): # if task["status"] == "ok": @@ -2338,7 +2542,7 @@ def create_instance(mydb, tenant_id, instance_dict): # elif task["name"] == "new-net": # mydb.update_rows("instance_nets", UPDATE={"vim_net_id": task["result"]}, # WHERE={"vim_net_id": task["id"]}) - return mydb.get_instance_scenario(instance_id) + return mydb.get_instance_scenario(instance_uuid) except (NfvoException, vimconn.vimconnException,db_base_Exception) as e: message = rollback(mydb, myvims, rollbackList) if isinstance(e, db_base_Exception): @@ -2954,7 +3158,7 @@ def edit_datacenter_to_tenant(mydb, nfvo_tenant, datacenter_id, vim_tenant_id=No def deassociate_datacenter_to_tenant(mydb, tenant_id, datacenter, vim_tenant_id=None): #get datacenter info - datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, None, datacenter) + datacenter_id, myvim = get_datacenter_by_name_uuid(mydb, tenant_id, datacenter) #get nfvo_tenant info if not tenant_id or tenant_id=="any": diff --git a/osm_ro/nfvo_db.py b/osm_ro/nfvo_db.py index ac392c6d..071d03ab 100644 --- a/osm_ro/nfvo_db.py +++ b/osm_ro/nfvo_db.py @@ -38,6 +38,7 @@ tables_with_createdat_field=["datacenters","instance_nets","instance_scenarios", "interfaces","nets","nfvo_tenants","scenarios","sce_interfaces","sce_nets", "sce_vnfs","tenants_datacenters","datacenter_tenants","vms","vnfs", "datacenter_nets"] + class nfvo_db(db_base.db_base): def __init__(self, host=None, user=None, passwd=None, database=None, log_name='openmano.db', log_level=None): db_base.db_base.__init__(self, host, user, passwd, database, log_name, log_level) @@ -585,15 +586,19 @@ class nfvo_db(db_base.db_base): scenario_dict['vnfs'] = self.cur.fetchall() for vnf in scenario_dict['vnfs']: #sce_interfaces - cmd = "SELECT scei.uuid,scei.sce_net_id,scei.interface_id,i.external_name,scei.ip_address FROM sce_interfaces as scei join interfaces as i on scei.interface_id=i.uuid WHERE scei.sce_vnf_id='{}' ORDER BY scei.created_at".format(vnf['uuid']) + cmd = "SELECT scei.uuid,scei.sce_net_id,scei.interface_id,i.external_name,scei.ip_address"\ + " FROM sce_interfaces as scei join interfaces as i on scei.interface_id=i.uuid"\ + " WHERE scei.sce_vnf_id='{}' ORDER BY scei.created_at".format(vnf['uuid']) self.logger.debug(cmd) self.cur.execute(cmd) vnf['interfaces'] = self.cur.fetchall() #vms - cmd = "SELECT vms.uuid as uuid, flavor_id, image_id, vms.name as name, vms.description as description, vms.boot_data as boot_data " \ - " FROM vnfs join vms on vnfs.uuid=vms.vnf_id " \ - " WHERE vnfs.uuid='" + vnf['vnf_id'] +"'" \ - " ORDER BY vms.created_at" + cmd = "SELECT vms.uuid as uuid, flavor_id, image_id, vms.name as name," \ + " vms.description as description, vms.boot_data as boot_data, count," \ + " vms.availability_zone as availability_zone" \ + " FROM vnfs join vms on vnfs.uuid=vms.vnf_id" \ + " WHERE vnfs.uuid='" + vnf['vnf_id'] + "'" \ + " ORDER BY vms.created_at" self.logger.debug(cmd) self.cur.execute(cmd) vnf['vms'] = self.cur.fetchall() @@ -720,6 +725,43 @@ class nfvo_db(db_base.db_base): self._format_error(e, tries, "delete", "instances running") tries -= 1 + def new_rows(self, tables, uuid_list=None): + """ + Make a transactional insertion of rows at several tables + :param tables: list with dictionary where the keys are the table names and the values are a row or row list + with the values to be inserted at the table. Each row is a dictionary with the key values. E.g.: + tables = [ + {"table1": [ {"column1": value, "column2: value, ... }, {"column1": value, "column2: value, ... }, ...], + {"table2": [ {"column1": value, "column2: value, ... }, {"column1": value, "column2: value, ... }, ...], + {"table3": {"column1": value, "column2: value, ... } + } + :param uuid_list: list of created uuids, first one is the root (#TODO to store at uuid table) + :return: None if success, raise exception otherwise + """ + tries = 2 + while tries: + created_time = time.time() + try: + with self.con: + self.cur = self.con.cursor() + for table in tables: + for table_name, row_list in table.items(): + index = 0 + if isinstance(row_list, dict): + row_list = (row_list, ) #create a list with the single value + for row in row_list: + if table_name in self.tables_with_created_field: + created_time_param = created_time + index*0.00001 + else: + created_time_param=0 + self._new_row_internal(table_name, row, add_uuid=False, root_uuid=None, + created_time=created_time_param) + index += 1 + return + except (mdb.Error, AttributeError) as e: + self._format_error(e, tries) + tries -= 1 + def new_instance_scenario_as_a_whole(self,tenant_id,instance_scenario_name,instance_scenario_description,scenarioDict): tries = 2 while tries: diff --git a/osm_ro/openmano_schemas.py b/osm_ro/openmano_schemas.py index 7d218ec1..fb12d9f1 100644 --- a/osm_ro/openmano_schemas.py +++ b/osm_ro/openmano_schemas.py @@ -386,7 +386,7 @@ internal_connection_schema = { "name": name_schema, "description":description_schema, "type":{"type":"string", "enum":["bridge","data","ptp"]}, - "elements": {"type" : "array", "items": internal_connection_element_schema, "minItems":2} + "elements": {"type" : "array", "items": internal_connection_element_schema, "minItems":1} }, "required": ["name", "type", "elements"], "additionalProperties": False @@ -400,7 +400,7 @@ internal_connection_schema_v02 = { "type": {"type": "string", "enum":["e-line", "e-lan"]}, "implementation": {"type": "string", "enum":["overlay", "underlay"]}, "ip-profile": ip_profile_schema, - "elements": {"type" : "array", "items": internal_connection_element_schema_v02, "minItems":2} + "elements": {"type" : "array", "items": internal_connection_element_schema_v02, "minItems":1} }, "required": ["name", "type", "implementation", "elements"], "additionalProperties": False @@ -541,8 +541,10 @@ vnfc_schema = { "properties":{ "name": name_schema, "description": description_schema, - "VNFC image": {"oneOf": [path_schema, http_schema]}, + "count": integer1_schema, "image name": name_schema, + "availability_zone": name_schema, + "VNFC image": {"oneOf": [path_schema, http_schema]}, "image checksum": checksum_schema, "image metadata": metadata_schema, #"cloud-config": cloud_config_schema, #common for all vnfs in the scenario @@ -592,6 +594,7 @@ vnfd_schema_v01 = { "properties":{ "name": name_schema, "description": description_schema, + "class": nameshort_schema, "public": {"type" : "boolean"}, "physical": {"type" : "boolean"}, diff --git a/osm_ro/vim_thread.py b/osm_ro/vim_thread.py index 9f396a26..0074dfe9 100644 --- a/osm_ro/vim_thread.py +++ b/osm_ro/vim_thread.py @@ -144,8 +144,9 @@ class vim_thread(threading.Thread): #delete old port if task_interface.get("sdn_port_id"): try: - self.ovim.delete_port(task_interface["sdn_port_id"]) - task_interface["sdn_port_id"] = None + with self.db_lock: + self.ovim.delete_port(task_interface["sdn_port_id"]) + task_interface["sdn_port_id"] = None except ovimException as e: self.logger.error("ovimException deleting external_port={} ".format( task_interface["sdn_port_id"]) + str(e), exc_info=True) @@ -174,11 +175,15 @@ class vim_thread(threading.Thread): continue else: db_iface = db_ifaces[0] - #If there is no sdn_net_id, check if it is because an already created vim network is being used - #in that case, the sdn_net_id will be in that entry of the instance_nets table + # If there is no sdn_net_id, check if it is because an already created vim network is being used + # in that case, the sdn_net_id will be in that entry of the instance_nets table if not db_iface.get("sdn_net_id"): - result = self.db.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', - WHERE={'vim_net_id': db_iface.get("vim_net_id"), 'instance_scenario_id': None, "datacenter_tenant_id": self.datacenter_tenant_id}) + with self.db_lock: + result = self.db.get_rows( + SELECT=('sdn_net_id',), FROM='instance_nets', + WHERE={'vim_net_id': db_iface.get("vim_net_id"), + 'instance_scenario_id': None, + 'datacenter_tenant_id': self.datacenter_tenant_id}) if len(result) == 1: db_iface["sdn_net_id"] = result[0]['sdn_net_id'] @@ -187,15 +192,16 @@ class vim_thread(threading.Thread): sdn_port_name = sdn_net_id + "." + db_iface["vm_id"] sdn_port_name = sdn_port_name[:63] try: - sdn_port_id = self.ovim.new_external_port( - {"compute_node": interface["compute_node"], - "pci": interface["pci"], - "vlan": interface.get("vlan"), - "net_id": sdn_net_id, - "region": self.vim["config"]["datacenter_id"], - "name": sdn_port_name, - "mac": interface.get("mac_address")}) - interface["sdn_port_id"] = sdn_port_id + with self.db_lock: + sdn_port_id = self.ovim.new_external_port( + {"compute_node": interface["compute_node"], + "pci": interface["pci"], + "vlan": interface.get("vlan"), + "net_id": sdn_net_id, + "region": self.vim["config"]["datacenter_id"], + "name": sdn_port_name, + "mac": interface.get("mac_address")}) + interface["sdn_port_id"] = sdn_port_id except (ovimException, Exception) as e: self.logger.error( "ovimException creating new_external_port compute_node={} " \ @@ -248,7 +254,8 @@ class vim_thread(threading.Thread): if db_net.get("sdn_net_id"): # get ovim status try: - sdn_net = self.ovim.show_network(db_net["sdn_net_id"]) + with self.db_lock: + sdn_net = self.ovim.show_network(db_net["sdn_net_id"]) if sdn_net["status"] == "ERROR": if not vim_info.get("error_msg"): vim_info["error_msg"] = sdn_net["error_msg"] @@ -421,7 +428,8 @@ class vim_thread(threading.Thread): net_name, net_type, vim_net['encapsulation'])) network["vlan"] = vim_net.get('segmentation_id') try: - sdn_net_id = self.ovim.new_network(network) + with self.db_lock: + sdn_net_id = self.ovim.new_network(network) except (ovimException, Exception) as e: self.logger.error("task=%s cannot create SDN network vim_net_id=%s input='%s' ovimException='%s'", str(task_id), net_id, str(network), str(e)) @@ -531,7 +539,8 @@ class vim_thread(threading.Thread): for iface in interfaces: if iface.get("sdn_port_id"): try: - self.ovim.delete_port(iface["sdn_port_id"]) + with self.db_lock: + self.ovim.delete_port(iface["sdn_port_id"]) except ovimException as e: self.logger.error("ovimException deleting external_port={} at VM vim_id={} deletion ".format( iface["sdn_port_id"], vm_id) + str(e), exc_info=True) @@ -559,17 +568,19 @@ class vim_thread(threading.Thread): self._remove_refresh("get-net", net_id) result = self.vim.delete_network(net_id) if sdn_net_id: - #Delete any attached port to this sdn network - #At this point, there will be ports associated to this network in case it was manually done using 'openmano vim-net-sdn-attach' + # Delete any attached port to this sdn network + # At this point, there will be ports associated to this network in case it was manually done using 'openmano vim-net-sdn-attach' try: - port_list = self.ovim.get_ports(columns={'uuid'}, filter={'name': 'external_port', 'net_id': sdn_net_id}) + with self.db_lock: + port_list = self.ovim.get_ports(columns={'uuid'}, filter={'name': 'external_port', 'net_id': sdn_net_id}) except ovimException as e: raise vimconn.vimconnException( "ovimException obtaining external ports for net {}. ".format(sdn_net_id) + str(e)) for port in port_list: try: - self.ovim.delete_port(port['uuid']) + with self.db_lock: + self.ovim.delete_port(port['uuid']) except ovimException as e: raise vimconn.vimconnException( "ovimException deleting port {} for net {}. ".format(port['uuid'], sdn_net_id) + str(e)) diff --git a/osm_ro/vimconn.py b/osm_ro/vimconn.py index f1f6b2d8..8b6f80ee 100644 --- a/osm_ro/vimconn.py +++ b/osm_ro/vimconn.py @@ -82,6 +82,7 @@ class vimconnNotImplemented(vimconnException): def __init__(self, message, http_code=HTTP_Not_Implemented): vimconnException.__init__(self, message, http_code) + class vimconnector(): """Abstract base class for all the VIM connector plugins These plugins must implement a vimconnector class derived from this @@ -115,6 +116,7 @@ class vimconnector(): self.user = user self.passwd = passwd self.config = config + self.availability_zone = None self.logger = logging.getLogger('openmano.vim') if log_level: self.logger.setLevel( getattr(logging, log_level) ) @@ -353,8 +355,8 @@ class vimconnector(): """ raise vimconnNotImplemented( "Should have implemented this" ) - def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, - disk_list=None): + def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None, + availability_zone_index=None, availability_zone_list=None): """Adds a VM instance to VIM Params: 'start': (boolean) indicates if VM must start or created in pause mode. @@ -385,7 +387,8 @@ class vimconnector(): 'users': (optional) list of users to be inserted, each item is a dict with: 'name': (mandatory) user name, 'key-pairs': (optional) list of strings with the public key to be inserted to the user - 'user-data': (optional) string is a text script to be passed directly to cloud-init + 'user-data': (optional) can be a string with the text script to be passed directly to cloud-init, + or a list of strings, each one contains a script to be passed, usually with a MIMEmultipart file 'config-files': (optional). List of files to be transferred. Each item is a dict with: 'dest': (mandatory) string with the destination absolute path 'encoding': (optional, by default text). Can be one of: @@ -397,6 +400,9 @@ class vimconnector(): 'disk_list': (optional) list with additional disks to the VM. Each item is a dict with: 'image_id': (optional). VIM id of an existing image. If not provided an empty disk must be mounted 'size': (mandatory) string with the size of the disk in GB + availability_zone_index: Index of availability_zone_list to use for this this VM. None if not AV required + availability_zone_list: list of availability zones given by user in the VNFD descriptor. Ignore if + availability_zone_index is None Returns the instance identifier or raises an exception on error """ raise vimconnNotImplemented( "Should have implemented this" ) diff --git a/osm_ro/vimconn_aws.py b/osm_ro/vimconn_aws.py index 6621345b..3cccbfcf 100644 --- a/osm_ro/vimconn_aws.py +++ b/osm_ro/vimconn_aws.py @@ -590,7 +590,7 @@ class vimconnector(vimconn.vimconnector): self.format_vimconn_exception(e) def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, - disk_list=None): + disk_list=None, availability_zone_index=None, availability_zone_list=None): """Create a new VM/instance in AWS Params: name decription diff --git a/osm_ro/vimconn_openstack.py b/osm_ro/vimconn_openstack.py index bcb80ae1..319f8c1a 100644 --- a/osm_ro/vimconn_openstack.py +++ b/osm_ro/vimconn_openstack.py @@ -35,6 +35,8 @@ import netaddr import time import yaml import random +import sys +import re from novaclient import client as nClient, exceptions as nvExceptions from keystoneauth1.identity import v2, v3 @@ -50,8 +52,11 @@ from httplib import HTTPException from neutronclient.neutron import client as neClient from neutronclient.common import exceptions as neExceptions from requests.exceptions import ConnectionError +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText -'''contain the openstack virtual machine status to openmano status''' + +"""contain the openstack virtual machine status to openmano status""" vmStatus2manoFormat={'ACTIVE':'ACTIVE', 'PAUSED':'PAUSED', 'SUSPENDED': 'SUSPENDED', @@ -64,7 +69,7 @@ netStatus2manoFormat={'ACTIVE':'ACTIVE','PAUSED':'PAUSED','INACTIVE':'INACTIVE', #global var to have a timeout creating and deleting volumes volume_timeout = 60 -server_timeout = 60 +server_timeout = 300 class vimconnector(vimconn.vimconnector): def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, @@ -77,6 +82,15 @@ class vimconnector(vimconn.vimconnector): if api_version and api_version not in ('v3.3', 'v2.0', '2', '3'): raise vimconn.vimconnException("Invalid value '{}' for config:APIversion. " "Allowed values are 'v3.3', 'v2.0', '2' or '3'".format(api_version)) + vim_type = config.get('vim_type') + if vim_type and vim_type not in ('vio', 'VIO'): + raise vimconn.vimconnException("Invalid value '{}' for config:vim_type." + "Allowed values are 'vio' or 'VIO'".format(vim_type)) + + if config.get('dataplane_net_vlan_range') is not None: + #validate vlan ranges provided by user + self._validate_vlan_ranges(config.get('dataplane_net_vlan_range')) + vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level, config) @@ -84,17 +98,31 @@ class vimconnector(vimconn.vimconnector): if not url: raise TypeError, 'url param can not be NoneType' self.persistent_info = persistent_info + self.availability_zone = persistent_info.get('availability_zone', None) self.session = persistent_info.get('session', {'reload_client': True}) self.nova = self.session.get('nova') self.neutron = self.session.get('neutron') self.cinder = self.session.get('cinder') self.glance = self.session.get('glance') + self.glancev1 = self.session.get('glancev1') self.keystone = self.session.get('keystone') self.api_version3 = self.session.get('api_version3') + self.vim_type = self.config.get("vim_type") + if self.vim_type: + self.vim_type = self.vim_type.upper() + if self.config.get("use_internal_endpoint"): + self.endpoint_type = "internalURL" + else: + self.endpoint_type = None self.logger = logging.getLogger('openmano.vim.openstack') + + ####### VIO Specific Changes ######### + if self.vim_type == "VIO": + self.logger = logging.getLogger('openmano.vim.vio') + if log_level: - self.logger.setLevel( getattr(logging, log_level) ) + self.logger.setLevel( getattr(logging, log_level)) def __getitem__(self, index): """Get individuals parameters. @@ -144,16 +172,36 @@ class vimconnector(vimconn.vimconnector): tenant_id=self.tenant_id) sess = session.Session(auth=auth, verify=not self.insecure) if self.api_version3: - self.keystone = ksClient_v3.Client(session=sess) + self.keystone = ksClient_v3.Client(session=sess, endpoint_type=self.endpoint_type) else: - self.keystone = ksClient_v2.Client(session=sess) + self.keystone = ksClient_v2.Client(session=sess, endpoint_type=self.endpoint_type) self.session['keystone'] = self.keystone - self.nova = self.session['nova'] = nClient.Client("2.1", session=sess) - self.neutron = self.session['neutron'] = neClient.Client('2.0', session=sess) - self.cinder = self.session['cinder'] = cClient.Client(2, session=sess) - self.glance = self.session['glance'] = glClient.Client(2, session=sess) + # In order to enable microversion functionality an explicit microversion must be specified in 'config'. + # This implementation approach is due to the warning message in + # https://developer.openstack.org/api-guide/compute/microversions.html + # where it is stated that microversion backwards compatibility is not guaranteed and clients should + # always require an specific microversion. + # To be able to use 'device role tagging' functionality define 'microversion: 2.32' in datacenter config + version = self.config.get("microversion") + if not version: + version = "2.1" + self.nova = self.session['nova'] = nClient.Client(str(version), session=sess, endpoint_type=self.endpoint_type) + self.neutron = self.session['neutron'] = neClient.Client('2.0', session=sess, endpoint_type=self.endpoint_type) + self.cinder = self.session['cinder'] = cClient.Client(2, session=sess, endpoint_type=self.endpoint_type) + if self.endpoint_type == "internalURL": + glance_service_id = self.keystone.services.list(name="glance")[0].id + glance_endpoint = self.keystone.endpoints.list(glance_service_id, interface="internal")[0].url + else: + glance_endpoint = None + self.glance = self.session['glance'] = glClient.Client(2, session=sess, endpoint=glance_endpoint) + #using version 1 of glance client in new_image() + self.glancev1 = self.session['glancev1'] = glClient.Client('1', session=sess, + endpoint=glance_endpoint) self.session['reload_client'] = False self.persistent_info['session'] = self.session + # add availablity zone info inside self.persistent_info + self._set_availablity_zones() + self.persistent_info['availability_zone'] = self.availability_zone def __net_os2mano(self, net_list_dict): '''Transform the net openstack format to mano format @@ -255,6 +303,19 @@ class vimconnector(vimconn.vimconnector): network_dict["provider:network_type"] = "vlan" if vlan!=None: network_dict["provider:network_type"] = vlan + + ####### VIO Specific Changes ######### + if self.vim_type == "VIO": + if vlan is not None: + network_dict["provider:segmentation_id"] = vlan + else: + if self.config.get('dataplane_net_vlan_range') is None: + raise vimconn.vimconnConflictException("You must provide "\ + "'dataplane_net_vlan_range' in format [start_ID - end_ID]"\ + "at config value before creating sriov network with vlan tag") + + network_dict["provider:segmentation_id"] = self._genrate_vlanID() + network_dict["shared"]=shared new_net=self.neutron.create_network({'network':network_dict}) #print new_net @@ -484,7 +545,7 @@ class vimconnector(vimconn.vimconnector): while name in fl_names: name_suffix += 1 name = flavor_data['name']+"-" + str(name_suffix) - + ram = flavor_data.get('ram',64) vcpus = flavor_data.get('vcpus',1) numa_properties=None @@ -500,6 +561,9 @@ class vimconnector(vimconn.vimconnector): numa_properties["hw:mem_page_size"] = "large" numa_properties["hw:cpu_policy"] = "dedicated" numa_properties["hw:numa_mempolicy"] = "strict" + if self.vim_type == "VIO": + numa_properties["vmware:extra_config"] = '{"numa.nodeAffinity":"0"}' + numa_properties["vmware:latency_sensitivity_level"] = "high" for numa in numas: #overwrite ram and vcpus ram = numa['memory']*1024 @@ -530,7 +594,7 @@ class vimconnector(vimconn.vimconnector): vcpus, flavor_data.get('disk',1), is_public=flavor_data.get('is_public', True) - ) + ) #add metadata if numa_properties: new_flavor.set_keys(numa_properties) @@ -564,9 +628,6 @@ class vimconnector(vimconn.vimconnector): metadata: metadata of the image Returns the image_id ''' - # ALF TODO: revise and change for the new method or session - #using version 1 of glance client - glancev1 = gl1Client.Client('1',self.glance_endpoint, token=self.keystone.auth_token, **self.k_creds) #TODO check k_creds vs n_creds retry=0 max_retries=3 while retry= 2.32: + port["tag"] = new_port["port"]["name"] + net_list_vim.append(port) if net.get('floating_ip', False): net['exit_on_floating_ip_error'] = True @@ -788,14 +979,17 @@ class vimconnector(vimconn.vimconnector): #cloud config userdata=None config_drive = None + userdata_list = [] if isinstance(cloud_config, dict): if cloud_config.get("user-data"): - userdata=cloud_config["user-data"] + if isinstance(cloud_config["user-data"], str): + userdata_list.append(cloud_config["user-data"]) + else: + for u in cloud_config["user-data"]: + userdata_list.append(u) if cloud_config.get("boot-data-drive") != None: config_drive = cloud_config["boot-data-drive"] if cloud_config.get("config-files") or cloud_config.get("users") or cloud_config.get("key-pairs"): - if userdata: - raise vimconn.vimconnConflictException("Cloud-config cannot contain both 'userdata' and 'config-files'/'users'/'key-pairs'") userdata_dict={} #default user if cloud_config.get("key-pairs"): @@ -829,8 +1023,9 @@ class vimconnector(vimconn.vimconnector): if file.get("owner"): file_info["owner"] = file["owner"] userdata_dict["write_files"].append(file_info) - userdata = "#cloud-config\n" - userdata += yaml.safe_dump(userdata_dict, indent=4, default_flow_style=False) + userdata_list.append("#cloud-config\n" + yaml.safe_dump(userdata_dict, indent=4, + default_flow_style=False)) + userdata = self._create_mimemultipart(userdata_list) self.logger.debug("userdata: %s", userdata) elif isinstance(cloud_config, str): userdata = cloud_config @@ -874,15 +1069,17 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException('Timeout creating volumes for instance ' + name, http_code=vimconn.HTTP_Request_Timeout) - - self.logger.debug("nova.servers.create({}, {}, {}, nics={}, meta={}, security_groups={}," \ - "availability_zone={}, key_name={}, userdata={}, config_drive={}, " \ - "block_device_mapping={})".format(name, image_id, flavor_id, net_list_vim, - metadata, security_groups, self.config.get('availability_zone'), - self.config.get('keypair'), userdata, config_drive, block_device_mapping)) + # get availability Zone + vm_av_zone = self._get_vm_availability_zone(availability_zone_index, availability_zone_list) + + self.logger.debug("nova.servers.create({}, {}, {}, nics={}, meta={}, security_groups={}, " + "availability_zone={}, key_name={}, userdata={}, config_drive={}, " + "block_device_mapping={})".format(name, image_id, flavor_id, net_list_vim, metadata, + security_groups, vm_av_zone, self.config.get('keypair'), + userdata, config_drive, block_device_mapping)) server = self.nova.servers.create(name, image_id, flavor_id, nics=net_list_vim, meta=metadata, security_groups=security_groups, - availability_zone=self.config.get('availability_zone'), + availability_zone=vm_av_zone, key_name=self.config.get('keypair'), userdata=userdata, config_drive=config_drive, @@ -1263,6 +1460,67 @@ class vimconnector(vimconn.vimconnector): self._format_exception(e) #TODO insert exception vimconn.HTTP_Unauthorized + ####### VIO Specific Changes ######### + def _genrate_vlanID(self): + """ + Method to get unused vlanID + Args: + None + Returns: + vlanID + """ + #Get used VLAN IDs + usedVlanIDs = [] + networks = self.get_network_list() + for net in networks: + if net.get('provider:segmentation_id'): + usedVlanIDs.append(net.get('provider:segmentation_id')) + used_vlanIDs = set(usedVlanIDs) + + #find unused VLAN ID + for vlanID_range in self.config.get('dataplane_net_vlan_range'): + try: + start_vlanid , end_vlanid = map(int, vlanID_range.replace(" ", "").split("-")) + for vlanID in xrange(start_vlanid, end_vlanid + 1): + if vlanID not in used_vlanIDs: + return vlanID + except Exception as exp: + raise vimconn.vimconnException("Exception {} occurred while generating VLAN ID.".format(exp)) + else: + raise vimconn.vimconnConflictException("Unable to create the SRIOV VLAN network."\ + " All given Vlan IDs {} are in use.".format(self.config.get('dataplane_net_vlan_range'))) + + + def _validate_vlan_ranges(self, dataplane_net_vlan_range): + """ + Method to validate user given vlanID ranges + Args: None + Returns: None + """ + for vlanID_range in dataplane_net_vlan_range: + vlan_range = vlanID_range.replace(" ", "") + #validate format + vlanID_pattern = r'(\d)*-(\d)*$' + match_obj = re.match(vlanID_pattern, vlan_range) + if not match_obj: + raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}.You must provide "\ + "'dataplane_net_vlan_range' in format [start_ID - end_ID].".format(vlanID_range)) + + start_vlanid , end_vlanid = map(int,vlan_range.split("-")) + if start_vlanid <= 0 : + raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\ + "Start ID can not be zero. For VLAN "\ + "networks valid IDs are 1 to 4094 ".format(vlanID_range)) + if end_vlanid > 4094 : + raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\ + "End VLAN ID can not be greater than 4094. For VLAN "\ + "networks valid IDs are 1 to 4094 ".format(vlanID_range)) + + if start_vlanid > end_vlanid: + raise vimconn.vimconnConflictException("Invalid dataplane_net_vlan_range {}."\ + "You must provide a 'dataplane_net_vlan_range' in format start_ID - end_ID and "\ + "start_ID < end_ID ".format(vlanID_range)) + #NOT USED FUNCTIONS def new_external_port(self, port_data): @@ -1376,3 +1634,4 @@ class vimconnector(vimconn.vimconnector): return error_value, error_text + diff --git a/osm_ro/vimconn_openvim.py b/osm_ro/vimconn_openvim.py index e722dc8d..abfffbe0 100644 --- a/osm_ro/vimconn_openvim.py +++ b/osm_ro/vimconn_openvim.py @@ -785,7 +785,8 @@ class vimconnector(vimconn.vimconnector): #print text return -vim_response.status_code,text - def new_vminstance(self,name,description,start,image_id,flavor_id,net_list, cloud_config=None, disk_list=None): + def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None, + availability_zone_index=None, availability_zone_list=None): '''Adds a VM instance to VIM Params: start: indicates if VM must start or boot in pause mode. Ignored diff --git a/osm_ro/vimconn_vmware.py b/osm_ro/vimconn_vmware.py index d8ca463f..0434900c 100644 --- a/osm_ro/vimconn_vmware.py +++ b/osm_ro/vimconn_vmware.py @@ -427,9 +427,61 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException("Failed create tenant {}".format(tenant_name)) def delete_tenant(self, tenant_id=None): - """Delete a tenant from VIM""" - 'Returns the tenant identifier' - raise vimconn.vimconnNotImplemented("Should have implemented this") + """ Delete a tenant from VIM + Args: + tenant_id is tenant_id to be deleted. + + Return: + returns the tenant identifier in UUID format. + If action is failed method will throw exception + """ + vca = self.connect_as_admin() + if not vca: + raise vimconn.vimconnConnectionException("self.connect() is failed") + + if tenant_id is not None: + if vca.vcloud_session and vca.vcloud_session.organization: + #Get OrgVDC + url_list = [self.vca.host, '/api/vdc/', tenant_id] + orgvdc_herf = ''.join(url_list) + response = Http.get(url=orgvdc_herf, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + + if response.status_code != requests.codes.ok: + self.logger.debug("delete_tenant():GET REST API call {} failed. "\ + "Return status code {}".format(orgvdc_herf, + response.status_code)) + raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id)) + + lxmlroot_respond = lxmlElementTree.fromstring(response.content) + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" + vdc_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href'] + vdc_remove_href = vdc_remove_href + '?recursive=true&force=true' + + #Delete OrgVDC + response = Http.delete(url=vdc_remove_href, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + + if response.status_code == 202: + delete_vdc_task = taskType.parseString(response.content, True) + if type(delete_vdc_task) is GenericTask: + self.vca.block_until_completed(delete_vdc_task) + self.logger.info("Deleted tenant with ID {}".format(tenant_id)) + return tenant_id + else: + self.logger.debug("delete_tenant(): DELETE REST API call {} failed. "\ + "Return status code {}".format(vdc_remove_href, + response.status_code)) + raise vimconn.vimconnException("Fail to delete tenant with ID {}".format(tenant_id)) + else: + self.logger.debug("delete_tenant():Incorrect tenant ID {}".format(tenant_id)) + raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id)) + def get_tenant_list(self, filter_dict={}): """Obtain tenants of VIM @@ -795,12 +847,81 @@ class vimconnector(vimconn.vimconnector): def delete_image(self, image_id): """ - - :param image_id: - :return: + Deletes a tenant image from VIM + Args: + image_id is ID of Image to be deleted + Return: + returns the image identifier in UUID format or raises an exception on error """ + vca = self.connect_as_admin() + if not vca: + raise vimconn.vimconnConnectionException("self.connect() is failed") + # Get Catalog details + url_list = [self.vca.host, '/api/catalog/', image_id] + catalog_herf = ''.join(url_list) + response = Http.get(url=catalog_herf, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + + if response.status_code != requests.codes.ok: + self.logger.debug("delete_image():GET REST API call {} failed. "\ + "Return status code {}".format(catalog_herf, + response.status_code)) + raise vimconn.vimconnNotFoundException("Fail to get image {}".format(image_id)) + + lxmlroot_respond = lxmlElementTree.fromstring(response.content) + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" + + catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems",namespaces) + catalogItems = catalogItems_section.iterfind("xmlns:CatalogItem",namespaces) + for catalogItem in catalogItems: + catalogItem_href = catalogItem.attrib['href'] + + #GET details of catalogItem + response = Http.get(url=catalogItem_href, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + + if response.status_code != requests.codes.ok: + self.logger.debug("delete_image():GET REST API call {} failed. "\ + "Return status code {}".format(catalog_herf, + response.status_code)) + raise vimconn.vimconnNotFoundException("Fail to get catalogItem {} for catalog {}".format( + catalogItem, + image_id)) + + lxmlroot_respond = lxmlElementTree.fromstring(response.content) + namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix} + namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" + catalogitem_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href'] + + #Remove catalogItem + response = Http.delete(url= catalogitem_remove_href, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + if response.status_code == requests.codes.no_content: + self.logger.debug("Deleted Catalog item {}".format(catalogItem)) + else: + raise vimconn.vimconnException("Fail to delete Catalog Item {}".format(catalogItem)) + + #Remove catalog + url_list = [self.vca.host, '/api/admin/catalog/', image_id] + catalog_remove_herf = ''.join(url_list) + response = Http.delete(url= catalog_remove_herf, + headers=vca.vcloud_session.get_vcloud_headers(), + verify=vca.verify, + logger=vca.logger) + + if response.status_code == requests.codes.no_content: + self.logger.debug("Deleted Catalog {}".format(image_id)) + return image_id + else: + raise vimconn.vimconnException("Fail to delete Catalog {}".format(image_id)) - raise vimconn.vimconnNotImplemented("Should have implemented this") def catalog_exists(self, catalog_name, catalogs): """ @@ -1252,7 +1373,7 @@ class vimconnector(vimconn.vimconnector): return None def new_vminstance(self, name=None, description="", start=False, image_id=None, flavor_id=None, net_list={}, - cloud_config=None, disk_list=None): + cloud_config=None, disk_list=None, availability_zone_index=None, availability_zone_list=None): """Adds a VM instance to VIM Params: start: indicates if VM must start or boot in pause mode. Ignored @@ -2892,8 +3013,7 @@ class vimconnector(vimconn.vimconnector): # application/vnd.vmware.admin.providervdc+xml # we need find a template from witch we instantiate VDC if child.tag.split("}")[1] == 'VdcTemplate': - if child.attrib.get('type') == 'application/vnd.vmware.admin.vdcTemplate+xml' and child.attrib.get( - 'name') == 'openmano': + if child.attrib.get('type') == 'application/vnd.vmware.admin.vdcTemplate+xml': vdc_template_ref = child.attrib.get('href') except: self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call)) @@ -2916,6 +3036,11 @@ class vimconnector(vimconn.vimconnector): headers['Content-Type'] = 'application/vnd.vmware.vcloud.instantiateVdcTemplateParams+xml' response = Http.post(url=vm_list_rest_call, headers=headers, data=data, verify=vca.verify, logger=vca.logger) + + vdc_task = taskType.parseString(response.content, True) + if type(vdc_task) is GenericTask: + self.vca.block_until_completed(vdc_task) + # if we all ok we respond with content otherwise by default None if response.status_code >= 200 and response.status_code < 300: return response.content @@ -3889,7 +4014,6 @@ class vimconnector(vimconn.vimconnector): "affinity".format(exp)) - def cloud_init(self, vapp, cloud_config): """ Method to inject ssh-key @@ -3899,7 +4023,8 @@ class vimconnector(vimconn.vimconnector): 'users': (optional) list of users to be inserted, each item is a dict with: 'name': (mandatory) user name, 'key-pairs': (optional) list of strings with the public key to be inserted to the user - 'user-data': (optional) string is a text script to be passed directly to cloud-init + 'user-data': (optional) can be a string with the text script to be passed directly to cloud-init, + or a list of strings, each one contains a script to be passed, usually with a MIMEmultipart file 'config-files': (optional). List of files to be transferred. Each item is a dict with: 'dest': (mandatory) string with the destination absolute path 'encoding': (optional, by default text). Can be one of: @@ -3909,9 +4034,10 @@ class vimconnector(vimconn.vimconnector): 'owner': (optional) file owner, string with the format 'owner:group' 'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk """ - try: - if isinstance(cloud_config, dict): + if not isinstance(cloud_config, dict): + raise Exception("cloud_init : parameter cloud_config is not a dictionary") + else: key_pairs = [] userdata = [] if "key-pairs" in cloud_config: @@ -3920,68 +4046,94 @@ class vimconnector(vimconn.vimconnector): if "users" in cloud_config: userdata = cloud_config["users"] - for key in key_pairs: - for user in userdata: - if 'name' in user: user_name = user['name'] - if 'key-pairs' in user and len(user['key-pairs']) > 0: - for user_key in user['key-pairs']: - customize_script = """ - #!/bin/bash - echo performing customization tasks with param $1 at `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log - if [ "$1" = "precustomization" ];then - echo performing precustomization tasks on `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log - if [ ! -d /root/.ssh ];then - mkdir /root/.ssh - chown root:root /root/.ssh - chmod 700 /root/.ssh - touch /root/.ssh/authorized_keys - chown root:root /root/.ssh/authorized_keys - chmod 600 /root/.ssh/authorized_keys - # make centos with selinux happy - which restorecon && restorecon -Rv /root/.ssh - echo '{key}' >> /root/.ssh/authorized_keys - else - touch /root/.ssh/authorized_keys - chown root:root /root/.ssh/authorized_keys - chmod 600 /root/.ssh/authorized_keys - echo '{key}' >> /root/.ssh/authorized_keys - fi - if [ -d /home/{user_name} ];then - if [ ! -d /home/{user_name}/.ssh ];then - mkdir /home/{user_name}/.ssh - chown {user_name}:{user_name} /home/{user_name}/.ssh - chmod 700 /home/{user_name}/.ssh - touch /home/{user_name}/.ssh/authorized_keys - chown {user_name}:{user_name} /home/{user_name}/.ssh/authorized_keys - chmod 600 /home/{user_name}/.ssh/authorized_keys - # make centos with selinux happy - which restorecon && restorecon -Rv /home/{user_name}/.ssh - echo '{user_key}' >> /home/{user_name}/.ssh/authorized_keys - else - touch /home/{user_name}/.ssh/authorized_keys - chown {user_name}:{user_name} /home/{user_name}/.ssh/authorized_keys - chmod 600 /home/{user_name}/.ssh/authorized_keys - echo '{user_key}' >> /home/{user_name}/.ssh/authorized_keys - fi - fi - fi""".format(key=key, user_name=user_name, user_key=user_key) - - for vm in vapp._get_vms(): - vm_name = vm.name - task = vapp.customize_guest_os(vm_name, customization_script=customize_script) - if isinstance(task, GenericTask): - self.vca.block_until_completed(task) - self.logger.info("cloud_init : customized guest os task "\ - "completed for VM {}".format(vm_name)) - else: - self.logger.error("cloud_init : task for customized guest os"\ - "failed for VM {}".format(vm_name)) + self.logger.debug("cloud_init : Guest os customization started..") + customize_script = self.format_script(key_pairs=key_pairs, users_list=userdata) + self.guest_customization(vapp, customize_script) + except Exception as exp: self.logger.error("cloud_init : exception occurred while injecting "\ "ssh-key") raise vimconn.vimconnException("cloud_init : Error {} failed to inject "\ "ssh-key".format(exp)) + def format_script(self, key_pairs=[], users_list=[]): + bash_script = """ + #!/bin/bash + echo performing customization tasks with param $1 at `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log + if [ "$1" = "precustomization" ];then + echo performing precustomization tasks on `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log + """ + + keys = "\n".join(key_pairs) + if keys: + keys_data = """ + if [ ! -d /root/.ssh ];then + mkdir /root/.ssh + chown root:root /root/.ssh + chmod 700 /root/.ssh + touch /root/.ssh/authorized_keys + chown root:root /root/.ssh/authorized_keys + chmod 600 /root/.ssh/authorized_keys + # make centos with selinux happy + which restorecon && restorecon -Rv /root/.ssh + else + touch /root/.ssh/authorized_keys + chown root:root /root/.ssh/authorized_keys + chmod 600 /root/.ssh/authorized_keys + fi + echo '{key}' >> /root/.ssh/authorized_keys + """.format(key=keys) + + bash_script+= keys_data + + for user in users_list: + if 'name' in user: user_name = user['name'] + if 'key-pairs' in user: + user_keys = "\n".join(user['key-pairs']) + else: + user_keys = None + + add_user_name = """ + useradd -d /home/{user_name} -m -g users -s /bin/bash {user_name} + """.format(user_name=user_name) + + bash_script+= add_user_name + + if user_keys: + user_keys_data = """ + mkdir /home/{user_name}/.ssh + chown {user_name}:{user_name} /home/{user_name}/.ssh + chmod 700 /home/{user_name}/.ssh + touch /home/{user_name}/.ssh/authorized_keys + chown {user_name}:{user_name} /home/{user_name}/.ssh/authorized_keys + chmod 600 /home/{user_name}/.ssh/authorized_keys + # make centos with selinux happy + which restorecon && restorecon -Rv /home/{user_name}/.ssh + echo '{user_key}' >> /home/{user_name}/.ssh/authorized_keys + """.format(user_name=user_name,user_key=user_keys) + + bash_script+= user_keys_data + + return bash_script+"\n\tfi" + + def guest_customization(self, vapp, customize_script): + """ + Method to customize guest os + vapp - Vapp object + customize_script - Customize script to be run at first boot of VM. + """ + for vm in vapp._get_vms(): + vm_name = vm.name + task = vapp.customize_guest_os(vm_name, customization_script=customize_script) + if isinstance(task, GenericTask): + self.vca.block_until_completed(task) + self.logger.info("guest_customization : customized guest os task "\ + "completed for VM {}".format(vm_name)) + else: + self.logger.error("guest_customization : task for customized guest os"\ + "failed for VM {}".format(vm_name)) + raise vimconn.vimconnException("guest_customization : failed to perform"\ + "guest os customization on VM {}".format(vm_name)) def add_new_disk(self, vapp_uuid, disk_size): """ @@ -4921,7 +5073,7 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException(message=exp) - def retry_rest(self, api, url, add_headers=None, data=None): + def retry_rest(self, method, url, add_headers=None, data=None): """ Method to get Token & retry respective REST request Args: api - REST API - Can be one of 'GET' or 'PUT' or 'POST' @@ -4941,25 +5093,30 @@ class vimconnector(vimconn.vimconnector): if add_headers: headers.update(add_headers) - if api == 'GET': + if method == 'GET': response = Http.get(url=url, headers=headers, verify=self.vca.verify, logger=self.vca.logger) - return response - elif api == 'PUT': - if headers: - headers.append + elif method == 'PUT': response = Http.put(url=url, data=data, headers=headers, - verify=self.vca.verify, logger=self.logger) - return response - elif api == 'POST': + verify=self.vca.verify, + logger=self.logger) + elif method == 'POST': response = Http.post(url=url, headers=headers, + data=data, verify=self.vca.verify, logger=self.vca.logger) + elif method == 'DELETE': + response = Http.delete(url=url, + headers=headers, + verify=self.vca.verify, + logger=self.vca.logger) + return response + def get_token(self): """ Generate a new token if expired @@ -5012,3 +5169,4 @@ class vimconnector(vimconn.vimconnector): return vdc + diff --git a/scripts/install-openmano.sh b/scripts/install-openmano.sh index 624dce35..ac28f0d7 100755 --- a/scripts/install-openmano.sh +++ b/scripts/install-openmano.sh @@ -283,7 +283,8 @@ echo -e "\n"\ "##### INSTALLING OVIM LIBRARY #####\n"\ "#################################################################" su $SUDO_USER -c "git -C ${BASEFOLDER} clone ${GIT_OVIM_URL} openvim" -[[ -z $DEVELOP ]] && su $SUDO_USER -c "git -C ${BASEFOLDER}/openvim checkout v2.0" +LATEST_STABLE_TAG=`git -C "${BASEFOLDER}/openvim" tag -l v[0-9].* | tail -n1` +[[ -z $DEVELOP ]] && su $SUDO_USER -c "git -C ${BASEFOLDER}/openvim checkout tags/${LATEST_STABLE_TAG}" # Install debian dependencies before setup.py [ "$_DISTRO" == "Ubuntu" ] && install_packages "libmysqlclient-dev" diff --git a/scripts/python-osm-ro.postinst b/scripts/python-osm-ro.postinst index d697afe5..b2a2ff2f 100755 --- a/scripts/python-osm-ro.postinst +++ b/scripts/python-osm-ro.postinst @@ -23,10 +23,11 @@ OSMRO_PATH=`python -c 'import osm_ro; print osm_ro.__path__[0]'` #Pip packages required for vmware connector pip install --upgrade pip -pip install pyvcloud -pip install progressbar -pip install prettytable -pip install pyvmomi +pip install --upgrade pyvcloud +pip install --upgrade progressbar +pip install --upgrade prettytable +pip install --upgrade pyvmomi +pip install --upgrade pyang pyangbind systemctl enable osm-ro.service diff --git a/setup.py b/setup.py index 303a6520..70cefd46 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ from os import system #import glob _name = 'osm_ro' -_version = open('RO_VERSION').read().strip() _description = 'OSM Resource Orchestrator' _author = 'ETSI OSM' _author_email = 'alfonso.tiernosepulveda@telefonica.com' @@ -18,7 +17,8 @@ _url = 'https://osm.etsi.org/gitweb/?p=osm/RO.git;a=summary' _requirements = [ "PyYAML", "bottle", - "MySQL-python", + #"mysqlclient", + #"MySQLdb", "jsonschema", "paramiko", "argcomplete", @@ -30,15 +30,17 @@ _requirements = [ "python-glanceclient", "python-neutronclient", "python-cinderclient", - "pyvcloud", - "progressbar", + #"pyvcloud", + #"progressbar", "prettytable", - "pyvmomi", + #"pyvmomi", "boto", + #"lib_osm_openvim", + #"osm_im", ] setup(name=_name, - version = _version, + version_command=('git describe', 'pep440-git'), description = _description, long_description = open('README.rst').read(), author = _author, @@ -60,5 +62,7 @@ setup(name=_name, scripts=['openmanod', 'openmano', 'osm_ro/scripts/service-openmano', 'osm_ro/scripts/openmano-report',], install_requires=_requirements, include_package_data=True, + setup_requires=['setuptools-version-command'], + #test_suite='nose.collector', ) diff --git a/stdeb.cfg b/stdeb.cfg index a0c20ec7..ea4c8f79 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -2,5 +2,5 @@ Suite: xenial XS-Python-Version: >= 2.7 Maintainer: Gerardo Garcia -Depends: python-pip, libmysqlclient-dev, libssl-dev, libffi-dev, python-argcomplete, python-boto, python-bottle, python-jsonschema, python-logutils, python-cinderclient, python-glanceclient, python-keystoneclient, python-neutronclient, python-novaclient, python-openstackclient, python-mysqldb +Depends: python-pip, libmysqlclient-dev, libssl-dev, libffi-dev, python-argcomplete, python-boto, python-bottle, python-jsonschema, python-logutils, python-cinderclient, python-glanceclient, python-keystoneclient, python-neutronclient, python-novaclient, python-openstackclient, python-mysqldb, python-lib-osm-openvim, python-osm-im diff --git a/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml b/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml new file mode 100644 index 00000000..deae332f --- /dev/null +++ b/test/RO_tests/afiinity_vnf/scenario_simple_2_vnf_afinnity.yaml @@ -0,0 +1,38 @@ +## +# Copyright 2015 Telefónica Investigación 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 +## +--- +schema_version: 2 +scenario: + name: simple_ha + description: Simple network scenario consisting of two VNF connected to an external network + vnfs: + linux1: # vnf/net name in the scenario + vnf_name: linux_test_2vms # VNF name as introduced in OPENMANO DB + networks: + mgmt: # provide a name for this net or connection + external: true + interfaces: + - linux1: control0 # Node and its interface + - linux1: control1 # Node and its interface + + + + diff --git a/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml b/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml new file mode 100644 index 00000000..9ec7f607 --- /dev/null +++ b/test/RO_tests/afiinity_vnf/vnfd_linux_2_vnfc_affinity.yaml @@ -0,0 +1,61 @@ +## +# Copyright 2015 Telefónica Investigación 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 +## +--- + +vnf: + name: linux_test_2vms + description: Single-VM VNF with a traditional cloud VM based on generic Linux OS + external-connections: + - name: control0 + type: mgmt # "mgmt" (autoconnect to management net), "bridge", "data" + VNFC: linux-VM-HA-A # Virtual Machine this interface belongs to + local_iface_name: eth0 # interface name inside this Virtual Machine (must be defined in the VNFC section) + description: Management interface 0 + - name: control1 + type: mgmt # "mgmt" (autoconnect to management net), "bridge", "data" + VNFC: linux-VM-HA-B # Virtual Machine this interface belongs to + local_iface_name: eth0 # interface name inside this Virtual Machine (must be defined in the VNFC section) + description: Management interface 1 + VNFC: + - name: linux-VM-HA-A + description: Generic Linux Virtual Machine + availability_zone: A # availanility zone A + #Copy the image to a compute path and edit this path + image name: TestVM + vcpus: 1 # Only for traditional cloud VMs. Number of virtual CPUs (oversubscription is allowed). + ram: 1024 # Only for traditional cloud VMs. Memory in MBytes (not from hugepages, oversubscription is allowed) + disk: 10 + bridge-ifaces: + - name: eth0 + vpci: "0000:00:11.0" + numas: [] + - name: linux-VM-HA-B + description: Generic Linux Virtual Machine + availability_zone: B # availanility zone B + #Copy the image to a compute path and edit this path + image name: TestVM + vcpus: 1 # Only for traditional cloud VMs. Number of virtual CPUs (oversubscription is allowed). + ram: 1024 # Only for traditional cloud VMs. Memory in MBytes (not from hugepages, oversubscription is allowed) + disk: 10 + bridge-ifaces: + - name: eth0 + vpci: "0000:00:12.0" + numas: [] diff --git a/test/RO_tests/simple_count3/scenario_linux_count3.yaml b/test/RO_tests/simple_count3/scenario_linux_count3.yaml new file mode 100644 index 00000000..2362c027 --- /dev/null +++ b/test/RO_tests/simple_count3/scenario_linux_count3.yaml @@ -0,0 +1,39 @@ +## +# Copyright 2015 Telefónica Investigación 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 +## +--- +schema_version: 2 +scenario: + name: simple_count3 + description: Simple network scenario consisting of a multi VNFC VNF connected to an external network + vnfs: + linux1: # vnf/net name in the scenario + vnf_name: simple_linux_count3 # VNF name as introduced in OPENMANO DB + networks: + mgmt: # provide a name for this net or connection + external: true + interfaces: + - linux1: control0 # Node and its interface + internal1: # provide a name for this net or connection + external: false + interfaces: + - linux1: data-eth1 + + diff --git a/test/RO_tests/simple_count3/vnfd_count3.yaml b/test/RO_tests/simple_count3/vnfd_count3.yaml new file mode 100644 index 00000000..a4c70705 --- /dev/null +++ b/test/RO_tests/simple_count3/vnfd_count3.yaml @@ -0,0 +1,68 @@ +## +# Copyright 2015 Telefónica Investigación 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 +## +--- +schema_version: "0.2" +vnf: + name: simple_linux_count3 + description: "Example of a linux VNF consisting of two VMs with one internal network" + # class: parent # Optional. Used to organize VNFs + internal-connections: + - name: internal-eth2 + description: internalnet + type: e-lan + implementation: overlay + ip-profile: + ip-version: IPv4 + subnet-address: 192.168.1.0/24 + gateway-address: 192.168.1.1 + dns-address: 8.8.8.8 + dhcp: + enabled: true + start-address: 192.168.1.100 + count: 100 + elements: + - VNFC: linux_3VMs + local_iface_name: eth2 + ip_address: 192.168.1.2 + external-connections: + - name: control0 + type: mgmt + VNFC: linux_3VMs + local_iface_name: eth0 + description: control interface VM1 + - name: data-eth1 + type: bridge + VNFC: linux_3VMs + local_iface_name: eth1 + description: data interface input + VNFC: + - name: linux_3VMs + count: 3 + description: "Linux VM1 2 CPUs, 2 GB RAM and 3 bridge interfaces" + #Copy the image to a compute path and edit this path + image name: TestVM + disk: 10 + vcpus: 2 + ram: 2048 + bridge-ifaces: + - name: eth0 + - name: eth1 + - name: eth2 diff --git a/test/test_RO.py b/test/test_RO.py index 21af36cd..5b47182d 100755 --- a/test/test_RO.py +++ b/test/test_RO.py @@ -280,24 +280,6 @@ class test_VIM_tenant_operations(test_base): assert ('deleted' in tenant.get('result', "")) class test_vimconn_connect(test_base): - # test_index = 1 - # test_text = None - - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 - - # def tearDown(self): - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) def test_000_connect(self): self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], @@ -312,25 +294,7 @@ class test_vimconn_connect(test_base): class test_vimconn_new_network(test_base): - # test_index = 1 network_name = None - # test_text = None - - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 - - # def tearDown(self): - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) def test_000_new_network(self): self.__class__.network_name = _get_random_string(20) @@ -345,7 +309,7 @@ class test_vimconn_new_network(test_base): self.__class__.network_id = network logger.debug("{}".format(network)) - network_list = test_config["vim_conn"].get_vcd_network_list() + network_list = test_config["vim_conn"].get_network_list() for net in network_list: if self.__class__.network_name in net.get('name'): self.assertIn(self.__class__.network_name, net.get('name')) @@ -373,7 +337,7 @@ class test_vimconn_new_network(test_base): delete_net_ids.append(network_id) logger.debug("{}".format(network_id)) - network_list = test_config["vim_conn"].get_vcd_network_list() + network_list = test_config["vim_conn"].get_network_list() for net in network_list: if self.__class__.network_name in net.get('name'): self.assertIn(self.__class__.network_name, net.get('name')) @@ -425,7 +389,7 @@ class test_vimconn_new_network(test_base): self.__class__.network_id = network logger.debug("{}".format(network)) - network_list = test_config["vim_conn"].get_vcd_network_list() + network_list = test_config["vim_conn"].get_network_list() for net in network_list: if self.__class__.network_name in net.get('name'): self.assertIn(self.__class__.network_name, net.get('name')) @@ -450,7 +414,7 @@ class test_vimconn_new_network(test_base): self.__class__.network_id = network logger.debug("{}".format(network)) - network_list = test_config["vim_conn"].get_vcd_network_list() + network_list = test_config["vim_conn"].get_network_list() for net in network_list: if self.__class__.network_name in net.get('name'): self.assertIn(self.__class__.network_name, net.get('name')) @@ -473,7 +437,7 @@ class test_vimconn_new_network(test_base): net_type='unknowntype') self.__class__.network_id = network logger.debug("{}".format(network)) - network_list = test_config["vim_conn"].get_vcd_network_list() + network_list = test_config["vim_conn"].get_network_list() for net in network_list: if self.__class__.network_name in net.get('name'): self.assertIn(self.__class__.network_name, net.get('name')) @@ -520,18 +484,8 @@ class test_vimconn_new_network(test_base): self.assertEqual(net_dict, {}) class test_vimconn_get_network_list(test_base): - # test_index = 1 network_name = None - # test_text = None - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 - def setUp(self): # creating new network self.__class__.network_name = _get_random_string(20) @@ -543,12 +497,6 @@ class test_vimconn_get_network_list(test_base): def tearDown(self): test_base.tearDown(self) - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) # Deleting created network result = test_config["vim_conn"].delete_network(self.__class__.network_id) @@ -666,17 +614,7 @@ class test_vimconn_get_network_list(test_base): self.assertEqual(network_list, []) class test_vimconn_get_network(test_base): - # test_index = 1 network_name = None - # test_text = None - - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 def setUp(self): # creating new network @@ -689,12 +627,6 @@ class test_vimconn_get_network(test_base): def tearDown(self): test_base.tearDown(self) - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) # Deleting created network result = test_config["vim_conn"].delete_network(self.__class__.network_id) @@ -726,25 +658,7 @@ class test_vimconn_get_network(test_base): self.assertEqual(network_info, {}) class test_vimconn_delete_network(test_base): - # test_index = 1 network_name = None - # test_text = None - - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 - - # def tearDown(self): - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) def test_000_delete_network(self): # Creating network @@ -784,24 +698,6 @@ class test_vimconn_delete_network(test_base): self.assertEqual((context.exception).http_code, 400) class test_vimconn_get_flavor(test_base): - # test_index = 1 - # test_text = None - - # @classmethod - # def setUpClass(cls): - # logger.info("{}. {}".format(test_config["test_number"], cls.__name__)) - - # @classmethod - # def tearDownClass(cls): - # test_config["test_number"] += 1 - - # def tearDown(self): - # exec_info = sys.exc_info() - # if exec_info == (None, None, None): - # logger.info(self.__class__.test_text+" -> TEST OK") - # else: - # logger.warning(self.__class__.test_text+" -> TEST NOK") - # logger.critical("Traceback error",exc_info=True) def test_000_get_flavor(self): test_directory_content = os.listdir(test_config["test_directory"]) @@ -927,6 +823,7 @@ class test_vimconn_new_image(test_base): image_path = test_config['image_path'] if image_path: image_id = test_config["vim_conn"].new_image({ 'name': 'TestImage', 'location' : image_path }) + time.sleep(20) self.assertEqual(type(image_id),str) self.assertIsInstance(uuid.UUID(image_id),uuid.UUID) else: @@ -945,6 +842,28 @@ class test_vimconn_new_image(test_base): self.assertEqual((context.exception).http_code, 400) + def test_020_delete_image(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + image_id = test_config["vim_conn"].delete_image(self.__class__.image_id) + self.assertEqual(type(image_id),str) + + def test_030_delete_image_negative(self): + Non_exist_image_id = str(uuid.uuid4()) + + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + with self.assertRaises(Exception) as context: + test_config["vim_conn"].delete_image(Non_exist_image_id) + + self.assertEqual((context.exception).http_code, 404) + class test_vimconn_get_image_id_from_path(test_base): def test_000_get_image_id_from_path(self): @@ -1333,6 +1252,127 @@ class test_vimconn_new_vminstance(test_base): test_config["vim_conn"].delete_vminstance(self.__class__.instance_id) time.sleep(10) +class test_vimconn_get_tenant_list(test_base): + tenant_id = None + + def test_000_get_tenant_list(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + # Getting tenant list + tenant_list = test_config["vim_conn"].get_tenant_list() + + for item in tenant_list: + if test_config['tenant'] == item['name']: + self.__class__.tenant_id = item['id'] + self.assertEqual(type(item['name']), str) + self.assertEqual(type(item['id']), str) + + def test_010_get_tenant_list_by_id(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + # Getting filter tenant list by its id + filter_tenant_list = test_config["vim_conn"].get_tenant_list({'id': self.__class__.tenant_id}) + + for item in filter_tenant_list: + self.assertEqual(type(item['id']), str) + self.assertEqual(item['id'], self.__class__.tenant_id) + + def test_020_get_tenant_list_by_name(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + # Getting filter tenant list by its name + filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': test_config['tenant']}) + + for item in filter_tenant_list: + self.assertEqual(type(item['name']), str) + self.assertEqual(item['name'], test_config['tenant']) + + def test_030_get_tenant_list_by_name_and_id(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + # Getting filter tenant list by its name and id + filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': test_config['tenant'], + 'id': self.__class__.tenant_id}) + + for item in filter_tenant_list: + self.assertEqual(type(item['name']), str) + self.assertEqual(type(item['id']), str) + self.assertEqual(item['name'], test_config['tenant']) + self.assertEqual(item['id'], self.__class__.tenant_id) + + def test_040_get_tenant_list_negative(self): + non_exist_tenant_name = "Tenant_123" + non_exist_tenant_id = "kjhgrt456-45345kjhdfgnbdk-34dsfjdfg" + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + filter_tenant_list = test_config["vim_conn"].get_tenant_list({'name': non_exist_tenant_name, + 'id': non_exist_tenant_id}) + + self.assertEqual(filter_tenant_list, []) + +class test_vimconn_new_tenant(test_base): + tenant_id = None + + def test_000_new_tenant(self): + tenant_name = _get_random_string(20) + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + self.__class__.tenant_id = test_config["vim_conn"].new_tenant(tenant_name) + time.sleep(15) + + self.assertEqual(type(self.__class__.tenant_id), str) + + def test_010_new_tenant_negative(self): + Invalid_tenant_name = 10121 + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + with self.assertRaises(Exception) as context: + test_config["vim_conn"].new_tenant(Invalid_tenant_name) + + self.assertEqual((context.exception).http_code, 400) + + def test_020_delete_tenant(self): + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + tenant_id = test_config["vim_conn"].delete_tenant(self.__class__.tenant_id) + self.assertEqual(type(tenant_id), str) + + def test_030_delete_tenant_negative(self): + Non_exist_tenant_name = 'Test_30_tenant' + self.__class__.test_text = "{}.{}. TEST {}".format(test_config["test_number"], + self.__class__.test_index, + inspect.currentframe().f_code.co_name) + self.__class__.test_index += 1 + + with self.assertRaises(Exception) as context: + test_config["vim_conn"].delete_tenant(Non_exist_tenant_name) + + self.assertEqual((context.exception).http_code, 404) + ''' IMPORTANT NOTE The following unittest class does not have the 'test_' on purpose. This test is the one used for the diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..025f4a0e --- /dev/null +++ b/tox.ini @@ -0,0 +1,22 @@ +[tox] +#envlist = py27,py3 +envlist = py27 +toxworkdir={homedir}/.tox + +[testenv] +deps=nose + mock +commands=nosetests + +[testenv:flake8] +basepython = python +deps = flake8 +commands = + flake8 setup.py + +[testenv:build] +basepython = python +deps = stdeb + setuptools-version-command +commands = python setup.py --command-packages=stdeb.command bdist_deb + diff --git a/vnfs/vnf-template.yaml b/vnfs/vnf-template.yaml index 121c5abb..b57ebfd7 100644 --- a/vnfs/vnf-template.yaml +++ b/vnfs/vnf-template.yaml @@ -46,6 +46,7 @@ vnf: description: Bridge interface VNFC: # Virtual machine array - name: TEMPLATE-VM # name of Virtual Machine + # count: 1 #by default 1 description: TEMPLATE description VNFC image: /path/to/imagefolder/TEMPLATE-VM.qcow2 # image metadata: {"bus":"ide", "os_type":"windows", "use_incremental": "no" } #Optional