Merge "Re-order stack.sh 3: logging and error traps"
diff --git a/files/apache-ceilometer.template b/files/apache-ceilometer.template
new file mode 100644
index 0000000..1c57b32
--- /dev/null
+++ b/files/apache-ceilometer.template
@@ -0,0 +1,15 @@
+Listen %PORT%
+
+<VirtualHost *:%PORT%>
+    WSGIDaemonProcess ceilometer-api processes=2 threads=10 user=%USER% display-name=%{GROUP}
+    WSGIProcessGroup ceilometer-api
+    WSGIScriptAlias / %WSGIAPP%
+    WSGIApplicationGroup %{GLOBAL}
+    <IfVersion >= 2.4>
+        ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/ceilometer.log
+    CustomLog /var/log/%APACHE_NAME%/ceilometer_access.log combined
+</VirtualHost>
+
+WSGISocketPrefix /var/run/%APACHE_NAME%
diff --git a/files/apache-horizon.template b/files/apache-horizon.template
index c1dd693..bca1251 100644
--- a/files/apache-horizon.template
+++ b/files/apache-horizon.template
@@ -17,10 +17,16 @@
 
     <Directory %HORIZON_DIR%/>
         Options Indexes FollowSymLinks MultiViews
-        %HORIZON_REQUIRE%
         AllowOverride None
-        Order allow,deny
-        allow from all
+        # Apache 2.4 uses mod_authz_host for access control now (instead of
+        #  "Allow")
+        <IfVersion < 2.4>
+            Order allow,deny
+            Allow from all
+        </IfVersion>
+        <IfVersion >= 2.4>
+            Require all granted
+        </IfVersion>
     </Directory>
 
     ErrorLog /var/log/%APACHE_NAME%/horizon_error.log
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 1bdb84c..88492d3 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -6,9 +6,14 @@
     WSGIProcessGroup keystone-public
     WSGIScriptAlias / %PUBLICWSGI%
     WSGIApplicationGroup %{GLOBAL}
-    %ERRORLOGFORMAT%
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
     ErrorLog /var/log/%APACHE_NAME%/keystone.log
     CustomLog /var/log/%APACHE_NAME%/keystone_access.log combined
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
 </VirtualHost>
 
 <VirtualHost *:%ADMINPORT%>
@@ -16,9 +21,14 @@
     WSGIProcessGroup keystone-admin
     WSGIScriptAlias / %ADMINWSGI%
     WSGIApplicationGroup %{GLOBAL}
-    %ERRORLOGFORMAT%
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
     ErrorLog /var/log/%APACHE_NAME%/keystone.log
     CustomLog /var/log/%APACHE_NAME%/keystone_access.log combined
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
 </VirtualHost>
 
 # Workaround for missing path on RHEL6, see
diff --git a/files/apts/horizon b/files/apts/horizon
index 8969046..03df3cb 100644
--- a/files/apts/horizon
+++ b/files/apts/horizon
@@ -9,13 +9,11 @@
 python-xattr
 python-sqlalchemy
 python-webob
-python-kombu
 pylint
 python-eventlet
 python-nose
 python-sphinx
 python-mox
-python-kombu
 python-coverage
 python-cherrypy3 # why?
 python-migrate
diff --git a/files/apts/neutron b/files/apts/neutron
index 9df5904..a48a800 100644
--- a/files/apts/neutron
+++ b/files/apts/neutron
@@ -11,13 +11,12 @@
 python-suds
 python-pastedeploy
 python-greenlet
-python-kombu
 python-eventlet
 python-sqlalchemy
 python-mysqldb
 python-mysql.connector
 python-pyudev
-python-qpid # dist:precise
+python-qpid # NOPRIME
 dnsmasq-base
 dnsmasq-utils # for dhcp_release only available in dist:precise
 rabbitmq-server # NOPRIME
diff --git a/files/apts/nova b/files/apts/nova
index 4e47d70..a3b0cb1 100644
--- a/files/apts/nova
+++ b/files/apts/nova
@@ -24,7 +24,7 @@
 curl
 genisoimage # required for config_drive
 rabbitmq-server # NOPRIME
-qpidd # dist:precise NOPRIME
+qpidd # NOPRIME
 socat # used by ajaxterm
 python-mox
 python-paste
@@ -42,7 +42,6 @@
 python-suds
 python-lockfile
 python-m2crypto
-python-kombu
 python-feedparser
 python-iso8601
-python-qpid # dist:precise
+python-qpid # NOPRIME
diff --git a/files/default_catalog.templates b/files/default_catalog.templates
index ff00e38..9016355 100644
--- a/files/default_catalog.templates
+++ b/files/default_catalog.templates
@@ -12,12 +12,6 @@
 catalog.RegionOne.compute.name = Compute Service
 
 
-catalog.RegionOne.computev3.publicURL = http://%SERVICE_HOST%:8774/v3
-catalog.RegionOne.computev3.adminURL = http://%SERVICE_HOST%:8774/v3
-catalog.RegionOne.computev3.internalURL = http://%SERVICE_HOST%:8774/v3
-catalog.RegionOne.computev3.name = Compute Service V3
-
-
 catalog.RegionOne.volume.publicURL = http://%SERVICE_HOST%:8776/v1/$(tenant_id)s
 catalog.RegionOne.volume.adminURL = http://%SERVICE_HOST%:8776/v1/$(tenant_id)s
 catalog.RegionOne.volume.internalURL = http://%SERVICE_HOST%:8776/v1/$(tenant_id)s
diff --git a/files/rpms-suse/horizon b/files/rpms-suse/horizon
index d3bde26..fa7e439 100644
--- a/files/rpms-suse/horizon
+++ b/files/rpms-suse/horizon
@@ -12,7 +12,6 @@
 python-coverage
 python-dateutil
 python-eventlet
-python-kombu
 python-mox
 python-nose
 python-pylint
diff --git a/files/rpms-suse/keystone b/files/rpms-suse/keystone
index a734cb9..4c37ade 100644
--- a/files/rpms-suse/keystone
+++ b/files/rpms-suse/keystone
@@ -10,6 +10,6 @@
 python-greenlet
 python-lxml
 python-mysql
-python-mysql.connector
+python-mysql-connector-python
 python-pysqlite
 sqlite3
diff --git a/files/rpms-suse/neutron b/files/rpms-suse/neutron
index 8ad69b0..8431bd1 100644
--- a/files/rpms-suse/neutron
+++ b/files/rpms-suse/neutron
@@ -7,9 +7,8 @@
 python-eventlet
 python-greenlet
 python-iso8601
-python-kombu
 python-mysql
-python-mysql.connector
+python-mysql-connector-python
 python-Paste
 python-PasteDeploy
 python-pyudev
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index 73c0604..b1c4f6a 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -28,13 +28,12 @@
 python-feedparser
 python-greenlet
 python-iso8601
-python-kombu
 python-libxml2
 python-lockfile
 python-lxml # needed for glance which is needed for nova --- this shouldn't be here
 python-mox
 python-mysql
-python-mysql.connector
+python-mysql-connector-python
 python-numpy # needed by websockify for spice console
 python-paramiko
 python-sqlalchemy-migrate
diff --git a/files/rpms/horizon b/files/rpms/horizon
index 8ecb030..fe3a2f4 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -9,7 +9,6 @@
 python-eventlet
 python-greenlet
 python-httplib2
-python-kombu
 python-migrate
 python-mox
 python-nose
diff --git a/files/rpms/keystone b/files/rpms/keystone
index 7182091..ce41ee5 100644
--- a/files/rpms/keystone
+++ b/files/rpms/keystone
@@ -1,3 +1,4 @@
+MySQL-python
 python-greenlet
 libxslt-devel       # dist:f20
 python-lxml         #dist:f19,f20
@@ -8,5 +9,6 @@
 python-sqlalchemy
 python-webob
 sqlite
+mod_ssl
 
 # Deps installed via pip for RHEL
diff --git a/files/rpms/neutron b/files/rpms/neutron
index 29d5cea..2c9dd3d 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -11,11 +11,10 @@
 python-eventlet
 python-greenlet
 python-iso8601
-python-kombu
 #rhel6 gets via pip
 python-paste        # dist:f19,f20,rhel7
 python-paste-deploy # dist:f19,f20,rhel7
-python-qpid
+python-qpid # NOPRIME
 python-routes
 python-sqlalchemy
 python-suds
diff --git a/files/rpms/nova b/files/rpms/nova
index fab4504..dc1944b 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -25,7 +25,6 @@
 python-feedparser
 python-greenlet
 python-iso8601
-python-kombu
 python-lockfile
 python-migrate
 python-mox
@@ -34,7 +33,7 @@
 # pip we need
 python-paste        # dist:f19,f20,rhel7
 python-paste-deploy # dist:f19,f20,rhel7
-python-qpid
+python-qpid # NOPRIME
 python-routes
 python-sqlalchemy
 python-suds
diff --git a/files/rpms/qpid b/files/rpms/qpid
new file mode 100644
index 0000000..62148ba
--- /dev/null
+++ b/files/rpms/qpid
@@ -0,0 +1,3 @@
+qpid-proton-c-devel # NOPRIME
+python-qpid-proton # NOPRIME
+
diff --git a/functions b/functions
index 76f7047..376aff0 100644
--- a/functions
+++ b/functions
@@ -21,18 +21,6 @@
     declare -f -F $1 > /dev/null
 }
 
-# Checks if installed Apache is <= given version
-# $1 = x.y.z (version string of Apache)
-function check_apache_version {
-    local cmd="apachectl"
-    if ! [[ -x $(which apachectl 2>/dev/null) ]]; then
-        cmd="/usr/sbin/apachectl"
-    fi
-
-    local version=$($cmd -v | grep version | grep -Po 'Apache/\K[^ ]*')
-    expr "$version" '>=' $1 > /dev/null
-}
-
 
 # Cleanup anything from /tmp on unstack
 # clean_tmp
@@ -85,7 +73,7 @@
     # OpenVZ-format images are provided as .tar.gz, but not decompressed prior to loading
     if [[ "$image_url" =~ 'openvz' ]]; then
         image_name="${image_fname%.tar.gz}"
-        openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
+        openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
         return
     fi
 
@@ -196,7 +184,7 @@
         vmdk_adapter_type="${props[1]:-$vmdk_adapter_type}"
         vmdk_net_adapter="${props[2]:-$vmdk_net_adapter}"
 
-        openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
+        openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
         return
     fi
 
@@ -214,7 +202,7 @@
         fi
         openstack \
             --os-token $token \
-            --os-url http://$GLANCE_HOSTPORT \
+            --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
             image create \
             "$image_name" --public \
             --container-format=ovf --disk-format=vhd \
@@ -229,7 +217,7 @@
         image_name="${image_fname%.xen-raw.tgz}"
         openstack \
             --os-token $token \
-            --os-url http://$GLANCE_HOSTPORT \
+            --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
             image create \
             "$image_name" --public \
             --container-format=tgz --disk-format=raw \
@@ -307,9 +295,9 @@
 
     if [ "$container_format" = "bare" ]; then
         if [ "$unpack" = "zcat" ]; then
-            openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
+            openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
         else
-            openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
+            openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
         fi
     else
         # Use glance client to add the kernel the root filesystem.
@@ -317,12 +305,12 @@
         # kernel for use when uploading the root filesystem.
         local kernel_id="" ramdisk_id="";
         if [ -n "$kernel" ]; then
