+#!/usr/bin/env bash
+
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+
# Set the Juju env variables for building a layer
export JUJU_REPOSITORY=`pwd`
export INTERFACE_PATH=$JUJU_REPOSITORY/interfaces
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com
+# 19-aug-2019 : changed vdu image from hackfest3-mgmt to ubuntu1604
+##
+
vnfd:vnfd-catalog:
vnfd:
- id: hackfest_cloudinit-vnf
vdu:
- id: mgmtVM
name: mgmtVM
- image: hackfest3-mgmt
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
cloud-init-file: cloud-config.txt
- id: dataVM
name: dataVM
- image: hackfest3-mgmt
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com
+# 19-aug-2019 : changed vdu image from hackfest3-mgmt & hackfest-pktgen to ubuntu1604
+##
+
vnfd:vnfd-catalog:
vnfd:
- id: hackfest_epasriov-vnf
vdu:
- id: mgmtVM
name: mgmtVM
- image: hackfest3-mgmt
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
cloud-init-file: cloud-config.txt
- id: dataVM
name: dataVM
- image: hackfest-pktgen
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '8'
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com
+# 19-aug-2019 : changed vdu image from US1604 to ubuntu1604
+##
+
vnfd:vnfd-catalog:
vnfd:
- id: hackfest_multivdu-vnf
vdu:
- id: mgmtVM
name: mgmtVM
- image: US1604
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
- id: dataVM
name: dataVM
- image: US1604
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 ETSI
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com
+# 19-aug-2019 : changed vdu image from hackfest3-mgmt to ubuntu1604
+##
+
vnfd:vnfd-catalog:
vnfd:
- id: hackfest-simplecharm-vnf
vdu:
- id: mgmtVM
name: mgmtVM
- image: hackfest3-mgmt
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
cloud-init-file: cloud-config.txt
- id: dataVM
name: dataVM
- image: hackfest3-mgmt
+ image: ubuntu1604
count: '1'
vm-flavor:
vcpu-count: '1'
# License for the specific language governing permissions and limitations
# under the License.
-PKG_DIRECTORIES="jenkins installers systest charms descriptor-packages tools docker"
+PKG_DIRECTORIES="jenkins installers systest charms descriptor-packages tools docker robot-systest"
MDG_NAME=devops
DEB_INSTALL=debian/osm-$MDG_NAME.install
export DEBEMAIL="mmarchetti@sandvine.com"
ENV OSMLCM_MESSAGE_HOST kafka
ENV OSMLCM_MESSAGE_PORT 9092
-HEALTHCHECK --interval=30s --timeout=140s --retries=1 \
- CMD python3 /usr/lib/python3/dist-packages/osm_lcm/lcm.py --health-check || exit 1
+HEALTHCHECK --start-period=120s --interval=30s --timeout=30s --retries=1 \
+ CMD python3 -m osm_lcm.lcm --health-check || exit 1
# Run app.py when the container launches
-CMD ["python3", "/usr/lib/python3/dist-packages/osm_lcm/lcm.py"]
+CMD python3 -m osm_lcm.lcm
+
# This creates osm/NBI docker from local NBI source code
-FROM ubuntu:16.04
+FROM ubuntu:18.04
-RUN apt-get update && apt-get -y install curl software-properties-common
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install curl software-properties-common
-RUN apt-get update && apt-get install -y git python3 python3-jsonschema \
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git python3 python3-jsonschema \
python3-pymongo python3-yaml python3-pip python3-keystoneclient \
&& pip3 install -U pip \
- && python3 -m pip install aiokafka aiohttp cherrypy==18.0.0 pyangbind keystoneauth1 \
+ && python3 -m pip install aiokafka aiohttp cherrypy==18.1.2 pyangbind keystoneauth1 \
&& mkdir -p /app/storage/kafka && mkdir -p /app/log
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
# server
ENV OSMNBI_SOCKET_HOST 0.0.0.0
ENV OSMNBI_SOCKET_PORT 9999
+ENV OSMNBI_SERVER_SSL_CERTIFICATE /app/osm_nbi/http/cert.pem
+ENV OSMNBI_SERVER_SSL_PRIVATE_KEY /app/osm_nbi/http/privkey.pem
# storage
ENV OSMNBI_STORAGE_PATH /app/storage
# database
# web
ENV OSMNBI_STATIC_DIR /app/osm_nbi/html_public
-# logs
-ENV OSMNBI_LOG_FILE /app/log
-ENV OSMNBI_LOG_LEVEL DEBUG
# message
ENV OSMNBI_MESSAGE_DRIVER kafka
ENV OSMNBI_MESSAGE_HOST kafka
CMD curl -k https://localhost:9999/osm/ | grep Welcome || exit 1
# Run app.py when the container launches
-CMD ["python3", "/usr/lib/python3/dist-packages/osm_nbi/nbi.py"]
+CMD python3 -m osm_nbi.nbi
+
##
# Copyright 2019 ETSI
#
+# 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
# under the License.
##
-########################################################################
FROM ubuntu:16.04
RUN apt-get update && apt-get -y install python \
libcurl4-gnutls-dev libgnutls-dev iputils-ping python-pip \
python-openstackclient wget
+
RUN pip install -U pip && python -m pip install python-magic pyangbind pytest==4.6.3
ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian
OSMLCM_VCA_HOST=__JUJU_CONTROLLER_IP__
OSMLCM_VCA_SECRET=__JUJU_PASSWORD__
OSMLCM_VCA_PUBKEY=__JUJU_PUBKEY__
+OSMLCM_VCA_APIPROXY=__JUJU_APIPROXY__
interval: 10s
timeout: 10s
retries: 3
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
kafka:
image: wurstmeister/kafka:${KAFKA_TAG:-latest}
ports:
interval: 20s
timeout: 10s
retries: 5
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
#depends_on:
# - zookeeper
mongo:
- prom_db:/prometheus
networks:
- netOSM
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
keystone:
image: ${DOCKER_USER:-opensourcemano}/keystone:${TAG:-6}
networks:
- ./keystone.env
ports:
- "${OSM_KEYSTONE_PORTS:-5000:5000}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
nbi:
image: ${DOCKER_USER:-opensourcemano}/nbi:${TAG:-6}
networks:
- ./nbi.env
ports:
- "${OSM_NBI_PORTS:-9999:9999}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
#depends_on:
# - kafka
# - mongo
OSMLCM_MESSAGE_HOST: kafka
env_file:
- ./lcm.env
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
#depends_on:
# - kafka
# - mongo
- ro_db:/var/lib/mysql
env_file:
- ./ro-db.env
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
# ports:
# - "3306:3306"
ro:
- ro:/var/log/osm
ports:
- "${OSM_RO_PORTS:-9090:9090}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
mon:
image: ${DOCKER_USER:-opensourcemano}/mon:${TAG:-6}
networks:
- ./lwui.env
ports:
- "${OSM_UI_PORTS:-80:80}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "100m"
+ max-file: "2"
echo -e " -S <VCA secret> use VCA/juju secret key"
echo -e " -P <VCA pubkey> use VCA/juju public key file"
echo -e " -C <VCA cacert> use VCA/juju CA certificate file"
+ echo -e " -A <VCA apiproxy> use VCA/juju API proxy"
echo -e " --vimemu: additionally deploy the VIM emulator as a docker container"
echo -e " --elk_stack: additionally deploy an ELK docker stack for event logging"
echo -e " --pm_stack: additionally deploy a Prometheus+Grafana stack for performance monitoring (PM)"
[ $(juju controllers | awk "/^${OSM_STACK_NAME}[\*| ]/{print $1}"|wc -l) -eq 1 ] || FATAL "Juju installation failed"
}
+function juju_createproxy() {
+ if ! sudo iptables -t nat -C PREROUTING -p tcp -m tcp --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST; then
+ sudo iptables -t nat -A PREROUTING -p tcp -m tcp --dport 17070 -j DNAT --to-destination $OSM_VCA_HOST
+ sudo netfilter-persistent save
+ fi
+}
+
function generate_docker_images() {
echo "Pulling and generating docker images"
_build_from=$COMMIT_ID
fi
}
-function generate_config_log_folders() {
- echo "Generating config and log folders"
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
- $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus.yml
- echo "Finished generation of config and log folders"
-}
function generate_docker_env_files() {
+ echo "Doing a backup of existing env files"
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/keystone-db.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/keystone.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/lcm.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/lwui.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/mon.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/nbi.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/pol.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/ro-db.env{,~}
+ $WORKDIR_SUDO cp $OSM_DOCKER_WORK_DIR/ro.env{,~}
+
echo "Generating docker env files"
+ # Docker-compose
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/docker-compose.yaml $OSM_DOCKER_WORK_DIR/docker-compose.yaml
+
+ # Prometheus
+ $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/prometheus.yml $OSM_DOCKER_WORK_DIR/prometheus.yml
+
# LCM
if [ ! -f $OSM_DOCKER_WORK_DIR/lcm.env ]; then
echo "OSMLCM_DATABASE_COMMONKEY=${OSM_DATABASE_COMMONKEY}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
# $WORKDIR_SUDO sed -i "s|OSMLCM_VCA_CACERT.*|OSMLCM_VCA_CACERT=\"${OSM_VCA_CACERT}\"|g" $OSM_DOCKER_WORK_DIR/lcm.env
#fi
+ if ! grep -Fq "OSMLCM_VCA_APIPROXY" $OSM_DOCKER_WORK_DIR/lcm.env; then
+ echo "OSMLCM_VCA_APIPROXY=${OSM_VCA_APIPROXY}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env
+ else
+ $WORKDIR_SUDO sed -i "s|OSMLCM_VCA_APIPROXY.*|OSMLCM_VCA_APIPROXY=${OSM_VCA_APIPROXY}|g" $OSM_DOCKER_WORK_DIR/lcm.env
+ fi
+
# RO
MYSQL_ROOT_PASSWORD=$(generate_secret)
if [ ! -f $OSM_DOCKER_WORK_DIR/ro-db.env ]; then
#OSM_VCA_CACERT=$(juju controllers --format json | jq -r '.controllers["osm"]["ca-cert"]' | grep -v "\-\-\-\-\-.*CERTIFICATE\-\-\-\-\-")
# [ -z "$OSM_VCA_CACERT" ] && FATAL "Cannot obtain juju CA certificate"
#fi
+ if [ -z "$OSM_VCA_APIPROXY" ]; then
+ OSM_VCA_APIPROXY=$DEFAULT_IP
+ [ -z "$OSM_VCA_APIPROXY" ] && FATAL "Cannot obtain juju api proxy"
+ fi
+ juju_createproxy
+
if [ -z "$OSM_DATABASE_COMMONKEY" ]; then
OSM_DATABASE_COMMONKEY=$(generate_secret)
[ -z "OSM_DATABASE_COMMONKEY" ] && FATAL "Cannot generate common db secret"
[ -z "$DOCKER_NOBUILD" ] && generate_docker_images
track docker_build
generate_docker_env_files
- generate_config_log_folders
# remove old stack
remove_stack $OSM_STACK_NAME
ELASTIC_VERSION=6.4.2
ELASTIC_CURATOR_VERSION=5.5.4
-while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:H:S:s:w:t:U:P:" o; do
+while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:H:S:s:w:t:U:P:A:" o; do
case "${o}" in
h)
usage && exit 0
P)
OSM_VCA_PUBKEY=$(cat ${OPTARG})
;;
+ A)
+ OSM_VCA_APIPROXY="${OPTARG}"
+ ;;
w)
# when specifying workdir, do not use sudo for access
WORKDIR_SUDO=
* 1. Bug 745 : Jayant Madavi, Mrityunjay Yadav : JM00553988@techmahindra.com : 23-july-2019 : Improvement to the code, typically we have 2 * or more branches whose build gets triggered, ex master & release branch, the previous code was removing any/all docker.
* Now removing previous docker of the same branch, so that the other branch failed docker should not be removed. It also
* acts as clean-up for previous docker remove failure.
+ * 2. Feature 7829 : Mrityunjay Yadav, Jayant Madavi: MY00514913@techmahindra.com : 19-Aug-2019 : Added a parameters & function to invoke Robot test.
*/
+
properties([
parameters([
string(defaultValue: env.GERRIT_BRANCH, description: '', name: 'GERRIT_BRANCH'),
string(defaultValue: '', description: '', name: 'UPSTREAM_JOB_NAME'),
string(defaultValue: '', description: '', name: 'UPSTREAM_JOB_NUMBER'),
string(defaultValue: '', description: '', name: 'UPSTREAM_JOB_NUMBER'),
- string(defaultValue: 'dpkg1', description: '', name: 'GPG_KEY_NAME'),
+ string(defaultValue: 'OSMETSI', description: '', name: 'GPG_KEY_NAME'),
string(defaultValue: 'artifactory-osm', description: '', name: 'ARTIFACTORY_SERVER'),
string(defaultValue: 'osm-stage_4', description: '', name: 'DOWNSTREAM_STAGE_NAME'),
string(defaultValue: 'releasesix-daily', description: '', name: 'DOCKER_TAG'),
booleanParam(defaultValue: true, description: '', name: 'DO_DOCKERPUSH'),
booleanParam(defaultValue: false, description: '', name: 'SAVE_ARTIFACTS_OVERRIDE'),
string(defaultValue: '/home/jenkins/hive/openstack-etsi.rc', description: '', name: 'HIVE_VIM_1'),
+ booleanParam(defaultValue: true, description: '', name: 'DO_ROBOT'),
+ string(defaultValue: 'sanity', description: 'smoke/vim/sanity/comprehensive are the options', name: 'TEST_NAME'),
+ string(defaultValue: '/home/jenkins/hive/robot-systest.cfg', description: '', name: 'ROBOT_VIM'),
])
])
junit '*.xml'
}
+def run_robot_systest(stackName,tagName,testName,envfile=null) {
+ tempdir = sh(returnStdout: true, script: "mktemp -d").trim()
+ if ( !envfile )
+ {
+ sh(script: "touch ${tempdir}/env")
+ envfile="${tempdir}/env"
+ }
+ sh "docker run --network net${stackName} --env-file ${envfile} -v ${tempdir}:/usr/share/osm-devops/robot-systest/reports opensourcemano/osmclient:${tagName} bash -C /usr/share/osm-devops/robot-systest/run_test.sh --do_install -t ${testName}"
+ sh "cp ${tempdir}/* ."
+ outputDirectory = sh(returnStdout: true, script: "pwd").trim()
+ println ("Present Directory is : ${outputDirectory}")
+ step([
+ $class : 'RobotPublisher',
+ outputPath : "${outputDirectory}",
+ outputFileName : "*.xml",
+ disableArchiveOutput : false,
+ reportFileName : "report.html",
+ logFileName : "log.html",
+ passThreshold : 80,
+ unstableThreshold: 60.0,
+ otherFiles : "*.png",
+ ])
+}
+
node("${params.NODE}") {
sh 'env'
if ( params.DO_STAGE_4 ) {
// override stage_archive to only archive on stable
stage_archive = false
- stage("stage_4") {
- run_systest(container_name,container_name,"openstack_stage_4",params.HIVE_VIM_1)
+ stage("System Integration Test") {
+ if ( params.DO_ROBOT ) {
+ run_robot_systest(container_name,container_name,params.TEST_NAME,params.ROBOT_VIM)
+ } else {
+ run_systest(container_name,container_name,"openstack_stage_4",params.HIVE_VIM_1)
+ }
if ( ! currentBuild.result.equals('UNSTABLE') ) {
stage_archive = keep_artifacts
currentBuild.result = 'FAILURE'
}
finally {
-
-
if ( params.DO_INSTALL ) {
if (error) {
if ( !params.SAVE_CONTAINER_ON_FAIL ) {
--- /dev/null
+<!--
+Copyright 2019 Tech Mahindra Limited
+
+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.
+-->
+
+
+# Step to run robot framework test standalone linux environment
+
+All installation commands run using root user(`sudo su`)
+## Step 1: Install python packages
+Install below python packages using pip
+>pip install python-magic pyangbind haikunator requests pyvcloud progressbar pathlib robotframework robotframework-seleniumlibrary robotframework-requests
+
+## Step 2: Install linux packages
+Install below linux packages
+>curl http://osm-download.etsi.org/repository/osm/debian/ReleaseSIX/OSM%20ETSI%20Release%20Key.gpg | apt-key add -
+
+>add-apt-repository -y "deb http://osm-download.etsi.org/repository/osm/debian/ReleaseSIX stable devops osmclient IM" && apt update
+
+>curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
+
+>echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
+
+> apt-get install -y python-osmclient python-osm-im google-chrome-stable chromium-chromedriver
+
+>./git-repo/devops/tools/OVF_converter/install.sh
+
+## Step 3: checkout robot seed code
+Checkout devops from gerrit
+> git clone "https://osm.etsi.org/gerrit/osm/devops"
+
+If robot seed code not merged to to master, pull it
+> git pull "https://osm.etsi.org/gerrit/osm/devops" refs/changes/52/7852/4
+
+## Step 4: Set environmet
+for build test need to create env-file and provide below details and for Standalone testing export them
+```
+export OSM_HOSTNAME=<OSM server IP>
+```
+
+OpenStack Details
+```
+export OS_AUTH_URL=<auth url>
+export OS_PASSWORD=<password>
+export OS_PROJECT_NAME=<project name>
+export OS_VIM_CONFIG=<config value>
+```
+
+VCD Details
+```
+export VCD_AUTH_URL=<VCD auth url>
+export VCD_USERNAME=<VCD username>
+export VCD_PASSWORD=<VCD password>
+export VCD_TENANT_NAME=<VCD Tenant name>
+export VCD_ORGANIZATION=<VCD Org name>
+export VCD_VIM_CONFIG=<config value>
+```
+
+Note:- Optional
+```
+export NS_CONFIG=<NS Config Details>
+e.g. export NS_CONFIG="'{vld: [ {name: mgmtnet, vim-network-name: mgmt}]}'"
+```
+
+## Step 5: Run Test
+There are two ways to run the test-case:
+* use `devops/robot-systest/run_test.sh` file and provide test-name(vim/smoke/sanity/comprehensive).
+ > ./devops/robot-systest/run_test.sh -t smoke
+
+* use `robot` command
+ > robot -d path/to/report/dir -i test-tag-to-be-included -e test-tag-to-be-excluded path/to/testsuiet
+
+ > robot -d devops/robot-systest/reports -i comprehensive devops/robot-systest/testsuite
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com
+##
+
+
+*** Variables ***
+${token}= ${EMPTY}
+${HOST}= ${EMPTY}
+
+
+*** Keywords ***
+Get Auth Token
+ [Tags] auth_token
+
+ ${nbi_host}= Get Environment Variable OSM_HOSTNAME
+ ${passed}= Run Keyword And Return Status Should Contain ${nbi_host} :
+ Run Keyword If ${passed} Set Dockerized Host ${nbi_host}
+ ... ELSE Set Standalone Host ${nbi_host}
+
+ Create Session osmhit ${HOST} verify=${FALSE} debug=1 headers=${HEADERS}
+
+ Log Many ${auth_token_uri} @{data} ${data}
+
+ ${resp}= Post Request osmhit ${auth_token_uri} data=${data}
+ log ${resp}
+
+ Pass Execution If ${resp.status_code} in ${success_status_code_list} Get Auth Token completed
+
+ ${content}= To Json ${resp.content}
+ ${t}= Get From Dictionary ${content} _id
+
+ Set Suite Variable ${token} ${t}
+
+
+Set Dockerized Host
+ [Arguments] ${env_host}
+
+ Set Suite Variable ${HOST} https://${env_host}
+
+
+Set Standalone Host
+ [Arguments] ${env_host}
+
+ Set Suite Variable ${HOST} https://${env_host}:9999
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-sep-2019
+##
+
+
+*** Keywords ***
+Create Vim
+ [Arguments] ${vim_name} ${account_type} ${auth_url} ${user} ${password} ${tenant} ${description}
+
+ &{request_data}= Create Dictionary vim_user=${user} vim_password=${password} vim_url=${auth_url} vim_tenant_name=${tenant} vim_type=${account_type} description=${description} name=${vim_name}
+
+ &{headers}= Create Dictionary Authorization=Bearer ${token} Content-Type=application/json Accept=application/json
+
+ Create Session osmvim ${HOST} verify=${FALSE} headers=${headers}
+
+ LOG ${request_data}
+ ${res}= Post Request osmvim ${create_vim_uri} data=${request_data}
+ log ${res.content}
+ Pass Execution If ${res.status_code} in ${success_status_code_list} Create Vim Request completed
+ Get Vim ID ${res.content}
+
+
+Delete Vim
+ [Arguments] ${vim_id}
+
+ ${uri} = Catenate SEPARATOR=/ ${create_vim_uri} ${vim_id}
+ ${resp}= Delete Request osmvim ${uri}
+
+ log ${resp.content}
+ Pass Execution If ${resp.status_code} in ${success_status_code_list} Delete Vim Request completed
+
+
+Get Vim ID
+ [Arguments] ${res}
+
+# log to console ${res}
+ ${content}= To Json ${res}
+ ${id}= Get From Dictionary ${content} id
+ Set Suite Variable ${vim_id} ${id}
+ log Vim Id is ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+*** Variables ***
+${success_return_code} 0
+${ns_launch_max_wait_time} 5min
+${ns_launch_pol_time} 30sec
+${ns_delete_max_wait_time} 1min
+${ns_delete_pol_time} 15sec
+
+
+*** Keywords ***
+Get NS List
+ [Documentation] Get ns instance list
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-list
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Launch Network Services and Return
+ [Arguments] ${vim_name}
+
+ Should Not Be Empty ${nsd_ids} There are no NS descriptors to launch the NS
+ :FOR ${nsd} IN @{nsd_ids}
+ \ ${ns_name}= GENERATE NAME
+ \ Append To List ${ns_ids} ${ns_name}
+ \ Create Network Service ${nsd} ${vim_name} ${ns_name}
+ \ Delete NS ${ns_name}
+
+
+Create Network Service
+ [Documentation] Create ns at osm
+ [Arguments] ${nsd} ${vim_name} ${ns_name}
+
+ ${ns_config}= Get Environment Variable NS_CONFIG ${EMPTY}
+ Run Keyword If ${ns_config}!='${EMPTY}' Create Network Service With Config ${nsd} ${vim_name} ${ns_name} ${ns_config}
+ ... ELSE Create Network Service Without Config ${nsd} ${vim_name} ${ns_name}
+
+ WAIT UNTIL KEYWORD SUCCEEDS ${ns_launch_max_wait_time} ${ns_launch_pol_time} Check For NS Instance To Configured ${ns_name}
+ Check For NS Instance For Failure ${ns_name}
+
+
+Create Network Service Without Config
+ [Documentation] Create ns at osm
+ [Arguments] ${nsd} ${vim_name} ${ns_name}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-create --ns_name ${ns_name} --nsd_name ${nsd} --vim_account ${vim_name}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Create Network Service With Config
+ [Documentation] Create ns at osm
+ [Arguments] ${nsd} ${vim_name} ${ns_name} ${ns_config}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-create --ns_name ${ns_name} --nsd_name ${nsd} --vim_account ${vim_name} --config ${ns_config}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Delete NS
+ [Documentation] Delete ns
+ [Arguments] ${ns}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-delete ${ns}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+ WAIT UNTIL KEYWORD SUCCEEDS ${ns_delete_max_wait_time} ${ns_delete_pol_time} Check For NS Instance To Be Delete ${ns}
+
+
+Check For NS Instance To Configured
+ [Arguments] ${ns_name}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-list --filter name="${ns_name}"
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Should Contain Any ${stdout} configured failed
+
+
+Check For NS Instance For Failure
+ [Arguments] ${ns_name}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-list --filter name="${ns_name}"
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Should Not Contain ${stdout} failed
+
+
+Check For NS Instance To Be Delete
+ [Arguments] ${ns}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-list
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Should Not Contain ${stdout} ${ns}
+
+
+Force Delete NS
+ [Documentation] Forcely Delete ns
+ [Arguments] ${ns}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm ns-delete ${ns}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ WAIT UNTIL KEYWORD SUCCEEDS ${ns_delete_max_wait_time} ${ns_delete_pol_time} Check For NS Instance To Be Delete ${ns}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-sep-2019
+##
+
+*** Variables ***
+${success_return_code} 0
+${delete_max_wait_time} 1min
+${delete_pol_time} 15sec
+
+
+*** Keywords ***
+Get NSDs List
+ [Documentation] Get nsds list
+
+ ${rc} ${stdout}= Run and Return RC and Output osm nsd-list
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Create NSD
+ [Documentation] Create nsd at osm
+ [Arguments] ${nsd_pkg}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm nsd-create ${nsd_pkg}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ [Return] ${stdout}
+
+
+Delete NSD
+ [Documentation] Delete nsd
+ [Arguments] ${nsd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm nsd-delete ${nsd_id}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ WAIT UNTIL KEYWORD SUCCEEDS ${delete_max_wait_time} ${delete_pol_time} Check For NSD ${nsd_id}
+
+
+Check For NSD
+ [Arguments] ${nsd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm nsd-list
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Should Not Contain ${stdout} ${nsd_id}
+
+
+Force Delete NSD
+ [Documentation] Forcely Delete nsd
+ [Arguments] ${nsd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm nsd-delete ${nsd_id}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Build NS Descriptor
+ [Documentation] Build NS Descriptor from the descriptor-packages
+ [Arguments] ${nsd path}
+
+ ${rc} ${stdout}= Run and Return RC and Output make -C '${CURDIR}${/}../../..${nsd path}'
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+
+*** Variables ***
+${success_return_code} 0
+${name} "OpenSite"
+${user} "admin"
+${password} "admin"
+${ip} "1.1.1.1"
+${type} "onos"
+${port} "5858"
+${dpid} ""
+
+
+*** Keywords ***
+Create SDNC Account
+ [Documentation] create new sdnc account
+
+ ${rc} ${stdout}= Run and Return RC and Output osm sdnc-create --name ${name} --type ${type} --ip-address ${ip} --user ${user} --password ${password} --port ${port} --switch_dpid ${dpid} return_rc=True
+ log ${rc}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Get SDNC List
+ [Documentation] Get a sdnc account list
+
+ ${rc} ${stdout}= Run and Return RC and Output osm sdnc-list
+ log ${stdout}
+
+
+Show SDNC Account
+ [Documentation] Get sdnc account details
+
+ ${rc} ${stdout}= Run and Return RC and Output osm sdnc-show ${name} return_rc=True
+ log ${rc}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Delete SDNC Account
+ [Documentation] Get sdnc account details
+
+ ${rc} ${stdout}= Run and Return RC and Output osm sdnc-delete ${name} return_rc=True
+ log ${rc}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-sep-2019
+##
+
+
+*** Variables ***
+${success_return_code} 0
+${name} "helloworld-os"
+${user} "robottest"
+${password} "fred"
+${authurl} "https://169.254.169.245/"
+${type} "openstack"
+${desc} "a test vim"
+${tenant} "robottest2"
+
+
+*** Keywords ***
+Create Vim Account
+ [Documentation] Create a new vim account
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-create --name ${name} --user ${user} --password ${password} --auth_url ${authurl} --tenant ${tenant} --account_type ${type} --description ${desc}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Get Vim List
+ [Documentation] Get a vim account list
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-list
+ log ${stdout}
+ Log To Console ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Delete Vim Account
+ [Documentation] delete vim account details
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-delete ${name}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+VIM Setup To Launch Network Services
+ [Documentation] Setup a VIM to launch network services
+
+ ${vmware_url}= Get Environment Variable VCD_AUTH_URL ${EMPTY}
+ ${openstack_url}= Get Environment Variable OS_AUTH_URL ${EMPTY}
+ ${vmware_vim}= Run Keyword And Return If '${vmware_url}'!='${EMPTY}' Setup Vmware Vim ${vmware_url} 'vmware' 'pytest system test'
+ ${openstack_vim}= Run Keyword And Return If '${openstack_url}'!='${EMPTY}' Setup Openstack Vim ${openstack_url} 'openstack' 'pytest system test'
+
+ Log Many @{vim}
+
+
+Setup Openstack Vim
+ [Documentation] Openstack Vim Account Setup
+ [Arguments] ${authurl} ${type} ${desc}
+
+ ${user}= Get Environment Variable OS_USERNAME ''
+ ${password}= Get Environment Variable OS_PASSWORD ''
+ ${tenant}= Get Environment Variable OS_PROJECT_NAME ''
+ ${vim-config}= Get Environment Variable OS_VIM_CONFIG ''
+ ${vim_name}= GENERATE NAME
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-create --name ${vim_name} --user ${user} --password ${password} --auth_url ${authurl} --tenant ${tenant} --account_type ${type} --description ${desc} --config ${vim-config}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Append To List ${vim} ${stdout}
+ [Return] ${stdout}
+
+
+Setup Vmware Vim
+ [Documentation] Vmware Vim Account Setup
+ [Arguments] ${authurl} ${type} ${desc}
+
+ ${user}= Get Environment Variable VCD_USERNAME ''
+ ${password}= Get Environment Variable VCD_PASSWORD ''
+ ${tenant}= Get Environment Variable VCD_TENANT_NAME ''
+ ${vcd-org}= Get Environment Variable VCD_ORGANIZATION ''
+ ${vim-config}= Get Environment Variable VCD_VIM_CONFIG ''
+ ${vim_name}= GENERATE NAME
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-create --name ${vim_name} --user ${user} --password ${password} --auth_url ${authurl} --tenant ${tenant} --account_type ${type} --description ${desc} --config ${vim-config}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Append To List ${vim} ${stdout}
+ [Return] ${stdout}
+
+
+Force Delete Vim Account
+ [Documentation] delete vim account details
+ [Arguments] ${vim_name}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vim-delete ${vim_name}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-sep-2019
+##
+
+*** Variables ***
+${success_return_code} 0
+${delete_max_wait_time} 1min
+${delete_pol_time} 15sec
+
+
+*** Keywords ***
+Get VNFDs List
+ [Documentation] Get vnfds list
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vnfd-list
+ log ${stdout}
+ log ${rc}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Create VNFD
+ [Documentation] Create vnfd at osm
+ [Arguments] ${vnfd_pkg}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vnfd-create ${vnfd_pkg}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ [Return] ${stdout}
+
+
+Delete VNFD
+ [Documentation] Delete vnfd
+ [Arguments] ${vnfd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vnfd-delete ${vnfd_id}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ WAIT UNTIL KEYWORD SUCCEEDS ${delete_max_wait_time} ${delete_pol_time} Check For VNFD ${vnfd_id}
+
+
+Check For VNFD
+ [Arguments] ${vnfd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vnfd-list
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+ Should Not Contain ${stdout} ${vnfd_id}
+
+
+Force Delete VNFD
+ [Documentation] Forcely Delete vnfd
+ [Arguments] ${vnfd_id}
+
+ ${rc} ${stdout}= Run and Return RC and Output osm vnfd-delete ${vnfd_id}
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
+
+
+Build VNF Descriptor
+ [Documentation] Build VNF Descriptor from the descriptor-packages
+ [Arguments] ${vnfd path}
+
+ ${rc} ${stdout}= Run and Return RC and Output make -C '${CURDIR}${/}../../..${vnfd path}'
+ log ${stdout}
+ Should Be Equal As Integers ${rc} ${success_return_code}
--- /dev/null
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+
+from osmclient import client
+from robot.api import logger
+import json
+
+
+class ClientLib:
+ def __init__(self, host="127.0.0.1", user=None, password=None, project=None):
+
+ kwargs = {}
+ if user is not None:
+ kwargs['user'] = user
+ if password is not None:
+ kwargs['password'] = password
+ if project is not None:
+ kwargs['project'] = project
+ self.client = client.Client(host=host, sol005=True, **kwargs)
+
+ def get_vim_list(self):
+ resp = self.client.vim.list()
+ logger.info('VIM List: {}'.format(resp))
+ return json.dumps(resp)
+
+ def create_vim_account(self, name, vim_type, user, password, auth_url, tenant, desc='', config=None):
+ vim_access = {}
+ if config is not None:
+ vim_access['config'] = config
+ vim_access['vim-type'] = vim_type
+ vim_access['vim-username'] = user
+ vim_access['vim-password'] = password
+ vim_access['vim-url'] = auth_url
+ vim_access['vim-tenant-name'] = tenant
+ vim_access['description'] = desc
+
+ resp = self.client.vim.create(name, vim_access)
+ logger.info('Create VIM Account: {}'.format(resp))
+ return json.dumps(resp)
+
+ def delete_vim_account(self, name):
+ resp = self.client.vim.delete(name)
+ return json.dumps(resp)
+
+ def get_vnfd_list(self):
+ resp = self.client.vnfd.list()
+ logger.info('VNF Descriptor List: {}'.format(resp))
+ return json.dumps(resp)
+
+ def get_nsd_list(self):
+ resp = self.client.nsd.list()
+ logger.info('NS Descriptor List: {}'.format(resp))
+ return json.dumps(resp)
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+from haikunator import Haikunator
+
+
+def generate_name():
+ haikunator = Haikunator()
+ name = haikunator.haikunate(delimiter='_', token_length=2)
+ return name
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+*** Variables ***
+${DESIRED_CAPABILITIES} desired_capabilities
+${BROWSER} Chrome
+${DELAY} 0
+${VALID USER} admin
+${VALID PASSWORD} admin
+${LOGIN URL} /auth/
+${WELCOME URL} /projects/
+${NS LIST URL} /packages/ns/list
+${VNF LIST URL} /packages/vnf/list
+
+
+*** Keywords ***
+Set Server URL
+ ${env_host}= Get Environment Variable OSM_HOSTNAME
+ ${passed}= Run Keyword And Return Status Should Contain ${env_host} :
+ Run Keyword If ${passed} Set Dockerized Host
+ ... ELSE Set Standalone Host ${env_host}
+
+
+Open Browser To Login Page
+ ${chrome_options} = Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys, selenium.webdriver
+ Call Method ${chrome_options} add_argument headless
+ Call Method ${chrome_options} add_argument disable-gpu
+ Call Method ${chrome_options} add_argument no-sandbox
+ ${options}= Call Method ${chrome_options} to_capabilities
+ Open Browser ${SERVER}${LOGIN URL} ${BROWSER} desired_capabilities=${options}
+ Maximize Browser Window
+ Set Selenium Speed ${DELAY}
+ Login Page Should Be Open
+
+
+Login Page Should Be Open
+ Element Text Should Be //*[@id="main_content"]/div/div[2]/p Sign in to start your session
+
+
+Enter Credentials
+ [Arguments] ${username} ${password}
+ Input Text name:username ${username}
+ Input Password name:password ${password}
+
+
+Submit Credentials
+ Click Button //*[@id="main_content"]/div/div[2]/form/div[3]/div[2]/button
+
+
+Home Page Should Be Open
+ Location Should Be ${SERVER}${WELCOME URL}
+# Element Should Contain id:title_header 6e3a8415-9014-4100-9727-90e0150263be ignore_case=True
+ Element Attribute Value Should Be //*[@id="main_content"]/div/div[2]/div[1]/div[1]/div/a href ${SERVER}${NS LIST URL}
+ Element Attribute Value Should Be //*[@id="main_content"]/div/div[2]/div[1]/div[2]/div/a href ${SERVER}${VNF LIST URL}
+
+
+Set Dockerized Host
+
+ Set Suite Variable ${SERVER} http://light-ui
+
+
+Set Standalone Host
+ [Arguments] ${env_host}
+
+ Set Suite Variable ${SERVER} http://${env_host}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com
+##
+
+
+*** Variables ***
+&{HEADERS} Content-Type=application/json Accept=application/json
+&{data} username=admin password=admin project-id=admin
+@{success_status_code_list} 200 201 202 204
+
+${descriptor_content_type_gzip} application/gzip
+
+${auth_token_uri} /osm/admin/v1/tokens
+
+${get_all_vnfd_uri} /osm/vnfpkgm/v1/vnf_packages
+${create_vnfd_uri} /osm/vnfpkgm/v1/vnf_packages_content
+${delete_vnfd_uri} /osm/vnfpkgm/v1/vnf_packages
+
+${get_all_nsd_uri} /osm/nsd/v1/ns_descriptors
+${create_nsd_uri} /osm/nsd/v1/ns_descriptors_content
+${delete_nsd_uri} /osm/nsd/v1/ns_descriptors
+
+${base_ns_uri} /osm/nslcm/v1/ns_instances_content
+${create_ns_uri} /osm/nslcm/v1/ns_instances_content
+
+${create_vim_uri} /osm/admin/v1/vim_accounts
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-sep-2019
+##
+
+
+# Create/Delete Vim Account
+vim_name = 'API-TEST-VIM'
+account_type = 'openstack'
+auth_url = 'http://127.0.0.1:5000/v3'
+user = 'admin'
+password = 'admin'
+tenant = 'admin'
+description = 'Test OpenStack Vim Account'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/hackfest_basic_vnf"
+vnfdPckg = '/build/hackfest_basic_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/hackfest_basic_ns"
+nsdPckg = '/build/hackfest_basic_ns.tar.gz'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/hackfest_cloudinit_vnf"
+vnfdPckg = '/build/hackfest_cloudinit_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/hackfest_cloudinit_ns"
+nsdPckg = '/build/hackfest_cloudinit_ns.tar.gz'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/hackfest_epasriov_vnf"
+vnfdPckg = '/build/hackfest_epasriov_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/hackfest_epasriov_ns"
+nsdPckg = '/build/hackfest_epasriov_ns.tar.gz'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/hackfest_multivdu_vnf"
+vnfdPckg = '/build/hackfest_multivdu_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/hackfest_multivdu_ns"
+nsdPckg = '/build/hackfest_multivdu_ns.tar.gz'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/hackfest_simplecharm_vnf"
+vnfdPckg = '/build/hackfest_simplecharm_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/hackfest_simplecharm_ns"
+nsdPckg = '/build/hackfest_simplecharm_ns.tar.gz'
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com
+##
+
+
+# VNFD Details
+vnfdPckgPath = "/descriptor-packages/vnfd/cirros_vnf"
+vnfdPckg = '/build/cirros_vnf.tar.gz'
+
+# NSD Details
+nsdPckgPath = "/descriptor-packages/nsd/cirros_ns"
+nsdPckg = '/build/cirros_ns.tar.gz'
--- /dev/null
+#!/usr/bin/env bash
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-Sep-2019
+# Entry script to start the vim, smoke, openstack_stage_4 and comprehensive test using Robot Framework as a Automation Test Framework
+##
+
+BASEDIR=$(dirname "$0")
+TOPDIR=$(dirname "$BASEDIR")
+DESCRIPTOR_DIR=$TOPDIR/descriptor-packages
+
+
+robot_prerequisite(){
+ echo -e "\nInstalling robot requirements"
+ # installing python packages
+ pip install haikunator requests robotframework robotframework-seleniumlibrary robotframework-requests
+
+ # installing chrome driver and chrome for UI testing
+ curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
+ echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
+ apt-get update && apt-get -y install google-chrome-stable chromium-chromedriver
+}
+
+while getopts ":t:-:" o; do
+ case "${o}" in
+ t)
+ TEST=${OPTARG}
+ ;;
+ -)
+ [[ "${OPTARG}" == "do_install" ]] && robot_prerequisite && continue
+ ;;
+ \?)
+ echo -e "Invalid option: '-$OPTARG'\n" >&2
+ exit 1
+ ;;
+ esac
+done
+
+if [[ -z $TEST ]]; then
+ printf "Test not provided. \nRunning default test: smoke\n"
+ TEST="smoke"
+fi
+
+if [[ "$TEST" == "vim" ]]; then
+ echo "Robot Framework Vim Test"
+ robot -d $BASEDIR/reports -i vim $BASEDIR/testsuite/
+ exit 0
+elif [[ "$TEST" == "smoke" ]]; then
+ echo "Robot Framework SMOKE test"
+ robot -d $BASEDIR/reports -i smoke $BASEDIR/testsuite/
+ exit 0
+elif [[ "$TEST" == "sanity" ]]; then
+ echo "Robot Framework Cirros VNF Test"
+ mkdir -p $BASEDIR/images/cache
+ if [[ ! -z $OS_AUTH_URL ]]; then
+ (openstack image show cirros-0.3.5-x86_64-disk.img) || (wget -r -nc http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img -O $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img && make $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img && openstack image create --file $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img cirros-0.3.5-x86_64-disk.img)
+ fi
+ if [[ ! -z $VCD_AUTH_URL ]]; then
+# TODO: Check for image over VIM before downloading
+ if [[ ! -s $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img ]]; then
+ wget -r -nc http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img -O $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img
+ fi
+ ovf_converter $BASEDIR/images/cache/cirros-0.3.5-x86_64-disk.img -n cirros
+ python $TOPDIR/tools/vmware_ovf_upload.py $VCD_AUTH_URL $VCD_USERNAME $VCD_PASSWORD $VCD_ORGANIZATION $BASEDIR/images/cache/cirros.ovf
+ fi
+ robot -d $BASEDIR/reports -i sanity $BASEDIR/testsuite/
+ exit 0
+elif [[ "$TEST" == "comprehensive" ]]; then
+ echo "Robot Framework Comprehensive Test"
+ mkdir -p $BASEDIR/images/cache
+ if [[ ! -z $OS_AUTH_URL ]]; then
+ (openstack image show ubuntu1604) || (wget -r -nc https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img -O $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img && make $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img && openstack image create --file $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img ubuntu1604)
+ (openstack image show hackfest3-mgmt) || (wget -r -nc https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img -O $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img && make $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img && openstack image create --file $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img hackfest3-mgmt)
+ fi
+ if [[ ! -z $VCD_AUTH_URL ]]; then
+# TODO: Check for image over VIM before downloading
+ if [[ ! -s $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img ]]; then
+ wget -r -nc https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img -O $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img
+ fi
+ ovf_converter $BASEDIR/images/cache/xenial-server-cloudimg-amd64-disk1.img -n ubuntu1604
+ python $TOPDIR/tools/vmware_ovf_upload.py $VCD_AUTH_URL $VCD_USERNAME $VCD_PASSWORD $VCD_ORGANIZATION $BASEDIR/images/cache/ubuntu1604.ovf
+ fi
+ robot -d $BASEDIR/reports -i comprehensive $BASEDIR/testsuite/
+ exit 0
+else
+ echo "wrong test provided"
+ exit 1
+fi
+
+exit 1
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+*** Settings ***
+Documentation Test Suite to create and delete vim account
+Library Collections
+Library RequestsLibrary
+Library OperatingSystem
+Resource ../../lib/api/common.robot
+Resource ../../lib/api/vim_lib.robot
+Resource ../../resource/api/common.robot
+Variables ../../resource/api/variables.py
+
+Suite Setup Get Auth Token
+Suite Teardown Delete All Sessions
+
+
+*** Variables ***
+${vim_id} ${EMPTY}
+
+
+*** Test Cases ***
+Create Vim Account
+ [Tags] comprehensive api_vim_test
+ [Template] Create Vim
+ ${vim name} ${account type} ${auth url} ${user} ${password} ${tenant} ${description}
+
+
+Delete Vim Account
+ [Tags] comprehensive api_vim_test
+ [Template] Delete Vim
+ ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+
+*** Settings ***
+Documentation Test suiet to create/delete sdnc account via osmclient
+Library OperatingSystem
+Library Collections
+Resource ../../lib/cli/sdnc_account_lib.robot
+
+
+*** Test Cases ***
+Create SDNC Account Test
+ [Tags] comprehensive sdnc
+
+ Create SDNC Account
+
+
+Get SDNC Accounts List Test
+ [Tags] comprehensive sdnc
+
+ Get SDNC List
+
+
+Delete SDNC Account Test
+ [Tags] comprehensive sdnc
+
+ Delete SDNC Account
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to test basic cirros VNF and NS using osm-client
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/test_vnf_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+#${vim_name} robot_test
+
+
+*** Test Cases ***
+Create VNF Descriptor Test
+ [Tags] sanity smoke
+
+ Build VNF Descriptor ${vnfdPckgPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create NS Descriptor Test
+ [Tags] sanity smoke
+
+ Build NS Descriptor ${nsdPckgPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] sanity
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] sanity smoke
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] sanity smoke
+
+ :FOR ${vnfd} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd}
+
+ :FOR ${vnfd} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns} IN @{ns_ids}
+ \ Force Delete NS ${ns}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com : 06-aug-2019 : Improvement to the code, robot framework initial seed code.
+##
+
+
+*** Settings ***
+Documentation Test suiet to create/delete vim account via osmclient
+Library OperatingSystem
+Library Collections
+Resource ../../lib/cli/vim_account_lib.robot
+
+
+*** Test Cases ***
+Create Vim Account Test
+ [Tags] smoke vim
+
+ Create Vim Account
+
+
+Get Vim Accounts List Test
+ [Tags] vim
+
+ Get Vim List
+
+
+Delete Vim Account Test
+ [Tags] smoke vim
+
+ Delete Vim Account
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to create hackfest basic nestwork service
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/hackfest_basic_ns_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+${nsd_id}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+
+
+*** Test Cases ***
+Create Hackfest Basic VNF Descriptor
+ [Tags] comprehensive hackfest_basic_ns
+
+ Build VNF Descriptor ${vnfdPckgPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create Hackfest Basic NS Descriptor
+ [Tags] comprehensive hackfest_basic_ns
+
+ Build NS Descriptor ${nsdPckgPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] comprehensive hackfest_basic_ns
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] comprehensive hackfest_basic_ns
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] comprehensive hackfest_basic_ns
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd_id}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd_id}
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd_id}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns_id} IN @{ns_ids}
+ \ Force Delete NS ${ns_id}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to create hackfest simplecharm ns
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/hackfest_simplecharm_ns_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+${nsd_id}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+${vnfdftpPath} https://osm-download.etsi.org/ftp/osm-6.0-six/7th-hackfest/packages/hackfest_simplecharm_vnf.tar.gz
+${nsdftpPath} https://osm-download.etsi.org/ftp/osm-6.0-six/7th-hackfest/packages/hackfest_simplecharm_ns.tar.gz
+
+
+*** Test Cases ***
+Create Hackfest Simple Charm VNF Descriptor
+ [Tags] hackfest_simplecharm comprehensive
+
+ #Build VNF Descriptor ${vnfdPckgPath}
+ #Workarround for charm build issue
+ ${rc} ${stdout}= Run and Return RC and Output wget -P '${CURDIR}${/}../../..${vnfdPckgPath}${/}build/' ${vnfdftpPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create Hackfest Simple Charm NS Descriptor
+ [Tags] hackfest_simplecharm comprehensive
+
+ #Build NS Descriptor ${nsdPckgPath}
+ ${rc} ${stdout}= Run and Return RC and Output wget -P '${CURDIR}${/}../../..${nsdPckgPath}${/}build/' ${nsdftpPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] hackfest_simplecharm comprehensive
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] hackfest_simplecharm comprehensive
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] hackfest_simplecharm comprehensive
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd_id}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd_id}
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd_id}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns_id} IN @{ns_ids}
+ \ Force Delete NS ${ns_id}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to create hackfest multivdu ns
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/hackfest_multivdu_ns_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+${nsd_id}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+
+
+*** Test Cases ***
+Create Hackfest Multivdu VNF Descriptor
+ [Tags] comprehensive hackfest_multivdu
+
+ Build VNF Descriptor ${vnfdPckgPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create Hackfest Multivdu NS Descriptor
+ [Tags] comprehensive hackfest_multivdu
+
+ Build NS Descriptor ${nsdPckgPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] comprehensive hackfest_multivdu
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] comprehensive hackfest_multivdu
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] comprehensive hackfest_multivdu
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd_id}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd_id}
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd_id}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns_id} IN @{ns_ids}
+ \ Force Delete NS ${ns_id}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to create hackfest cloudinit ns
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/hackfest_cloudinit_ns_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+${nsd_id}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+
+
+*** Test Cases ***
+Create Hackfest Cloudinit VNF Descriptor
+ [Tags] comprehensive hackfest_cloudinit
+
+ Build VNF Descriptor ${vnfdPckgPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create Hackfest Cloudinit NS Descriptor
+ [Tags] comprehensive hackfest_cloudinit
+
+ Build NS Descriptor ${nsdPckgPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] comprehensive hackfest_cloudinit
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] comprehensive hackfest_cloudinit
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] comprehensive hackfest_cloudinit
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd_id}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd_id}
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd_id}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns_id} IN @{ns_ids}
+ \ Force Delete NS ${ns_id}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Mrityunjay Yadav, Jayant Madavi : MY00514913@techmahindra.com : 06-aug-2019
+##
+
+
+*** Settings ***
+Documentation Test Suite to create hackfest epa ns
+Library OperatingSystem
+Library String
+Library Collections
+Resource ../../lib/cli/vnfd_lib.robot
+Resource ../../lib/cli/nsd_lib.robot
+Resource ../../lib/cli/ns_lib.robot
+Resource ../../lib/cli/vim_account_lib.robot
+Library ../../lib/custom_lib.py
+Variables ../../resource/cli/hackfest_epa_ns_data.py
+
+Suite Teardown Run Keyword And Ignore Error Test Cleanup
+
+
+*** Variables ***
+@{vnfd_ids}
+${nsd_id}
+@{nsd_ids}
+@{ns_ids}
+@{vim}
+
+
+*** Test Cases ***
+Create Hackfest EPA VNF Descriptor
+ [Tags] hackfest_epa
+
+ Build VNF Descriptor ${vnfdPckgPath}
+ ${vnfd_id}= Create VNFD '${CURDIR}${/}../../..${vnfdPckgPath}${vnfdPckg}'
+ Append To List ${vnfd_ids} ${vnfd_id}
+
+
+Create Hackfest EPA NS Descriptor
+ [Tags] hackfest_epa
+
+ Build NS Descriptor ${nsdPckgPath}
+ ${nsd_id}= Create NSD '${CURDIR}${/}../../..${nsdPckgPath}${nsdPckg}'
+ Append To List ${nsd_ids} ${nsd_id}
+
+
+Network Service Instance Test
+ [Documentation] Launch and terminate network services
+ [Tags] hackfest_epa
+ [Setup] VIM Setup To Launch Network Services
+ [Teardown] Run Keyword And Ignore Error Network Service Instance Cleanup
+
+ Should Not Be Empty ${vim} VIM details not provided
+ :FOR ${vim_name} IN @{vim}
+ \ Launch Network Services and Return ${vim_name}
+
+
+Delete NS Descriptor Test
+ [Tags] hackfest_epa
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Delete NSD ${nsd}
+
+
+Delete VNF Descriptor Test
+ [Tags] hackfest_epa
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Delete VNFD ${vnfd_id}
+
+
+*** Keywords ***
+Test Cleanup
+ [Documentation] Test Suit Cleanup: Forcefully delete NSD and VNFD
+
+ :FOR ${nsd} IN @{nsd_ids}
+ \ Force Delete NSD ${nsd_id}
+
+ :FOR ${vnfd_id} IN @{vnfd_ids}
+ \ Force Delete VNFD ${vnfd_id}
+
+
+Network Service Instance Cleanup
+ [Documentation] Forcefully delete created network service instances and vim account
+
+ :FOR ${ns_id} IN @{ns_ids}
+ \ Force Delete NS ${ns_id}
+
+ :FOR ${vim_id} IN @{vim}
+ \ Force Delete Vim Account ${vim_id}
--- /dev/null
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+
+*** Settings ***
+Documentation Test suite to test osmclient python library
+Library OperatingSystem
+
+Suite Setup Setup OSM Client
+
+
+*** Variables ***
+${name} helloworld-os
+${user} robottest
+${password} fred
+${authurl} https://169.254.169.245/
+${type} openstack
+${desc} a test vim
+${tenant} robottest
+
+
+*** Test Cases ***
+Get VIM Account List Test
+ [Tags] comprehensive osmclient_lib
+ [Documentation] Using python's osmclient library to get vim account list
+
+ ${vim_list}= osmclient.get_vim_list
+ log to console ${vim_list}
+ log ${vim_list}
+
+
+Get VNF Descriptor List Test
+ [Tags] comprehensive osmclient_lib
+ [Documentation] Using python's osmclient library to get vnfd list
+
+ ${vnfd_list}= osmclient.get_vnfd_list
+ log to console ${vnfd_list}
+ log ${vnfd_list}
+
+
+Get NS Descriptor List Test
+ [Tags] comprehensive osmclient_lib
+ [Documentation] Using python's osmclient library to get nsd list
+
+ ${nsd_list}= osmclient.get_nsd_list
+ log to console ${nsd_list}
+ log ${nsd_list}
+
+
+Create Vim Account Test
+ [Tags] comprehensive osmclient_lib
+ [Documentation] Using python's osmclient library to create vim account
+ [Template] osmclient.create_vim_account
+ ${name} ${type} ${user} ${password} ${authurl} ${tenant} ${desc}
+
+
+Delete Vim Account Test
+ [Tags] comprehensive osmclient_lib
+ [Documentation] Using python's osmclient library to delete vim account
+ osmclient.delete_vim_account ${name}
+
+
+*** Keywords ***
+Setup OSM Client
+ evaluate sys.path.append('${CURDIR}${/}../../lib/client_lib') modules=sys
+ ${host}= Get Environment Variable OSM_HOSTNAME 127.0.0.1
+ Import Library ClientLib host=${host} WITH NAME osmclient
--- /dev/null
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2019 Tech Mahindra Limited
+#
+# 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.
+##
+
+## Change log:
+# 1. Feature 7829: Jayant Madavi, Mrityunjay Yadav : MY00514913@techmahindra.com
+##
+
+
+*** Settings ***
+Documentation Suite description
+Library SeleniumLibrary
+Library OperatingSystem
+Resource ../../lib/gui/login_gui.robot
+
+
+*** Test Cases ***
+Valid Login
+ [Tags] comprehensive gui_login_test
+ [Setup] Set Server URL
+ Open Browser To Login Page
+ Enter Credentials admin admin
+ Submit Credentials
+ Home Page Should Be Open
+ [Teardown] Close Browser
--- /dev/null
+##
+# Copyright 2016-2019 VMware Inc.
+# This file is part of ETSI OSM
+# 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: osslegalrouting@vmware.com
+##
+
+The following two tools are provided to help simplify VMware based image
+management:
+
+o ovf_converter - converts libvirt .qcow2 files to VMware .vmdk format.
+o ovf_uploader - uploads .ovf and .vmdk files to vCD, similar to
+ openstack image upload command.
+
+OVF Converter Usage
+===================
+
+This utility can be used for both VMware Integrated Openstack (VIO) or
+vCloud Director (vCD). It converts libvirt images, such as files that end
+in .qcow2 or .img to VMware .vmdk format. Both an .ovf and .vmdk file are
+created and can be used as needed.
+
+OVF Uploader Usage
+==================
+
+This utility is only used for vCD, as there is no equivalent CLI that provides
+the ability to upload images into vCD. It takes the output OVF from the
+converter and uploads both it and the VMDK file to the vCD catalog.
+
+Examples:
+=========
+
+o Upload a CentOS .qcow2 file to VIO
+
+ $ ovf_converter CentOS-7-x86_64-GenericCloud.qcow2
+ $ openstack image create --public \
+ --file CentOS-7-x86_64-GenericCloud.vmdk \
+ --disk-format vmdk CentOS-7
+
+o Upload a CentOS .qcow2 file to vCD
+
+ $ ovf_converter CentOS-7-x86_64-GenericCloud.qcow2
+ $ ovf_uploader -u orgadmin -p password -o osm -l https://vcd \
+ CentOS-7-x86_64-GenericCloud.ovf
+
+Both commands suport -h to display help options.
+
--- /dev/null
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# #
+# Copyright 2016-2017 VMware Inc.
+# This file is part of ETSI OSM
+# 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: osslegalrouting@vmware.com
+# #
+
+import logging
+import os
+import subprocess
+import yaml
+from lxml import etree as ET
+
+# file paths
+MODULE_DIR = os.path.dirname(__file__)
+OVF_TEMPLATE_PATH = os.path.join(MODULE_DIR,
+ "ovf_template/template.xml")
+IDE_CDROM_XML_PATH = os.path.join(MODULE_DIR,
+ "ovf_template/ide_cdrom.xml")
+OS_INFO_FILE_PATH = os.path.join(MODULE_DIR,
+ "config/os_type.yaml")
+DISK_CONTROLLER_INFO_FILE_PATH = os.path.join(MODULE_DIR,
+ "config/disk_controller.yaml")
+
+# Set logger
+LOG_FILE = os.path.join(MODULE_DIR, "logs/ovf_converter.log")
+os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
+logger = logging.getLogger(__name__)
+hdlr = logging.FileHandler(LOG_FILE)
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+hdlr.setFormatter(formatter)
+logger.addHandler(hdlr)
+logger.setLevel(10)
+
+__version__ = "1.2"
+__description__ = "OVF Hardware Version 14 compatible"
+
+
+def get_version(*args, **kwargs):
+ """ get version of this application"""
+ version = str(__version__) + " - " + str(__description__)
+ return version
+
+
+# converter class
+class OVFConverter(object):
+ """ Class to convert input image into OVF format """
+
+ def __init__(self, source_img_path, output_location=None, output_ovf_name=None,
+ memory=None, cpu=None, disk=None, os_type=None,
+ disk_controller=None, cdrom=None, hwversion=14):
+ """
+ Constructor to initialize object of class OVFConverter
+ Args:
+ source_img_path - absolute path to source image which will get convert into ovf
+ output_location - location where created OVF will be kept. This location
+ should have write access. If not given file will get
+ created at source location (optional)
+ output_ovf_name - name of output ovf.If not given source image name will
+ be used (optional)
+ memory - required memory for VM in MB (optional)
+ cpu - required number of virtual cpus for VM (optional)
+ disk - required size of disk for VM in GB (optional)
+ os_type- required operating system type as specified in user document
+ (default os type other 32 bit) (optional)
+ disk_controller - required disk controller type
+ (default controller SCSI with lsilogicsas)
+ (SATA, IDE, Paravirtual, Buslogic, Lsilogic, Lsilogicsas) (optional)
+ hwversion - VMware ESXi hardware family version (optional)
+
+ Returns:
+ Nothing.
+ """
+ self.logger = logger
+ self.ovf_template_path = OVF_TEMPLATE_PATH
+
+ self.source_img_path = source_img_path
+ self.source_img_filename, file_extension = os.path.splitext(os.path.basename(self.source_img_path))
+ self.source_img_location = os.path.dirname(self.source_img_path)
+ self.source_format = file_extension[1:]
+
+ self.output_format = "ovf"
+ self.output_ovf_name = output_ovf_name.split('.')[0] if output_ovf_name else self.source_img_filename
+ self.output_location = output_location if output_location else "."
+ self.output_ovf_name_ext = self.output_ovf_name + "." + self.output_format
+ self.output_path = os.path.join(self.output_location, self.output_ovf_name_ext)
+
+ self.output_diskimage_format = "vmdk"
+ self.output_diskimage_name = self.source_img_filename + "." + self.output_diskimage_format
+ self.output_diskimage_path = os.path.join(self.output_location, self.output_diskimage_name)
+
+ self.logger.info("Input parameters to Converter: \n ovf_template_path = {}, \n source_img_path = {}, \n"
+ "source_img_location ={} , \n source_format = {}, \n source_img_filename = {}".format(
+ self.ovf_template_path,
+ self.source_img_path, self.source_img_location,
+ self.source_format, self.source_img_filename))
+
+ self.logger.info("Output parameters to Converter: \n output_format = {}, \n output_ovf_name = {}, \n"
+ "output_location ={} , \n output_path = {}, \n output_diskimage_name = {} , \n"
+ " output_diskimage_path = {} ".format(self.output_format, self.output_ovf_name,
+ self.output_location, self.output_path,
+ self.output_diskimage_name, self.output_diskimage_path))
+
+ self.disk_capacity = 1
+ self.disk_populated_size = 0
+
+ self.vm_name = self.output_ovf_name
+ self.memory = str(memory) if memory is not None else None
+ self.cpu = str(cpu) if cpu is not None else None
+ self.os_type = str(os_type).strip() if os_type else None
+ self.cdrom = cdrom
+ self.hwversion = hwversion
+
+ if self.os_type:
+ self.osID, self.osType = self.__get_osType()
+ if self.osID is None or self.osType is None:
+ error_msg = "ERROR: Invalid input can not find OS type {} ".format(self.os_type)
+ self.__raise_exception(error_msg)
+
+ self.disk_controller = str(disk_controller).strip() if disk_controller else None
+
+ if self.disk_controller:
+ self.disk_controller_info = self.__get_diskcontroller()
+
+ if not self.disk_controller_info:
+ error_msg = "ERROR: Invalid input can not find Disk Controller {} ".format(self.disk_controller)
+ self.__raise_exception(error_msg)
+
+ if disk is not None:
+ # convert disk size from GB to bytes
+ self.disk_size = int(disk) * 1024 * 1024 * 1024
+ else:
+ self.disk_size = None
+
+ self.logger.info("Other input parameters to Converter: \n vm_name = {}, \n memory = {}, \n"
+ "disk_size ={} \n os type = {} \n disk controller = {}".format(
+ self.vm_name, self.memory, self.disk_size, self.os_type, self.disk_controller))
+
+ # check access for read input location and write output location return none if no access
+ if not os.access(self.source_img_path, os.F_OK):
+ error_msg = "ERROR: Source image file {} not present".format(self.source_img_path)
+ self.__raise_exception(error_msg, exception_type="IO")
+
+ elif not os.access(self.source_img_path, os.R_OK):
+ error_msg = "ERROR: Cannot read source image file {}".format(self.source_img_path)
+ self.__raise_exception(error_msg, exception_type="IO")
+
+ if not os.access(self.output_location, os.W_OK):
+ error_msg = "ERROR: No write access to location {} to write output OVF ".format(self.output_location)
+ self.__raise_exception(error_msg, exception_type="IO")
+
+ def __get_image_info(self):
+ """
+ Private method to get information about source imager.
+ Args : None
+ Return : True on success else False
+ """
+ try:
+ print("Getting source image information")
+ command = "qemu-img info \t " + self.source_img_path
+ output, error, returncode = self.__execute_command(command)
+
+ if error or returncode:
+ self.logger.error("ERROR: Error occurred while getting information about source image : {} \n "
+ "return code : {} ".format(error, returncode))
+ return False
+
+ elif output:
+ self.logger.info("Get Image Info Output : {} \n ".format(output))
+ split_output = output.decode().split("\n")
+ for line in split_output:
+ line = line.strip()
+ if "virtual size" in line:
+ virtual_size_info = line.split(":")[1].split()
+ if len(virtual_size_info) == 3 and virtual_size_info[2].strip(")") == "bytes":
+ self.disk_capacity = int(virtual_size_info[1].strip("("))
+ else:
+ self.disk_capacity = self.__convert_size(virtual_size_info[0])
+
+ elif "disk size" in line:
+ size = line.split(":")[1].split()[0]
+ self.disk_populated_size = self.__convert_size(size)
+ elif "file format" in line:
+ self.source_format = line.split(":")[1]
+
+ self.logger.info("Updated source image virtual disk capacity : {} ,"
+ "Updated source image populated size: {}".format(self.disk_capacity,
+ self.disk_populated_size))
+ return True
+ except Exception as exp:
+ error_msg = "ERROR: Error occurred while getting information about source image : {}".format(exp)
+ self.logger.error(error_msg)
+ print(error_msg)
+ return False
+
+ def __convert_image(self):
+ """
+ Private method to convert source disk image into .vmdk disk image.
+ Args : None
+ Return : True on success else False
+ """
+
+ print("Converting source disk image to .vmdk ")
+
+ command = "qemu-img convert -p -f " + self.source_format + " -O " + self.output_diskimage_format + \
+ " -o subformat=streamOptimized " + self.source_img_path + " " + self.output_diskimage_path
+
+ _, error, returncode = self.__execute_command(command, show_output=True)
+
+ if error or returncode:
+ error_msg = "ERROR: Error occurred while converting source disk image into vmdk: {}\n" + \
+ "return code : {} ".format(error, returncode)
+ self.logger.error(error_msg)
+ print(error_msg)
+ return False
+ else:
+ if os.path.isfile(self.output_diskimage_path):
+ self.logger.info("Successfully converted source image {} into {} \n "
+ "return code : {} ".format(self.source_img_path,
+ self.output_diskimage_path,
+ returncode))
+ result = self.__make_image_bootable()
+ if result:
+ self.logger.info("Made {} bootable".format(self.output_diskimage_path))
+ print("Output VMDK is at: {}".format(self.output_diskimage_path))
+ return True
+ else:
+ self.logger.error("Cannot make {} bootable".format(self.output_diskimage_path))
+ print("ERROR: Fail to convert source image into .vmdk")
+ return False
+ else:
+ self.logger.error("Converted vmdk disk file {} is not present \n ".format(
+ self.output_diskimage_path))
+ print("Fail to convert source image into .vmdk")
+ return False
+
+ def __make_image_bootable(self):
+ """
+ Private method to make source disk image bootable.
+ Args : None
+ Return : True on success else False
+ """
+ command = "printf '\x03' | dd conv=notrunc of=" + self.output_diskimage_path + "\t bs=1 seek=$((0x4))"
+ output, error, returncode = self.__execute_command(command)
+
+ if error and returncode:
+ error_msg = "ERROR:Error occurred while making source disk image bootable : {} \n "\
+ "return code : {} ".format(error, returncode)
+ self.logger.error(error_msg)
+ print(error_msg)
+ return False
+ else:
+ self.logger.info("Make Image Bootable Output : {} ".format(output))
+ return True
+
+ def __edit_ovf_template(self):
+ """
+ Private method to create new OVF file by editing OVF template
+ Args : None
+ Return : True on success else False
+ """
+ try:
+ print("Creating OVF")
+ # Read OVF template file
+ OVF_tree = ET.parse(self.ovf_template_path)
+ root = OVF_tree.getroot()
+
+ # Collect namespaces
+ nsmap = {k: v for k, v in root.nsmap.items() if k}
+ nsmap["xmlns"] = "http://schemas.dmtf.org/ovf/envelope/1"
+
+ # Edit OVF template
+ references = root.find('xmlns:References', nsmap)
+ if references is not None:
+ file_tag = references.find('xmlns:File', nsmap)
+ if file_tag is not None:
+ file_tag.attrib['{' + nsmap['ovf'] + '}href'] = self.output_diskimage_name
+
+ disksection = root.find('xmlns:DiskSection', nsmap)
+ if disksection is not None:
+ diak_tag = disksection.find('xmlns:Disk', nsmap)
+ if diak_tag is not None:
+ if self.disk_size and self.disk_size > self.disk_capacity:
+ self.disk_capacity = self.disk_size
+
+ diak_tag.attrib['{' + nsmap['ovf'] + '}capacity'] = str(self.disk_capacity)
+ diak_tag.attrib['{' + nsmap['ovf'] + '}populatedSize'] = str(self.disk_populated_size)
+
+ virtuasystem = root.find('xmlns:VirtualSystem', nsmap)
+ if virtuasystem is not None:
+ name_tag = virtuasystem.find('xmlns:Name', nsmap)
+ if name_tag is not None:
+ name_tag.text = self.vm_name
+
+ if self.os_type is not None:
+ operatingSystemSection = virtuasystem.find('xmlns:OperatingSystemSection', nsmap)
+ if self.osID and self.osType:
+ operatingSystemSection.attrib['{' + nsmap['ovf'] + '}id'] = self.osID
+ os_discription_tag = operatingSystemSection.find('xmlns:Description', nsmap)
+ os_discription_tag.text = self.osType
+
+ virtualHardwareSection = virtuasystem.find('xmlns:VirtualHardwareSection', nsmap)
+ system = virtualHardwareSection.find('xmlns:System', nsmap)
+ virtualSystemIdentifier = system.find('vssd:VirtualSystemIdentifier', nsmap)
+ if virtualSystemIdentifier is not None:
+ virtualSystemIdentifier.text = self.vm_name
+ VirtualSystemType = system.find('vssd:VirtualSystemType', nsmap)
+ if VirtualSystemType is not None:
+ VirtualSystemType.text = "vmx-{}".format(self.hwversion)
+
+ if self.memory is not None or self.cpu is not None or self.disk_controller is not None:
+ for item in virtualHardwareSection.iterfind('xmlns:Item', nsmap):
+ description = item.find("rasd:Description", nsmap)
+
+ if self.cpu is not None:
+ if description is not None and description.text == "Number of Virtual CPUs":
+ cpu_item = item.find("rasd:VirtualQuantity", nsmap)
+ name_item = item.find("rasd:ElementName", nsmap)
+ if cpu_item is not None:
+ cpu_item.text = self.cpu
+ name_item.text = self.cpu + " virtual CPU(s)"
+
+ if self.memory is not None:
+ if description is not None and description.text == "Memory Size":
+ mem_item = item.find("rasd:VirtualQuantity", nsmap)
+ name_item = item.find("rasd:ElementName", nsmap)
+ if mem_item is not None:
+ mem_item.text = self.memory
+ name_item.text = self.memory + " MB of memory"
+
+ if self.disk_controller is not None:
+ if description is not None and description.text == "SCSI Controller":
+ if self.disk_controller_info is not None:
+ name_item = item.find("rasd:ElementName", nsmap)
+ name_item.text = str(self.disk_controller_info["controllerName"]) + "0"
+
+ resource_type = item.find("rasd:ResourceType", nsmap)
+ resource_type.text = self.disk_controller_info["resourceType"]
+
+ description.text = self.disk_controller_info["controllerName"]
+ resource_subtype = item.find("rasd:ResourceSubType", nsmap)
+ if self.disk_controller_info["controllerName"] == "IDE Controller":
+ # Remove resource subtype item
+ resource_subtype.getparent().remove(resource_subtype)
+ if "resourceSubType" in self.disk_controller_info:
+ resource_subtype.text = self.disk_controller_info["resourceSubType"]
+ if self.cdrom:
+ last_item = list(virtualHardwareSection.iterfind('xmlns:Item', nsmap))[-1]
+ ide_cdrom_items_etree = ET.parse(IDE_CDROM_XML_PATH)
+ ide_cdrom_items = list(ide_cdrom_items_etree.iterfind('Item'))
+ for item in ide_cdrom_items:
+ last_item.addnext(item)
+
+ # Save output OVF
+ OVF_tree.write(self.output_path, xml_declaration=True, encoding='utf-8',
+ method="xml")
+
+ if os.path.isfile(self.output_path):
+ logger.info("Successfully written output OVF at {}".format(self.output_path))
+ print("Output OVF is at: {}".format(self.output_path))
+ return self.output_path
+ else:
+ error_msg = "ERROR: Error occurred while creating OVF file"
+ print(error_msg)
+ return False
+
+ except Exception as exp:
+ error_msg = "ERROR: Error occurred while editing OVF template : {}".format(exp)
+ self.logger.error(error_msg)
+ print(error_msg)
+ return False
+
+ def __convert_size(self, size):
+ """
+ Private method to convert disk size from GB,MB to bytes.
+ Args :
+ size : disk size with prefix 'G' for GB and 'M' for MB
+ Return : disk size in bytes
+ """
+ byte_size = 0
+ try:
+ if not size:
+ self.logger.error("No size {} to convert in bytes".format(size))
+ else:
+ size = str(size)
+ disk_size = float(size[:-1])
+ input_type = size[-1].strip()
+
+ self.logger.info("Disk size : {} , size type : {} ".format(disk_size, input_type))
+
+ if input_type == "G":
+ byte_size = disk_size * 1024 * 1024 * 1024
+ elif input_type == "M":
+ byte_size = disk_size * 1024 * 1024
+
+ self.logger.info("Disk size in bytes: {} ".format(byte_size))
+
+ return int(byte_size)
+
+ except Exception as exp:
+ error_msg = "ERROR:Error occurred while converting disk size in bytes : {}".format(exp)
+ self.logger.error(error_msg)
+ print(error_msg)
+ return False
+
+ def __get_osType(self):
+ """
+ Private method to get OS ID and Type
+ Args :
+ None
+ Return :
+ osID : OS ID
+ osType: OS Type
+ """
+ osID = None
+ osType = None
+ os_info = self.__read_yaml_file(OS_INFO_FILE_PATH)
+
+ try:
+ if self.os_type and os_info:
+ for os_id, os_type in os_info.items():
+ if self.os_type.lower() == os_type.lower():
+ osID = os_id
+ osType = os_type
+ break
+ except Exception as exp:
+ error_msg = "ERROR:Error occurred while getting OS details : {}".format(exp)
+ self.logger.error(error_msg)
+ print(error_msg)
+
+ return osID, osType
+
+ def __get_diskcontroller(self):
+ """
+ Private method to get details of Disk Controller
+ Args :
+ None
+ Return :
+ disk_controller : dict with details of Disk Controller
+ """
+ disk_controller = {}
+ scsi_subtype = None
+ if self.disk_controller.lower() in ["paravirtual", "lsilogic", "buslogic", "lsilogicsas"]:
+ scsi_subtype = self.disk_controller
+ self.disk_controller = "SCSI"
+
+ disk_controller_info = self.__read_yaml_file(DISK_CONTROLLER_INFO_FILE_PATH)
+ try:
+ if self.disk_controller and disk_controller_info:
+ for key, value in disk_controller_info.iteritems():
+ if self.disk_controller.lower() in key.lower():
+ disk_controller['controllerName'] = key
+ disk_controller['resourceType'] = str(value["ResourceType"])
+ resourceSubTypes = value["ResourceSubTypes"] if "ResourceSubTypes" in value else None
+ if key == "SATA Controller":
+ disk_controller["resourceSubType"] = resourceSubTypes[0]
+ elif key == "SCSI Controller":
+ if scsi_subtype:
+ if scsi_subtype.lower() == "paravirtual":
+ scsi_subtype = "VirtualSCSI"
+ for subtype in resourceSubTypes:
+ if scsi_subtype.lower() == subtype.lower():
+ disk_controller["resourceSubType"] = subtype
+ break
+ else:
+ error_msg = "ERROR: Invalid inputs can not "\
+ "find SCSI subtype {}".format(scsi_subtype)
+ self.__raise_exception(error_msg)
+
+ except KeyError as exp:
+ error_msg = "ERROR:Error occurred while getting Disk Controller details : {}".format(exp)
+ self.logger.error(error_msg)
+ print(error_msg)
+
+ return disk_controller
+
+ def __read_yaml_file(self, file_path):
+ """
+ Private method to execute command
+ Args :
+ command : command to execute
+ Return :
+ Dict of yaml data
+ """
+ with open(file_path) as data_file:
+ data = yaml.load(data_file, Loader=yaml.SafeLoader)
+ return data
+
+ def __raise_exception(self, error_msg, exception_type="Generic"):
+ """
+ Private method to execute command
+ Args :
+ command : command to execute
+ Return :
+ None
+ """
+ if error_msg:
+ self.logger.debug(error_msg)
+ print(error_msg)
+ if exception_type == "Generic":
+ raise Exception(error_msg)
+ elif exception_type == "IO":
+ raise Exception(error_msg)
+
+ def __execute_command(self, command, show_output=False):
+ """
+ Private method to execute command
+ Args :
+ command : command to execute
+ Return :
+ stdout : output of command
+ stderr: error occurred while executing command if any
+ returncode : return code of command execution
+ """
+ try:
+ self.logger.info("Execute command: {} ".format(command))
+
+ proc = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True, bufsize=1)
+
+ stdout = b''
+ stderr = b''
+
+ while True:
+ output = proc.stdout.read(1)
+ stdout += output
+ if show_output:
+ print(output.decode(), end='')
+ returncode = proc.poll()
+ if returncode is not None:
+ for output in proc.stdout.readlines():
+ stdout += output
+ if show_output:
+ print(output.decode(), end='')
+ break
+
+ for output in proc.stderr.readlines():
+ stderr += output
+
+ except Exception as exp:
+ self.logger.error("Error {} occurred while executing command {} ".format(exp, command))
+
+ return stdout, stderr, returncode
+
+ def create_ovf(self):
+ """
+ Method to convert source image into OVF
+ Args : None
+ Return : True on success else False
+ """
+ # check output format
+ if self.source_format == self.output_format:
+ self.logger.info("Source format is OVF. No need to convert: {} ")
+ return self.source_img_path
+
+ # Get source img properties
+ img_info = self.__get_image_info()
+ if img_info:
+
+ # Create vmdk disk image
+ disk_img = self.__convert_image()
+ if disk_img:
+
+ # Edit OVF tempalte
+ ovf_path = self.__edit_ovf_template()
+ return ovf_path
+ else:
+ self.logger.error("Error in getting image information cannot convert image")
+ raise Exception("Error in getting image information cannot convert image")
+ return False
+++ /dev/null
-##
-# Copyright 2016-2017 VMware Inc.
-# This file is part of ETSI OSM
-# 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: osslegalrouting@vmware.com
-##
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-##
-# Copyright 2016-2017 VMware Inc.
-# This file is part of ETSI OSM
-# 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: osslegalrouting@vmware.com
-##
-
-import threading
-import sys
-
-class RepeatingTimer(threading._Timer):
- """ Class to run thread parally """
- def run(self):
- """ Method to run thread """
- while True:
- self.finished.wait(self.interval)
- if self.finished.is_set():
- return
- else:
- self.function(*self.args, **self.kwargs)
-
-
-class CommandProgressbar(object):
- """ Class to show progressbar while waiting fro command output """
-
- def __init__(self):
- self.timer = None
-
- def __show_progressbar(self):
- """
- Private method to show progressbar while waiting for command to complete
- Args : None
- Return : None
- """
- print '\b.',
- sys.stdout.flush()
-
- def start_progressbar(self):
- """
- Method to start progressbar thread
- Args : None
- Return : None
- """
- self.timer = RepeatingTimer(1.0, self.__show_progressbar)
- self.timer.daemon = True # Allows program to exit if only the thread is alive
- self.timer.start()
-
- def stop_progressbar(self):
- """
- Method to stop progressbar thread
- Args : None
- Return : None
- """
- self.timer.cancel()
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-##
-# Copyright 2016-2017 VMware Inc.
-# This file is part of ETSI OSM
-# 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: osslegalrouting@vmware.com
-##
-
-import logging
-import os
-import subprocess
-import yaml
-from lxml import etree as ET
-from command_progress import CommandProgressbar
-
-#file paths
-MODULE_DIR = os.path.dirname(__file__)
-OVF_TEMPLATE_PATH = os.path.join(os.path.dirname(MODULE_DIR),
- "ovf_template/template.xml")
-IDE_CDROM_XML_PATH = os.path.join(os.path.dirname(MODULE_DIR),
- "ovf_template/ide_cdrom.xml")
-OS_INFO_FILE_PATH = os.path.join(os.path.dirname(MODULE_DIR),
- "config/os_type.yaml")
-DISK_CONTROLLER_INFO_FILE_PATH = os.path.join(os.path.dirname(MODULE_DIR),
- "config/disk_controller.yaml")
-
-
-#Set logger
-LOG_FILE = os.path.join(os.path.dirname(MODULE_DIR),"logs/ovf_converter.log")
-logger = logging.getLogger(__name__)
-hdlr = logging.FileHandler(LOG_FILE)
-formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-hdlr.setFormatter(formatter)
-logger.addHandler(hdlr)
-logger.setLevel(10)
-
-__version__ = "1.0"
-__description__ = "initial Release"
-
-def get_version(*args, **kwargs):
- """ get version of this application"""
- version = str(__version__ ) +" - "+ str( __description__ )
- return version
-
-#converter class
-class OVFConverter(object):
- """ Class to convert input image into OVF format """
-
- def __init__(self, source_img_path, output_location=None, output_ovf_name=None,
- memory=None, cpu=None, disk=None, os_type=None,
- disk_controller=None, cdrom=None,
- options={'subformat':'streamOptimized'}):
- """
- Constructor to initialize object of class OVFConverter
- Args:
- source_img_path - absolute path to source image which will get convert into ovf
- output_location - location where created OVF will be kept. This location
- should have write access. If not given file will get
- created at source location (optional)
- output_ovf_name - name of output ovf.If not given source image name will
- be used (optional)
- memory - required memory for VM in MB (optional)
- cpu - required number of virtual cpus for VM (optional)
- disk - required size of disk for VM in GB (optional)
- os_type- required operating system type as specified in user document
- (default os type other 32 bit) (optional)
- disk_controller - required disk controller type
- (default controller SCSI with lsilogicsas)
- (SATA, IDE, Paravirtual, Buslogic, Lsilogic, Lsilogicsas) (optional)
- options - subformat option for OVF (optional)
-
- Returns:
- Nothing.
- """
- self.logger = logger
- self.ovf_template_path = OVF_TEMPLATE_PATH
-
- self.source_img_path = source_img_path
- file_location, file_extension = os.path.splitext(self.source_img_path)
- self.source_img_location = os.path.dirname(self.source_img_path)
- self.source_format = file_extension[1:]
- self.source_img_filename = os.path.basename(self.source_img_path).split('.')[0]
-
- self.output_format = "ovf"
- self.output_ovf_name = output_ovf_name.split('.')[0] if output_ovf_name else self.source_img_filename
- self.output_location = output_location if output_location else self.source_img_location
- self.output_ovf_name_ext = self.output_ovf_name + "." + self.output_format
- self.output_path = os.path.join(self.output_location , self.output_ovf_name_ext )
-
- self.output_diskimage_format = "vmdk"
- self.output_diskimage_name = self.source_img_filename + "."+ self.output_diskimage_format
- self.output_diskimage_path = os.path.join(self.output_location, self.output_diskimage_name)
-
-
- self.logger.info("Input parameters to Converter: \n ovf_template_path = {}, \n source_img_path = {}, \n"\
- "source_img_location ={} , \n source_format = {}, \n source_img_filename = {}".format(
- self.ovf_template_path,
- self.source_img_path, self.source_img_location,
- self.source_format, self.source_img_filename ))
-
- self.logger.info("Output parameters to Converter: \n output_format = {}, \n output_ovf_name = {}, \n"\
- "output_location ={} , \n output_path = {}, \n output_diskimage_name = {} , \n"\
- " output_diskimage_path = {} ".format(self.output_format, self.output_ovf_name,
- self.output_location, self.output_path,
- self.output_diskimage_name,self.output_diskimage_path ))
-
-
- self.disk_capacity = 1
- self.disk_populated_size = 0
-
- self.vm_name = self.output_ovf_name
- self.memory = str(memory) if memory is not None else None
- self.cpu = str(cpu) if cpu is not None else None
- self.os_type=str(os_type).strip() if os_type else None
- self.cdrom = cdrom
-
- if self.os_type:
- self.osID , self.osType = self.__get_osType()
- if self.osID is None or self.osType is None:
- error_msg = "ERROR: Invalid input can not find OS type {} ".format(self.os_type)
- self.__raise_exception(error_msg)
-
- self.disk_controller = str(disk_controller).strip() if disk_controller else None
-
- if self.disk_controller:
- self.disk_controller_info = self.__get_diskcontroller()
-
- if not self.disk_controller_info:
- error_msg = "ERROR: Invalid input can not find Disk Controller {} ".format(self.disk_controller)
- self.__raise_exception(error_msg)
-
- if disk is not None:
- #convert disk size from GB to bytes
- self.disk_size = int(disk) * 1024 * 1024 * 1024
- else:
- self.disk_size = None
-
- self.logger.info("Other input parameters to Converter: \n vm_name = {}, \n memory = {}, \n"\
- "disk_size ={} \n os type = {} \n disk controller = {}".format(
- self.vm_name, self.memory, self.disk_size, self.os_type, self.disk_controller
- ))
-
- #check access for read input location and write output location return none if no access
- if not os.access(self.source_img_path, os.F_OK):
- error_msg = "ERROR: Source image file {} not present".format(self.source_img_path)
- self.__raise_exception(error_msg, exception_type="IO")
-
- elif not os.access(self.source_img_path, os.R_OK):
- error_msg = "ERROR: Cannot read source image file {}".format(self.source_img_path)
- self.__raise_exception(error_msg, exception_type="IO")
-
- if not os.access(self.output_location, os.W_OK):
- error_msg = "ERROR: Not have write access to location {} to write output OVF ".format(self.source_img_path)
- self.__raise_exception(error_msg, exception_type="IO")
-
- def __get_image_info(self):
- """
- Private method to get information about source imager.
- Args : None
- Return : True on success else False
- """
- try:
- print("Getting source image information")
- command = "qemu-img info \t " + self.source_img_path
- output, error, returncode= self.__execute_command(command)
-
- if error or returncode:
- self.logger.error("ERROR: Error occurred while getting information about source image : {} \n "\
- "return code : {} ".format(error, returncode))
- return False
-
- elif output:
- self.logger.info("Get Image Info Output : {} \n ".format(output))
- split_output = output.split("\n")
- for line in split_output:
- line = line.strip()
- if "virtual size" in line:
- virtual_size_info = line.split(":")[1].split()
- if len(virtual_size_info) == 3 and virtual_size_info[2].strip(")") == "bytes":
- self.disk_capacity = int(virtual_size_info[1].strip("("))
- else:
- self.disk_capacity = self.__convert_size(virtual_size_info[0])
-
- elif "disk size" in line:
- size = line.split(":")[1].split()[0]
- self.disk_populated_size = self.__convert_size(size)
- elif "file format" in line:
- self.source_format = line.split(":")[1]
-
- self.logger.info("Updated source image virtual disk capacity : {} ,"\
- "Updated source image populated size: {}".format(self.disk_capacity,
- self.disk_populated_size))
- return True
- except Exception as exp:
- error_msg = "ERROR: Error occurred while getting information about source image : {}".format(exp)
- self.logger.error(error_msg)
- print(error_msg)
- return False
-
- def __convert_image(self):
- """
- Private method to convert source disk image into .vmdk disk image.
- Args : None
- Return : True on success else False
- """
-
- print("Converting source disk image to .vmdk ")
-
- progress = CommandProgressbar()
- progress.start_progressbar()
-
- command = "qemu-img convert -f "+ self.source_format +" -O " + self.output_diskimage_format + \
- " -o subformat=streamOptimized " + self.source_img_path + "\t" + self.output_diskimage_path
-
- output, error , returncode = self.__execute_command(command)
-
- progress.stop_progressbar()
-
- if error or returncode :
- error_msg = "ERROR: Error occurred while converting source disk image into vmdk : {} \n "\
- "return code : {} ".format(error, returncode)
- self.logger.error(error_msg)
- print(error_msg)
- return False
- else:
- if os.path.isfile(self.output_diskimage_path):
- self.logger.info("Successfully converted source image {} into {} \n "\
- "return code : {} ".format(self.source_img_path,
- self.output_diskimage_path,
- returncode))
- result = self.__make_image_bootable()
- if result:
- self.logger.info("Made {} bootable".format(self.output_diskimage_path))
- return True
- else:
- self.logger.error("Cannot make {} bootable".format(self.output_diskimage_path))
- print("ERROR: Fail to convert source image into .vmdk")
- return False
- else:
- self.logger.error("Converted vmdk disk file {} is not present \n ".format(
- self.output_diskimage_path))
- print("Fail to convert source image into .vmdk")
- return False
-
- def __make_image_bootable(self):
- """
- Private method to make source disk image bootable.
- Args : None
- Return : True on success else False
- """
- command = "printf '\x03' | dd conv=notrunc of="+ self.output_diskimage_path + "\t bs=1 seek=$((0x4))"
- output, error, returncode = self.__execute_command(command)
-
- if error and returncode :
- error_msg = "ERROR:Error occurred while making source disk image bootable : {} \n "\
- "return code : {} ".format(error, returncode)
- self.logger.error(error_msg)
- print(error_msg)
- return False
- else:
- self.logger.info("Make Image Bootable Output : {} ".format(output))
- return True
-
-
- def __edit_ovf_template(self):
- """
- Private method to create new OVF file by editing OVF template
- Args : None
- Return : True on success else False
- """
- try:
- print("\nCreating OVF")
- #Read OVF template file
- OVF_tree = ET.parse(self.ovf_template_path)
- root = OVF_tree.getroot()
-
- #Collect namespaces
- nsmap = {k:v for k,v in root.nsmap.iteritems() if k}
- nsmap["xmlns"]= "http://schemas.dmtf.org/ovf/envelope/1"
-
- #Edit OVF template
- references = root.find('xmlns:References',nsmap)
- if references is not None:
- file_tag = references.find('xmlns:File', nsmap)
- if file_tag is not None:
- file_tag.attrib['{'+nsmap['ovf']+'}href'] = self.output_diskimage_name
-
- disksection = root.find('xmlns:DiskSection',nsmap)
- if disksection is not None:
- diak_tag = disksection.find('xmlns:Disk', nsmap)
- if diak_tag is not None:
- if self.disk_size and self.disk_size > self.disk_capacity:
- self.disk_capacity = self.disk_size
-
- diak_tag.attrib['{'+nsmap['ovf']+'}capacity'] = str(self.disk_capacity)
- diak_tag.attrib['{'+nsmap['ovf']+'}populatedSize'] = str(self.disk_populated_size)
-
- virtuasystem = root.find('xmlns:VirtualSystem',nsmap)
- if virtuasystem is not None:
- name_tag = virtuasystem.find('xmlns:Name', nsmap)
- if name_tag is not None:
- name_tag.text = self.vm_name
-
- if self.os_type is not None:
- operatingSystemSection = virtuasystem.find('xmlns:OperatingSystemSection', nsmap)
- if self.osID and self.osType:
- operatingSystemSection.attrib['{'+nsmap['ovf']+'}id'] = self.osID
- os_discription_tag = operatingSystemSection.find('xmlns:Description', nsmap)
- os_discription_tag.text = self.osType
-
- virtualHardwareSection = virtuasystem.find('xmlns:VirtualHardwareSection', nsmap)
- system = virtualHardwareSection.find('xmlns:System', nsmap)
- virtualSystemIdentifier = system.find('vssd:VirtualSystemIdentifier', nsmap)
- if virtualSystemIdentifier is not None:
- virtualSystemIdentifier.text = self.vm_name
-
- if self.memory is not None or self.cpu is not None or self.disk_controller is not None:
- for item in virtualHardwareSection.iterfind('xmlns:Item',nsmap):
- description = item.find("rasd:Description",nsmap)
-
- if self.cpu is not None:
- if description is not None and description.text == "Number of Virtual CPUs":
- cpu_item = item.find("rasd:VirtualQuantity", nsmap)
- name_item = item.find("rasd:ElementName", nsmap)
- if cpu_item is not None:
- cpu_item.text = self.cpu
- name_item.text = self.cpu+" virtual CPU(s)"
-
- if self.memory is not None:
- if description is not None and description.text == "Memory Size":
- mem_item = item.find("rasd:VirtualQuantity", nsmap)
- name_item = item.find("rasd:ElementName", nsmap)
- if mem_item is not None:
- mem_item.text = self.memory
- name_item.text = self.memory + " MB of memory"
-
- if self.disk_controller is not None:
- if description is not None and description.text == "SCSI Controller":
- if self.disk_controller_info is not None:
- name_item = item.find("rasd:ElementName", nsmap)
- name_item.text = str(self.disk_controller_info["controllerName"])+"0"
-
- resource_type = item.find("rasd:ResourceType", nsmap)
- resource_type.text = self.disk_controller_info["resourceType"]
-
- description.text = self.disk_controller_info["controllerName"]
- resource_subtype = item.find("rasd:ResourceSubType", nsmap)
- if self.disk_controller_info["controllerName"] == "IDE Controller":
- #Remove resource subtype item
- resource_subtype.getparent().remove(resource_subtype)
- if "resourceSubType" in self.disk_controller_info:
- resource_subtype.text = self.disk_controller_info["resourceSubType"]
- if self.cdrom:
- last_item = list(virtualHardwareSection.iterfind('xmlns:Item',nsmap))[-1]
- ide_cdrom_items_etree = ET.parse(IDE_CDROM_XML_PATH)
- ide_cdrom_items = list(ide_cdrom_items_etree.iterfind('Item'))
- for item in ide_cdrom_items:
- last_item.addnext(item)
-
- # Save output OVF
- OVF_tree.write(self.output_path, xml_declaration=True,encoding='utf-8',
- method="xml" )
-
- if os.path.isfile(self.output_path):
- logger.info("Successfully written output OVF at {}".format(self.output_path))
- print("Output OVF is at : {}".format(self.output_path))
- return self.output_path
- else:
- error_msg = "ERROR: Error occurred while creating OVF file"
- print(error_msg)
- return False
-
- except Exception as exp:
- error_msg = "ERROR: Error occurred while editing OVF template : {}".format(exp)
- self.logger.error(error_msg)
- print(error_msg)
- return False
-
-
- def __convert_size(self,size):
- """
- Private method to convert disk size from GB,MB to bytes.
- Args :
- size : disk size with prefix 'G' for GB and 'M' for MB
- Return : disk size in bytes
- """
- byte_size= 0
- try:
- if not size:
- self.logger.error("No size {} to convert in bytes".format(size))
- else:
- size = str(size)
- disk_size = float(size[:-1])
- input_type = size[-1].strip()
-
- self.logger.info("Disk size : {} , size type : {} ".format(disk_size,input_type))
-
- if input_type == "G":
- byte_size = disk_size * 1024 * 1024 *1024
- elif input_type == "M":
- byte_size = disk_size * 1024 * 1024
-
- self.logger.info("Disk size in bytes: {} ".format(byte_size))
-
- return int(byte_size)
-
- except Exception as exp:
- error_msg = "ERROR:Error occurred while converting disk size in bytes : {}".format(exp)
- self.logger.error(error_msg)
- print(error_msg)
- return False
-
- def __get_osType(self):
- """
- Private method to get OS ID and Type
- Args :
- None
- Return :
- osID : OS ID
- osType: OS Type
- """
- osID = None
- osType = None
- os_info = self.__read_yaml_file(OS_INFO_FILE_PATH)
- try:
- if self.os_type and os_info:
- for os_id , os_type in os_info.iteritems():
- if self.os_type.lower() == os_type.lower():
- osID = os_id
- osType = os_type
- break
- except Exception as exp:
- error_msg = "ERROR:Error occurred while getting OS details : {}".format(exp)
- self.logger.error(error_msg)
- print(error_msg)
-
- return osID, osType
-
-
- def __get_diskcontroller(self):
- """
- Private method to get details of Disk Controller
- Args :
- None
- Return :
- disk_controller : dict with details of Disk Controller
- """
- disk_controller = {}
- scsi_subtype = None
- if self.disk_controller.lower() in ["paravirtual", "lsilogic", "buslogic", "lsilogicsas"]:
- scsi_subtype = self.disk_controller
- self.disk_controller = "SCSI"
-
- disk_controller_info = self.__read_yaml_file(DISK_CONTROLLER_INFO_FILE_PATH)
- try:
- if self.disk_controller and disk_controller_info:
- for key , value in disk_controller_info.iteritems():
- if self.disk_controller.lower() in key.lower():
- disk_controller['controllerName'] = key
- disk_controller['resourceType'] = str(value["ResourceType"])
- resourceSubTypes = value["ResourceSubTypes"] if "ResourceSubTypes" in value else None
- if key == "SATA Controller":
- disk_controller["resourceSubType"] = resourceSubTypes[0]
- elif key == "SCSI Controller":
- if scsi_subtype:
- if scsi_subtype.lower() == "paravirtual":
- scsi_subtype = "VirtualSCSI"
- for subtype in resourceSubTypes:
- if scsi_subtype.lower() == subtype.lower():
- disk_controller["resourceSubType"] = subtype
- break
- else:
- error_msg = "ERROR: Invalid inputs can not "\
- "find SCSI subtype {}".format(scsi_subtype)
- self.__raise_exception(error_msg)
-
- except KeyError as exp:
- error_msg = "ERROR:Error occurred while getting Disk Controller details : {}".format(exp)
- self.logger.error(error_msg)
- print(error_msg)
-
- return disk_controller
-
- def __read_yaml_file(self, file_path):
- """
- Private method to execute command
- Args :
- command : command to execute
- Return :
- Dict of yaml data
- """
- with open(file_path) as data_file:
- data = yaml.load(data_file)
- return data
-
- def __raise_exception(self, error_msg , exception_type="Generic"):
- """
- Private method to execute command
- Args :
- command : command to execute
- Return :
- None
- """
- if error_msg:
- self.logger.debug(error_msg)
- print(error_msg)
- if exception_type == "Generic":
- raise Exception(error_msg)
- elif exception_type == "IO":
- raise Exception(error_msg)
-
- def __execute_command(self, command):
- """
- Private method to execute command
- Args :
- command : command to execute
- Return :
- stdout : output of command
- stderr: error occurred while executing command if any
- returncode : return code of command execution
- """
- try:
- self.logger.info("Execute command: {} ".format(command))
-
- proc = subprocess.Popen(command , stdout = subprocess.PIPE, stdin = subprocess.PIPE,
- stderr = subprocess.PIPE,shell=True)
- stdout, stderr = proc.communicate()
- returncode = proc.returncode
-
- except Exception as exp:
- self.logger.error("Error {} occurred while executing command {} ".format(exp,command))
-
- return stdout, stderr , returncode
-
-
- def create_ovf(self):
- """
- Method to convert source image into OVF
- Args : None
- Return : True on success else False
- """
- #check output format
- if self.source_format == self.output_format:
- self.logger.info("Source format is OVF. No need to convert: {} ")
- return self.source_img_path
-
- #Get source img properties
- img_info = self.__get_image_info()
- if img_info:
-
- #Create vmdk disk image
- disk_img = self.__convert_image()
- if disk_img:
-
- #Edit OVF tempalte
- ovf_path = self.__edit_ovf_template()
- return ovf_path
- else:
- self.logger.error("Error in getting image information cannot convert image")
- raise Exception("Error in getting image information cannot convert image")
- return False
-
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-##
-# Copyright 2016-2017 VMware Inc.
-# This file is part of ETSI OSM
-# 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: osslegalrouting@vmware.com
-##
-
-import argparse
-from converter import OVFConverter , get_version
-
-def execute_cli():
-
- """
- Method to parse CLI arguments and execute commands accordingly
- Args : None
- Return : None
- """
- parser = argparse.ArgumentParser(description='OVF converter to convert .qcow2 or raw image into OVF')
-
- parser.add_argument("-v","--version", action="version", version=str(get_version()),
- help="shows version of OVF Converter tool")
-
- parser.add_argument("path", action="store",
- help=" absolute path to source image which will get convert into ovf")
-
- parser.add_argument("-o", "--output_location", action="store",
- help="location where created OVF will be kept. This location "\
- "should have write access. If not given file will get "\
- "created at source location (optional)")
-
- parser.add_argument("-n","--ovf_name", action="store",
- help="name of output ovf file. If not given source image name will "\
- " be used (optional)")
-
- parser.add_argument("-m","--memory", action="store",
- help="required memory for VM in MB (default 1 GB)(optional)")
-
- parser.add_argument("-c","--cpu", action="store",
- help="required number of virtual cpus for VM (default 1 cpu) (optional)")
-
- parser.add_argument("-d","--disk", action="store",
- help="required size of disk for VM in GB "\
- "(default as in source disk img) (optional)")
-
- parser.add_argument("-s","--osType", action="store",
- help="required operating system type as specified "\
- "in user document (default os type other 32 bit) (optional)")
-
- parser.add_argument("-dc","--disk_Controller", action="store",
- help="required disk controller type "\
- " (default controller SCSI with lsilogicsas) "\
- "(SATA, IDE, Paravirtual, Buslogic, Lsilogic, Lsilogicsas) (optional)")
-
- parser.add_argument("--cdrom", action="store_true",
- help="whether to include a cd/dvd device (optional)")
-
- args = parser.parse_args()
-
- if args.path:
- con = OVFConverter(args.path,
- output_location=args.output_location,
- output_ovf_name=args.ovf_name,
- memory=args.memory,
- cpu=args.cpu,
- disk=args.disk,
- os_type=args.osType,
- disk_controller=args.disk_Controller,
- cdrom=args.cdrom,
- )
-
- print("#### Start OVF conversion ####")
- con.create_ovf()
- print("#### Completed OVF conversion ####")
-
-
-if __name__ == "__main__":
- execute_cli()
-
##
echo '
- #################################################################
- ##### Installing Require Packages #####
- #################################################################'
+ ################################################################
+ ##### Installing Required Packages #####
+ ################################################################'
# Paths to copy application files
Install_dir="/usr/local/bin"
App_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-App_CLI_path="${App_dir}/format_converter/ovf_converter_cli.py"
-Install_CLI_path="${Install_dir}/OVF_converter/format_converter/ovf_converter_cli.py"
+Converter_App_CLI_path="${App_dir}/ovf_converter_cli.py"
+Converter_Install_CLI_path="${Install_dir}/OVF_converter/ovf_converter_cli.py"
+Uploader_App_CLI_path="${App_dir}/ovf_uploader_cli.py"
+Uploader_Install_CLI_path="${Install_dir}/OVF_converter/ovf_uploader_cli.py"
Logs_Folder="${Install_dir}/OVF_converter/logs"
-Log_Path="${Install_dir}/OVF_converter/logs/ovf_converter.log"
#Function to install packages using apt-get
function install_packages(){
[ -x /usr/bin/apt-get ] && apt-get install -y $*
-
+
#check properly installed
for PACKAGE in $*
do
fi
done
}
-
+
apt-get update # To get the latest package lists
install_packages "libxml2-dev libxslt-dev python-dev python-pip python-lxml python-yaml"
install_packages "qemu-utils"
#Create logs folder and file
mkdir "${Logs_Folder}"
-touch "${Log_Path}"
#Change permission
-chmod -R 777 $Install_CLI_path
-chmod -R 777 $Log_Path
+chmod -R 777 ${Converter_Install_CLI_path}
+chmod -R 777 ${Uploader_Install_CLI_path}
+chmod -R 777 ${Logs_Folder}
touch "${Install_dir}/ovf_converter"
echo "#!/bin/sh" > "${Install_dir}/ovf_converter"
-echo "python ${Install_CLI_path} \"\$@\"" >> "${Install_dir}/ovf_converter"
+echo "python3 ${Converter_Install_CLI_path} \"\$@\"" >> "${Install_dir}/ovf_converter"
chmod a+x "${Install_dir}/ovf_converter"
-echo '
- #################################################################
- ##### Done #####
- #################################################################'
+touch "${Install_dir}/ovf_uploader"
+echo "#!/bin/sh" > "${Install_dir}/ovf_uploader"
+echo "python3 ${Uploader_Install_CLI_path} \"\$@\"" >> "${Install_dir}/ovf_uploader"
+chmod a+x "${Install_dir}/ovf_uploader"
+
+echo "Installation complete. More information can be found at:"
+echo " ${Install_dir}/OVF_converter/Usage.txt"
--- /dev/null
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2016-2017 VMware Inc.
+# This file is part of ETSI OSM
+# 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: osslegalrouting@vmware.com
+##
+
+import argparse
+import yaml
+
+from converter import OVFConverter, get_version, OS_INFO_FILE_PATH
+
+
+def execute_cli():
+
+ """
+ Method to parse CLI arguments and execute commands accordingly
+ Args : None
+ Return : None
+ """
+
+ with open(OS_INFO_FILE_PATH) as data_file:
+ os_info = yaml.load(data_file, Loader=yaml.SafeLoader)
+
+ valid_os_strings = "Valid values for osType are:\n"
+ for os_name in os_info.values():
+ valid_os_strings += os_name + ", "
+
+ valid_os_strings = valid_os_strings[:-2]
+
+ parser = argparse.ArgumentParser(description='OVF converter to convert .qcow2 or raw image into OVF')
+
+ parser.add_argument("-v", "--version", action="version", version=str(get_version()),
+ help="shows version of OVF Converter tool")
+
+ parser.add_argument("path", action="store",
+ help="absolute path to source image which will get converted into ovf")
+
+ parser.add_argument("-o", "--output_location", action="store",
+ help="location where created OVF will be kept. This location "
+ "should have write access. If not given file will get "
+ "created at source location (optional)")
+
+ parser.add_argument("-n", "--ovf_name", action="store",
+ help="name of output ovf file. If not given source image name will "
+ " be used (optional)")
+
+ parser.add_argument("-m", "--memory", action="store",
+ help="required memory for VM in MB (default 1 GB)(optional)")
+
+ parser.add_argument("-c", "--cpu", action="store",
+ help="required number of virtual cpus for VM (default 1 cpu) (optional)")
+
+ parser.add_argument("-d", "--disk", action="store",
+ help="required size of disk for VM in GB "
+ "(default as in source disk img) (optional)")
+
+ parser.add_argument("-s", "--osType", action="store",
+ help="required operating system type as specified "
+ "in user document (default os type other 32 bit) (optional) " + valid_os_strings)
+
+ parser.add_argument("-dc", "--disk_Controller", action="store",
+ help="required disk controller type "
+ "(default controller SCSI with lsilogicsas) "
+ "(SATA, IDE, Paravirtual, Buslogic, Lsilogic, Lsilogicsas) (optional)")
+
+ parser.add_argument("--cdrom", action="store_true", default=True,
+ help="whether to include a cd/dvd device (optional)")
+
+ parser.add_argument("-hw", "--hwversion", action="store", default=14,
+ help="Virtual hardware version (default 14)")
+
+ args = parser.parse_args()
+
+ if args.path:
+ con = OVFConverter(args.path,
+ output_location=args.output_location,
+ output_ovf_name=args.ovf_name,
+ memory=args.memory,
+ cpu=args.cpu,
+ disk=args.disk,
+ os_type=args.osType,
+ disk_controller=args.disk_Controller,
+ cdrom=args.cdrom,
+ hwversion=args.hwversion,
+ )
+
+ con.create_ovf()
+
+
+if __name__ == "__main__":
+ execute_cli()
+<!--
+ Copyright 2016-2019 VMware Inc.
+ This file is part of ETSI OSM
+ 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: osslegalrouting@vmware.com
+-->
<Items>
<Item xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData">
<rasd:AddressOnParent>0</rasd:AddressOnParent>
-<?xml version="1.0" encoding="UTF-8"?>\r
-<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
- <References>\r
- <File ovf:href="disk_img_filename.vmdk" ovf:id="file1" />\r
- </References>\r
- <DiskSection>\r
- <Info>Virtual disk information</Info>\r
- <Disk ovf:capacity="1" ovf:capacityAllocationUnits="byte" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="0"/>\r
- </DiskSection>\r
- \r
- <NetworkSection>\r
- <Info>List of logical networks used in the package</Info> \r
- </NetworkSection>\r
- \r
- <VirtualSystem ovf:id="vm">\r
- <Info>A virtual machine</Info>\r
- <Name>Virtual machine name</Name>\r
- \r
- <OperatingSystemSection ovf:id="1">\r
- <Info>The kind of installed guest operating system</Info>\r
- <Description>Other (32-bit)</Description>\r
- </OperatingSystemSection>\r
-\r
- <VirtualHardwareSection>\r
- <Info>Virtual hardware requirements</Info>\r
- <System>\r
- <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>\r
- <vssd:InstanceID>0</vssd:InstanceID>\r
- <vssd:VirtualSystemIdentifier>Test1</vssd:VirtualSystemIdentifier>\r
- <vssd:VirtualSystemType>vmx-7</vssd:VirtualSystemType>\r
- </System>\r
- \r
- <Item>\r
- <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\r
- <rasd:Description>Number of Virtual CPUs</rasd:Description>\r
- <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>\r
- <rasd:InstanceID>1</rasd:InstanceID>\r
- <rasd:ResourceType>3</rasd:ResourceType>\r
- <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\r
- </Item>\r
- <Item>\r
- <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\r
- <rasd:Description>Memory Size</rasd:Description>\r
- <rasd:ElementName>1GB of memory</rasd:ElementName>\r
- <rasd:InstanceID>2</rasd:InstanceID>\r
- <rasd:ResourceType>4</rasd:ResourceType>\r
- <rasd:VirtualQuantity>1024</rasd:VirtualQuantity>\r
- </Item>\r
- <Item>\r
- <rasd:Address>0</rasd:Address>\r
- <rasd:Description>SCSI Controller</rasd:Description>\r
- <rasd:ElementName>scsiController0</rasd:ElementName>\r
- <rasd:InstanceID>3</rasd:InstanceID>\r
- <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType>\r
- <rasd:ResourceType>6</rasd:ResourceType>\r
- </Item>\r
- <Item>\r
- <rasd:AddressOnParent>0</rasd:AddressOnParent>\r
- <rasd:ElementName>disk0</rasd:ElementName>\r
- <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\r
- <rasd:InstanceID>4</rasd:InstanceID>\r
- <rasd:Parent>3</rasd:Parent>\r
- <rasd:ResourceType>17</rasd:ResourceType>\r
- </Item>\r
- <Item ovf:required="false">\r
- <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\r
- <rasd:ElementName>video</rasd:ElementName>\r
- <rasd:InstanceID>5</rasd:InstanceID>\r
- <rasd:ResourceType>24</rasd:ResourceType>\r
- </Item>\r
- <Item ovf:required="false">\r
- <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\r
- <rasd:ElementName>vmci</rasd:ElementName>\r
- <rasd:InstanceID>6</rasd:InstanceID>\r
- <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>\r
- <rasd:ResourceType>1</rasd:ResourceType>\r
- </Item>\r
- <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="true"/>\r
- <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" vmw:value="soft"/>\r
- <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" vmw:value="soft"/>\r
- <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" vmw:value="soft"/>\r
- <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" vmw:value="true"/>\r
- <vmw:Config ovf:required="false" vmw:key="tools.toolsUpgradePolicy" vmw:value="upgradeAtPowerCycle"/>\r
- </VirtualHardwareSection>\r
- \r
- </VirtualSystem>\r
-</Envelope>
\ No newline at end of file
+<!--
+ Copyright 2016-2019 VMware Inc.
+ This file is part of ETSI OSM
+ 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: osslegalrouting@vmware.com
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <References>
+ <File ovf:href="disk_img_filename.vmdk" ovf:id="file1" />
+ </References>
+ <DiskSection>
+ <Info>Virtual disk information</Info>
+ <Disk ovf:capacity="1" ovf:capacityAllocationUnits="byte" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="0"/>
+ </DiskSection>
+
+ <NetworkSection>
+ <Info>List of logical networks used in the package</Info>
+ </NetworkSection>
+
+ <VirtualSystem ovf:id="vm">
+ <Info>A virtual machine</Info>
+ <Name>Virtual machine name</Name>
+
+ <OperatingSystemSection ovf:id="1">
+ <Info>The kind of installed guest operating system</Info>
+ <Description>Other (32-bit)</Description>
+ </OperatingSystemSection>
+
+ <VirtualHardwareSection>
+ <Info>Virtual hardware requirements</Info>
+ <System>
+ <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+ <vssd:InstanceID>0</vssd:InstanceID>
+ <vssd:VirtualSystemIdentifier>Test1</vssd:VirtualSystemIdentifier>
+ <vssd:VirtualSystemType>vmx-14</vssd:VirtualSystemType>
+ </System>
+
+ <Item>
+ <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
+ <rasd:Description>Number of Virtual CPUs</rasd:Description>
+ <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
+ <rasd:InstanceID>1</rasd:InstanceID>
+ <rasd:ResourceType>3</rasd:ResourceType>
+ <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
+ </Item>
+ <Item>
+ <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
+ <rasd:Description>Memory Size</rasd:Description>
+ <rasd:ElementName>1GB of memory</rasd:ElementName>
+ <rasd:InstanceID>2</rasd:InstanceID>
+ <rasd:ResourceType>4</rasd:ResourceType>
+ <rasd:VirtualQuantity>1024</rasd:VirtualQuantity>
+ </Item>
+ <Item>
+ <rasd:Address>0</rasd:Address>
+ <rasd:Description>SCSI Controller</rasd:Description>
+ <rasd:ElementName>scsiController0</rasd:ElementName>
+ <rasd:InstanceID>3</rasd:InstanceID>
+ <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType>
+ <rasd:ResourceType>6</rasd:ResourceType>
+ </Item>
+ <Item>
+ <rasd:AddressOnParent>0</rasd:AddressOnParent>
+ <rasd:ElementName>disk0</rasd:ElementName>
+ <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>
+ <rasd:InstanceID>4</rasd:InstanceID>
+ <rasd:Parent>3</rasd:Parent>
+ <rasd:ResourceType>17</rasd:ResourceType>
+ </Item>
+ <Item ovf:required="false">
+ <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+ <rasd:ElementName>video</rasd:ElementName>
+ <rasd:InstanceID>5</rasd:InstanceID>
+ <rasd:ResourceType>24</rasd:ResourceType>
+ </Item>
+ <Item ovf:required="false">
+ <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+ <rasd:ElementName>vmci</rasd:ElementName>
+ <rasd:InstanceID>6</rasd:InstanceID>
+ <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>
+ <rasd:ResourceType>1</rasd:ResourceType>
+ </Item>
+ <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="true"/>
+ <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" vmw:value="soft"/>
+ <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" vmw:value="soft"/>
+ <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" vmw:value="soft"/>
+ <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" vmw:value="true"/>
+ <vmw:Config ovf:required="false" vmw:key="tools.toolsUpgradePolicy" vmw:value="upgradeAtPowerCycle"/>
+ </VirtualHardwareSection>
+
+ </VirtualSystem>
+</Envelope>
--- /dev/null
+##
+# Copyright 2019 VMware Inc.
+# This file is part of ETSI OSM
+# 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: osslegalrouting@vmware.com
+##
+
+import argparse
+from uploader import OVFUploader, get_version
+
+
+def execute_cli():
+
+ """
+ Method to parse CLI arguments and execute commands accordingly
+ Args : None
+ Return : None
+ """
+ parser = argparse.ArgumentParser(description='Utility to upload an OVF package to vCD')
+
+ parser.add_argument("-v", "--version", action="version", version=str(get_version()),
+ help="shows version of vCD Uploader tool")
+
+ parser.add_argument("ovf_file", action="store",
+ help="filename of OVF file to upload to vCD")
+
+ parser.add_argument("-l", "--vcd_url", action="store",
+ required=True,
+ help="URL for vCD login (ie: https://vcd.local/")
+
+ parser.add_argument("-u", "--username", action="store",
+ required=True,
+ help="Username for vCD login")
+
+ parser.add_argument("-p", "--password", action="store",
+ required=True,
+ help="Password for vCD login")
+
+ parser.add_argument("-o", "--orgname", action="store",
+ required=True,
+ help="Organization name for vCD login")
+
+ args = parser.parse_args()
+
+ if args.ovf_file:
+ try:
+ uploader = OVFUploader(args.ovf_file,
+ vcd_url=args.vcd_url,
+ username=args.username,
+ password=args.password,
+ orgname=args.orgname)
+ uploader.make_catalog()
+ uploader.upload_ovf()
+ uploader.wait_for_task_completion()
+ except Exception as exp:
+ print(exp)
+ exit(1)
+
+
+if __name__ == "__main__":
+ execute_cli()
##
-# Copyright 2016-2017 VMware Inc.
+# Copyright 2016-2019 VMware Inc.
# This file is part of ETSI OSM
# All Rights Reserved.
#
# contact: osslegalrouting@vmware.com
##
+
This README file explains how to use OVF Converter Tool to generate OVF file from .qcow2, .img (raw) disk images.
CONTENTS OF THIS FILE
Introduction
==================
-OVF Converter Tool is a Command Line Interface (CLI) basically designed to generate OVF files from disk image such as .qcow2, and .img (raw format) which are other than .vmdk.
-Given a path to .qcow2 image this tool can generate .vmdk and .ovf files.
-User can optionally specify name and location of ovf file. Also, one can use command line options to give disk size (GB), memory (MB), number of cpus, OS type, disk controller required for VM which will get deployed using generated OVF.
+OVF Converter Tool is a Command Line Interface (CLI) basically designed to generate OVF files from disk image such as
+.qcow2, and .img (raw format) which are other than .vmdk. Given a path to .qcow2 image this tool can generate .vmdk
+and .ovf files.
+
+The user can optionally specify name and location of ovf file. Also, one can use command line options to give disk
+size (GB), memory (MB), number of cpus, OS type, disk controller required for VM which will get deployed using
+generated OVF.
+
Generated OVF file can be used to deploy VM in Vmware vSphere or vCloud Director.
Note- Currently this tool supports only Ubuntu platform.
==================
This tool requires the following software package:
-o apt-get package manager
-o qemu-utils
-o python 2.7
-o python-lxml
-o libxml2-dev
-o libxslt-dev
-o python-dev
-o python-pip
-
-Install.sh script in this folder will install all of these
-software packages.
+o apt-get package manager
+o qemu-utils
+o python 2.7
+o python-lxml
+o libxml2-dev
+o libxslt-dev
+o python-dev
+o python-pip
+
+Install.sh script in this folder will install all of these software packages.
Installation
chmod a+x install.sh
2. Run install.sh script as:
./install.sh
-
+
Sample output -
- #################################################################
- ##### Installing Require Packages #####
- #################################################################
- Hit:1 http://us.archive.ubuntu.com/ubuntu xenial InRelease
- Get:2 http://us.archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
- Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
- Get:4 http://us.archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]
- Fetched 306 kB in 1s (286 kB/s)
- Reading package lists... Done
- Reading package lists... Done
- Building dependency tree
- Reading state information... Done
- Note, selecting 'libxslt1-dev' instead of 'libxslt-dev'
- libxslt1-dev is already the newest version (1.1.28-2.1).
- python-dev is already the newest version (2.7.11-1).
- python-lxml is already the newest version (3.5.0-1build1).
- libxml2-dev is already the newest version (2.9.3+dfsg1-1ubuntu0.1).
-
- t version (1:2.5+dfsg-5ubuntu10.6).
- 0 upgraded, 0 newly installed, 0 to remove and 72 not upgraded.
-
- #################################################################
- ##### Done #####
- #################################################################
- root@ubuntu:/home/vmware/OVF_converter#
- root@ubuntu:/home/vmware/OVF_converter#
-
+ #################################################################
+ ##### Installing Require Packages #####
+ #################################################################
+ Hit:1 http://us.archive.ubuntu.com/ubuntu xenial InRelease
+ Get:2 http://us.archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
+ Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
+ Get:4 http://us.archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]
+ Fetched 306 kB in 1s (286 kB/s)
+ Reading package lists... Done
+ Reading package lists... Done
+ Building dependency tree
+ Reading state information... Done
+ Note, selecting 'libxslt1-dev' instead of 'libxslt-dev'
+ libxslt1-dev is already the newest version (1.1.28-2.1).
+ python-dev is already the newest version (2.7.11-1).
+ python-lxml is already the newest version (3.5.0-1build1).
+ libxml2-dev is already the newest version (2.9.3+dfsg1-1ubuntu0.1).
+
+ t version (1:2.5+dfsg-5ubuntu10.6).
+ 0 upgraded, 0 newly installed, 0 to remove and 72 not upgraded.
+
+ #################################################################
+ ##### Done #####
+ #################################################################
+ root@ubuntu:/home/vmware/OVF_converter#
+ root@ubuntu:/home/vmware/OVF_converter#
+
3. Now tool is installed at /usr/local/bin and available for all users
4. User can access commands of OVF Generator Tool as:
ovf_converter path [output location] [ovf name][memory][cpu][disk][ostype][disk_controller]
Usage
===================
-o Get version of tool as:
-
- Command - ovf_converter -v
- Sample output -
- root@ubuntu:/home/vmware/OVF_converter# ovf_converter -v
- 1.0 - Initial Realse
- root@ubuntu:/home/vmware/OVF_converter#
-
-o See all command line options of tool as:
- Command - ovf_converter -h
- Sample output -
- root@ubuntu:/home/vmware/OVF_converter#
- root@ubuntu:/home/vmware/OVF_converter# ovf_converter -h
- Usage: ovf_converter_cli.py [-h] [-v] [-o OUTPUT_LOCATION] [-n OVF_NAME]
+o Get version of tool as:
+
+ Command - ovf_converter -v
+ Sample output -
+ root@ubuntu:/home/vmware/OVF_converter# ovf_converter -v
+ 1.0 - Initial Realse
+ root@ubuntu:/home/vmware/OVF_converter#
+
+o See all command line options of tool as:
+ Command - ovf_converter -h
+ Sample output -
+ root@ubuntu:/home/vmware/OVF_converter#
+ root@ubuntu:/home/vmware/OVF_converter# ovf_converter -h
+ Usage: ovf_converter_cli.py [-h] [-v] [-o OUTPUT_LOCATION] [-n OVF_NAME]
[-m MEMORY] [-c CPU] [-d DISK] [-s OSTYPE]
- [-dc DISK_CONTROLLER] [--cdrom]
+ [-dc DISK_CONTROLLER] [--cdrom] [-w 14]
path
- OVF converter to convert .qcow2 or raw image into OVF
-
- positional arguments:
- path absolute path to source image which will get convert
- into ovf
-
- optional arguments:
- -h, --help show this help message and exit
- -v, --version shows version of OVF Converter tool
- -o OUTPUT_LOCATION, --output_location OUTPUT_LOCATION
- location where created OVF will be kept. This location
- should have write access. If not given file will get
- created at source location (optional)
- -n OVF_NAME, --ovf_name OVF_NAME
- name of output ovf file. If not given source image
- name will be used (optional)
- -m MEMORY, --memory MEMORY
- required memory for VM in MB (default 1 GB)(optional)
- -c CPU, --cpu CPU required number of virtual cpus for VM (default 1 cpu)
- (optional)
- -d DISK, --disk DISK required size of disk for VM in GB (default as
- in source disk img) (optional)
- -s OSTYPE, --osType OSTYPE
- required operating system type as specified in user
- document (default os type other 32 bit) (optional)
- -dc DISK_CONTROLLER, --disk_Controller DISK_CONTROLLER
- required disk controller type (default controller SCSI
- with lsilogicsas) (SATA, IDE, Paravirtual, Buslogic,
- lsilogic, lsilogicsas) (optional)
- --cdrom whether to include a cd/dvd device (optional)
-
-
-o Create OVF file from qcow2 or raw disk image as:
- Command - ovf_converter /home/vmware/centos_ovf/CentOS-7-x86_64-GenericCloud-1503.qcow2 -n centos_qcow2.ovf -m 2048 -c 4 -d 10 -s "Centos 32-bit" -dc "SATA"
- Sample output -
- root@ubuntu:/home/vmware/OVF_converter# ovf_converter /home/vmware/centos_ovf/CentOS-7-x86_64-GenericCloud-1503.qcow2 -n centos_qcow2.ovf -m 2048 -c 4 -d 10
- #### Start OVF conversion ####
- Getting source image information
- Converting source disk image to .vmdk
- .....................................................
- Creating OVF
- Output OVF is at: /home/vmware/centos_ovf/centos_qcow2.ovf
- #### Completed OVF conversion ####
+ OVF converter to convert .qcow2 or raw image into OVF
+
+ positional arguments:
+ path absolute path to source image which will get convert
+ into ovf
+
+ optional arguments:
+ -h, --help show this help message and exit
+ -v, --version shows version of OVF Converter tool
+ -o OUTPUT_LOCATION, --output_location OUTPUT_LOCATION
+ location where created OVF will be kept. This location
+ should have write access. If not given file will get
+ created at source location (optional)
+ -n OVF_NAME, --ovf_name OVF_NAME
+ name of output ovf file. If not given source image
+ name will be used (optional)
+ -m MEMORY, --memory MEMORY
+ required memory for VM in MB (default 1 GB)(optional)
+ -c CPU, --cpu CPU required number of virtual cpus for VM (default 1 cpu)
+ (optional)
+ -d DISK, --disk DISK required size of disk for VM in GB (default as
+ in source disk img) (optional)
+ -s OSTYPE, --osType OSTYPE
+ required operating system type as specified in user
+ document (default os type other 32 bit) (optional)
+ -dc DISK_CONTROLLER, --disk_Controller DISK_CONTROLLER
+ required disk controller type (default controller SCSI
+ with lsilogicsas) (SATA, IDE, Paravirtual, Buslogic,
+ lsilogic, lsilogicsas) (optional)
+ --cdrom whether to include a cd/dvd device (optional)
+ -hw VERSION, --hwversion VERSION
+ VMware ESXi hardware family version (optional)
+
+
+o Create OVF file from qcow2 or raw disk image as:
+ Command - ovf_converter /home/vmware/centos_ovf/CentOS-7-x86_64-GenericCloud-1503.qcow2 -n centos_qcow2.ovf -m 2048 -c 4 -d 10 -s "Centos 32-bit" -dc "SATA"
+ Sample output -
+ root@ubuntu:/home/vmware/OVF_converter# ovf_converter /home/vmware/centos_ovf/CentOS-7-x86_64-GenericCloud-1503.qcow2 -n centos_qcow2.ovf -m 2048 -c 4 -d 10
+ #### Start OVF conversion ####
+ Getting source image information
+ Converting source disk image to .vmdk
+ .....................................................
+ Creating OVF
+ Output OVF is at: /home/vmware/centos_ovf/centos_qcow2.ovf
+ #### Completed OVF conversion ####
Trouble shooting
Version 1.0
-------------
-Initial release
+Initial release
+
+Version 1.1
+-------------
+
+Adds support for cdrom
+
+Version 1.2
+-------------
+
+Adds support for hardware version
+Improves progress indicator
--- /dev/null
+# #
+# Copyright 2019 VMware Inc.
+# This file is part of ETSI OSM
+# 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: osslegalrouting@vmware.com
+# #
+
+import logging
+from lxml import etree
+import os
+from pyvcloud.vcd.client import BasicLoginCredentials, Client, QueryResultFormat, ResourceType, TaskStatus
+from pyvcloud.vcd.exceptions import EntityNotFoundException, InternalServerException
+from pyvcloud.vcd.org import Org
+import sys
+import tarfile
+import time
+
+MODULE_DIR = os.path.dirname(__file__)
+
+# Set logger
+LOG_FILE = os.path.join(MODULE_DIR, "logs/ovf_uploader.log")
+os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
+logger = logging.getLogger(__name__)
+file_handler = logging.FileHandler(LOG_FILE)
+file_handler.setLevel(logging.DEBUG)
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+file_handler.setFormatter(formatter)
+logger.addHandler(file_handler)
+stdout_handler = logging.StreamHandler(sys.stdout)
+stdout_handler.setLevel(logging.INFO)
+logger.addHandler(stdout_handler)
+logger.setLevel(10)
+logging.captureWarnings(True)
+
+__version__ = "1.0"
+__description__ = "Initial Release"
+
+
+def get_version():
+ """ get version of this application"""
+ version = str(__version__) + " - " + str(__description__)
+ return version
+
+
+def report_progress(bytes_written, total_size):
+ percent_complete = int((bytes_written * 100) / total_size)
+ print("{}% complete \r".format(percent_complete), end='')
+
+
+class OVFUploader(object):
+ """ Class to convert input image into OVF format """
+
+ def __init__(self, ovf_file, vcd_url=None, username=None, password=None, orgname=None):
+ self.ovf_file = os.path.abspath(ovf_file)
+ self.vcd_url = vcd_url
+ self.username = username
+ self.password = password
+ self.orgname = orgname
+ try:
+ client = Client(self.vcd_url, verify_ssl_certs=False)
+ client.set_highest_supported_version()
+ client.set_credentials(BasicLoginCredentials(self.username, self.orgname,
+ self.password))
+ logger.info("Logged into {} using version {}".format(self.vcd_url, client.get_api_version()))
+ self.client = client
+ self.org = Org(self.client, resource=self.client.get_org())
+
+ except Exception as exp:
+ problem = Exception("Failed to connect to vCD at {}, org {}, username {}:\n{}".format(
+ self.vcd_url, self.orgname, self.username, exp))
+ logger.error(problem)
+ raise problem
+
+ try:
+ # Retrieve the VM name from the OVF. We will use this as both the image and catalog name
+ OVF_tree = etree.parse(self.ovf_file)
+ root = OVF_tree.getroot()
+ nsmap = {k: v for k, v in root.nsmap.items() if k}
+ nsmap["xmlns"] = "http://schemas.dmtf.org/ovf/envelope/1"
+
+ virtuasystem = root.find('xmlns:VirtualSystem', nsmap)
+ name_tag = virtuasystem.find('xmlns:Name', nsmap)
+ self.image_name = name_tag.text
+ info_tag = virtuasystem.find('xmlns:Info', nsmap)
+ self.image_description = info_tag.text
+
+ references = root.find('xmlns:References', nsmap)
+ file = references.find('xmlns:File', nsmap)
+ self.vmdk_file = "{}/{}".format(
+ os.path.dirname(self.ovf_file),
+ file.attrib['{http://schemas.dmtf.org/ovf/envelope/1}href'])
+ logger.info("Loaded VM {}: {}".format(self.image_name, self.image_description))
+
+ except Exception as exp:
+ problem = Exception("Failed to fetch VirtualSystem Name element from OVF {}:\n{}".format(
+ self.ovf_file, exp))
+ logger.error(problem)
+ raise problem
+
+ def make_catalog(self):
+ try:
+ try:
+ catalog = self.org.get_catalog(self.image_name)
+ self.catalog_id = catalog.attrib['id'].split(':')[-1]
+ except EntityNotFoundException:
+ logger.info("Creating a new catalog entry {} in vCD".format(self.image_name))
+ result = self.org.create_catalog(self.image_name, self.image_description)
+ if result is None:
+ raise Exception("Failed to create new catalog entry")
+ self.catalog_id = result.attrib['id'].split(':')[-1]
+ self.org.reload()
+
+ logger.debug("Using catalog {}, id {}".format(self.image_name, self.catalog_id))
+
+ except Exception as exp:
+ problem = Exception("Failed to fetch catalog for {}:\n{} ".format(self.image_name, exp))
+ logger.error(problem)
+ raise problem
+
+ def upload_ovf(self):
+
+ try:
+ # Check if the content already exists:
+ items = self.org.list_catalog_items(self.image_name)
+ for item in items:
+ if item['name'] == self.image_name:
+ logger.info("Removing old version from catalog")
+ try:
+ self.org.delete_catalog_item(self.image_name, self.image_name)
+ except InternalServerException as exp:
+ problem = Exception(
+ "Cannot delete vAppTemplate {}. Please check in vCD if "
+ "the content is still being imported into the catalog".format(
+ self.image_name))
+ raise problem
+
+ # Create a single OVA bundle
+ ova_tarfilename, _ = os.path.splitext(self.ovf_file)
+ ova_tarfilename += '.ova'
+ ova = tarfile.open(name=ova_tarfilename,
+ mode='w')
+ ova.add(self.ovf_file, arcname=os.path.basename(self.ovf_file))
+ ova.add(self.vmdk_file, arcname=os.path.basename(self.vmdk_file))
+ ova.close()
+ logger.info("Uploading content to vCD")
+ self.org.upload_ovf(self.image_name,
+ ova_tarfilename,
+ item_name=self.image_name,
+ description=self.image_description,
+ callback=report_progress)
+ except Exception as exp:
+ problem = Exception("Failed to upload OVF {}:\n{} ".format(self.ovf_file, exp))
+ logger.error(problem)
+ raise problem
+ finally:
+ if os.path.exists(ova_tarfilename):
+ os.remove(ova_tarfilename)
+
+ def wait_for_task_completion(self):
+
+ logger.info("Importing content to vCD")
+ try:
+
+ query = self.client.get_typed_query(
+ query_type_name=ResourceType.TASK.value,
+ qfilter='ownerName==' + self.username + ';(status==queued,status==preRunning,status==running)',
+ query_result_format=QueryResultFormat.REFERENCES)
+
+ upload_task = None
+ tasks = list(query.execute())
+ for task in tasks:
+ if task.get('name') == 'VDC_UPLOAD_OVF_CONTENTS':
+ upload_task = self.client.get_resource(task.get('href'))
+ break
+
+ bad_statuses = [
+ TaskStatus.ABORTED,
+ TaskStatus.CANCELED,
+ TaskStatus.ERROR
+ ]
+
+ except Exception as exp:
+ problem = Exception("Failed to import OVF {}:\n{} ".format(self.ovf_file, exp))
+ logger.error(problem)
+ raise problem
+
+ while(True):
+ task_status = upload_task.get('status').lower()
+ if(hasattr(upload_task, 'Progress')):
+ print("{}% complete \r".format(upload_task.Progress), end='')
+
+ for status in bad_statuses:
+ if task_status == status.value.lower():
+ problem = Exception(
+ "vCD failed to import OVF {}:\n{}: {} ".format(self.ovf_file,
+ task_status,
+ upload_task.Error.get('Message')))
+ logger.error(problem)
+ raise problem
+ if task_status == str(TaskStatus.SUCCESS.value).lower():
+ break
+
+ time.sleep(2)
+ upload_task = self.client.get_resource(upload_task.get('href'))
+
+ logger.info("OVF upload and import complete, content is ready to use")
# -*- coding: utf-8 -*-
-##
+# #
# Copyright 2016-2017 VMware Inc.
# This file is part of ETSI OSM
# All Rights Reserved.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: osslegalrouting@vmware.com
-##
+# #
-
-from xml.etree import ElementTree as XmlElementTree
-from pyvcloud.vcd.client import BasicLoginCredentials,Client
-from pyvcloud.vcd.vdc import VDC
-from pyvcloud.vcd.org import Org
-import sys,os
import logging
+import os
+from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar
+from pyvcloud.vcd.client import BasicLoginCredentials, Client
+from pyvcloud.vcd.org import Org
+import re
import requests
+import sys
import time
-import re
-import hashlib
-from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar
-
+from xml.etree import ElementTree as XmlElementTree
API_VERSION = '5.6'
+
class vCloudconfig(object):
- def __init__(self, host=None, user=None, password=None,orgname=None, logger=None):
+
+ def __init__(self, host=None, user=None, password=None, orgname=None, logger=None):
self.url = host
self.user = user
self.password = password
try:
self.logger.debug("Logging in to a vcd {} as user {}".format(self.org,
- self.user))
+ self.user))
client = Client(self.url, verify_ssl_certs=False)
client.set_credentials(BasicLoginCredentials(self.user, self.org, self.password))
- except:
+ except Exception:
raise Exception("Can't connect to a vCloud director org: "
- "{} as user: {}".format(self.org, self.user))
+ "{} as user: {}".format(self.org, self.user))
return client
self.logger.debug("get_catalog_id_from_path() client requesting {} ".format(path))
- dirpath, filename = os.path.split(path)
- flname, file_extension = os.path.splitext(path)
+ _, filename = os.path.split(path)
+ _, file_extension = os.path.splitext(path)
if file_extension != '.ovf':
self.logger.debug("Wrong file extension {} connector support only OVF container.".format(file_extension))
raise Exception("Wrong container. vCloud director supports only OVF.")
self.logger.debug("File name {} Catalog Name {} file path {} ".format(filename,
- catalog_name,
- path))
+ catalog_name,
+ path))
try:
client = self.connect()
if not client:
- raise Exception("Failed to connect vCD")
+ raise Exception("Failed to connect vCD")
org = Org(client, resource=client.get_org())
catalogs = org.list_catalogs()
except Exception as exp:
if result is None:
raise Exception("Failed to create new catalog {} ".format(catalog_name))
result = self.upload_ovf(org=org, catalog_name=catalog_name, image_name=filename.split(".")[0],
- media_file_name=path, description='medial_file_name', progress=progress)
+ media_file_name=path, description='medial_file_name', progress=progress)
if not result:
raise Exception("Failed to create vApp template for catalog {} ".format(catalog_name))
return self.get_catalogid(catalog_name, catalogs)
# search for existing catalog if we find same name we return ID
if catalog['name'] == catalog_name:
self.logger.debug("Found existing catalog entry for {} "
- "catalog id {}".format(catalog_name,
- self.get_catalogid(catalog_name, catalogs)))
+ "catalog id {}".format(catalog_name,
+ self.get_catalogid(catalog_name, catalogs)))
return self.get_catalogid(catalog_name, catalogs)
# if we didn't find existing catalog we create a new one and upload image.
self.logger.debug("Creating new catalog entry {} - {}".format(catalog_name, catalog_name))
- result = org.create_catalog(catalog_name, catalog_name)
+ result = org.create_catalog(catalog_name, catalog_name)
if result is None:
raise Exception("Failed to create new catalog {} ".format(catalog_name))
result = self.upload_ovf(org=org, catalog_name=catalog_name, image_name=filename.split(".")[0],
- media_file_name=path, description='medial_file_name', progress=progress)
+ media_file_name=path, description='medial_file_name', progress=progress)
if not result:
raise Exception("Failed create vApp template for catalog {} ".format(catalog_name))
continue
catalog_href = "{}/api/catalog/{}/action/upload".format(self.url, catalog['id'])
data = """
- <UploadVAppTemplateParams name="{}" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"><Description>{} vApp Template</Description></UploadVAppTemplateParams>
+ <UploadVAppTemplateParams name="{}" xmlns="http://www.vmware.com/vcloud/v1.5"
+ xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1">
+ <Description>{} vApp Template</Description></UploadVAppTemplateParams>
""".format(catalog_name, description)
if client:
- headers = {'Accept':'application/*+xml;version=' + API_VERSION,
- 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
+ headers = {'Accept': 'application/*+xml;version=' + API_VERSION,
+ 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
headers['Content-Type'] = 'application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml'
response = requests.post(url=catalog_href,
- headers=headers,
- data=data,
- verify=False)
+ headers=headers,
+ data=data,
+ verify=False)
if response.status_code != 201:
self.logger.debug("Failed to create vApp template")
- raise Exception("Failed to create vApp template")
+ raise Exception("Failed to create vApp template")
if response.status_code == requests.codes.created:
catalogItem = XmlElementTree.fromstring(response.content)
template = href
response = requests.get(url=href,
- headers=headers,
- verify=False)
+ headers=headers,
+ verify=False)
if response.status_code == requests.codes.ok:
headers['Content-Type'] = 'Content-Type text/xml'
- result = re.search('rel="upload:default"\shref="(.*?\/descriptor.ovf)"',response.content)
+ result = re.search('rel="upload:default"\shref="(.*?\/descriptor.ovf)"', response.content)
if result:
transfer_href = result.group(1)
response = requests.put(url=transfer_href, headers=headers,
- data=open(media_file_name, 'rb'),
- verify=False)
+ data=open(media_file_name, 'rb'),
+ verify=False)
if response.status_code != requests.codes.ok:
self.logger.debug(
- "Failed create vApp template for catalog name {} and image {}".format(catalog_name,
- media_file_name))
+ "Failed create vApp template for catalog name {} and image {}".format(
+ catalog_name,
+ media_file_name))
return False
# TODO fix this with aync block
time.sleep(5)
- self.logger.debug("vApp template for catalog name {} and image {}".format(catalog_name, media_file_name))
+ self.logger.debug("vApp template for catalog name {} and image {}".format(
+ catalog_name,
+ media_file_name))
# uploading VMDK file
# check status of OVF upload and upload remaining files.
response = requests.get(url=template,
- headers=headers,
+ headers=headers,
verify=False)
if response.status_code == requests.codes.ok:
- result = re.search('rel="upload:default"\s*href="(.*?vmdk)"',response.content)
+ result = re.search('rel="upload:default"\s*href="(.*?vmdk)"', response.content)
if result:
link_href = result.group(1)
# we skip ovf since it already uploaded.
if 'ovf' in link_href:
continue
# The OVF file and VMDK must be in a same directory
- head, tail = os.path.split(media_file_name)
+ head, _ = os.path.split(media_file_name)
file_vmdk = head + '/' + link_href.split("/")[-1]
if not os.path.isfile(file_vmdk):
return False
hrefvmdk = link_href
if progress:
widgets = ['Uploading file: ', Percentage(), ' ', Bar(), ' ', ETA(), ' ',
- FileTransferSpeed()]
+ FileTransferSpeed()]
progress_bar = ProgressBar(widgets=widgets, maxval=statinfo.st_size).start()
bytes_transferred = 0
bytes_transferred, len(my_bytes) - 1, statinfo.st_size)
headers['Content-Length'] = str(len(my_bytes))
response = requests.put(url=hrefvmdk,
- headers=headers,
- data=my_bytes,
- verify=False)
+ headers=headers,
+ data=my_bytes,
+ verify=False)
if response.status_code == requests.codes.ok:
bytes_transferred += len(my_bytes)
if progress:
else:
self.logger.debug(
'file upload failed with error: [%s] %s' % (response.status_code,
- response.content))
+ response.content))
f.close()
return False
else:
self.logger.debug("Failed retrieve vApp template for catalog name {} for OVF {}".
format(catalog_name, media_file_name))
- return False
+ return False
except Exception as exp:
self.logger.debug("Failed while uploading OVF to catalog {} for OVF file {} with Exception {}"
- .format(catalog_name,media_file_name, exp))
+ .format(catalog_name, media_file_name, exp))
raise Exception(
"Failed while uploading OVF to catalog {} for OVF file {} with Exception {}"
- .format(catalog_name,media_file_name, exp))
+ .format(catalog_name, media_file_name, exp))
self.logger.debug("Failed to retrieve catalog name {} for OVF file {}".format(catalog_name, media_file_name))
- return False
+ return False
+
if __name__ == "__main__":
+ print("This file is deprecated. Please use ovf_uplader_cli instead.")
+
# vmware vcloud director credentials
vcd_hostname = sys.argv[1]
vcd_username = sys.argv[2]
# OVF image path to be upload to vCD
ovf_file_path = sys.argv[5]
- # changing virtual system type in ovf file
- fh = open(ovf_file_path,'r')
- content = fh.read()
- content = content.replace('<vssd:VirtualSystemType>vmx-7','<vssd:VirtualSystemType>vmx-07')
- fh.close()
- fh1 = open(ovf_file_path,'w')
- fh1.write(content)
- fh1.close()
-
-
- logging.basicConfig(filename='ovf_upload.log',level=logging.DEBUG)
+ logging.basicConfig(filename='ovf_upload.log', level=logging.DEBUG)
logger = logging.getLogger(__name__)
obj = vCloudconfig(vcd_hostname, vcd_username, vcd_password, orgname, logger)
# Get image name from cirros vnfd
cirros_yaml = '../descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml'
- rh = open(cirros_yaml,'r')
- match = re.search("image:\s'(.*?)'\n",rh.read())
- if match: catalog = match.group(1)
+ rh = open(cirros_yaml, 'r')
+ match = re.search("image:\s'(.*?)'\n", rh.read())
+ if match:
+ catalog = match.group(1)
if file_extension == '.ovf':
obj.get_catalog_id_from_path(catalog_name=catalog, path=ovf_file_path,
- progress=True)
+ progress=True)