Update for Euphrates; build/use Tacker container 09/50309/1
authorBryan Sullivan <bryan.sullivan@att.com>
Tue, 9 Jan 2018 17:29:04 +0000 (09:29 -0800)
committerBryan Sullivan <bryan.sullivan@att.com>
Tue, 9 Jan 2018 17:29:04 +0000 (09:29 -0800)
JIRA: MODELS-2

Change-Id: I71db2f530a055e17d8012ba37487a9ae76be0fd1
Signed-off-by: Bryan Sullivan <bryan.sullivan@att.com>
build/tacker.sh [new file with mode: 0644]
build/tacker/Dockerfile [new file with mode: 0644]
build/tacker/start.sh [new file with mode: 0644]
build/tacker/tacker.conf [new file with mode: 0644]
tests/utils/tacker-setup.sh
tests/vHello_Tacker.sh

diff --git a/build/tacker.sh b/build/tacker.sh
new file mode 100644 (file)
index 0000000..a416fc4
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/bash
+# Copyright 2017 AT&T Intellectual Property, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#. What this is: Build script for the OpenStack Tacker project
+#.   https://github.com/openstack/tacker
+#.
+#. Prerequisites:
+#.   Docker hub user logged on so images can be pushed to docker hub, i.e. via
+#.   $ docker login -u <hub-user>
+#.
+#. Usage:
+#.   bash tacker.sh <hub-user> <branch>
+#.     hub-user: username for dockerhub
+#.     branch: branch to use (default: master)
+#.
+#. Status: this is a work in progress, under test.
+
+trap 'fail' ERR
+
+fail() {
+  echo "Build Failed!"
+  exit 1
+}
+
+dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`
+
+hub_user=$1
+branch=$2
+
+echo; echo "$0 $(date): Update package repos"
+if [ "$dist" == "Ubuntu" ]; then
+  sudo apt-get update
+else
+  sudo yum update -y
+fi
+
+if [[ ! -d /tmp/models ]]; then
+  echo; echo "$0 $(date): Cloning models repo to /tmp/models"
+  git clone https://gerrit.opnfv.org/gerrit/models /tmp/models
+fi
+
+echo; echo "$0 $(date): Starting Tacker build process"
+cd /tmp/models/build/tacker
+sed -i -- "s/<branch>/$branch/g" Dockerfile
+sudo docker build -t tacker .
+
+echo; echo "$0 $(date): Tagging the image as models-tacker:$branch"
+if [[ "$branch" == "" ]]; then branch="latest"; fi
+id=$(sudo docker images | grep tacker | awk '{print $3}')
+id=$(echo $id | cut -d ' ' -f 1)
+sudo docker tag $id $1/models-tacker:$branch
+
+echo; echo "$0 $(date): Pushing the image to dockerhub as $1/models-tacker"
+sudo docker push $1/models-tacker
diff --git a/build/tacker/Dockerfile b/build/tacker/Dockerfile
new file mode 100644 (file)
index 0000000..f7c7af6
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright 2017 AT&T Intellectual Property, Inc
+#  
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#  
+# http://www.apache.org/licenses/LICENSE-2.0
+#  
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# What this is: A Dockerfile for building an OpenStack Tacker container image.
+#
+# Status: this is a work in progress, under test.
+#
+
+FROM ubuntu:xenial
+
+MAINTAINER Bryan Sullivan
+
+# Per http://docs.openstack.org/developer/tacker/install/manual_installation.html
+RUN apt-get update --fix-missing
+RUN apt-get install -y apt-utils
+RUN apt-get upgrade -y
+RUN apt-get install -y python
+RUN apt-get install -y python-dev
+RUN apt-get install -y python-pip
+RUN apt-get install -y wget
+RUN apt-get install -y openssh-server
+RUN apt-get install -y git
+RUN apt-get install -y apg
+RUN apt-get install -y libffi-dev
+RUN apt-get install -y libssl-dev
+# newton: tacker uses ping for monitoring VIM (not in default docker containers)
+RUN apt-get install -y inetutils-ping
+# apt-utils is not installed in xenial container image
+RUN apt-get install -y apt-utils
+# Upgrage pip again - needs to be the latest version due to errors found in testing
+RUN pip install --upgrade pip
+
+# Install OpenStack clients
+RUN git clone https://github.com/openstack/python-openstackclient.git; \
+cd python-openstackclient; \
+if [[ "<branch>" != "" ]]; then git checkout <branch>; fi; \
+pip install -r requirements.txt; \
+pip install .
+
+RUN git clone https://github.com/openstack/python-neutronclient.git; \
+cd python-neutronclient; \
+if [[ "<branch>" != "" ]]; then git checkout <branch>; fi; \
+pip install -r requirements.txt; \
+pip install .
+
+RUN git clone https://github.com/openstack/python-novaclient.git; \
+cd python-novaclient; \
+if [[ "<branch>" != "" ]]; then git checkout <branch>; fi; \
+pip install -r requirements.txt; \
+pip install .
+
+RUN git clone https://github.com/openstack/python-tackerclient; \
+cd python-tackerclient; \
+if [[ "<branch>" != "" ]]; then git checkout <branch>; fi; \
+python setup.py install
+
+# Setup Tacker
+RUN git clone https://github.com/openstack/tacker.git; \
+if [[ "<branch>" != "" ]]; then cd tacker; git checkout <branch>; fi; \
+cd tacker; \
+pip install -r requirements.txt; \
+pip install tosca-parser; \
+python setup.py install; \
+mkdir /var/log/tacker; \
+mkdir /var/lib/tacker
+
+COPY tacker.conf /usr/local/etc/tacker/tacker.conf
+COPY start.sh start.sh
+ENTRYPOINT ["/bin/bash", "start.sh"]
diff --git a/build/tacker/start.sh b/build/tacker/start.sh
new file mode 100644 (file)
index 0000000..b824589
--- /dev/null
@@ -0,0 +1,213 @@
+#!/bin/bash
+# Copyright 2017 AT&T Intellectual Property, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# What this is: Startup script for OpenStack Tacker running under docker.
+
+function log() {
+  f=$(caller 0 | awk '{print $2}')
+  l=$(caller 0 | awk '{print $1}')
+  echo; echo "$f:$l ($(date)) $1"
+}
+
+export MYSQL_PASSWORD=$(/usr/bin/apg -n 1 -m 16 -c cl_seed)
+echo $MYSQL_PASSWORD >~/mysql
+debconf-set-selections <<< 'mysql-server mysql-server/root_password password '$MYSQL_PASSWORD
+debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password '$MYSQL_PASSWORD
+apt-get -q -y install mysql-server python-mysqldb
+service mysql restart
+
+log "create Tacker database"
+mysql --user=root --password=$MYSQL_PASSWORD -e "CREATE DATABASE tacker; GRANT ALL PRIVILEGES ON tacker.* TO 'root@localhost' IDENTIFIED BY '"$MYSQL_PASSWORD"'; GRANT ALL PRIVILEGES ON tacker.* TO 'tacker'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"';"
+
+log "Setup OpenStack CLI environment"
+source /opt/tacker/admin-openrc.sh
+
+uid=$(openstack user list | awk "/ tacker / { print \$2 }")
+if [[ $uid ]]; then
+  log "Remove prior Tacker user etc"
+  openstack user delete tacker
+  openstack service delete tacker
+  # Note: deleting the service deletes the endpoint
+fi
+
+log "Setup Tacker user in OpenStack"
+service_project=$(openstack project list | awk "/service/ { print \$4 }")
+openstack user create --project $service_project --password tacker tacker
+openstack role add --project $service_project --user tacker admin
+
+log "Create Tacker service in OpenStack"
+sid=$(openstack service list | awk "/ tacker / { print \$2 }")
+openstack service create --name tacker --description "Tacker Project" nfv-orchestration
+sid=$(openstack service list | awk "/ tacker / { print \$2 }")
+
+log "Create Tacker service endpoint in OpenStack"
+ip=$(ip route get 8.8.8.8 | awk '{print $NF; exit}')
+region=$(openstack endpoint list | awk "/ nova / { print \$4 }" | head -1)
+openstack endpoint create --region $region \
+  --publicurl "http://$ip:9890/" \
+  --adminurl "http://$ip:9890/" \
+  --internalurl "http://$ip:9890/" nfv-orchestration
+
+# TODO: find a generic way to set extension_drivers = port_security in ml2_conf.ini
+  # On the neutron service host, update ml2_conf.ini and and restart neutron service
+  # sed -i -- 's~#extension_drivers =~extension_drivers = port_security~' /etc/neutron/plugins/ml2/ml2_conf.ini
+  # For devstack, set in local.conf per http://docs.openstack.org/developer/devstack/guides/neutron.html
+  # Q_ML2_PLUGIN_EXT_DRIVERS=port_security
+
+log "Update tacker.conf values"
+
+# [DEFAULT] section (update)
+sed -i -- 's/#auth_strategy = keystone/auth_strategy = keystone/' /usr/local/etc/tacker/tacker.conf
+# [DEFAULT] section (add to)
+sed -i -- "/\[DEFAULT\]/adebug = True" /usr/local/etc/tacker/tacker.conf
+sed -i -- "/\[DEFAULT\]/ause_syslog = False" /usr/local/etc/tacker/tacker.conf
+sed -i -- "/\[DEFAULT\]/alogging_context_format_string = %(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s" /usr/local/etc/tacker/tacker.conf
+sed -i -- 's~#policy_file = policy.json~policy_file = /usr/local/etc/tacker/policy.json~' /usr/local/etc/tacker/tacker.conf
+sed -i -- 's~#state_path = /var/lib/tacker~state_path = /var/lib/tacker~' /usr/local/etc/tacker/tacker.conf
+
+# Not sure what the effect of the next line is, given that we are running as root in the container
+#sed -i -- "s~# root_helper = sudo~root_helper = sudo /usr/local/bin/tacker-rootwrap /usr/local/etc/tacker/rootwrap.conf~" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s~#api_paste_config = api-paste.ini~api_paste_config = /usr/local/etc/tacker/api-paste.ini~" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s/#bind_host = 0.0.0.0/bind_host = $ip/" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s/#bind_port = 8888/bind_port = 9890/" /usr/local/etc/tacker/tacker.conf
+
+# Newton changes, based upon sample newton gate test conf file provided by sridhar_ram on #tacker
+sed -i -- "s/#nova_region_name = <None>/#nova_region_name = $region/" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s/#nova_api_insecure = false/nova_api_insecure = False/" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s/#nova_ca_certificates_file = <None>/nova_ca_certificates_file =/" /usr/local/etc/tacker/tacker.conf
+keystone_adminurl=$(openstack endpoint show keystone | awk "/ adminurl / { print \$4 }")
+sed -i -- "s~#nova_admin_auth_url = http://localhost:5000/v2.0~nova_admin_auth_url = $keystone_adminurl~" /usr/local/etc/tacker/tacker.conf
+# TODO: don't hard-code service tenant ID
+sed -i -- "s/#nova_admin_tenant_id = <None>/nova_admin_tenant_id = service/" /usr/local/etc/tacker/tacker.conf
+sed -i -- "s/#nova_admin_password = <None>/nova_admin_password = $OS_PASSWORD/" /usr/local/etc/tacker/tacker.conf
+# this diff seems superfluous < nova_admin_user_name = nova
+  #  only one ref in tacker (setting the default value)
+  # devstack/lib/tacker:    iniset $TACKER_CONF DEFAULT nova_admin_user_name nova
+# set nova_url to "/v2" (normal value is "/v2.1") due to tacker API version compatibility (?)
+nova_ipport=$(openstack endpoint show nova | awk "/ adminurl / { print \$4 }" | awk -F'[/]' '{print $3}')
+sed -i -- "s~#nova_url = http://127.0.0.1:8774/v2~nova_url = http://$nova_ipport/v2~" /usr/local/etc/tacker/tacker.conf
+
+sed -i -- "s~#state_path = /var/lib/tacker~state_path = /var/lib/tacker~" /usr/local/etc/tacker/tacker.conf
+
+# [alarm_auth] section - optional (?)
+# < url = http://15.184.66.78:35357/v3
+# < project_name = service
+# < password = secretservice
+# < uername = tacker
+
+# [nfvo_vim] section
+sed -i -- "s/#default_vim = <None>/default_vim = VIM0/" /usr/local/etc/tacker/tacker.conf
+
+# [openstack_vim] section - only change this if you want to override values in models/tests/utils/tacker/tacker.conf.sample
+#sed -i -- "s/#stack_retries = 60/stack_retries = 10/" /usr/local/etc/tacker/tacker.conf
+#sed -i -- "s/#stack_retry_wait = 5/stack_retry_wait = 60/" /usr/local/etc/tacker/tacker.conf
+
+# newton: add [keystone_authtoken] missing in generated tacker.conf.sample, excluding the following
+# (not referenced) memcached_servers = 15.184.66.78:11211
+# (not referenced) signing_dir = /var/cache/tacker
+# (not referenced) cafile = /opt/stack/data/ca-bundle.pem
+# (not referenced) auth_uri = http://15.184.66.78/identity
+# auth_uri is required for keystonemiddleware.auth_token use of public identity endpoint
+# removed due to issues with "ERROR oslo_middleware.catch_errors DiscoveryFailure: Cannot use v2 authentication with domain scope"
+  # project_domain_name = Default
+  # user_domain_name = Default
+
+cat >>/usr/local/etc/tacker/tacker.conf <<EOF
+[keystone_authtoken]
+auth_uri = $(openstack endpoint show keystone | awk "/ publicurl / { print \$4 }")
+auth_url = $(openstack endpoint show keystone | awk "/ internalurl / { print \$4 }")
+project_name = $service_project
+password = tacker
+username = tacker
+auth_type = password
+EOF
+
+# these diffs seem superfluous - not referenced at all:
+  # < transport_url = rabbit://stackrabbit:secretrabbit@15.184.66.78:5672/
+  # < heat_uri = http://15.184.66.78:8004/v1
+
+# newton: add [tacker_heat] missing in generated tacker.conf.sample
+heat_ipport=$(openstack endpoint show heat | awk "/ internalurl / { print \$4 }" | awk -F'[/]' '{print $3}')
+cat >>/usr/local/etc/tacker/tacker.conf <<EOF
+[tacker_heat]
+stack_retry_wait = 10
+stack_retries = 60
+heat_uri = http://$heat_ipport/v1
+EOF
+
+# newton: add [database] missing in generated tacker.conf.sample
+cat >>/usr/local/etc/tacker/tacker.conf <<EOF
+[database]
+connection = mysql://tacker:$MYSQL_PASSWORD@localhost:3306/tacker?charset=utf8
+EOF
+
+# newton: add [tacker_nova] missing in generated tacker.conf.sample, excluding the following
+  # these diffs seem superfluous - the only ref'd field is region_name:
+  # project_domain_id = default
+  # project_name = service
+  # user_domain_id = default
+  # password = secretservice
+  # username = nova
+  # auth_url = http://15.184.66.78/identity_v2_admin
+  # auth_plugin = password
+cat >>/usr/local/etc/tacker/tacker.conf <<EOF
+[tacker_nova]
+region_name = $region
+EOF
+
+log "/usr/local/etc/tacker/tacker.conf"
+cat /usr/local/etc/tacker/tacker.conf
+
+log "Populate Tacker database"
+/usr/local/bin/tacker-db-manage --config-file /usr/local/etc/tacker/tacker.conf upgrade head
+
+# deferred until its determined how to get this to Horizon
+## Install Tacker Horizon plugin"
+#cd /opt/tacker
+#git clone https://github.com/openstack/tacker-horizon
+#cd tacker-horizon
+#python setup.py install
+# The next two commands must affect the Horizon server
+#cp openstack_dashboard_extensions/* /usr/share/openstack-dashboard/openstack_dashboard/enabled/
+#service apache2 restart
+
+log "Start the Tacker Server"
+nohup python /usr/local/bin/tacker-server \
+  --config-file /usr/local/etc/tacker/tacker.conf \
+  --log-file /var/log/tacker/tacker.log &
+
+# Wait 30 seconds for Tacker server to come online"
+sleep 30
+
+log "Register default VIM"
+cd /opt/tacker
+# TODO: bug in https://github.com/openstack/python-tackerclient/blob/stable/newton/tackerclient/common/utils.py
+# expects that there will be a port specified in the auth_url
+# TODO: bug: user_domain_name: Default is required even for identity v2
+# removed due to issues with "DiscoveryFailure" as above
+  # project_domain_name: Default
+  # user_domain_name: Default
+cat <<EOF >vim-config.yaml
+auth_url: $OS_AUTH_URL
+username: $OS_USERNAME
+password: $OS_PASSWORD
+project_id: $(openstack project show admin | awk '/ id / {print $4}')
+project_name: admin
+user_id: $(openstack user list | awk "/ admin / { print \$2 }")
+EOF
+
+# newton: NAME (was "--name") is now a positional parameter
+tacker vim-register --is-default --config-file vim-config.yaml --description OpenStack VIM0
+tail -f /var/log/tacker/tacker.log
diff --git a/build/tacker/tacker.conf b/build/tacker/tacker.conf
new file mode 100644 (file)
index 0000000..d7dff09
--- /dev/null
@@ -0,0 +1,315 @@
+[DEFAULT]
+
+#
+# From tacker.common.config
+#
+
+# The host IP to bind to (string value)
+#bind_host = 0.0.0.0
+
+# The port to bind to (integer value)
+#bind_port = 9890
+
+# The API paste config file to use (string value)
+#api_paste_config = api-paste.ini
+
+# The path for API extensions (string value)
+#api_extensions_path =
+
+# The service plugins Tacker will use (list value)
+#service_plugins = nfvo,vnfm
+
+# The policy file to use (string value)
+#policy_file = policy.json
+
+# The type of authentication to use (string value)
+#auth_strategy = keystone
+
+# Allow the usage of the bulk API (boolean value)
+#allow_bulk = true
+
+# Allow the usage of the pagination (boolean value)
+#allow_pagination = false
+
+# Allow the usage of the sorting (boolean value)
+#allow_sorting = false
+
+# The maximum number of items returned in a single response, value was
+# 'infinite' or negative integer means no limit (string value)
+#pagination_max_limit = -1
+
+# The hostname Tacker is running on (string value)
+#host = fa719b05f53c
+
+# URL for connection to nova (string value)
+#nova_url = http://127.0.0.1:8774/v2
+
+# Username for connecting to nova in admin context (string value)
+#nova_admin_username = <None>
+
+# Password for connection to nova in admin context (string value)
+#nova_admin_password = <None>
+
+# The uuid of the admin nova tenant (string value)
+#nova_admin_tenant_id = <None>
+
+# Authorization URL for connecting to nova in admin context (string value)
+#nova_admin_auth_url = http://localhost:5000/v2.0
+
+# CA file for novaclient to verify server certificates (string value)
+#nova_ca_certificates_file = <None>
+
+# If True, ignore any SSL validation issues (boolean value)
+#nova_api_insecure = false
+
+# Name of nova region to use. Useful if keystone manages more than one region.
+# (string value)
+#nova_region_name = <None>
+
+# Where to store Tacker state files. This directory must be writable by the
+# agent. (string value)
+#state_path = /var/lib/tacker
+
+#
+# From tacker.service
+#
+
+# Seconds between running periodic tasks (integer value)
+#periodic_interval = 40
+
+# Number of separate worker processes for service (integer value)
+#api_workers = 0
+
+# Range of seconds to randomly delay when starting the periodic task scheduler
+# to reduce stampeding. (Disable by setting to 0) (integer value)
+#periodic_fuzzy_delay = 5
+
+#
+# From tacker.wsgi
+#
+
+# Number of backlog requests to configure the socket with (integer value)
+#backlog = 4096
+
+# Sets the value of TCP_KEEPIDLE in seconds for each server socket. Not
+# supported on OS X. (integer value)
+#tcp_keepidle = 600
+
+# Number of seconds to keep retrying to listen (integer value)
+#retry_until_window = 30
+
+# Max header line to accommodate large tokens (integer value)
+#max_header_line = 16384
+
+# Enable SSL on the API server (boolean value)
+#use_ssl = false
+
+# CA certificate file to use to verify connecting clients (string value)
+#ssl_ca_file = <None>
+
+# Certificate file to use when starting the server securely (string value)
+#ssl_cert_file = <None>
+
+# Private key file to use when starting the server securely (string value)
+#ssl_key_file = <None>
+
+
+[alarm_auth]
+
+#
+# From tacker.alarm_receiver
+#
+
+# User name for alarm monitoring (string value)
+#username = tacker
+
+# password for alarm monitoring (string value)
+#password = nomoresecret
+
+# project name for alarm monitoring (string value)
+#project_name = service
+
+# url for alarm monitoring (string value)
+#url = http://localhost:35357/v3
+
+
+[ceilometer]
+
+#
+# From tacker.vnfm.monitor_drivers.ceilometer.ceilometer
+#
+
+# Address which drivers use to trigger (string value)
+#host = fa719b05f53c
+
+# port number which drivers use to trigger (port value)
+# Minimum value: 0
+# Maximum value: 65535
+#port = 9890
+
+
+[monitor]
+
+#
+# From tacker.vnfm.monitor
+#
+
+# check interval for monitor (integer value)
+#check_intvl = 10
+
+
+[monitor_http_ping]
+
+#
+# From tacker.vnfm.monitor_drivers.http_ping.http_ping
+#
+
+# number of times to retry (integer value)
+#retry = 5
+
+# number of seconds to wait for a response (integer value)
+#timeout = 1
+
+# HTTP port number to send request (integer value)
+#port = 80
+
+
+[monitor_ping]
+
+#
+# From tacker.vnfm.monitor_drivers.ping.ping
+#
+
+# number of ICMP packets to send (string value)
+#count = 1
+
+# number of seconds to wait for a response (string value)
+#timeout = 1
+
+# number of seconds to wait between packets (string value)
+#interval = 1
+
+
+[nfvo_vim]
+
+#
+# From tacker.nfvo.nfvo_plugin
+#
+
+# VIM driver for launching VNFs (list value)
+#vim_drivers = openstack
+
+# Interval to check for VIM health (integer value)
+#monitor_interval = 30
+
+#
+# From tacker.vnfm.vim_client
+#
+
+# DEPRECATED: Default VIM for launching VNFs. This option is deprecated and
+# will be removed in Ocata release. (string value)
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
+#default_vim = <None>
+
+
+[openstack_vim]
+
+#
+# From tacker.vnfm.infra_drivers.openstack.openstack
+#
+
+# Number of attempts to retry for stack creation/deletion (integer value)
+stack_retries = 60
+
+# Wait time (in seconds) between consecutive stack create/delete retries
+# (integer value)
+stack_retry_wait = 10
+
+# Flavor Extra Specs (dict value)
+#flavor_extra_specs =
+
+
+[openwrt]
+
+#
+# From tacker.vnfm.mgmt_drivers.openwrt.openwrt
+#
+
+# user name to login openwrt (string value)
+#user = root
+
+# password to login openwrt (string value)
+#password =
+
+
+[tacker]
+
+#
+# From tacker.vnfm.monitor
+#
+
+# Monitor driver to communicate with Hosting VNF/logical service instance
+# tacker plugin will use (list value)
+#monitor_driver = ping,http_ping
+
+# Alarm monitoring driver to communicate with Hosting VNF/logical service
+# instance tacker plugin will use (list value)
+#alarm_monitor_driver = ceilometer
+
+#
+# From tacker.vnfm.plugin
+#
+
+# MGMT driver to communicate with Hosting VNF/logical service instance tacker
+# plugin will use (list value)
+#mgmt_driver = noop,openwrt
+
+# Time interval to wait for VM to boot (integer value)
+#boot_wait = 30
+
+# Hosting vnf drivers tacker plugin will use (list value)
+#infra_driver = nova,heat,noop,openstack
+
+
+[tacker_heat]
+
+#
+# From tacker.vnfm.infra_drivers.heat.heat
+#
+
+# Number of attempts to retry for stack creation/deletion (integer value)
+#stack_retries = 60
+
+# Wait time (in seconds) between consecutive stack create/delete retries
+# (integer value)
+#stack_retry_wait = 5
+
+# Flavor Extra Specs (dict value)
+#flavor_extra_specs =
+
+
+[vim_keys]
+
+#
+# From tacker.nfvo.drivers.vim.openstack_driver
+#
+
+# Dir.path to store fernet keys. (string value)
+#openstack = /etc/tacker/vim/fernet_keys
+
+
+[vim_monitor]
+
+#
+# From tacker.nfvo.drivers.vim.openstack_driver
+#
+
+# number of ICMP packets to send (string value)
+#count = 1
+
+# number of seconds to wait for a response (string value)
+#timeout = 1
+
+# number of seconds to wait between packets (string value)
+#interval = 1
index e9ba823..5ebf1f4 100644 (file)
 # Status: this is a work in progress, under test.
 #
 # How to use:
-#   $ bash tacker-setup.sh [init|setup|clean] [branch]
-#     init: Initialize docker container
-#     setup: Setup of Tacker in the docker container
-#     clean: Remove the Tacker service, container, and data in /opt/tacker
+#   $ bash tacker-setup.sh setup|clean> <openrc> [branch]
+#     setup: Start and setup Tacker container
+#     clean: Remove Tacker service and container
+#.    openrc: location of OpenStack openrc file
 #     branch: OpenStack branch to install (default: master)
 
 trap 'fail' ERR
 
+function log() {
+  f=$(caller 0 | awk '{print $2}')
+  l=$(caller 0 | awk '{print $1}')
+  echo "$f:$l ($(date)) $1"
+}
+
 pass() {
-  echo "$0: $(date) Hooray!"
+  log "Hooray!"
   end=`date +%s`
   runtime=$((end-start))
-  echo "$0: $(date) Duration = $runtime seconds"
+  log "Duration = $runtime seconds"
   exit 0
 }
 
 fail() {
-  echo "$0: $(date) Test Failed!"
+  log "Test Failed!"
   end=`date +%s`
   runtime=$((end-start))
   runtime=$((runtime/60))
-  echo "$0: $(date) Duration = $runtime seconds"
+  log "Duration = $runtime seconds"
   exit 1
 }
 
-function setenv () {
-  echo "$0: $(date) Setup shared virtual folders and save this script there"
-  mkdir /opt/tacker
-  cp $0 /opt/tacker/.
-  cp `dirname $0`/tacker.conf.sample /opt/tacker/.
-  chmod 755 /opt/tacker/*.sh
-
-  echo "$0: $(date) Setup admin-openrc.sh"
-  source /opt/tacker/admin-openrc.sh
-}
-
-function get_external_net () {
-  network_ids=($(neutron net-list|grep -v "+"|grep -v name|awk '{print $2}'))
-  for id in "${network_ids[@]}"; do
-      [[ $(neutron net-show ${id}|grep 'router:external'|grep -i "true") != "" ]] && ext_net_id=${id}
-  done
-  if [[ $ext_net_id ]]; then
-    EXTERNAL_NETWORK_NAME=$(neutron net-show $ext_net_id | awk "/ name / { print \$4 }")
-    EXTERNAL_SUBNET_ID=$(neutron net-show $EXTERNAL_NETWORK_NAME | awk "/ subnets / { print \$4 }")
-  else
-    echo "$0: $(date) External network not found"
-    exit 1
-  fi
-}
+function create_container() {
+  log "Delete any existing tacker container"
+  sudo docker stop tacker
+  sudo docker rm -v tacker
 
-function create_container () {
-  echo "$0: $(date) Creating docker container for Tacker installation"
-  # STEP 1: Create the Tacker container and launch it
-  echo "$0: $(date) Setup container"
+  log "Start tacker container"
   if [ "$dist" == "Ubuntu" ]; then
-    echo "$0: $(date) Ubuntu-based install"
+    log "Ubuntu-based install"
     dpkg -l docker-engine
     if [[ $? -eq 1 ]]; then
       sudo apt-get install -y apt-transport-https ca-certificates
@@ -89,11 +72,8 @@ function create_container () {
       sudo apt-get install -y docker-engine
       sudo service docker start
     fi
-
-    # xenial is needed for python 3.5
-    sudo docker pull ubuntu:xenial
     sudo service docker start
-    sudo docker run -it -d -v /opt/tacker/:/opt/tacker --name tacker ubuntu:xenial /bin/bash
+    sudo apt-get install -y wget
   else
     # Centos
     echo "Centos-based install"
@@ -106,313 +86,23 @@ gpgcheck=1
 gpgkey=https://yum.dockerproject.org/gpg
 EOF
     sudo yum install -y docker-engine
-    # xenial is needed for python 3.5
     sudo service docker start
-    sudo docker pull ubuntu:xenial
-    sudo docker run -i -t -d -v /opt/tacker/:/opt/tacker --name tacker ubuntu:xenial /bin/bash
-  fi
-}
-
-
-install_client () {
-  echo "$0: $(date) Install $1"
-  git clone https://github.com/openstack/$1.git
-  cd $1
-  if [ $# -eq 2 ]; then git checkout $2; fi
-  pip install -r requirements.txt
-  pip install .
-  cd ..
-}
-
-function setup () {
-  branch=$1
-  echo "$0: $(date) Installing Tacker"
-  # STEP 2: Install Tacker in the container
-  # Per http://docs.openstack.org/developer/tacker/install/manual_installation.html
-  echo "$0: $(date) Install dependencies"
-  apt-get update
-  apt-get install -y python
-  apt-get install -y python-dev
-  apt-get install -y python-pip
-  apt-get install -y wget
-  apt-get install -y openssh-server
-  apt-get install -y git
-  apt-get install -y apg
-  apt-get install -y libffi-dev
-  apt-get install -y libssl-dev
-  # newton: tacker uses ping for monitoring VIM (not in default docker containers)
-  apt-get install -y inetutils-ping
-  # apt-utils is not installed in xenial container image
-  apt-get install -y apt-utils
-  export MYSQL_PASSWORD=$(/usr/bin/apg -n 1 -m 16 -c cl_seed)
-  echo $MYSQL_PASSWORD >~/mysql
-  debconf-set-selections <<< 'mysql-server mysql-server/root_password password '$MYSQL_PASSWORD
-  debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password '$MYSQL_PASSWORD
-  apt-get -q -y install mysql-server python-mysqldb
-  service mysql restart
-
-  cd /opt/tacker
-
-  echo "$0: $(date) create Tacker database"
-  mysql --user=root --password=$MYSQL_PASSWORD -e "CREATE DATABASE tacker; GRANT ALL PRIVILEGES ON tacker.* TO 'root@localhost' IDENTIFIED BY '"$MYSQL_PASSWORD"'; GRANT ALL PRIVILEGES ON tacker.* TO 'tacker'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"';"
-
-  echo "$0: $(date) Upgrage pip again - needs to be the latest version due to errors found in earlier testing"
-  pip install --upgrade pip
-
-  echo "$0: $(date) Install OpenStack clients"
-  install_client python-openstackclient $branch
-  install_client python-neutronclient $branch
-  install_client python-novaclient $branch
-
-#  pip install --upgrade python-openstackclient python-glanceclient python-neutronclient keystonemiddleware
-
-  echo "$0: $(date) Setup admin-openrc.sh"
-  source /opt/tacker/admin-openrc.sh
-
-  echo "$0: $(date) Create image models-xenial-server"
-  image_id=$(openstack image list | awk "/ models-xenial-server / { print \$2 }")
-  if [[ -z "$image_id" ]]; then glance --os-image-api-version 1 image-create --name models-xenial-server --disk-format qcow2 --location http://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img --container-format bare; fi
-
-  uid=$(openstack user list | awk "/ tacker / { print \$2 }")
-  if [[ $uid ]]; then
-    echo "$0: $(date) Remove prior Tacker user etc"
-    openstack user delete tacker
-    openstack service delete tacker
-    # Note: deleting the service deletes the endpoint
-  fi
-
-  echo "$0: $(date) Setup Tacker user in OpenStack"
-  service_project=$(openstack project list | awk "/service/ { print \$4 }")
-  openstack user create --project $service_project --password tacker tacker
-  openstack role add --project $service_project --user tacker admin
-
-  echo "$0: $(date) Create Tacker service in OpenStack"
-  sid=$(openstack service list | awk "/ tacker / { print \$2 }")
-  openstack service create --name tacker --description "Tacker Project" nfv-orchestration
-  sid=$(openstack service list | awk "/ tacker / { print \$2 }")
-
-  echo "$0: $(date) Create Tacker service endpoint in OpenStack"
-  ip=$(ip addr | awk "/ global eth0/ { print \$2 }" | sed -- 's/\/16//')
-  region=$(openstack endpoint list | awk "/ nova / { print \$4 }" | head -1)
-  openstack endpoint create --region $region \
-      --publicurl "http://$ip:9890/" \
-      --adminurl "http://$ip:9890/" \
-      --internalurl "http://$ip:9890/" nfv-orchestration
-
-  echo "$0: $(date) Clone Tacker"
-  if [[ -d /opt/tacker/tacker ]]; then rm -rf /opt/tacker/tacker; fi
-  git clone git://git.openstack.org/openstack/tacker
-  cd tacker
-  git checkout $branch
-
-  echo "$0: $(date) Setup Tacker"
-  pip install -r requirements.txt
-  pip install tosca-parser
-  python setup.py install
-  mkdir /var/log/tacker
-
-#  "tox -e config-gen" is throwing errors, disabled - see tacker.conf.sample above
-#  echo "$0: $(date) install tox"
-#  pip install --upgrade tox
-#  echo "$0: $(date) generate tacker.conf.sample"
-#  tox -e config-gen
-
-  echo "$0: $(date) Update tacker.conf values"
-  mkdir /usr/local/etc/tacker
-  cp /opt/tacker/tacker.conf.sample /usr/local/etc/tacker/tacker.conf
-
-  # [DEFAULT] section (update)
-  sed -i -- 's/#auth_strategy = keystone/auth_strategy = keystone/' /usr/local/etc/tacker/tacker.conf
-  # [DEFAULT] section (add to)
-  sed -i -- "/\[DEFAULT\]/adebug = True" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "/\[DEFAULT\]/ause_syslog = False" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "/\[DEFAULT\]/alogging_context_format_string = %(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s" /usr/local/etc/tacker/tacker.conf
-  sed -i -- 's~#policy_file = policy.json~policy_file = /usr/local/etc/tacker/policy.json~' /usr/local/etc/tacker/tacker.conf
-  sed -i -- 's~#state_path = /var/lib/tacker~state_path = /var/lib/tacker~' /usr/local/etc/tacker/tacker.conf
-
-  # Not sure what the effect of the next line is, given that we are running as root in the container
-  #sed -i -- "s~# root_helper = sudo~root_helper = sudo /usr/local/bin/tacker-rootwrap /usr/local/etc/tacker/rootwrap.conf~" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s~#api_paste_config = api-paste.ini~api_paste_config = /opt/tacker/tacker/etc/tacker/api-paste.ini~" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s/#bind_host = 0.0.0.0/bind_host = $ip/" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s/#bind_port = 8888/bind_port = 9890/" /usr/local/etc/tacker/tacker.conf
-
-# Newton changes, based upon sample newton gate test conf file provided by sridhar_ram on #tacker
-  sed -i -- "s/#nova_region_name = <None>/#nova_region_name = $region/" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s/#nova_api_insecure = false/nova_api_insecure = False/" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s/#nova_ca_certificates_file = <None>/nova_ca_certificates_file =/" /usr/local/etc/tacker/tacker.conf
-  keystone_adminurl=$(openstack endpoint show keystone | awk "/ adminurl / { print \$4 }")
-  sed -i -- "s~#nova_admin_auth_url = http://localhost:5000/v2.0~nova_admin_auth_url = $keystone_adminurl~" /usr/local/etc/tacker/tacker.conf
-  # TODO: don't hard-code service tenant ID
-  sed -i -- "s/#nova_admin_tenant_id = <None>/nova_admin_tenant_id = service/" /usr/local/etc/tacker/tacker.conf
-  sed -i -- "s/#nova_admin_password = <None>/nova_admin_password = $OS_PASSWORD/" /usr/local/etc/tacker/tacker.conf
-  # this diff seems superfluous < nova_admin_user_name = nova
-    #  only one ref in tacker (setting the default value)
-    # devstack/lib/tacker:    iniset $TACKER_CONF DEFAULT nova_admin_user_name nova
-  # set nova_url to "/v2" (normal value is "/v2.1") due to tacker API version compatibility (?)
-  nova_ipport=$(openstack endpoint show nova | awk "/ adminurl / { print \$4 }" | awk -F'[/]' '{print $3}')
-  sed -i -- "s~#nova_url = http://127.0.0.1:8774/v2~nova_url = http://$nova_ipport/v2~" /usr/local/etc/tacker/tacker.conf
-  mkdir /var/lib/tacker
-  sed -i -- "s~#state_path = /var/lib/tacker~state_path = /var/lib/tacker~" /usr/local/etc/tacker/tacker.conf
-
-  # [alarm_auth] section - optional (?)
-  # < url = http://15.184.66.78:35357/v3
-  # < project_name = service
-  # < password = secretservice
-  # < uername = tacker
-
-  # [nfvo_vim] section
-  sed -i -- "s/#default_vim = <None>/default_vim = VIM0/" /usr/local/etc/tacker/tacker.conf
-
-  # [openstack_vim] section - only change this if you want to override values in models/tests/utils/tacker/tacker.conf.sample
-  #sed -i -- "s/#stack_retries = 60/stack_retries = 10/" /usr/local/etc/tacker/tacker.conf
-  #sed -i -- "s/#stack_retry_wait = 5/stack_retry_wait = 60/" /usr/local/etc/tacker/tacker.conf
-
-  # newton: add [keystone_authtoken] missing in generated tacker.conf.sample, excluding the following
-  # (not referenced) memcached_servers = 15.184.66.78:11211
-  # (not referenced) signing_dir = /var/cache/tacker
-  # (not referenced) cafile = /opt/stack/data/ca-bundle.pem
-  # (not referenced) auth_uri = http://15.184.66.78/identity
-  # auth_uri is required for keystonemiddleware.auth_token use of public identity endpoint
-  # removed due to issues with "ERROR oslo_middleware.catch_errors DiscoveryFailure: Cannot use v2 authentication with domain scope"
-    # project_domain_name = Default
-    # user_domain_name = Default
-  cat >>/usr/local/etc/tacker/tacker.conf <<EOF
-[keystone_authtoken]
-auth_uri = $(openstack endpoint show keystone | awk "/ publicurl / { print \$4 }")
-auth_url = $(openstack endpoint show keystone | awk "/ internalurl / { print \$4 }")
-project_name = $service_project
-password = tacker
-username = tacker
-auth_type = password
-EOF
-
-  # these diffs seem superfluous - not referenced at all:
-    # < transport_url = rabbit://stackrabbit:secretrabbit@15.184.66.78:5672/
-    # < heat_uri = http://15.184.66.78:8004/v1
-
-  # newton: add [tacker_heat] missing in generated tacker.conf.sample
-  heat_ipport=$(openstack endpoint show heat | awk "/ internalurl / { print \$4 }" | awk -F'[/]' '{print $3}')
-  cat >>/usr/local/etc/tacker/tacker.conf <<EOF
-[tacker_heat]
-stack_retry_wait = 10
-stack_retries = 60
-heat_uri = http://$heat_ipport/v1
-EOF
-
-  # newton: add [database] missing in generated tacker.conf.sample
-  cat >>/usr/local/etc/tacker/tacker.conf <<EOF
-[database]
-connection = mysql://tacker:$MYSQL_PASSWORD@localhost:3306/tacker?charset=utf8
-EOF
-
-  # newton: add [tacker_nova] missing in generated tacker.conf.sample, excluding the following
-    # these diffs seem superfluous - the only ref'd field is region_name:
-    # project_domain_id = default
-    # project_name = service
-    # user_domain_id = default
-    # password = secretservice
-    # username = nova
-    # auth_url = http://15.184.66.78/identity_v2_admin
-    # auth_plugin = password
-  cat >>/usr/local/etc/tacker/tacker.conf <<EOF
-[tacker_nova]
-region_name = $region
-EOF
-
-  echo "$0: $(date) Populate Tacker database"
-  /usr/local/bin/tacker-db-manage --config-file /usr/local/etc/tacker/tacker.conf upgrade head
-
-  echo "$0: $(date) Install Tacker Client"
-  cd /opt/tacker
-  if [[ -d /opt/tacker/python-tackerclient ]]; then rm -rf /opt/tacker/python-tackerclient; fi
-  git clone https://github.com/openstack/python-tackerclient
-  cd python-tackerclient
-  git checkout $branch
-  python setup.py install
-
-  # deferred until its determined how to get this to Horizon
-  #echo "$0: $(date) Install Tacker Horizon plugin"
-  #cd /opt/tacker
-  #git clone https://github.com/openstack/tacker-horizon
-  #cd tacker-horizon
-  #python setup.py install
-  # The next two commands must affect the Horizon server
-  #cp openstack_dashboard_extensions/* /usr/share/openstack-dashboard/openstack_dashboard/enabled/
-  #service apache2 restart
-
-  echo "$0: $(date) Start the Tacker Server"
-  nohup python /usr/local/bin/tacker-server --config-file /usr/local/etc/tacker/tacker.conf --log-file /var/log/tacker/tacker.log & disown
-
-  echo "$0: $(date) Wait 30 seconds for Tacker server to come online"
-  sleep 30
-
-  echo "$0: $(date) Register default VIM"
-  cd /opt/tacker
-  # TODO: bug in https://github.com/openstack/python-tackerclient/blob/stable/newton/tackerclient/common/utils.py
-  # expects that there will be a port specified in the auth_url
-  # TODO: bug: user_domain_name: Default is required even for identity v2
-  # removed due to issues with "DiscoveryFailure" as above
-    # project_domain_name: Default
-    # user_domain_name: Default
-  keystone_ipport=$(openstack endpoint show keystone | awk "/ internalurl / { print \$4 }" | awk -F'[/]' '{print $3}')
-  cat <<EOF >vim-config.yaml
-auth_url: $OS_AUTH_URL
-username: $OS_USERNAME
-password: $OS_PASSWORD
-project_id: $OS_TENANT_ID
-project_name: admin
-user_id: $(openstack user list | awk "/ admin / { print \$2 }")
-EOF
-
-  # newton: NAME (was "--name") is now a positional parameter
-  tacker vim-register --is-default --config-file vim-config.yaml --description OpenStack VIM0
-  if [ $? -eq 1 ]; then fail; fi
-
-  setup_test_environment
-}
-
-function setup_test_environment () {
-  echo "Create management network"
-  if [ $(neutron net-list | awk "/ vnf_mgmt / { print \$2 }") ]; then
-    echo "$0: $(date) vnf_mgmt network exists"
-  else
-    neutron net-create vnf_mgmt
-    echo "$0: $(date) Create management subnet"
-    neutron subnet-create vnf_mgmt 192.168.200.0/24 --name vnf_mgmt --gateway 192.168.200.1 --enable-dhcp --allocation-pool start=192.168.200.2,end=192.168.200.254 --dns-nameserver 8.8.8.8
-  fi
-
-  echo "$0: $(date) Create router for vnf_mgmt network"
-  if [ $(neutron router-list | awk "/ vnf_mgmt / { print \$2 }") ]; then
-    echo "$0: $(date) vnf_mgmt router exists"
-  else
-    neutron router-create vnf_mgmt_router
-    echo "$0: $(date) Create router gateway for vnf_mgmt network"
-    get_external_net
-    neutron router-gateway-set vnf_mgmt_router $EXTERNAL_NETWORK_NAME
-    echo "$0: $(date) Add router interface for vnf_mgmt network"
-    neutron router-interface-add vnf_mgmt_router subnet=vnf_mgmt
-  fi
-
-  echo "Create private network"
-  if [ $(neutron net-list | awk "/ vnf_private / { print \$2 }") ]; then
-    echo "$0: $(date) vnf_private network exists"
-  else
-    neutron net-create vnf_private
-    echo "$0: $(date) Create private subnet"
-    neutron subnet-create vnf_private 192.168.201.0/24 --name vnf_private --gateway 192.168.201.1 --enable-dhcp --allocation-pool start=192.168.201.2,end=192.168.201.254 --dns-nameserver 8.8.8.8
+    sudo yum install -y wget
   fi
 
-  echo "$0: $(date) Create router for vnf_private network"
-  if [ $(neutron router-list | awk "/ vnf_private / { print \$2 }") ]; then
-    echo "$0: $(date) vnf_private router exists"
-  else
-    neutron router-create vnf_private_router
-    echo "$0: $(date) Create router gateway for vnf_private network"
-    get_external_net
-    neutron router-gateway-set vnf_private_router $EXTERNAL_NETWORK_NAME
-    echo "$0: $(date) Add router interface for vnf_private network"
-    neutron router-interface-add vnf_private_router subnet=vnf_private
-  fi
+  if [ -d /opt/tacker ]; then sudo rm -rf /opt/tacker; fi
+  sudo mkdir -p /opt/tacker
+  sudo chown $USER /opt/tacker
+  cp $openrc /opt/tacker/admin-openrc.sh
+
+  if [[ "$branch" == "" ]]; then branch="latest"; fi
+  log "Start tacker container with image blsaws/models-tacker:$branch"
+  OS_TENANT_ID=$(openstack project show admin | awk '/ id / {print $4}')
+  sudo docker run -it -d -p 9890:9890 -v /opt/tacker:/opt/tacker --name tacker \
+    -e OS_AUTH_URL=$OS_AUTH_URL \
+    -e OS_USERNAME=$OS_USERNAME \
+    -e OS_PASSWORD=$OS_PASSWORD \
+    blsaws/models-tacker:$branch
 }
 
 function clean () {
@@ -420,30 +110,19 @@ function clean () {
   eid=($(openstack endpoint list | awk "/tacker/ { print \$2 }")); for id in "${eid[@]}"; do openstack endpoint delete ${id}; done
   openstack user delete $(openstack user list | awk "/tacker/ { print \$2 }")
   openstack service delete $(openstack service list | awk "/tacker/ { print \$2 }")
-  pid=($(neutron port-list|grep -v "+"|grep -v id|awk '{print $2}')); for id in "${pid[@]}"; do neutron port-delete ${id};  done
   sid=($(openstack stack list|grep -v "+"|grep -v id|awk '{print $2}')); for id in "${sid[@]}"; do openstack stack delete ${id};  done
-  sid=($(openstack security group list|grep security_group_local_security_group|awk '{print $2}')); for id in "${sid[@]}"; do openstack security group delete ${id};  done
-  neutron router-gateway-clear vnf_mgmt_router
-  pid=($(neutron router-port-list vnf_mgmt_router|grep -v name|awk '{print $2}')); for id in "${pid[@]}"; do neutron router-interface-delete vnf_mgmt_router vnf_mgmt;  done
-  neutron router-delete vnf_mgmt_router
-  neutron net-delete vnf_mgmt
-  neutron router-gateway-clear vnf_private_router
-  pid=($(neutron router-port-list vnf_private_router|grep -v name|awk '{print $2}')); for id in "${pid[@]}"; do neutron router-interface-delete vnf_private_router vnf_private;  done
-  neutron router-delete vnf_private_router
-  neutron net-delete vnf_private
   pass
 }
 
 start=`date +%s`
 dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`