-            kernel_id=$(openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
+            kernel_id=$(openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
         fi
         if [ -n "$ramdisk" ]; then
-            ramdisk_id=$(openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
+            ramdisk_id=$(openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
         fi
-        openstack --os-token $token --os-url http://$GLANCE_HOSTPORT image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
+        openstack --os-token $token --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
     fi
 }
 
@@ -351,7 +339,7 @@
 function wait_for_service {
     local timeout=$1
     local url=$2
-    timeout $timeout sh -c "while ! curl --noproxy '*' -s $url >/dev/null; do sleep 1; done"
+    timeout $timeout sh -c "while ! curl -k --noproxy '*' -s $url >/dev/null; do sleep 1; done"
 }
 
 
diff --git a/lib/apache b/lib/apache
index 6d22290..2c43681 100644
--- a/lib/apache
+++ b/lib/apache
@@ -59,6 +59,11 @@
     else
         exit_distro_not_supported "apache installation"
     fi
+
+    # ensure mod_version enabled for <IfVersion ...>.  This is
+    # built-in statically on anything recent, but precise (2.2)
+    # doesn't have it enabled
+    sudo a2enmod version || true
 }
 
 # get_apache_version() - return the version of Apache installed
diff --git a/lib/ceilometer b/lib/ceilometer
index a71643a..9bb3121 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -41,6 +41,7 @@
 CEILOMETER_CONF=$CEILOMETER_CONF_DIR/ceilometer.conf
 CEILOMETER_API_LOG_DIR=/var/log/ceilometer-api
 CEILOMETER_AUTH_CACHE_DIR=${CEILOMETER_AUTH_CACHE_DIR:-/var/cache/ceilometer}
+CEILOMETER_WSGI_DIR=${CEILOMETER_WSGI_DIR:-/var/www/ceilometer}
 
 # Support potential entry-points console scripts
 CEILOMETER_BIN_DIR=$(get_python_exec_prefix)
@@ -52,6 +53,7 @@
 CEILOMETER_SERVICE_PROTOCOL=http
 CEILOMETER_SERVICE_HOST=$SERVICE_HOST
 CEILOMETER_SERVICE_PORT=${CEILOMETER_SERVICE_PORT:-8777}
+CEILOMETER_USE_MOD_WSGI=$(trueorfalse False $CEILOMETER_USE_MOD_WSGI)
 
 # To enable OSprofiler change value of this variable to "notifications,profiler"
 CEILOMETER_NOTIFICATION_TOPICS=${CEILOMETER_NOTIFICATION_TOPICS:-notifications}
@@ -105,12 +107,39 @@
 }
 
 
+# _cleanup_keystone_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
+function _cleanup_ceilometer_apache_wsgi {
+    sudo rm -f $CEILOMETER_WSGI_DIR/*
+    sudo rm -f $(apache_site_config_for ceilometer)
+}
+
 # cleanup_ceilometer() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_ceilometer {
     if [ "$CEILOMETER_BACKEND" != 'mysql' ] && [ "$CEILOMETER_BACKEND" != 'postgresql' ] ; then
         mongo ceilometer --eval "db.dropDatabase();"
     fi
+    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
+        _cleanup_ceilometer_apache_wsgi
+    fi
+}
+
+function _config_ceilometer_apache_wsgi {
+    sudo mkdir -p $CEILOMETER_WSGI_DIR
+
+    local ceilometer_apache_conf=$(apache_site_config_for ceilometer)
+    local apache_version=$(get_apache_version)
+
+    # copy proxy vhost and wsgi file
+    sudo cp $CEILOMETER_DIR/ceilometer/api/app.wsgi $CEILOMETER_WSGI_DIR/app
+
+    sudo cp $FILES/apache-ceilometer.template $ceilometer_apache_conf
+    sudo sed -e "
+        s|%PORT%|$CEILOMETER_SERVICE_PORT|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%WSGIAPP%|$CEILOMETER_WSGI_DIR/app|g;
+        s|%USER%|$STACK_USER|g
+    " -i $ceilometer_apache_conf
 }
 
 # configure_ceilometer() - Set config files, create data dirs, etc
@@ -146,15 +175,11 @@
     iniset $CEILOMETER_CONF service_credentials os_password $SERVICE_PASSWORD
     iniset $CEILOMETER_CONF service_credentials os_tenant_name $SERVICE_TENANT_NAME
 
-    iniset $CEILOMETER_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $CEILOMETER_CONF keystone_authtoken admin_user ceilometer
-    iniset $CEILOMETER_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $CEILOMETER_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $CEILOMETER_CONF keystone_authtoken signing_dir $CEILOMETER_AUTH_CACHE_DIR
+    configure_auth_token_middleware $CEILOMETER_CONF ceilometer $CEILOMETER_AUTH_CACHE_DIR
 
     if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] ; then
         iniset $CEILOMETER_CONF database connection `database_connection_url ceilometer`
-        iniset $CEILOMETER_CONF DEFAULT collector_workers $(( ($(nproc) + 1) / 2 ))
+        iniset $CEILOMETER_CONF DEFAULT collector_workers $API_WORKERS
     else
         iniset $CEILOMETER_CONF database connection mongodb://localhost:27017/ceilometer
         configure_mongodb
@@ -167,6 +192,11 @@
         iniset $CEILOMETER_CONF vmware host_username "$VMWAREAPI_USER"
         iniset $CEILOMETER_CONF vmware host_password "$VMWAREAPI_PASSWORD"
     fi
+
+    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
+        iniset $CEILOMETER_CONF api pecan_debug "False"
+        _config_ceilometer_apache_wsgi
+    fi
 }
 
 function configure_mongodb {
@@ -227,12 +257,21 @@
     run_process ceilometer-acentral "ceilometer-agent-central --config-file $CEILOMETER_CONF"
     run_process ceilometer-anotification "ceilometer-agent-notification --config-file $CEILOMETER_CONF"
     run_process ceilometer-collector "ceilometer-collector --config-file $CEILOMETER_CONF"
-    run_process ceilometer-api "ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
+
+    if [[ "$CEILOMETER_USE_MOD_WSGI" == "False" ]]; then
+        run_process ceilometer-api "ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
+    else
+        enable_apache_site ceilometer
+        restart_apache_server
+        tail_log ceilometer /var/log/$APACHE_NAME/ceilometer.log
+        tail_log ceilometer-api /var/log/$APACHE_NAME/ceilometer_access.log
+    fi
+
 
     # Start the compute agent last to allow time for the collector to
     # fully wake up and connect to the message bus. See bug #1355809
     if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
-        run_process ceilometer-acompute "sg $LIBVIRT_GROUP 'ceilometer-agent-compute --config-file $CEILOMETER_CONF'"
+        run_process ceilometer-acompute "ceilometer-agent-compute --config-file $CEILOMETER_CONF" $LIBVIRT_GROUP
     fi
     if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then
         run_process ceilometer-acompute "ceilometer-agent-compute --config-file $CEILOMETER_CONF"
@@ -252,6 +291,10 @@
 
 # stop_ceilometer() - Stop running processes
 function stop_ceilometer {
+    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
+        disable_apache_site ceilometer
+        restart_apache_server
+    fi
     # Kill the ceilometer screen windows
     for serv in ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-evaluator; do
         stop_process $serv
diff --git a/lib/ceph b/lib/ceph
index 8464042..30ca903 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -198,10 +198,11 @@
     sudo ceph -c ${CEPH_CONF_FILE} auth get-or-create client.${GLANCE_CEPH_USER} mon "allow r" osd "allow class-read object_prefix rbd_children, allow rwx pool=${GLANCE_CEPH_POOL}" | sudo tee ${CEPH_CONF_DIR}/ceph.client.${GLANCE_CEPH_USER}.keyring
     sudo chown ${STACK_USER}:$(id -g -n $whoami) ${CEPH_CONF_DIR}/ceph.client.${GLANCE_CEPH_USER}.keyring
     iniset $GLANCE_API_CONF DEFAULT default_store rbd
-    iniset $GLANCE_API_CONF DEFAULT rbd_store_ceph_conf $CEPH_CONF_FILE
-    iniset $GLANCE_API_CONF DEFAULT rbd_store_user $GLANCE_CEPH_USER
-    iniset $GLANCE_API_CONF DEFAULT rbd_store_pool $GLANCE_CEPH_POOL
     iniset $GLANCE_API_CONF DEFAULT show_image_direct_url True
+    iniset $GLANCE_API_CONF glance_store stores "file, http, rbd"
+    iniset $GLANCE_API_CONF glance_store rbd_store_ceph_conf $CEPH_CONF_FILE
+    iniset $GLANCE_API_CONF glance_store rbd_store_user $GLANCE_CEPH_USER
+    iniset $GLANCE_API_CONF glance_store rbd_store_pool $GLANCE_CEPH_POOL
 }
 
 # configure_ceph_nova() - Nova config needs to come after Nova is set up
diff --git a/lib/cinder b/lib/cinder
index 5c487a2..b30a036 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -46,6 +46,9 @@
 CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini
 
 # Public facing bits
+if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
+    CINDER_SERVICE_PROTOCOL="https"
+fi
 CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
 CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
 CINDER_SERVICE_PORT_INT=${CINDER_SERVICE_PORT_INT:-18776}
@@ -212,12 +215,7 @@
     inicomment $CINDER_API_PASTE_INI filter:authtoken admin_password
     inicomment $CINDER_API_PASTE_INI filter:authtoken signing_dir
 
-    iniset $CINDER_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $CINDER_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
-    iniset $CINDER_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $CINDER_CONF keystone_authtoken admin_user cinder
-    iniset $CINDER_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $CINDER_CONF keystone_authtoken signing_dir $CINDER_AUTH_CACHE_DIR
+    configure_auth_token_middleware $CINDER_CONF cinder $CINDER_AUTH_CACHE_DIR
 
     iniset $CINDER_CONF DEFAULT auth_strategy keystone
     iniset $CINDER_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
@@ -302,14 +300,22 @@
             -e 's/snapshot_autoextend_percent =.*/snapshot_autoextend_percent = 20/' \
             /etc/lvm/lvm.conf
     fi
-    configure_API_version $CINDER_CONF $IDENTITY_API_VERSION
-    iniset $CINDER_CONF keystone_authtoken admin_user cinder
-    iniset $CINDER_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $CINDER_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
 
-    if [ -n "$API_WORKERS" ]; then
-        iniset $CINDER_CONF DEFAULT osapi_volume_workers "$API_WORKERS"
+    iniset $CINDER_CONF DEFAULT osapi_volume_workers "$API_WORKERS"
+
+    iniset $CINDER_CONF DEFAULT glance_api_servers "${GLANCE_SERVICE_PROTOCOL}://${GLANCE_HOSTPORT}"
+    if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
+        iniset $CINDER_CONF DEFAULT glance_protocol https
     fi
+
+    # Register SSL certificates if provided
+    if is_ssl_enabled_service cinder; then
+        ensure_certificates CINDER
+
+        iniset $CINDER_CONF DEFAULT ssl_cert_file "$CINDER_SSL_CERT"
+        iniset $CINDER_CONF DEFAULT ssl_key_file "$CINDER_SSL_KEY"
+    fi
+
 }
 
 # create_cinder_accounts() - Set up common required cinder accounts
@@ -410,6 +416,12 @@
 
 # start_cinder() - Start running processes, including screen
 function start_cinder {
+    local service_port=$CINDER_SERVICE_PORT
+    local service_protocol=$CINDER_SERVICE_PROTOCOL
+    if is_service_enabled tls-proxy; then
+        service_port=$CINDER_SERVICE_PORT_INT
+        service_protocol="http"
+    fi
     if is_service_enabled c-vol; then
         # Delete any old stack.conf
         sudo rm -f /etc/tgt/conf.d/stack.conf
@@ -436,7 +448,7 @@
 
     run_process c-api "$CINDER_BIN_DIR/cinder-api --config-file $CINDER_CONF"
     echo "Waiting for Cinder API to start..."
-    if ! wait_for_service $SERVICE_TIMEOUT $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT; then
+    if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$CINDER_SERVICE_HOST:$service_port; then
         die $LINENO "c-api did not start"
     fi
 
diff --git a/lib/glance b/lib/glance
index d6d12ca..4194842 100644
--- a/lib/glance
+++ b/lib/glance
@@ -51,8 +51,18 @@
     GLANCE_BIN_DIR=$(get_python_exec_prefix)
 fi
 
+if is_ssl_enabled_service "glance" || is_service_enabled tls-proxy; then
+    GLANCE_SERVICE_PROTOCOL="https"
+fi
+
 # Glance connection info.  Note the port must be specified.
-GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$SERVICE_HOST:9292}
+GLANCE_SERVICE_HOST=${GLANCE_SERVICE_HOST:-$SERVICE_HOST}
+GLANCE_SERVICE_PORT=${GLANCE_SERVICE_PORT:-9292}
+GLANCE_SERVICE_PORT_INT=${GLANCE_SERVICE_PORT_INT:-19292}
+GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$GLANCE_SERVICE_HOST:$GLANCE_SERVICE_PORT}
+GLANCE_SERVICE_PROTOCOL=${GLANCE_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+GLANCE_REGISTRY_PORT=${GLANCE_REGISTRY_PORT:-9191}
+GLANCE_REGISTRY_PORT_INT=${GLANCE_REGISTRY_PORT_INT:-19191}
 
 # Tell Tempest this project is present
 TEMPEST_SERVICES+=,glance
@@ -96,13 +106,7 @@
     iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $dburl
     iniset $GLANCE_REGISTRY_CONF DEFAULT use_syslog $SYSLOG
     iniset $GLANCE_REGISTRY_CONF paste_deploy flavor keystone
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
-    configure_API_version $GLANCE_REGISTRY_CONF $IDENTITY_API_VERSION
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_user glance
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $GLANCE_REGISTRY_CONF keystone_authtoken signing_dir $GLANCE_AUTH_CACHE_DIR/registry
+    configure_auth_token_middleware $GLANCE_REGISTRY_CONF glance $GLANCE_AUTH_CACHE_DIR/registry
     if is_service_enabled qpid || [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; then
         iniset $GLANCE_REGISTRY_CONF DEFAULT notification_driver messaging
     fi
@@ -115,17 +119,11 @@
     iniset $GLANCE_API_CONF DEFAULT use_syslog $SYSLOG
     iniset $GLANCE_API_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
     iniset $GLANCE_API_CONF paste_deploy flavor keystone+cachemanagement
-    iniset $GLANCE_API_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $GLANCE_API_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
-    configure_API_version $GLANCE_API_CONF $IDENTITY_API_VERSION
-    iniset $GLANCE_API_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $GLANCE_API_CONF keystone_authtoken admin_user glance
-    iniset $GLANCE_API_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
+    configure_auth_token_middleware $GLANCE_API_CONF glance $GLANCE_AUTH_CACHE_DIR/api
     if is_service_enabled qpid || [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; then
         iniset $GLANCE_API_CONF DEFAULT notification_driver messaging
     fi
     iniset_rpc_backend glance $GLANCE_API_CONF DEFAULT
-    iniset $GLANCE_API_CONF keystone_authtoken signing_dir $GLANCE_AUTH_CACHE_DIR/api
     if [ "$VIRT_DRIVER" = 'xenserver' ]; then
         iniset $GLANCE_API_CONF DEFAULT container_formats "ami,ari,aki,bare,ovf,tgz"
         iniset $GLANCE_API_CONF DEFAULT disk_formats "ami,ari,aki,vhd,raw,iso"
@@ -138,9 +136,7 @@
     # sections.
     iniset $GLANCE_API_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/
 
-    if [ -n "$API_WORKERS" ]; then
-        iniset $GLANCE_API_CONF DEFAULT workers "$API_WORKERS"
-    fi
+    iniset $GLANCE_API_CONF DEFAULT workers "$API_WORKERS"
 
     # Store the images in swift if enabled.
     if is_service_enabled s-proxy; then
@@ -162,6 +158,26 @@
         iniset $GLANCE_API_CONF glance_store stores "file, http, swift"
     fi
 
+    if is_service_enabled tls-proxy; then
+        iniset $GLANCE_API_CONF DEFAULT bind_port $GLANCE_SERVICE_PORT_INT
+        iniset $GLANCE_REGISTRY_CONF DEFAULT bind_port $GLANCE_REGISTRY_PORT_INT
+    fi
+
+    # Register SSL certificates if provided
+    if is_ssl_enabled_service glance; then
+        ensure_certificates GLANCE
+
+        iniset $GLANCE_API_CONF DEFAULT cert_file "$GLANCE_SSL_CERT"
+        iniset $GLANCE_API_CONF DEFAULT key_file "$GLANCE_SSL_KEY"
+
+        iniset $GLANCE_REGISTRY_CONF DEFAULT cert_file "$GLANCE_SSL_CERT"
+        iniset $GLANCE_REGISTRY_CONF DEFAULT key_file "$GLANCE_SSL_KEY"
+    fi
+
+    if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
+        iniset $GLANCE_API_CONF DEFAULT registry_client_protocol https
+    fi
+
     cp -p $GLANCE_DIR/etc/glance-registry-paste.ini $GLANCE_REGISTRY_PASTE_INI
 
     cp -p $GLANCE_DIR/etc/glance-api-paste.ini $GLANCE_API_PASTE_INI
@@ -190,6 +206,14 @@
     cp -p $GLANCE_DIR/etc/schema-image.json $GLANCE_SCHEMA_JSON
 
     cp -p $GLANCE_DIR/etc/metadefs/*.json $GLANCE_METADEF_DIR
+
+    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
+        CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
+        CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
+
+        iniset $GLANCE_API_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
+        iniset $GLANCE_CACHE_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
+    fi
 }
 
 # create_glance_accounts() - Set up common required glance accounts
@@ -220,9 +244,9 @@
                 "image" "Glance Image Service")
             get_or_create_endpoint $glance_service \
                 "$REGION_NAME" \
-                "http://$GLANCE_HOSTPORT" \
-                "http://$GLANCE_HOSTPORT" \
-                "http://$GLANCE_HOSTPORT"
+                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT" \
+                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT" \
+                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT"
         fi
     fi
 }
@@ -279,10 +303,17 @@
 
 # start_glance() - Start running processes, including screen
 function start_glance {
+    local service_protocol=$GLANCE_SERVICE_PROTOCOL
+    if is_service_enabled tls-proxy; then
+        start_tls_proxy '*' $GLANCE_SERVICE_PORT $GLANCE_SERVICE_HOST $GLANCE_SERVICE_PORT_INT &
+        start_tls_proxy '*' $GLANCE_REGISTRY_PORT $GLANCE_SERVICE_HOST $GLANCE_REGISTRY_PORT_INT &
+    fi
+
     run_process g-reg "$GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
     run_process g-api "$GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
+
     echo "Waiting for g-api ($GLANCE_HOSTPORT) to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$GLANCE_HOSTPORT; do sleep 1; done"; then
+    if ! wait_for_service $SERVICE_TIMEOUT $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT; then
         die $LINENO "g-api did not start"
     fi
 }
diff --git a/lib/heat b/lib/heat
index a74d7b5..ff3b307 100644
--- a/lib/heat
+++ b/lib/heat
@@ -110,17 +110,10 @@
         setup_colorized_logging $HEAT_CONF DEFAULT tenant user
     fi
 
-    # keystone authtoken
-    iniset $HEAT_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    configure_API_version $HEAT_CONF $IDENTITY_API_VERSION
-    iniset $HEAT_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
-    iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $HEAT_CONF keystone_authtoken admin_user heat
-    iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR
+    configure_auth_token_middleware $HEAT_CONF heat $HEAT_AUTH_CACHE_DIR
 
     if is_ssl_enabled_service "key"; then
-        iniset $HEAT_CONF clients_keystone ca_file $KEYSTONE_SSL_CA
+        iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
     fi
 
     # ec2authtoken
@@ -138,6 +131,18 @@
     # Cloudwatch API
     iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT
 
+    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
+        iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
+        iniset $HEAT_CONF clients_nova ca_file $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
+        iniset $HEAT_CONF clients_cinder ca_file $SSL_BUNDLE_FILE
+    fi
+
     # heat environment
     sudo mkdir -p $HEAT_ENV_DIR
     sudo chown $STACK_USER $HEAT_ENV_DIR
diff --git a/lib/horizon b/lib/horizon
index a422529..755be18 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -92,26 +92,11 @@
     local local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
     cp $HORIZON_SETTINGS $local_settings
 
-    if is_service_enabled neutron; then
-        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_security_group $Q_USE_SECGROUP
-    fi
-    # enable loadbalancer dashboard in case service is enabled
-    if is_service_enabled q-lbaas; then
-        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_lb True
-    fi
-
-    # enable firewall dashboard in case service is enabled
-    if is_service_enabled q-fwaas; then
-        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_firewall True
-    fi
-
-    # enable VPN dashboard in case service is enabled
-    if is_service_enabled q-vpn; then
-        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_vpn True
-    fi
-
     _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
     _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v2.0\""
+    if [[ -n "$KEYSTONE_TOKEN_HASH_ALGORITHM" ]]; then
+        _horizon_config_set $local_settings "" OPENSTACK_TOKEN_HASH_ALGORITHM \""$KEYSTONE_TOKEN_HASH_ALGORITHM"\"
+    fi
 
     if [ -f $SSL_BUNDLE_FILE ]; then
         _horizon_config_set $local_settings "" OPENSTACK_SSL_CACERT \"${SSL_BUNDLE_FILE}\"
@@ -120,12 +105,6 @@
     # Create an empty directory that apache uses as docroot
     sudo mkdir -p $HORIZON_DIR/.blackhole
 
-    # Apache 2.4 uses mod_authz_host for access control now (instead of "Allow")
-    local horizon_require=''
-    if check_apache_version "2.4" ; then
-        horizon_require='Require all granted'
-    fi
-
     local horizon_conf=$(apache_site_config_for horizon)
 
     # Configure apache to run horizon
@@ -135,7 +114,6 @@
         s,%HORIZON_DIR%,$HORIZON_DIR,g;
         s,%APACHE_NAME%,$APACHE_NAME,g;
         s,%DEST%,$DEST,g;
-        s,%HORIZON_REQUIRE%,$horizon_require,g;
     \" $FILES/apache-horizon.template >$horizon_conf"
 
     if is_ubuntu; then
diff --git a/lib/ironic b/lib/ironic
index 47cc7dc..5f3ebcd 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -243,14 +243,8 @@
 function configure_ironic_api {
     iniset $IRONIC_CONF_FILE DEFAULT auth_strategy keystone
     iniset $IRONIC_CONF_FILE DEFAULT policy_file $IRONIC_POLICY_JSON
-    iniset $IRONIC_CONF_FILE keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $IRONIC_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
-    iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI
-    iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
-    iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
+    configure_auth_token_middleware $IRONIC_CONF_FILE ironic $IRONIC_AUTH_CACHE_DIR/api
     iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
-    iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
 
     cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
 }
diff --git a/lib/keystone b/lib/keystone
index 66ab3db..1c67835 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -6,6 +6,7 @@
 # - ``functions`` file
 # - ``tls`` file
 # - ``DEST``, ``STACK_USER``
+# - ``FILES``
 # - ``IDENTITY_API_VERSION``
 # - ``BASE_SQL_CONN``
 # - ``SERVICE_HOST``, ``SERVICE_PROTOCOL``
@@ -37,7 +38,11 @@
 KEYSTONE_CONF=$KEYSTONE_CONF_DIR/keystone.conf
 KEYSTONE_PASTE_INI=${KEYSTONE_PASTE_INI:-$KEYSTONE_CONF_DIR/keystone-paste.ini}
 KEYSTONE_AUTH_CACHE_DIR=${KEYSTONE_AUTH_CACHE_DIR:-/var/cache/keystone}
-KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/var/www/keystone}
+if is_suse; then
+    KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/srv/www/htdocs/keystone}
+else
+    KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/var/www/keystone}
+fi
 
 KEYSTONEMIDDLEWARE_DIR=$DEST/keystonemiddleware
 KEYSTONECLIENT_DIR=$DEST/python-keystoneclient
@@ -90,7 +95,7 @@
 KEYSTONE_VALID_ASSIGNMENT_BACKENDS=kvs,ldap,sql
 
 # if we are running with SSL use https protocols
-if is_ssl_enabled_service "key"; then
+if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
     KEYSTONE_AUTH_PROTOCOL="https"
     KEYSTONE_SERVICE_PROTOCOL="https"
 fi
@@ -104,18 +109,13 @@
 # cleanup_keystone() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_keystone {
-    # kill instances (nova)
-    # delete image files (glance)
-    # This function intentionally left blank
-    :
+    _cleanup_keystone_apache_wsgi
 }
 
 # _cleanup_keystone_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
 function _cleanup_keystone_apache_wsgi {
     sudo rm -f $KEYSTONE_WSGI_DIR/*.wsgi
-    disable_apache_site keystone
     sudo rm -f $(apache_site_config_for keystone)
-    restart_apache_server
 }
 
 # _config_keystone_apache_wsgi() - Set WSGI config files of Keystone
@@ -123,12 +123,20 @@
     sudo mkdir -p $KEYSTONE_WSGI_DIR
 
     local keystone_apache_conf=$(apache_site_config_for keystone)
-    local apache_version=$(get_apache_version)
+    local keystone_ssl=""
+    local keystone_certfile=""
+    local keystone_keyfile=""
+    local keystone_service_port=$KEYSTONE_SERVICE_PORT
+    local keystone_auth_port=$KEYSTONE_AUTH_PORT
 
-    if [[ ${apache_version#*\.} -ge 4 ]]; then
-        # Apache 2.4 supports custom error log formats
-        # this should mirror the original log formatting.
-        local errorlogformat='ErrorLogFormat "%{cu}t %M"'
+    if is_ssl_enabled_service key; then
+        keystone_ssl="SSLEngine On"
+        keystone_certfile="SSLCertificateFile $KEYSTONE_SSL_CERT"
+        keystone_keyfile="SSLCertificateKeyFile $KEYSTONE_SSL_KEY"
+    fi
+    if is_service_enabled tls-proxy; then
+        keystone_service_port=$KEYSTONE_SERVICE_PORT_INT
+        keystone_auth_port=$KEYSTONE_AUTH_PORT_INT
     fi
 
     # copy proxy vhost and wsgi file
@@ -137,15 +145,16 @@
 
     sudo cp $FILES/apache-keystone.template $keystone_apache_conf
     sudo sed -e "
-        s|%PUBLICPORT%|$KEYSTONE_SERVICE_PORT|g;
-        s|%ADMINPORT%|$KEYSTONE_AUTH_PORT|g;
+        s|%PUBLICPORT%|$keystone_service_port|g;
+        s|%ADMINPORT%|$keystone_auth_port|g;
         s|%APACHE_NAME%|$APACHE_NAME|g;
         s|%PUBLICWSGI%|$KEYSTONE_WSGI_DIR/main|g;
         s|%ADMINWSGI%|$KEYSTONE_WSGI_DIR/admin|g;
+        s|%SSLENGINE%|$keystone_ssl|g;
+        s|%SSLCERTFILE%|$keystone_certfile|g;
+        s|%SSLKEYFILE%|$keystone_keyfile|g;
         s|%USER%|$STACK_USER|g
-        s|%ERRORLOGFORMAT%|$errorlogformat|g;
     " -i $keystone_apache_conf
-    enable_apache_site keystone
 }
 
 # configure_keystone() - Set config files, create data dirs, etc
@@ -208,8 +217,13 @@
     fi
 
     # Set the URL advertised in the ``versions`` structure returned by the '/' route
-    iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(public_port)s/"
-    iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(admin_port)s/"
+    if is_service_enabled tls-proxy; then
+        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/"
+        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/"
+    else
+        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(public_port)s/"
+        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(admin_port)s/"
+    fi
     iniset $KEYSTONE_CONF DEFAULT admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"
 
     # Register SSL certificates if provided
@@ -288,7 +302,7 @@
     fi
 
     if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
-        iniset $KEYSTONE_CONF DEFAULT debug "True"
+        iniset $KEYSTONE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
         # Eliminate the %(asctime)s.%(msecs)03d from the log format strings
         iniset $KEYSTONE_CONF DEFAULT logging_context_format_string "%(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s"
         iniset $KEYSTONE_CONF DEFAULT logging_default_format_string "%(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s"
@@ -298,6 +312,13 @@
     fi
 
     iniset $KEYSTONE_CONF DEFAULT max_token_size 16384
+
+    iniset $KEYSTONE_CONF DEFAULT admin_workers "$API_WORKERS"
+    # Public workers will use the server default, typically number of CPU.
+
+    if [[ -n "$KEYSTONE_TOKEN_HASH_ALGORITHM" ]]; then
+        iniset $KEYSTONE_CONF token hash_algorithm "$KEYSTONE_TOKEN_HASH_ALGORITHM"
+    fi
 }
 
 function configure_keystone_extensions {
@@ -388,11 +409,40 @@
 }
 
 # Configure the API version for the OpenStack projects.
-# configure_API_version conf_file version
+# configure_API_version conf_file version [section]
 function configure_API_version {
     local conf_file=$1
     local api_version=$2
-    iniset $conf_file keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$api_version
+    local section=${3:-keystone_authtoken}
+    iniset $conf_file $section auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$api_version
+}
+
+# Configure the service to use the auth token middleware.
+#
+# configure_auth_token_middleware conf_file admin_user signing_dir [section]
+#
+# section defaults to keystone_authtoken, which is where auth_token looks in
+# the .conf file. If the paste config file is used (api-paste.ini) then
+# provide the section name for the auth_token filter.
+function configure_auth_token_middleware {
+    local conf_file=$1
+    local admin_user=$2
+    local signing_dir=$3
+    local section=${4:-keystone_authtoken}
+
+    iniset $conf_file $section auth_host $KEYSTONE_AUTH_HOST
+    iniset $conf_file $section auth_port $KEYSTONE_AUTH_PORT
+    iniset $conf_file $section auth_protocol $KEYSTONE_AUTH_PROTOCOL
+    iniset $conf_file $section identity_uri $KEYSTONE_AUTH_URI
+    iniset $conf_file $section cafile $SSL_BUNDLE_FILE
+    configure_API_version $conf_file $IDENTITY_API_VERSION $section
+    iniset $conf_file $section admin_tenant_name $SERVICE_TENANT_NAME
+    iniset $conf_file $section admin_user $admin_user
+    iniset $conf_file $section admin_password $SERVICE_PASSWORD
+    iniset $conf_file $section signing_dir $signing_dir
+    if [[ -n "$KEYSTONE_TOKEN_HASH_ALGORITHM" ]]; then
+        iniset $conf_file keystone_authtoken hash_algorithms "$KEYSTONE_TOKEN_HASH_ALGORITHM"
+    fi
 }
 
 # init_keystone() - Initialize databases, etc.
@@ -461,6 +511,9 @@
     setup_develop $KEYSTONE_DIR
     if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
         install_apache_wsgi
+        if is_ssl_enabled_service "key"; then
+            enable_mod_ssl
+        fi
     fi
 }
 
@@ -468,24 +521,31 @@
 function start_keystone {
     # Get right service port for testing
     local service_port=$KEYSTONE_SERVICE_PORT
+    local auth_protocol=$KEYSTONE_AUTH_PROTOCOL
     if is_service_enabled tls-proxy; then
         service_port=$KEYSTONE_SERVICE_PORT_INT
+        auth_protocol="http"
     fi
 
     if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
+        enable_apache_site keystone
         restart_apache_server
         tail_log key /var/log/$APACHE_NAME/keystone.log
         tail_log key-access /var/log/$APACHE_NAME/keystone_access.log
     else
+        local EXTRA_PARAMS=""
+        if [ "$ENABLE_DEBUG_LOG_LEVEL" == "True" ]; then
+            EXTRA_PARAMS="--debug"
+        fi
         # Start Keystone in a screen window
-        run_process key "$KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF --debug"
+        run_process key "$KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF $EXTRA_PARAMS"
     fi
 
     echo "Waiting for keystone to start..."
     # Check that the keystone service is running. Even if the tls tunnel
     # should be enabled, make sure the internal port is checked using
     # unencryted traffic at this point.
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -k -s http://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -k -s $auth_protocol://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
         die $LINENO "keystone did not start"
     fi
 
@@ -498,10 +558,12 @@
 
 # stop_keystone() - Stop running processes
 function stop_keystone {
+    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
+        disable_apache_site keystone
+        restart_apache_server
+    fi
     # Kill the Keystone screen window
     stop_process key
-    # Cleanup the WSGI files and VHOST
-    _cleanup_keystone_apache_wsgi
 }
 
 function is_keystone_enabled {
diff --git a/lib/ldap b/lib/ldap
index efe2f09..2bb8a4c 100644
--- a/lib/ldap
+++ b/lib/ldap
@@ -79,7 +79,7 @@
 function init_ldap {
     local keystone_ldif
 
-    TMP_LDAP_DIR=$(mktemp -d -t ldap.$$.XXXXXXXXXX)
+    local tmp_ldap_dir=$(mktemp -d -t ldap.$$.XXXXXXXXXX)
 
     # Remove data but not schemas
     clear_ldap_state
@@ -91,17 +91,17 @@
         printf "Configuring LDAP for $LDAP_BASE_DC\n"
         # If BASE_DN is changed, the user may override the default file
         if [[ -r $FILES/ldap/${LDAP_BASE_DC}.ldif.in ]]; then
-            keystone_ldif=${LDAP_BASE_DC}.ldif
+            local keystone_ldif=${LDAP_BASE_DC}.ldif
         else
-            keystone_ldif=keystone.ldif
+            local keystone_ldif=keystone.ldif
         fi
-        _ldap_varsubst $FILES/ldap/${keystone_ldif}.in >$TMP_LDAP_DIR/${keystone_ldif}
-        if [[ -r $TMP_LDAP_DIR/${keystone_ldif} ]]; then
-            ldapadd -x -w $LDAP_PASSWORD -D "$LDAP_MANAGER_DN" -H $LDAP_URL -c -f $TMP_LDAP_DIR/${keystone_ldif}
+        _ldap_varsubst $FILES/ldap/${keystone_ldif}.in >$tmp_ldap_dir/${keystone_ldif}
+        if [[ -r $tmp_ldap_dir/${keystone_ldif} ]]; then
+            ldapadd -x -w $LDAP_PASSWORD -D "$LDAP_MANAGER_DN" -H $LDAP_URL -c -f $tmp_ldap_dir/${keystone_ldif}
         fi
     fi
 
-    rm -rf TMP_LDAP_DIR
+    rm -rf $tmp_ldap_dir
 }
 
 # install_ldap
@@ -110,7 +110,7 @@
     echo "Installing LDAP inside function"
     echo "os_VENDOR is $os_VENDOR"
 
-    TMP_LDAP_DIR=$(mktemp -d -t ldap.$$.XXXXXXXXXX)
+    local tmp_ldap_dir=$(mktemp -d -t ldap.$$.XXXXXXXXXX)
 
     printf "installing OpenLDAP"
     if is_ubuntu; then
@@ -119,19 +119,19 @@
     elif is_fedora; then
         start_ldap
     elif is_suse; then
-        _ldap_varsubst $FILES/ldap/suse-base-config.ldif.in >$TMP_LDAP_DIR/suse-base-config.ldif
-        sudo slapadd -F /etc/openldap/slapd.d/ -bcn=config -l $TMP_LDAP_DIR/suse-base-config.ldif
+        _ldap_varsubst $FILES/ldap/suse-base-config.ldif.in >$tmp_ldap_dir/suse-base-config.ldif
+        sudo slapadd -F /etc/openldap/slapd.d/ -bcn=config -l $tmp_ldap_dir/suse-base-config.ldif
         sudo sed -i '/^OPENLDAP_START_LDAPI=/s/"no"/"yes"/g' /etc/sysconfig/openldap
         start_ldap
     fi
 
     echo "LDAP_PASSWORD is $LDAP_PASSWORD"
-    SLAPPASS=$(slappasswd -s $LDAP_PASSWORD)
-    printf "LDAP secret is $SLAPPASS\n"
+    local slappass=$(slappasswd -s $LDAP_PASSWORD)
+    printf "LDAP secret is $slappass\n"
 
     # Create manager.ldif and add to olcdb
-    _ldap_varsubst $FILES/ldap/manager.ldif.in >$TMP_LDAP_DIR/manager.ldif
-    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f $TMP_LDAP_DIR/manager.ldif
+    _ldap_varsubst $FILES/ldap/manager.ldif.in >$tmp_ldap_dir/manager.ldif
+    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f $tmp_ldap_dir/manager.ldif
 
     # On fedora we need to manually add cosine and inetorgperson schemas
     if is_fedora; then
@@ -139,7 +139,7 @@
         sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
     fi
 
-    rm -rf TMP_LDAP_DIR
+    rm -rf $tmp_ldap_dir
 }
 
 # start_ldap() - Start LDAP
diff --git a/lib/neutron b/lib/neutron
index f72ee59..81f2697 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -69,6 +69,11 @@
 PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
 PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
 
+if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
+    Q_PROTOCOL="https"
+fi
+
+
 # Set up default directories
 NEUTRON_DIR=$DEST/neutron
 NEUTRONCLIENT_DIR=$DEST/python-neutronclient
@@ -105,8 +110,12 @@
 Q_PLUGIN=${Q_PLUGIN:-ml2}
 # Default Neutron Port
 Q_PORT=${Q_PORT:-9696}
+# Default Neutron Internal Port when using TLS proxy
+Q_PORT_INT=${Q_PORT_INT:-19696}
 # Default Neutron Host
 Q_HOST=${Q_HOST:-$SERVICE_HOST}
+# Default protocol
+Q_PROTOCOL=${Q_PROTOCOL:-$SERVICE_PROTOCOL}
 # Default admin username
 Q_ADMIN_USERNAME=${Q_ADMIN_USERNAME:-neutron}
 # Default auth strategy
@@ -409,7 +418,7 @@
     iniset $NOVA_CONF neutron auth_strategy "$Q_AUTH_STRATEGY"
     iniset $NOVA_CONF neutron admin_tenant_name "$SERVICE_TENANT_NAME"
     iniset $NOVA_CONF neutron region_name "$REGION_NAME"
-    iniset $NOVA_CONF neutron url "http://$Q_HOST:$Q_PORT"
+    iniset $NOVA_CONF neutron url "${Q_PROTOCOL}://$Q_HOST:$Q_PORT"
 
     if [[ "$Q_USE_SECGROUP" == "True" ]]; then
         LIBVIRT_FIREWALL_DRIVER=nova.virt.firewall.NoopFirewallDriver
@@ -447,24 +456,24 @@
 # Migrated from keystone_data.sh
 function create_neutron_accounts {
 
-    SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
-    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
+    local service_tenant=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
+    local admin_role=$(openstack role list | awk "/ admin / { print \$2 }")
 
     if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
 
-        NEUTRON_USER=$(get_or_create_user "neutron" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT)
-        get_or_add_user_role $ADMIN_ROLE $NEUTRON_USER $SERVICE_TENANT
+        local neutron_user=$(get_or_create_user "neutron" \
+            "$SERVICE_PASSWORD" $service_tenant)
+        get_or_add_user_role $admin_role $neutron_user $service_tenant
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
-            NEUTRON_SERVICE=$(get_or_create_service "neutron" \
+            local neutron_service=$(get_or_create_service "neutron" \
                 "network" "Neutron Service")
-            get_or_create_endpoint $NEUTRON_SERVICE \
+            get_or_create_endpoint $neutron_service \
                 "$REGION_NAME" \
-                "http://$SERVICE_HOST:$Q_PORT/" \
-                "http://$SERVICE_HOST:$Q_PORT/" \
-                "http://$SERVICE_HOST:$Q_PORT/"
+                "$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/" \
+                "$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/" \
+                "$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/"
         fi
     fi
 }
@@ -590,12 +599,25 @@
 # Start running processes, including screen
 function start_neutron_service_and_check {
     local cfg_file_options="$(determine_config_files neutron-server)"
+    local service_port=$Q_PORT
+    local service_protocol=$Q_PROTOCOL
+    if is_service_enabled tls-proxy; then
+        service_port=$Q_PORT_INT
+        service_protocol="http"
+    fi
     # Start the Neutron service
     run_process q-svc "python $NEUTRON_BIN_DIR/neutron-server $cfg_file_options"
     echo "Waiting for Neutron to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$Q_HOST:$Q_PORT; do sleep 1; done"; then
+    if is_ssl_enabled_service "neutron"; then
+        ssl_ca="--ca-certificate=${SSL_BUNDLE_FILE}"
+    fi
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$Q_HOST:$service_port; do sleep 1; done"; then
         die $LINENO "Neutron did not start"
     fi
+    # Start proxy if enabled
+    if is_service_enabled tls-proxy; then
+        start_tls_proxy '*' $Q_PORT $Q_HOST $Q_PORT_INT &
+    fi
 }
 
 # Start running processes, including screen
@@ -730,6 +752,23 @@
         setup_colorized_logging $NEUTRON_CONF DEFAULT project_id
     fi
 
+    if is_service_enabled tls-proxy; then
+        # Set the service port for a proxy to take the original
+        iniset $NEUTRON_CONF DEFAULT bind_port "$Q_PORT_INT"
+    fi
+
+    if is_ssl_enabled_service "nova"; then
+        iniset $NEUTRON_CONF DEFAULT nova_ca_certificates_file "$SSL_BUNDLE_FILE"
+    fi
+
+    if is_ssl_enabled_service "neutron"; then
+        ensure_certificates NEUTRON
+
+        iniset $NEUTRON_CONF DEFAULT use_ssl True
+        iniset $NEUTRON_CONF DEFAULT ssl_cert_file "$NEUTRON_SSL_CERT"
+        iniset $NEUTRON_CONF DEFAULT ssl_key_file "$NEUTRON_SSL_KEY"
+    fi
+
     _neutron_setup_rootwrap
 }
 
@@ -794,12 +833,12 @@
     iniset $Q_META_CONF_FILE DEFAULT nova_metadata_ip $Q_META_DATA_IP
     iniset $Q_META_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
 
-    _neutron_setup_keystone $Q_META_CONF_FILE DEFAULT True True
+    _neutron_setup_keystone $Q_META_CONF_FILE DEFAULT
 
 }
 
 function _configure_neutron_ceilometer_notifications {
-    iniset $NEUTRON_CONF DEFAULT notification_driver neutron.openstack.common.notifier.rpc_notifier
+    iniset $NEUTRON_CONF DEFAULT notification_driver messaging
 }
 
 function _configure_neutron_lbaas {
@@ -936,19 +975,9 @@
 function _neutron_setup_keystone {
     local conf_file=$1
     local section=$2
-    local use_auth_url=$3
-    local skip_auth_cache=$4
 
-    iniset $conf_file $section auth_uri $KEYSTONE_SERVICE_URI
-    iniset $conf_file $section identity_uri $KEYSTONE_AUTH_URI
-    iniset $conf_file $section admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $conf_file $section admin_user $Q_ADMIN_USERNAME
-    iniset $conf_file $section admin_password $SERVICE_PASSWORD
-    if [[ -z $skip_auth_cache ]]; then
-        iniset $conf_file $section signing_dir $NEUTRON_AUTH_CACHE_DIR
-        # Create cache dir
-        create_neutron_cache_dir
-    fi
+    create_neutron_cache_dir
+    configure_auth_token_middleware $conf_file $Q_ADMIN_USERNAME $NEUTRON_AUTH_CACHE_DIR $section
 }
 
 function _neutron_setup_interface_driver {
diff --git a/lib/neutron_plugins/cisco b/lib/neutron_plugins/cisco
index da90ee3..1406e37 100644
--- a/lib/neutron_plugins/cisco
+++ b/lib/neutron_plugins/cisco
@@ -20,38 +20,12 @@
 # Specify the VLAN range
 Q_CISCO_PLUGIN_VLAN_RANGES=${Q_CISCO_PLUGIN_VLAN_RANGES:-vlan:1:4094}
 
-# Specify ncclient package information
-NCCLIENT_DIR=$DEST/ncclient
-NCCLIENT_VERSION=${NCCLIENT_VERSION:-0.3.1}
-NCCLIENT_REPO=${NCCLIENT_REPO:-git://github.com/CiscoSystems/ncclient.git}
-NCCLIENT_BRANCH=${NCCLIENT_BRANCH:-master}
-
 # This routine put a prefix on an existing function name
 function _prefix_function {
     declare -F $1 > /dev/null || die "$1 doesn't exist"
     eval "$(echo "${2}_${1}()"; declare -f ${1} | tail -n +2)"
 }
 
-function _has_ovs_subplugin {
-    local subplugin
-    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
-        if [[ "$subplugin" == "openvswitch" ]]; then
-            return 0
-        fi
-    done
-    return 1
-}
-
-function _has_nexus_subplugin {
-    local subplugin
-    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
-        if [[ "$subplugin" == "nexus" ]]; then
-            return 0
-        fi
-    done
-    return 1
-}
-
 function _has_n1kv_subplugin {
     local subplugin
     for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
@@ -62,27 +36,6 @@
     return 1
 }
 
-# This routine populates the cisco config file with the information for
-# a particular nexus switch
-function _config_switch {
-    local cisco_cfg_file=$1
-    local switch_ip=$2
-    local username=$3
-    local password=$4
-    local ssh_port=$5
-    shift 5
-
-    local section="NEXUS_SWITCH:$switch_ip"
-    iniset $cisco_cfg_file $section username $username
-    iniset $cisco_cfg_file $section password $password
-    iniset $cisco_cfg_file $section ssh_port $ssh_port
-
-    while [[ ${#@} != 0 ]]; do
-        iniset  $cisco_cfg_file $section $1 $2
-        shift 2
-    done
-}
-
 # Prefix openvswitch plugin routines with "ovs" in order to differentiate from
 # cisco plugin routines. This means, ovs plugin routines will coexist with cisco
 # plugin routines in this script.
@@ -98,73 +51,17 @@
 _prefix_function neutron_plugin_setup_interface_driver ovs
 _prefix_function has_neutron_plugin_security_group ovs
 
-# Check the version of the installed ncclient package
-function check_ncclient_version {
-python << EOF
-version = '$NCCLIENT_VERSION'
-import sys
-try:
-    import pkg_resources
-    import ncclient
-    module_version = pkg_resources.get_distribution('ncclient').version
-    if version != module_version:
-        sys.exit(1)
-except:
-    sys.exit(1)
-EOF
-}
-
-# Install the ncclient package
-function install_ncclient {
-    git_clone $NCCLIENT_REPO $NCCLIENT_DIR $NCCLIENT_BRANCH
-    (cd $NCCLIENT_DIR; sudo python setup.py install)
-}
-
-# Check if the required version of ncclient has been installed
-function is_ncclient_installed {
-    # Check if the Cisco ncclient repository exists
-    if [[ -d $NCCLIENT_DIR ]]; then
-        remotes=$(cd $NCCLIENT_DIR; git remote -v | grep fetch | awk '{ print $2}')
-        for remote in $remotes; do
-            if [[ $remote == $NCCLIENT_REPO ]]; then
-                break;
-            fi
-        done
-        if [[ $remote != $NCCLIENT_REPO ]]; then
-            return 1
-        fi
-    else
-        return 1
-    fi
-
-    # Check if the ncclient is installed with the right version
-    if ! check_ncclient_version; then
-        return 1
-    fi
-    return 0
-}
-
 function has_neutron_plugin_security_group {
-    if _has_ovs_subplugin; then
-        ovs_has_neutron_plugin_security_group
-    else
-        return 1
-    fi
+    return 1
 }
 
 function is_neutron_ovs_base_plugin {
-    # Cisco uses OVS if openvswitch subplugin is deployed
-    _has_ovs_subplugin
     return
 }
 
 # populate required nova configuration parameters
 function neutron_plugin_create_nova_conf {
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_create_nova_conf
-    else
-        _neutron_ovs_base_configure_nova_vif_driver
-    fi
+    _neutron_ovs_base_configure_nova_vif_driver
 }
 
 function neutron_plugin_install_agent_packages {
@@ -177,32 +74,14 @@
     # setup default subplugins
     if [ ! -v Q_CISCO_PLUGIN_SUBPLUGINS ]; then
         declare -ga Q_CISCO_PLUGIN_SUBPLUGINS
-        Q_CISCO_PLUGIN_SUBPLUGINS=(openvswitch nexus)
+        Q_CISCO_PLUGIN_SUBPLUGINS=(n1kv)
     fi
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_configure_common
-        Q_PLUGIN_EXTRA_CONF_PATH=etc/neutron/plugins/cisco
-        Q_PLUGIN_EXTRA_CONF_FILES=(cisco_plugins.ini)
-        # Copy extra config files to /etc so that they can be modified
-        # later according to Cisco-specific localrc settings.
-        mkdir -p /$Q_PLUGIN_EXTRA_CONF_PATH
-        local f
-        local extra_conf_file
-        for (( f=0; $f < ${#Q_PLUGIN_EXTRA_CONF_FILES[@]}; f+=1 )); do
-            extra_conf_file=$Q_PLUGIN_EXTRA_CONF_PATH/${Q_PLUGIN_EXTRA_CONF_FILES[$f]}
-            cp $NEUTRON_DIR/$extra_conf_file /$extra_conf_file
-        done
-    else
-        Q_PLUGIN_CONF_PATH=etc/neutron/plugins/cisco
-        Q_PLUGIN_CONF_FILENAME=cisco_plugins.ini
-    fi
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/cisco
+    Q_PLUGIN_CONF_FILENAME=cisco_plugins.ini
     Q_PLUGIN_CLASS="neutron.plugins.cisco.network_plugin.PluginV2"
 }
 
 function neutron_plugin_configure_debug_command {
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_configure_debug_command
-    fi
 }
 
 function neutron_plugin_configure_dhcp_agent {
@@ -210,53 +89,6 @@
 }
 
 function neutron_plugin_configure_l3_agent {
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_configure_l3_agent
-    fi
-}
-
-function _configure_nexus_subplugin {
-    local cisco_cfg_file=$1
-
-    # Install a known compatible ncclient from the Cisco repository if necessary
-    if ! is_ncclient_installed; then
-        # Preserve the two global variables
-        local offline=$OFFLINE
-        local reclone=$RECLONE
-        # Change their values to allow installation
-        OFFLINE=False
-        RECLONE=yes
-        install_ncclient
-        # Restore their values
-        OFFLINE=$offline
-        RECLONE=$reclone
-    fi
-
-    # Setup default nexus switch information
-    if [ ! -v Q_CISCO_PLUGIN_SWITCH_INFO ]; then
-        declare -A Q_CISCO_PLUGIN_SWITCH_INFO
-        HOST_NAME=$(hostname)
-        Q_CISCO_PLUGIN_SWITCH_INFO=([1.1.1.1]=stack:stack:22:${HOST_NAME}:1/10)
-    else
-        iniset $cisco_cfg_file CISCO nexus_driver neutron.plugins.cisco.nexus.cisco_nexus_network_driver_v2.CiscoNEXUSDriver
-    fi
-
-    # Setup the switch configurations
-    local nswitch
-    local sw_info
-    local segment
-    local sw_info_array
-    declare -i count=0
-    for nswitch in ${!Q_CISCO_PLUGIN_SWITCH_INFO[@]}; do
-        sw_info=${Q_CISCO_PLUGIN_SWITCH_INFO[$nswitch]}
-        sw_info_array=${sw_info//:/ }
-        sw_info_array=( $sw_info_array )
-        count=${#sw_info_array[@]}
-        if [[ $count < 5 || $(( ($count-3) % 2 )) != 0 ]]; then
-            die $LINENO "Incorrect switch configuration: ${Q_CISCO_PLUGIN_SWITCH_INFO[$nswitch]}"
-        fi
-        _config_switch $cisco_cfg_file $nswitch ${sw_info_array[@]}
-    done
 }
 
 # Configure n1kv plugin
@@ -279,48 +111,29 @@
 }
 
 function neutron_plugin_configure_plugin_agent {
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_configure_plugin_agent
-    fi
 }
 
 function neutron_plugin_configure_service {
     local subplugin
     local cisco_cfg_file
 
-    if _has_ovs_subplugin; then
-        ovs_neutron_plugin_configure_service
-        cisco_cfg_file=/${Q_PLUGIN_EXTRA_CONF_FILES[0]}
-    else
-        cisco_cfg_file=/$Q_PLUGIN_CONF_FILE
-    fi
+    cisco_cfg_file=/$Q_PLUGIN_CONF_FILE
 
     # Setup the [CISCO_PLUGINS] section
     if [[ ${#Q_CISCO_PLUGIN_SUBPLUGINS[@]} > 2 ]]; then
         die $LINENO "At most two subplugins are supported."
     fi
 
-    if _has_ovs_subplugin && _has_n1kv_subplugin; then
-        die $LINENO "OVS subplugin and n1kv subplugin cannot coexist"
-    fi
-
     # Setup the subplugins
-    inicomment $cisco_cfg_file CISCO_PLUGINS nexus_plugin
     inicomment $cisco_cfg_file CISCO_PLUGINS vswitch_plugin
     inicomment $cisco_cfg_file CISCO_TEST host
     for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
         case $subplugin in
-            nexus) iniset $cisco_cfg_file CISCO_PLUGINS nexus_plugin neutron.plugins.cisco.nexus.cisco_nexus_plugin_v2.NexusPlugin;;
-            openvswitch) iniset $cisco_cfg_file CISCO_PLUGINS vswitch_plugin neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2;;
             n1kv) iniset $cisco_cfg_file CISCO_PLUGINS vswitch_plugin neutron.plugins.cisco.n1kv.n1kv_neutron_plugin.N1kvNeutronPluginV2;;
             *) die $LINENO "Unsupported cisco subplugin: $subplugin";;
         esac
     done
 
-    if _has_nexus_subplugin; then
-        _configure_nexus_subplugin $cisco_cfg_file
-    fi
-
     if _has_n1kv_subplugin; then
         _configure_n1kv_subplugin $cisco_cfg_file
     fi
diff --git a/lib/neutron_plugins/ofagent_agent b/lib/neutron_plugins/ofagent_agent
index b4c2ada..a5a58f4 100644
--- a/lib/neutron_plugins/ofagent_agent
+++ b/lib/neutron_plugins/ofagent_agent
@@ -34,10 +34,18 @@
     iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
 }
 
+function _neutron_ofagent_configure_firewall_driver {
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
+    fi
+}
+
 function neutron_plugin_configure_plugin_agent {
     # Set up integration bridge
     _neutron_ovs_base_setup_bridge $OVS_BRIDGE
-    _neutron_ovs_base_configure_firewall_driver
+    _neutron_ofagent_configure_firewall_driver
 
     # Check a supported openflow version
     OF_VERSION=`ovs-ofctl --version | grep "OpenFlow versions" | awk '{print $3}' | cut -d':' -f2`
diff --git a/lib/neutron_plugins/plumgrid b/lib/neutron_plugins/plumgrid
index 37b9e4c..7950ac0 100644
--- a/lib/neutron_plugins/plumgrid
+++ b/lib/neutron_plugins/plumgrid
@@ -45,8 +45,8 @@
 }
 
 function has_neutron_plugin_security_group {
-    # False
-    return 1
+    # return 0 means enabled
+    return 0
 }
 
 function neutron_plugin_check_adv_test_requirements {
diff --git a/lib/neutron_plugins/services/loadbalancer b/lib/neutron_plugins/services/loadbalancer
index 78e7738..f84b710 100644
--- a/lib/neutron_plugins/services/loadbalancer
+++ b/lib/neutron_plugins/services/loadbalancer
@@ -10,11 +10,8 @@
 LBAAS_PLUGIN=neutron.services.loadbalancer.plugin.LoadBalancerPlugin
 
 function neutron_agent_lbaas_install_agent_packages {
-    if is_ubuntu || is_fedora; then
+    if is_ubuntu || is_fedora || is_suse; then
         install_package haproxy
-    elif is_suse; then
-        ### FIXME: Find out if package can be pushed to Factory
-        echo "HAProxy packages can be installed from server:http project in OBS"
     fi
 }
 
diff --git a/lib/nova b/lib/nova
index 14d07b0..c24bc2f 100644
--- a/lib/nova
+++ b/lib/nova
@@ -44,11 +44,20 @@
 
 NOVA_API_PASTE_INI=${NOVA_API_PASTE_INI:-$NOVA_CONF_DIR/api-paste.ini}
 
+if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
+    NOVA_SERVICE_PROTOCOL="https"
+    EC2_SERVICE_PROTOCOL="https"
+else
+    EC2_SERVICE_PROTOCOL="http"
+fi
+
 # Public facing bits
 NOVA_SERVICE_HOST=${NOVA_SERVICE_HOST:-$SERVICE_HOST}
 NOVA_SERVICE_PORT=${NOVA_SERVICE_PORT:-8774}
 NOVA_SERVICE_PORT_INT=${NOVA_SERVICE_PORT_INT:-18774}
 NOVA_SERVICE_PROTOCOL=${NOVA_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+EC2_SERVICE_PORT=${EC2_SERVICE_PORT:-8773}
+EC2_SERVICE_PORT_INT=${EC2_SERVICE_PORT_INT:-18773}
 
 # Support entry points installation of console scripts
 if [[ -d $NOVA_DIR/bin ]]; then
@@ -349,14 +358,6 @@
                 "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
                 "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s" \
                 "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2/\$(tenant_id)s"
-
-            local nova_v3_service=$(get_or_create_service "novav3" \
-                "computev3" "Nova Compute Service V3")
-            get_or_create_endpoint $nova_v3_service \
-                "$REGION_NAME" \
-                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
-                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3" \
-                "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v3"
         fi
     fi
 
@@ -375,9 +376,9 @@
                 "ec2" "EC2 Compatibility Layer")
             get_or_create_endpoint $ec2_service \
                 "$REGION_NAME" \
-                "http://$SERVICE_HOST:8773/services/Cloud" \
-                "http://$SERVICE_HOST:8773/services/Admin" \
-                "http://$SERVICE_HOST:8773/services/Cloud"
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud" \
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Admin" \
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud"
         fi
     fi
 
@@ -406,12 +407,12 @@
     iniset $NOVA_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
     iniset $NOVA_CONF DEFAULT auth_strategy "keystone"
     iniset $NOVA_CONF DEFAULT allow_resize_to_same_host "True"
+    iniset $NOVA_CONF DEFAULT allow_migrate_to_same_host "True"
     iniset $NOVA_CONF DEFAULT api_paste_config "$NOVA_API_PASTE_INI"
     iniset $NOVA_CONF DEFAULT rootwrap_config "$NOVA_CONF_DIR/rootwrap.conf"
     iniset $NOVA_CONF DEFAULT scheduler_driver "$SCHEDULER"
     iniset $NOVA_CONF DEFAULT dhcpbridge_flagfile "$NOVA_CONF"
     iniset $NOVA_CONF DEFAULT force_dhcp_release "True"
-    iniset $NOVA_CONF DEFAULT fixed_range ""
     iniset $NOVA_CONF DEFAULT default_floating_pool "$PUBLIC_NETWORK_NAME"
     iniset $NOVA_CONF DEFAULT s3_host "$SERVICE_HOST"
     iniset $NOVA_CONF DEFAULT s3_port "$S3_SERVICE_PORT"
@@ -437,16 +438,17 @@
             iniset $NOVA_CONF DEFAULT osapi_compute_listen_port "$NOVA_SERVICE_PORT_INT"
         fi
 
-        # Add keystone authtoken configuration
-
-        iniset $NOVA_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-        iniset $NOVA_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-        iniset $NOVA_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
-        iniset $NOVA_CONF keystone_authtoken admin_user nova
-        iniset $NOVA_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
+        configure_auth_token_middleware $NOVA_CONF nova $NOVA_AUTH_CACHE_DIR
     fi
 
-    iniset $NOVA_CONF keystone_authtoken signing_dir $NOVA_AUTH_CACHE_DIR
+    if is_service_enabled cinder; then
+        if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
+            CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
+            CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
+            iniset $NOVA_CONF cinder endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
+            iniset $NOVA_CONF cinder ca_certificates_file $SSL_BUNDLE_FILE
+        fi
+    fi
 
     if [ -n "$NOVA_STATE_PATH" ]; then
         iniset $NOVA_CONF DEFAULT state_path "$NOVA_STATE_PATH"
@@ -515,13 +517,30 @@
     fi
 
     iniset $NOVA_CONF DEFAULT ec2_dmz_host "$EC2_DMZ_HOST"
+    iniset $NOVA_CONF DEFAULT keystone_ec2_url $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
     iniset_rpc_backend nova $NOVA_CONF DEFAULT
-    iniset $NOVA_CONF glance api_servers "$GLANCE_HOSTPORT"
+    iniset $NOVA_CONF glance api_servers "${GLANCE_SERVICE_PROTOCOL}://${GLANCE_HOSTPORT}"
 
-    if [ -n "$API_WORKERS" ]; then
-        iniset $NOVA_CONF DEFAULT osci_compute_workers "$API_WORKERS"
-        iniset $NOVA_CONF DEFAULT ec2_workers "$API_WORKERS"
-        iniset $NOVA_CONF DEFAULT metadata_workers "$API_WORKERS"
+    iniset $NOVA_CONF DEFAULT osapi_compute_workers "$API_WORKERS"
+    iniset $NOVA_CONF DEFAULT ec2_workers "$API_WORKERS"
+    iniset $NOVA_CONF DEFAULT metadata_workers "$API_WORKERS"
+
+    if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
+        iniset $NOVA_CONF DEFAULT glance_protocol https
+    fi
+
+    # Register SSL certificates if provided
+    if is_ssl_enabled_service nova; then
+        ensure_certificates NOVA
+
+        iniset $NOVA_CONF DEFAULT ssl_cert_file "$NOVA_SSL_CERT"
+        iniset $NOVA_CONF DEFAULT ssl_key_file "$NOVA_SSL_KEY"
+
+        iniset $NOVA_CONF DEFAULT enabled_ssl_apis "$NOVA_ENABLED_APIS"
+    fi
+
+    if is_service_enabled tls-proxy; then
+        iniset $NOVA_CONF DEFAULT ec2_listen_port $EC2_SERVICE_PORT_INT
     fi
 }
 
@@ -651,19 +670,22 @@
 function start_nova_api {
     # Get right service port for testing
     local service_port=$NOVA_SERVICE_PORT
+    local service_protocol=$NOVA_SERVICE_PROTOCOL
     if is_service_enabled tls-proxy; then
         service_port=$NOVA_SERVICE_PORT_INT
+        service_protocol="http"
     fi
 
     run_process n-api "$NOVA_BIN_DIR/nova-api"
     echo "Waiting for nova-api to start..."
-    if ! wait_for_service $SERVICE_TIMEOUT http://$SERVICE_HOST:$service_port; then
+    if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$SERVICE_HOST:$service_port; then
         die $LINENO "nova-api did not start"
     fi
 
     # Start proxies if enabled
     if is_service_enabled tls-proxy; then
         start_tls_proxy '*' $NOVA_SERVICE_PORT $NOVA_SERVICE_HOST $NOVA_SERVICE_PORT_INT &
+        start_tls_proxy '*' $EC2_SERVICE_PORT $NOVA_SERVICE_HOST $EC2_SERVICE_PORT_INT &
     fi
 }
 
diff --git a/lib/nova_plugins/functions-libvirt b/lib/nova_plugins/functions-libvirt
index f722836..6b9db48 100644
--- a/lib/nova_plugins/functions-libvirt
+++ b/lib/nova_plugins/functions-libvirt
@@ -57,7 +57,9 @@
 EOF
     fi
 
-    if [ "$os_VENDOR" = "Ubuntu" ]; then
+    # Since the release of Debian Wheezy the libvirt init script is libvirtd
+    # and not libvirtd-bin anymore.
+    if is_ubuntu && [ ! -f /etc/init.d/libvirtd ]; then
         LIBVIRT_DAEMON=libvirt-bin
     else
         LIBVIRT_DAEMON=libvirtd
diff --git a/lib/nova_plugins/hypervisor-fake b/lib/nova_plugins/hypervisor-fake
index e7a833f..dc93633 100644
--- a/lib/nova_plugins/hypervisor-fake
+++ b/lib/nova_plugins/hypervisor-fake
@@ -47,7 +47,7 @@
     iniset $NOVA_CONF DEFAULT quota_security_groups -1
     iniset $NOVA_CONF DEFAULT quota_security_group_rules -1
     iniset $NOVA_CONF DEFAULT quota_key_pairs -1
-    iniset $NOVA_CONF DEFAULT scheduler_default_filters "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter"
+    iniset $NOVA_CONF DEFAULT scheduler_default_filters "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,CoreFilter,RamFilter,DiskFilter"
 }
 
 # install_nova_hypervisor() - Install external components
diff --git a/lib/nova_plugins/hypervisor-ironic b/lib/nova_plugins/hypervisor-ironic
index 344ef04..4004cc9 100644
--- a/lib/nova_plugins/hypervisor-ironic
+++ b/lib/nova_plugins/hypervisor-ironic
@@ -37,12 +37,9 @@
     configure_libvirt
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.firewall.NoopFirewallDriver"}
 
-    # NOTE(adam_g): The ironic compute driver currently lives in the ironic
-    # tree.  We purposely configure Nova to load it from there until it moves
-    # back into Nova proper.
-    iniset $NOVA_CONF DEFAULT compute_driver ironic.nova.virt.ironic.IronicDriver
+    iniset $NOVA_CONF DEFAULT compute_driver nova.virt.ironic.IronicDriver
     iniset $NOVA_CONF DEFAULT firewall_driver $LIBVIRT_FIREWALL_DRIVER
-    iniset $NOVA_CONF DEFAULT scheduler_host_manager ironic.nova.scheduler.ironic_host_manager.IronicHostManager
+    iniset $NOVA_CONF DEFAULT scheduler_host_manager nova.scheduler.ironic_host_manager.IronicHostManager
     iniset $NOVA_CONF DEFAULT ram_allocation_ratio 1.0
     iniset $NOVA_CONF DEFAULT reserved_host_memory_mb 0
     # ironic section
@@ -51,7 +48,6 @@
     iniset $NOVA_CONF ironic admin_url $KEYSTONE_AUTH_URI/v2.0
     iniset $NOVA_CONF ironic admin_tenant_name demo
     iniset $NOVA_CONF ironic api_endpoint http://$SERVICE_HOST:6385/v1
-    iniset $NOVA_CONF ironic sql_connection `database_connection_url nova_bm`
 }
 
 # install_nova_hypervisor() - Install external components
diff --git a/lib/rpc_backend b/lib/rpc_backend
index d527c6b..de82fe1 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -6,6 +6,7 @@
 #
 # - ``functions`` file
 # - ``RABBIT_{HOST|PASSWORD}`` must be defined when RabbitMQ is used
+# - ``RPC_MESSAGING_PROTOCOL`` option for configuring the messaging protocol
 
 # ``stack.sh`` calls the entry points in this order:
 #
@@ -90,21 +91,56 @@
             exit_distro_not_supported "zeromq installation"
         fi
     fi
+
+    # Remove the AMQP 1.0 messaging libraries
+    if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
+        if is_fedora; then
+            uninstall_package qpid-proton-c-devel
+            uninstall_package python-qpid-proton
+        fi
+        # TODO(kgiusti) ubuntu cleanup
+    fi
 }
 
 # install rpc backend
 function install_rpc_backend {
+    # Regardless of the broker used, if AMQP 1.0 is configured load
+    # the necessary messaging client libraries for oslo.messaging
+    if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
+        if is_fedora; then
+            install_package qpid-proton-c-devel
+            install_package python-qpid-proton
+        elif is_ubuntu; then
+            # TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
+            # are not yet in the ubuntu repos. Enable these installs
+            # once they are present:
+            #install_package libqpid-proton2-dev
+            #install_package python-qpid-proton
+            # Also add 'uninstall' directives in cleanup_rpc_backend()!
+            exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
+        else
+            exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
+        fi
+        # Install pyngus client API
+        # TODO(kgiusti) can remove once python qpid bindings are
+        # available on all supported platforms _and_ pyngus is added
+        # to the requirements.txt file in oslo.messaging
+        pip_install pyngus
+    fi
+
     if is_service_enabled rabbit; then
         # Install rabbitmq-server
         install_package rabbitmq-server
     elif is_service_enabled qpid; then
+        local qpid_conf_file=/etc/qpid/qpidd.conf
         if is_fedora; then
             install_package qpid-cpp-server
             if [[ $DISTRO =~ (rhel6) ]]; then
+                qpid_conf_file=/etc/qpidd.conf
                 # RHEL6 leaves "auth=yes" in /etc/qpidd.conf, it needs to
                 # be no or you get GSS authentication errors as it
                 # attempts to default to this.
-                sudo sed -i.bak 's/^auth=yes$/auth=no/' /etc/qpidd.conf
+                sudo sed -i.bak 's/^auth=yes$/auth=no/' $qpid_conf_file
             fi
         elif is_ubuntu; then
             install_package qpidd
@@ -113,6 +149,22 @@
         else
             exit_distro_not_supported "qpid installation"
         fi
+        # If AMQP 1.0 is specified, ensure that the version of the
+        # broker can support AMQP 1.0 and configure the queue and
+        # topic address patterns used by oslo.messaging.
+        if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
+            QPIDD=$(type -p qpidd)
+            if ! $QPIDD --help | grep -q "queue-patterns"; then
+                exit_distro_not_supported "qpidd with AMQP 1.0 support"
+            fi
+            if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
+                cat <<EOF | sudo tee --append $qpid_conf_file
+queue-patterns=exclusive
+queue-patterns=unicast
+topic-patterns=broadcast
+EOF
+            fi
+        fi
     elif is_service_enabled zeromq; then
         # NOTE(ewindisch): Redis is not strictly necessary
         # but there is a matchmaker driver that works
@@ -130,6 +182,11 @@
         sudo mkdir -p /var/run/openstack
         sudo chown $STACK_USER /var/run/openstack
     fi
+
+    # If using the QPID broker, install the QPID python client API
+    if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
+        install_package python-qpid
+    fi
 }
 
 # restart the rpc backend
@@ -176,7 +233,12 @@
         MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
         iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
     elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
-        iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
+        # For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
+        if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
+            iniset $file $section rpc_backend "amqp"
+        else
+            iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
+        fi
         iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
         if is_ubuntu; then
             QPID_PASSWORD=`sudo strings /etc/qpid/qpidd.sasldb | grep -B1 admin | head -1`
diff --git a/lib/sahara b/lib/sahara
index b50ccde..5c7c253 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -106,16 +106,7 @@
     sudo chown $STACK_USER $SAHARA_AUTH_CACHE_DIR
     rm -rf $SAHARA_AUTH_CACHE_DIR/*
 
-    # Set actual keystone auth configs
-    iniset $SAHARA_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
-    iniset $SAHARA_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
-    iniset $SAHARA_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
-    iniset $SAHARA_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
-    iniset $SAHARA_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $SAHARA_CONF_FILE keystone_authtoken admin_user sahara
-    iniset $SAHARA_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $SAHARA_CONF_FILE keystone_authtoken signing_dir $SAHARA_AUTH_CACHE_DIR
-    iniset $SAHARA_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
+    configure_auth_token_middleware $SAHARA_CONF_FILE sahara $SAHARA_AUTH_CACHE_DIR
 
     # Set configuration to send notifications
 
diff --git a/lib/swift b/lib/swift
index 50e2482..8139552 100644
--- a/lib/swift
+++ b/lib/swift
@@ -29,6 +29,10 @@
 # Defaults
 # --------
 
+if is_ssl_enabled_service "s-proxy" || is_service_enabled tls-proxy; then
+    SWIFT_SERVICE_PROTOCOL="https"
+fi
+
 # Set up default directories
 SWIFT_DIR=$DEST/swift
 SWIFTCLIENT_DIR=$DEST/python-swiftclient
@@ -36,6 +40,9 @@
 SWIFT_APACHE_WSGI_DIR=${SWIFT_APACHE_WSGI_DIR:-/var/www/swift}
 SWIFT3_DIR=$DEST/swift3
 
+SWIFT_SERVICE_PROTOCOL=${SWIFT_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+SWIFT_DEFAULT_BIND_PORT_INT=${SWIFT_DEFAULT_BIND_PORT_INT:-8081}
+
 # TODO: add logging to different location.
 
 # Set ``SWIFT_DATA_DIR`` to the location of swift drives and objects.
@@ -269,7 +276,7 @@
     iniset ${swift_node_config} DEFAULT log_facility LOG_LOCAL${log_facility}
 
     iniuncomment ${swift_node_config} DEFAULT workers
-    iniset ${swift_node_config} DEFAULT workers 1
+    iniset ${swift_node_config} DEFAULT workers ${API_WORKERS:-1}
 
     iniuncomment ${swift_node_config} DEFAULT disable_fallocate
     iniset ${swift_node_config} DEFAULT disable_fallocate true
@@ -334,7 +341,18 @@
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT log_level DEBUG
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
+    if is_service_enabled tls-proxy; then
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT_INT}
+    else
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
+    fi
+
+    if is_ssl_enabled_service s-proxy; then
+        ensure_certificates SWIFT
+
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT cert_file "$SWIFT_SSL_CERT"
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT key_file "$SWIFT_SSL_KEY"
+    fi
 
     # Devstack is commonly run in a small slow environment, so bump the
     # timeouts up.
@@ -382,15 +400,7 @@
 
     # Configure Keystone
     sed -i '/^# \[filter:authtoken\]/,/^# \[filter:keystoneauth\]$/ s/^#[ \t]*//' ${SWIFT_CONFIG_PROXY_SERVER}
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_host $KEYSTONE_AUTH_HOST
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_port $KEYSTONE_AUTH_PORT
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken cafile $KEYSTONE_SSL_CA
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_user swift
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_password $SERVICE_PASSWORD
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken signing_dir $SWIFT_AUTH_CACHE_DIR
+    configure_auth_token_middleware ${SWIFT_CONFIG_PROXY_SERVER} swift $SWIFT_AUTH_CACHE_DIR filter:authtoken
     # This causes the authtoken middleware to use the same python logging
     # adapter provided by the swift proxy-server, so that request transaction
     # IDs will included in all of its log messages.
@@ -409,7 +419,7 @@
 auth_port = ${KEYSTONE_AUTH_PORT}
 auth_host = ${KEYSTONE_AUTH_HOST}
 auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
-cafile = ${KEYSTONE_SSL_CA}
+cafile = ${SSL_BUNDLE_FILE}
 auth_token = ${SERVICE_TOKEN}
 admin_token = ${SERVICE_TOKEN}
 
@@ -568,9 +578,9 @@
             "object-store" "Swift Service")
         get_or_create_endpoint $swift_service \
             "$REGION_NAME" \
-            "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s" \
-            "http://$SERVICE_HOST:8080" \
-            "http://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s"
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s" \
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080" \
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s"
     fi
 
     local swift_tenant_test1=$(get_or_create_project swifttenanttest1)
@@ -683,6 +693,10 @@
     for type in proxy ${todo}; do
         swift-init --run-dir=${SWIFT_DATA_DIR}/run ${type} stop || true
     done
+    if is_service_enabled tls-proxy; then
+        local proxy_port=${SWIFT_DEFAULT_BIND_PORT:-8080}
+        start_tls_proxy '*' $proxy_port $SERVICE_HOST $SWIFT_DEFAULT_BIND_PORT_INT &
+    fi
     run_process s-proxy "$SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
     if [[ ${SWIFT_REPLICAS} == 1 ]]; then
         for type in object container account; do
diff --git a/lib/tempest b/lib/tempest
index 933c059..d677c7e 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -48,6 +48,7 @@
 TEMPEST_CONFIG_DIR=${TEMPEST_CONFIG_DIR:-$TEMPEST_DIR/etc}
 TEMPEST_CONFIG=$TEMPEST_CONFIG_DIR/tempest.conf
 TEMPEST_STATE_PATH=${TEMPEST_STATE_PATH:=$DATA_DIR/tempest}
+TEMPEST_LIB_DIR=$DEST/tempest-lib
 
 NOVA_SOURCE_DIR=$DEST/nova
 
@@ -289,15 +290,12 @@
     iniset $TEMPEST_CONFIG compute ssh_connect_method $ssh_connect_method
 
     # Compute Features
-    iniset $TEMPEST_CONFIG compute-feature-enabled api_v3 ${TEMPEST_NOVA_API_V3:-False}
     iniset $TEMPEST_CONFIG compute-feature-enabled resize True
     iniset $TEMPEST_CONFIG compute-feature-enabled live_migration ${LIVE_MIGRATION_AVAILABLE:-False}
     iniset $TEMPEST_CONFIG compute-feature-enabled change_password False
     iniset $TEMPEST_CONFIG compute-feature-enabled block_migration_for_live_migration ${USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION:-False}
     iniset $TEMPEST_CONFIG compute-feature-enabled api_extensions ${COMPUTE_API_EXTENSIONS:-"all"}
     iniset $TEMPEST_CONFIG compute-feature-disabled api_extensions ${DISABLE_COMPUTE_API_EXTENSIONS}
-    iniset $TEMPEST_CONFIG compute-feature-enabled api_v3_extensions ${COMPUTE_API_V3_EXTENSIONS:-"all"}
-    iniset $TEMPEST_CONFIG compute-feature-disabled api_v3_extensions ${DISABLE_COMPUTE_API_V3_EXTENSIONS}
 
     # Compute admin
     iniset $TEMPEST_CONFIG "compute-admin" username $ADMIN_USERNAME
@@ -316,7 +314,7 @@
     iniset $TEMPEST_CONFIG network-feature-disabled api_extensions ${DISABLE_NETWORK_API_EXTENSIONS}
 
     # boto
-    iniset $TEMPEST_CONFIG boto ec2_url "http://$SERVICE_HOST:8773/services/Cloud"
+    iniset $TEMPEST_CONFIG boto ec2_url "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud"
     iniset $TEMPEST_CONFIG boto s3_url "http://$SERVICE_HOST:${S3_SERVICE_PORT:-3333}"
     iniset $TEMPEST_CONFIG boto s3_materials_path "$BOTO_MATERIALS_PATH"
     iniset $TEMPEST_CONFIG boto ari_manifest cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-initrd.manifest.xml
@@ -428,8 +426,15 @@
     fi
 }
 
+# install_tempest_lib() - Collect source, prepare, and install tempest-lib
+function install_tempest_lib {
+    git_clone $TEMPEST_LIB_REPO $TEMPEST_LIB_DIR $TEMPEST_LIB_BRANCH
+    setup_develop $TEMPEST_LIB_DIR
+}
+
 # install_tempest() - Collect source and prepare
 function install_tempest {
+    install_tempest_lib
     git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
     pip_install tox
 }
@@ -446,6 +451,7 @@
     if [ -f "$kernel" -a -f "$ramdisk" -a -f "$disk_image" -a  "$VIRT_DRIVER" != "openvz" \
         -a \( "$LIBVIRT_TYPE" != "lxc" -o "$VIRT_DRIVER" != "libvirt" \) ]; then
         echo "Prepare aki/ari/ami Images"
+        mkdir -p $BOTO_MATERIALS_PATH
         ( #new namespace
             # tenant:demo ; user: demo
             source $TOP_DIR/accrc/demo/demo
diff --git a/lib/tls b/lib/tls
index 061c1ca..15e8692 100644
--- a/lib/tls
+++ b/lib/tls
@@ -14,6 +14,7 @@
 #
 # - configure_CA
 # - init_CA
+# - cleanup_CA
 
 # - configure_proxy
 # - start_tls_proxy
@@ -27,6 +28,7 @@
 # - start_tls_proxy HOST_IP 5000 localhost 5000
 # - ensure_certificates
 # - is_ssl_enabled_service
+# - enable_mod_ssl
 
 # Defaults
 # --------
@@ -34,14 +36,9 @@
 if is_service_enabled tls-proxy; then
     # TODO(dtroyer): revisit this below after the search for HOST_IP has been done
     TLS_IP=${TLS_IP:-$SERVICE_IP}
-
-    # Set the default ``SERVICE_PROTOCOL`` for TLS
-    SERVICE_PROTOCOL=https
 fi
 
-# Make up a hostname for cert purposes
-# will be added to /etc/hosts?
-DEVSTACK_HOSTNAME=secure.devstack.org
+DEVSTACK_HOSTNAME=$(hostname -f)
 DEVSTACK_CERT_NAME=devstack-cert
 DEVSTACK_CERT=$DATA_DIR/$DEVSTACK_CERT_NAME.pem
 
@@ -209,6 +206,29 @@
 
     # Create the CA bundle
     cat $ROOT_CA_DIR/cacert.pem $INT_CA_DIR/cacert.pem >>$INT_CA_DIR/ca-chain.pem
+    cat $INT_CA_DIR/ca-chain.pem >> $SSL_BUNDLE_FILE
+
+    if is_fedora; then
+        sudo cp $INT_CA_DIR/ca-chain.pem /usr/share/pki/ca-trust-source/anchors/devstack-chain.pem
+        sudo update-ca-trust
+    elif is_ubuntu; then
+        sudo cp $INT_CA_DIR/ca-chain.pem /usr/local/share/ca-certificates/devstack-int.crt
+        sudo cp $ROOT_CA_DIR/cacert.pem /usr/local/share/ca-certificates/devstack-root.crt
+        sudo update-ca-certificates
+    fi
+}
+
+# Clean up the CA files
+# cleanup_CA
+function cleanup_CA {
+    if is_fedora; then
+        sudo rm -f /usr/share/pki/ca-trust-source/anchors/devstack-chain.pem
+        sudo update-ca-trust
+    elif is_ubuntu; then
+        sudo rm -f /usr/local/share/ca-certificates/devstack-int.crt
+        sudo rm -f /usr/local/share/ca-certificates/devstack-root.crt
+        sudo update-ca-certificates
+    fi
 }
 
 # Create an initial server cert
@@ -331,6 +351,9 @@
 function is_ssl_enabled_service {
     local services=$@
     local service=""
+    if [ "$USE_SSL" == "False" ]; then
+        return 1
+    fi
     for service in ${services}; do
         [[ ,${SSL_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
     done
@@ -345,8 +368,12 @@
 # The function expects to find a certificate, key and CA certificate in the
 # variables {service}_SSL_CERT, {service}_SSL_KEY and {service}_SSL_CA. For
 # example for keystone this would be KEYSTONE_SSL_CERT, KEYSTONE_SSL_KEY and
-# KEYSTONE_SSL_CA. If it does not find these certificates the program will
-# quit.
+# KEYSTONE_SSL_CA.
+#
+# If it does not find these certificates then the devstack-issued server
+# certificate, key and CA certificate will be associated with the service.
+#
+# If only some of the variables are provided then the function will quit.
 function ensure_certificates {
     local service=$1
 
@@ -358,7 +385,15 @@
     local key=${!key_var}
     local ca=${!ca_var}
 
-    if [[ -z "$cert" || -z "$key" || -z "$ca" ]]; then
+    if [[ -z "$cert" && -z "$key" && -z "$ca" ]]; then
+        local cert="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
+        local key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
+        local ca="$INT_CA_DIR/ca-chain.pem"
+        eval ${service}_SSL_CERT=\$cert
+        eval ${service}_SSL_KEY=\$key
+        eval ${service}_SSL_CA=\$ca
+        return # the CA certificate is already in the bundle
+    elif [[ -z "$cert" || -z "$key" || -z "$ca" ]]; then
         die $LINENO "Missing either the ${cert_var} ${key_var} or ${ca_var}" \
                     "variable to enable SSL for ${service}"
     fi
@@ -366,6 +401,21 @@
     cat $ca >> $SSL_BUNDLE_FILE
 }
 
+# Enable the mod_ssl plugin in Apache
+function enable_mod_ssl {
+    echo "Enabling mod_ssl"
+
+    if is_ubuntu; then
+        sudo a2enmod ssl
+    elif is_fedora; then
+        # Fedora enables mod_ssl by default
+        :
+    fi
+    if ! sudo `which httpd || which apache2ctl` -M | grep -w -q ssl_module; then
+        die $LINENO "mod_ssl is not enabled in apache2/httpd, please check for it manually and run stack.sh again"
+    fi
+}
+
 
 # Proxy Functions
 # ===============
diff --git a/lib/trove b/lib/trove
index 8628e35..1d1b5f4 100644
--- a/lib/trove
+++ b/lib/trove
@@ -128,12 +128,7 @@
     cp $TROVE_LOCAL_CONF_DIR/api-paste.ini $TROVE_CONF_DIR/api-paste.ini
     TROVE_API_PASTE_INI=$TROVE_CONF_DIR/api-paste.ini
 
-    iniset $TROVE_API_PASTE_INI filter:authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset $TROVE_API_PASTE_INI filter:authtoken cafile $KEYSTONE_SSL_CA
-    iniset $TROVE_API_PASTE_INI filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $TROVE_API_PASTE_INI filter:authtoken admin_user trove
-    iniset $TROVE_API_PASTE_INI filter:authtoken admin_password $SERVICE_PASSWORD
-    iniset $TROVE_API_PASTE_INI filter:authtoken signing_dir $TROVE_AUTH_CACHE_DIR
+    configure_auth_token_middleware $TROVE_API_PASTE_INI trove $TROVE_AUTH_CACHE_DIR filter:authtoken
 
     # (Re)create trove conf files
     rm -f $TROVE_CONF_DIR/trove.conf
@@ -144,6 +139,8 @@
     iniset $TROVE_CONF_DIR/trove.conf DEFAULT sql_connection `database_connection_url trove`
     iniset $TROVE_CONF_DIR/trove.conf DEFAULT default_datastore $TROVE_DATASTORE_TYPE
     setup_trove_logging $TROVE_CONF_DIR/trove.conf
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT trove_api_workers "$API_WORKERS"
+
 
     # (Re)create trove taskmanager conf file if needed
     if is_service_enabled tr-tmgr; then
diff --git a/lib/zaqar b/lib/zaqar
index 43fb5a1..93b727e 100644
--- a/lib/zaqar
+++ b/lib/zaqar
@@ -107,11 +107,7 @@
     iniset $ZAQAR_CONF DEFAULT log_file $ZAQAR_API_LOG_FILE
     iniset $ZAQAR_CONF 'drivers:transport:wsgi' bind $ZAQAR_SERVICE_HOST
 
-    iniset $ZAQAR_CONF keystone_authtoken auth_protocol http
-    iniset $ZAQAR_CONF keystone_authtoken admin_user zaqar
-    iniset $ZAQAR_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $ZAQAR_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $ZAQAR_CONF keystone_authtoken signing_dir $ZAQAR_AUTH_CACHE_DIR
+    configure_auth_token_middleware $ZAQAR_CONF zaqar $ZAQAR_AUTH_CACHE_DIR
 
     if [ "$ZAQAR_BACKEND" = 'mysql' ] || [ "$ZAQAR_BACKEND" = 'postgresql' ] ; then
         iniset $ZAQAR_CONF drivers storage sqlalchemy
@@ -193,7 +189,7 @@
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
         local zaqar_service=$(get_or_create_service "zaqar" \
-            "queuing" "Zaqar Service")
+            "messaging" "Zaqar Service")
         get_or_create_endpoint $zaqar_service \
             "$REGION_NAME" \
             "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT" \
diff --git a/stack.sh b/stack.sh
index f42e50a..d23417e 100755
--- a/stack.sh
+++ b/stack.sh
@@ -513,6 +513,15 @@
 # and the specified rpc backend is available on your platform.
 check_rpc_backend
 
+# Use native SSL for servers in SSL_ENABLED_SERVICES
+USE_SSL=$(trueorfalse False $USE_SSL)
+
+# Service to enable with SSL if USE_SSL is True
+SSL_ENABLED_SERVICES="key,nova,cinder,glance,s-proxy,neutron"
+
+if is_service_enabled tls-proxy && [ "$USE_SSL" == "True" ]; then
+    die $LINENO "tls-proxy and SSL are mutually exclusive"
+fi
 
 # Configure Projects
 # ==================
@@ -822,7 +831,7 @@
     configure_heat
 fi
 
-if is_service_enabled tls-proxy; then
+if is_service_enabled tls-proxy || [ "$USE_SSL" == "True" ]; then
     configure_CA
     init_CA
     init_cert
@@ -1454,7 +1463,7 @@
         echo_summary "WARNING: CINDER_MULTI_LVM_BACKEND is used"
         echo "You are using CINDER_MULTI_LVM_BACKEND to configure Cinder's multiple LVM backends"
         echo "Please convert that configuration in local.conf to use CINDER_ENABLED_BACKENDS."
-        echo "CINDER_ENABLED_BACKENDS will be removed early in the 'K' development cycle"
+        echo "CINDER_MULTI_LVM_BACKEND will be removed early in the 'K' development cycle"
         echo "
 [[local|localrc]]
 CINDER_ENABLED_BACKENDS=lvm:lvmdriver-1,lvm:lvmdriver-2
diff --git a/stackrc b/stackrc
index 53c8579..580fabf 100644
--- a/stackrc
+++ b/stackrc
@@ -311,6 +311,9 @@
 TEMPEST_REPO=${TEMPEST_REPO:-${GIT_BASE}/openstack/tempest.git}
 TEMPEST_BRANCH=${TEMPEST_BRANCH:-master}
 
+TEMPEST_LIB_REPO=${TEMPEST_LIB_REPO:-${GIT_BASE}/openstack/tempest-lib.git}
+TEMPEST_LIB_BRANCH=${TEMPEST_LIB_BRANCH:-master}
+
 # Tripleo elements for diskimage-builder images
 TIE_REPO=${TIE_REPO:-${GIT_BASE}/openstack/tripleo-image-elements.git}
 TIE_BRANCH=${TIE_BRANCH:-master}
@@ -508,10 +511,11 @@
 # Allow the use of an alternate protocol (such as https) for service endpoints
 SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
 
-# Sets the maximum number of workers for various services and can restrict
+# Sets the maximum number of workers for most services to reduce
 # the memory used where there are a large number of CPUs present
 # (the default number of workers for many services is the number of CPUs)
-# API_WORKERS=4
+# Also sets the minimum number of workers to 2.
+API_WORKERS=${API_WORKERS:=$(( ($(nproc)/2)<2 ? 2 : ($(nproc)/2) ))}
 
 # Local variables:
 # mode: shell-script
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 12e861e..9bf8f73 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -171,6 +171,7 @@
     echo "Waiting for the VM to halt.  Progress in-VM can be checked with vncviewer:"
     mgmt_ip=$(echo $XENAPI_CONNECTION_URL | tr -d -c '1234567890.')
     domid=$(get_domid "$GUEST_NAME")
+    sleep 20 # Wait for the vnc-port to be written
     port=$(xenstore-read /local/domain/$domid/console/vnc-port)
     echo "vncviewer -via root@$mgmt_ip localhost:${port:2}"
     while true; do
diff --git a/tools/xen/prepare_guest.sh b/tools/xen/prepare_guest.sh
index 2b5e418..cd189db 100755
--- a/tools/xen/prepare_guest.sh
+++ b/tools/xen/prepare_guest.sh
@@ -74,6 +74,7 @@
 apt-get update
 apt-get install -y cracklib-runtime curl wget ssh openssh-server tcpdump ethtool
 apt-get install -y curl wget ssh openssh-server python-pip git sudo python-netaddr
+apt-get install -y coreutils
 pip install xenapi
 
 # Install XenServer guest utilities