+
+openrc=$2
+branch=$3
+
 case "$1" in
-  "init")
-    setenv
-    create_container
-    pass
-    ;;
   "setup")
-    setup $2
+    create_container
     pass
     ;;
   "clean")
index ef343b4..1068763 100644 (file)
 #
 # Cleanup: bash vHello_Tacker.sh clean
 #
-# How to use:
-#   $ git clone https://gerrit.opnfv.org/gerrit/models
-#   $ cd models/tests
-#   $ bash vHello_Tacker.sh [setup|run] [<openrc>] [branch]
-#     setup: setup test environment
-#     <openrc>: location of OpenStack openrc file
-#     branch: OpenStack branch to install (default: master)
-#   $ bash vHello_Tacker.sh [start|stop|clean]
-#     run: setup test environment and run test
-#     start: install blueprint and run test
-#     stop: stop test and uninstall blueprint
-#     clean: cleanup after test
+#.How to use:
+#.  $ git clone https://gerrit.opnfv.org/gerrit/models
+#.  $ cd models/tests
+#.  $ bash vHello_Tacker.sh <setup|run> <openrc> [branch]
+#.    setup: setup test environment
+#.    openrc: location of OpenStack openrc file
+#.    branch: OpenStack branch to install (default: master)
+#.  $ source ~/venv/bin/activate
+#.    This is needed to use the OpenStack clients in the following steps.
+#.  $ bash vHello_Tacker.sh <start|stop|clean>
+#.    run: setup test environment and run test
+#.    start: install blueprint and run test
+#.    stop: stop test and uninstall blueprint
+#.    clean: cleanup after test
 
 trap 'fail' ERR
 
+function ignore() {
+  log "last command failed, but continuing anyway (fail on err is disabled...)"
+}
+
+function log() {
+  f=$(caller 0 | awk '{print $2}')
+  l=$(caller 0 | awk '{print $1}')
+  echo "$f:$l ($(date)) $1"
+}
+
 pass() {
-  echo "$0: $(date) Hooray!"
+  log "Hooray!"
   end=`date +%s`
   runtime=$((end-test_start))
-  echo "$0: $(date) Test Duration = $runtime seconds"
+  log "Test Duration = $runtime seconds"
   exit 0
 }
 
 fail() {
-  echo "$0: $(date) Test Failed!"
+  log "Test Failed!"
   end=`date +%s`
   runtime=$((end-test_start))
   runtime=$((runtime/60))
-  echo "$0: $(date) Test Duration = $runtime seconds"
+  log "Test Duration = $runtime seconds"
   exit 1
 }
 
@@ -117,7 +129,21 @@ get_floating_net () {
   if [[ $FLOATING_NETWORK_ID ]]; then
     FLOATING_NETWORK_NAME=$(neutron net-show $FLOATING_NETWORK_ID | awk "/ name / { print \$4 }")
   else
-    echo "$0: $(date) Floating network not found"
+    log "Floating network not found"
+    exit 1
+  fi
+}
+
+function get_external_net() {
+  network_ids=($(neutron net-list|grep -v "+"|grep -v name|awk '{print $2}'))
+  for id in "${network_ids[@]}"; do
+      [[ $(neutron net-show ${id}|grep 'router:external'|grep -i "true") != "" ]] && ext_net_id=${id}
+  done
+  if [[ $ext_net_id ]]; then
+    EXTERNAL_NETWORK_NAME=$(neutron net-show $ext_net_id | awk "/ name / { print \$4 }")
+    EXTERNAL_SUBNET_ID=$(neutron net-show $EXTERNAL_NETWORK_NAME | awk "/ subnets / { print \$4 }")
+  else
+    log "External network not found"
     exit 1
   fi
 }
@@ -130,62 +156,95 @@ try () {
     let count=$count-1
     $3
   done
-  if [[ $count -eq 0 ]]; then echo "$0: $(date) Command \"$3\" was not successful after $1 tries"; fi
+  if [[ $count -eq 0 ]]; then log "Command \"$3\" was not successful after $1 tries"; fi
 }
 
 setup () {
   trap 'fail' ERR
 
-  echo "$0: $(date) Setup shared test folder /opt/tacker"
-  if [ -d /opt/tacker ]; then sudo rm -rf /opt/tacker; fi
-  sudo mkdir -p /opt/tacker
-  sudo chown $USER /opt/tacker
-  chmod 777 /opt/tacker/
-
-  echo "$0: $(date) copy test script and openrc to /opt/tacker"
-  cp $0 /opt/tacker/.
-  cp $1 /opt/tacker/admin-openrc.sh
-
-  source /opt/tacker/admin-openrc.sh
-  chmod 755 /opt/tacker/*.sh
-
-  echo "$0: $(date) tacker-setup part 1"
-  bash utils/tacker-setup.sh init
+  log "run tacker-setup.sh"
+  bash utils/tacker-setup.sh setup $openrc $branch
   if [ $? -eq 1 ]; then fail; fi
+  assert "models-tacker-001 (Tacker installation in a docker container on the jumphost)" true
 
-  echo "$0: $(date) tacker-setup part 2"
-# TODO: find a generic way to set extension_drivers = port_security in ml2_conf.ini
-  # On the neutron service host, update ml2_conf.ini and and restart neutron service
-  # sed -i -- 's~#extension_drivers =~extension_drivers = port_security~' /etc/neutron/plugins/ml2/ml2_conf.ini
-  # For devstack, set in local.conf per http://docs.openstack.org/developer/devstack/guides/neutron.html
-  # Q_ML2_PLUGIN_EXT_DRIVERS=port_security
+  log "Install OpenStack clients"
+  source ../tools/setup_osc.sh $branch
+  source ~/venv/bin/activate
+
+  log "Install python-tackerclient"
+  cd ~/venv/git
+  git clone https://github.com/openstack/python-tackerclient.git
+  cd python-tackerclient
+  pip install .
+  cd ..
+
+  log "Setup OpenStack CLI environment"
+  source $openrc
+
+  log "Create image models-xenial-server"
+  image_id=$(openstack image list | awk "/ models-xenial-server / { print \$2 }")
+  if [[ -z "$image_id" ]]; then
+    wget http://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img \
+      -O ~/ubuntu-16.04-server-cloudimg-amd64-disk1.img
+    glance image-create --name models-xenial-server --disk-format qcow2 --container-format bare
+    image_id=$(openstack image list | awk "/ models-xenial-server / { print \$2 }")
+    glance image-upload --file ~/ubuntu-16.04-server-cloudimg-amd64-disk1.img $image_id
+   fi
+
+  log "Create management network"
+  if [ $(neutron net-list | awk "/ vnf_mgmt / { print \$2 }") ]; then
+    log "vnf_mgmt network exists"
+  else
+    neutron net-create vnf_mgmt
+    log "Create management subnet"
+    neutron subnet-create vnf_mgmt 192.168.200.0/24 --name vnf_mgmt --gateway 192.168.200.1 --enable-dhcp --allocation-pool start=192.168.200.2,end=192.168.200.254 --dns-nameserver 8.8.8.8
+  fi
 
+  log "Create router for vnf_mgmt network"
+  if [ $(neutron router-list | awk "/ vnf_mgmt / { print \$2 }") ]; then
+    log "vnf_mgmt router exists"
+  else
+    neutron router-create vnf_mgmt_router
+    log "Create router gateway for vnf_mgmt network"
+    get_external_net
+    neutron router-gateway-set vnf_mgmt_router $EXTERNAL_NETWORK_NAME
+    log "Add router interface for vnf_mgmt network"
+    neutron router-interface-add vnf_mgmt_router subnet=vnf_mgmt
+  fi
 
-  dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`
-  if [ "$dist" == "Ubuntu" ]; then
-    echo "$0: $(date) Execute tacker-setup.sh in the container"
-    sudo docker exec -it tacker /bin/bash /opt/tacker/tacker-setup.sh setup $2
-    if [ $? -eq 1 ]; then fail; fi
+  echo "Create private network"
+  if [ $(neutron net-list | awk "/ vnf_private / { print \$2 }") ]; then
+    log "vnf_private network exists"
   else
-    echo "$0: $(date) Execute tacker-setup.sh in the container"
-    sudo docker exec -i -t tacker /bin/bash /opt/tacker/tacker-setup.sh setup $2
-    if [ $? -eq 1 ]; then fail; fi
+    neutron net-create vnf_private
+    log "Create private subnet"
+    neutron subnet-create vnf_private 192.168.201.0/24 --name vnf_private --gateway 192.168.201.1 --enable-dhcp --allocation-pool start=192.168.201.2,end=192.168.201.254 --dns-nameserver 8.8.8.8
   fi
 
-  assert "models-tacker-001 (Tacker installation in a docker container on the jumphost)" true
+  log "Create router for vnf_private network"
+  if [ $(neutron router-list | awk "/ vnf_private / { print \$2 }") ]; then
+    log "vnf_private router exists"
+  else
+    neutron router-create vnf_private_router
+    log "Create router gateway for vnf_private network"
+    get_external_net
+    neutron router-gateway-set vnf_private_router $EXTERNAL_NETWORK_NAME
+    log "Add router interface for vnf_private network"
+    neutron router-interface-add vnf_private_router subnet=vnf_private
+  fi
 }
 
 copy_blueprint() {
-  echo "$0: $(date) copy test script to /opt/tacker"
+  log "copy test script to /opt/tacker"
   cp $0 /opt/tacker/.
 
-  echo "$0: $(date) reset blueprints folder"
+  log "reset blueprints folder"
   if [[ -d /opt/tacker/blueprints/tosca-vnfd-hello-world-tacker ]]; then
     rm -rf /opt/tacker/blueprints/tosca-vnfd-hello-world-tacker
   fi
   mkdir -p /opt/tacker/blueprints/tosca-vnfd-hello-world-tacker
 
-  echo "$0: $(date) copy tosca-vnfd-hello-world-tacker to blueprints folder"
+  log "copy tosca-vnfd-hello-world-tacker to blueprints folder"
   cp -r blueprints/tosca-vnfd-hello-world-tacker /opt/tacker/blueprints
 }
 
@@ -193,24 +252,24 @@ start() {
 #  Disable trap for now, need to test to ensure premature fail does not occur
 #  trap 'fail' ERR
 
-  echo "$0: $(date) setup OpenStack CLI environment"
+  log "setup OpenStack CLI environment"
   source /opt/tacker/admin-openrc.sh
 
-  echo "$0: $(date) Create Nova key pair"
+  log "Create Nova key pair"
   if [[ -f /opt/tacker/vHello ]]; then rm /opt/tacker/vHello; fi
   ssh-keygen -t rsa -N "" -f /opt/tacker/vHello -C ubuntu@vHello
   chmod 600 /opt/tacker/vHello
   openstack keypair create --public-key /opt/tacker/vHello.pub vHello
   assert "models-nova-001 (Keypair creation)" true
 
-  echo "$0: $(date) Inject public key into blueprint"
+  log "Inject public key into blueprint"
   pubkey=$(cat /opt/tacker/vHello.pub)
   sed -i -- "s~<pubkey>~$pubkey~" /opt/tacker/blueprints/tosca-vnfd-hello-world-tacker/blueprint.yaml
 
-  echo "$0: $(date) Get external network for Floating IP allocations"
+  log "Get external network for Floating IP allocations"
   get_floating_net
 
-  echo "$0: $(date) create VNFD"
+  log "create VNFD"
   cd /opt/tacker/blueprints/tosca-vnfd-hello-world-tacker
   # newton: NAME (was "--name") is now a positional parameter
   tacker vnfd-create --vnfd-file blueprint.yaml hello-world-tacker
@@ -220,34 +279,33 @@ start() {
     assert "models-tacker-002 (VNFD creation)" false
   fi
 
-
-  echo "$0: $(date) create VNF"
+  log "create VNF"
   # newton: NAME (was "--name") is now a positional parameter
   tacker vnf-create --vnfd-name hello-world-tacker hello-world-tacker
   if [ $? -eq 1 ]; then fail; fi
 
-  echo "$0: $(date) wait for hello-world-tacker to go ACTIVE"
+  log "wait for hello-world-tacker to go ACTIVE"
   active=""
   count=24
   while [[ -z $active && $count -gt 0 ]]
   do
     active=$(tacker vnf-show hello-world-tacker | grep ACTIVE)
     if [[ $(tacker vnf-show hello-world-tacker | grep -c ERROR) -gt 0 ]]; then
-      echo "$0: $(date) hello-world-tacker VNF creation failed with state ERROR"
+      log "hello-world-tacker VNF creation failed with state ERROR"
       assert "models-tacker-002 (VNF creation)" false
     fi
     let count=$count-1
     sleep 30
-    echo "$0: $(date) wait for hello-world-tacker to go ACTIVE"
+    log "wait for hello-world-tacker to go ACTIVE"
   done
   if [[ $count == 0 ]]; then
-    echo "$0: $(date) hello-world-tacker VNF creation failed - timed out"
+    log "hello-world-tacker VNF creation failed - timed out"
     assert "models-tacker-002 (VNF creation)" false
   fi
   assert "models-tacker-002 (VNF creation)" true
 
   # Setup for workarounds
-  echo "$0: $(date) directly set port security on ports (unsupported in Mitaka Tacker)"
+  log "directly set port security on ports (unsupported in Mitaka Tacker)"
   # Alternate method
   #  HEAT_ID=$(tacker vnf-show hello-world-tacker | awk "/instance_id/ { print \$4 }")
   #  SERVER_ID=$(openstack stack resource list $HEAT_ID | awk "/VDU1 / { print \$4 }")
@@ -257,7 +315,7 @@ start() {
     if [[ $(neutron port-show $id|grep $SERVER_ID) ]]; then neutron port-update ${id} --port-security-enabled=True; fi
   done
 
-  echo "$0: $(date) directly assign security group (unsupported in Mitaka Tacker)"
+  log "directly assign security group (unsupported in Mitaka Tacker)"
   if [[ $(neutron security-group-list | awk "/ vHello / { print \$2 }") ]]; then neutron security-group-delete vHello; fi
   neutron security-group-create vHello
   neutron security-group-rule-create --direction ingress --protocol TCP --port-range-min 22 --port-range-max 22 vHello
@@ -265,20 +323,22 @@ start() {
   openstack server add security group $SERVER_ID vHello
   openstack server add security group $SERVER_ID default
 
-  echo "$0: $(date) associate floating IP"
+  log "create floating IP"
   get_floating_net
-  FIP=$(nova floating-ip-create $FLOATING_NETWORK_NAME | awk "/$FLOATING_NETWORK_NAME/ { print \$4 }")
+  FIP=$(openstack floating ip create $FLOATING_NETWORK_NAME | awk "/floating_ip_address/ { print \$4 }")
+
+  log "associate floating IP \"$FIP\" to server \"$SERVER_ID\""
   nova floating-ip-associate $SERVER_ID $FIP
   # End setup for workarounds
 
-  echo "$0: $(date) get vHello server address"
+  log "get vHello server address"
   SERVER_IP=$(openstack server show $SERVER_ID | awk "/ addresses / { print \$6 }")
   SERVER_URL="http://$SERVER_IP"
 
-  echo "$0: $(date) wait 30 seconds for vHello server to startup at $SERVER_URL"
+  log "wait 30 seconds for vHello server to startup at $SERVER_URL"
   sleep 30
 
-  echo "$0: $(date) verify vHello server is running"
+  log "verify vHello server is running"
   apt-get install -y curl
   count=12
   while [[ $(curl $SERVER_URL | grep -c "Hello World") == 0 ]]
@@ -292,7 +352,7 @@ start() {
   assert "models-tacker-vnfd-002 (artifacts creation)" true
   assert "models-tacker-vnfd-003 (user_data creation)" true
 
-  echo "$0: $(date) verify contents of config drive are included in web page"
+  log "verify contents of config drive are included in web page"
   id=$(curl $SERVER_URL | awk "/uuid/ { print \$2 }")
   if [[ ! -z $id ]]; then
     assert "models-tacker-vnfd-001 (config_drive creation)" true
@@ -304,16 +364,16 @@ start() {
 stop() {
   trap 'fail' ERR
 
-  echo "$0: $(date) setup OpenStack CLI environment"
+  log "setup OpenStack CLI environment"
   source /opt/tacker/admin-openrc.sh
 
   if [[ "$(tacker vnf-list|grep hello-world-tacker|awk '{print $2}')" != '' ]]; then
-    echo "$0: $(date) uninstall vHello blueprint via CLI"
+    log "uninstall vHello blueprint via CLI"
     try 12 10 "tacker vnf-delete hello-world-tacker"
     # It can take some time to delete a VNF - thus wait 2 minutes
     count=12
     while [[ $count -gt 0 && "$(tacker vnf-list|grep hello-world-tacker|awk '{print $2}')" != '' ]]; do
-      echo "$0: $(date) waiting for hello-world-tacker VNF delete to complete"
+      log "waiting for hello-world-tacker VNF delete to complete"
       sleep 10
       let count=$count-1
     done
@@ -326,7 +386,7 @@ stop() {
 
   # It can take some time to delete a VNFD - thus wait 2 minutes
   if [[ "$(tacker vnfd-list|grep hello-world-tacker|awk '{print $2}')" != '' ]]; then
-    echo "$0: $(date) trying to delete the hello-world-tacker VNFD"
+    log "trying to delete the hello-world-tacker VNFD"
     try 12 10 "tacker vnfd-delete hello-world-tacker"
     if [[ "$(tacker vnfd-list|grep hello-world-tacker|awk '{print $2}')" == '' ]]; then
       assert "models-tacker-005 (VNFD deletion)" true
@@ -350,16 +410,33 @@ stop() {
   kid=($(openstack keypair list|grep vHello|awk '{print $2}')); for id in "${kid[@]}"; do openstack keypair delete ${id};  done
 }
 
-forward_to_container () {
-  echo "$0: $(date) pass $1 command to vHello.sh in tacker container"
-  CONTAINER=$(sudo docker ps -a | awk "/tacker/ { print \$1 }")
-  sudo docker exec $CONTAINER /bin/bash /opt/tacker/vHello_Tacker.sh $1
-  if [ $? -eq 1 ]; then fail; fi
+function clean() {
+  trap 'ignore' ERR
+  log "Uninstall Tacker"
+  bash utils/tacker-setup.sh clean
+  sudo docker stop tacker
+  sudo docker rm -v tacker
+  sudo rm -rf /opt/tacker
+
+  log "Uninstall test environment"
+  pid=($(neutron port-list|grep -v "+"|grep -v id|awk '{print $2}')); for id in "${pid[@]}"; do neutron port-delete ${id};  done
+  sid=($(openstack security group list|grep security_group_local_security_group|awk '{print $2}')); for id in "${sid[@]}"; do openstack security group delete ${id};  done
+  neutron router-gateway-clear vnf_mgmt_router
+  pid=($(neutron router-port-list vnf_mgmt_router|grep -v name|awk '{print $2}')); for id in "${pid[@]}"; do neutron router-interface-delete vnf_mgmt_router vnf_mgmt;  done
+  neutron router-delete vnf_mgmt_router
+  neutron net-delete vnf_mgmt
+  neutron router-gateway-clear vnf_private_router
+  pid=($(neutron router-port-list vnf_private_router|grep -v name|awk '{print $2}')); for id in "${pid[@]}"; do neutron router-interface-delete vnf_private_router vnf_private;  done
+  neutron router-delete vnf_private_router
+  neutron net-delete vnf_private
 }
 
 test_start=`date +%s`
 dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`
 
+openrc=$2
+branch=$3
+
 case "$1" in
   setup)
     setup $2 $3
@@ -369,48 +446,25 @@ case "$1" in
   run)
     setup $2 $3
     copy_blueprint
-    forward_to_container start
+    start
     if [ $? -eq 1 ]; then fail; fi
     pass
     ;;
   start)
-    if [[ -f /.dockerenv ]]; then
-      start
-    else
-      copy_blueprint
-      forward_to_container start
-    fi
+    copy_blueprint
+    start
     if [ $? -eq 1 ]; then fail; fi
     pass
     ;;
   stop)
-    if [[ -f /.dockerenv ]]; then
-      stop
-    else
-      forward_to_container stop
-    fi
+    stop
     if [ $? -eq 1 ]; then fail; fi
     pass
     ;;
   clean)
-    echo "$0: $(date) Uninstall Tacker and test environment"
-    forward_to_container stop
-    sudo docker exec -it tacker /bin/bash /opt/tacker/tacker-setup.sh clean
-    sudo docker stop tacker
-    sudo docker rm -v tacker
-    sudo rm -rf /opt/tacker
+    clean
     pass
     ;;
   *)
-    echo "usage: "
-    echo "$ bash vHello_Tacker.sh [setup|run] [<openrc>] [branch]"
-    echo "  setup: setup test environment"
-    echo "  <openrc>: location of OpenStack openrc file"
-    echo "  branch: OpenStack branch to install (default: master)"
-    echo "$ bash vHello_Tacker.sh [start|stop|clean]"
-    echo "  run: setup test environment and run test"
-    echo "  start: install blueprint and run test"
-    echo "  stop: stop test and uninstall blueprint"
-    echo "  clean: cleanup after test"
-    fail
+    if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then grep '#. ' $0; fi
 esac