Merge "Fix "sudo: sorry, you must have a tty to run sudo""
diff --git a/AUTHORS b/AUTHORS
index ba68e32..7ec1f66 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -35,6 +35,7 @@
 Osamu Habuka <xiu.yushen@gmail.com>
 Russell Bryant <rbryant@redhat.com>
 Scott Moser <smoser@ubuntu.com>
+Sumit Naiksatam <sumitnaiksatam@gmail.com>
 Thierry Carrez <thierry@openstack.org>
 Todd Willey <xtoddx@gmail.com>
 Tres Henry <tres@treshenry.net>
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index 5c5e0e4..45b8645 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -86,8 +86,12 @@
 fi
 
 # Configure Security Group Rules
-nova secgroup-add-rule $SECGROUP icmp -1 -1 0.0.0.0/0
-nova secgroup-add-rule $SECGROUP tcp 22 22 0.0.0.0/0
+if ! nova secgroup-list-rules $SECGROUP | grep -q icmp; then
+    nova secgroup-add-rule $SECGROUP icmp -1 -1 0.0.0.0/0
+fi
+if ! nova secgroup-list-rules $SECGROUP | grep -q " tcp .* 22 "; then
+    nova secgroup-add-rule $SECGROUP tcp 22 22 0.0.0.0/0
+fi
 
 # determinine instance type
 # -------------------------
diff --git a/extras.d/80-tempest.sh b/extras.d/80-tempest.sh
new file mode 100644
index 0000000..506ccef
--- /dev/null
+++ b/extras.d/80-tempest.sh
@@ -0,0 +1,20 @@
+# tempest.sh - DevStack extras script
+
+source $TOP_DIR/lib/tempest
+
+if [[ "$1" == "stack" ]]; then
+    # Configure Tempest last to ensure that the runtime configuration of
+    # the various OpenStack services can be queried.
+    if is_service_enabled tempest; then
+        echo_summary "Configuring Tempest"
+        install_tempest
+        configure_tempest
+    fi
+fi
+
+if [[ "$1" == "unstack" ]]; then
+    # no-op
+    :
+fi
+
+
diff --git a/extras.d/README b/extras.d/README
new file mode 100644
index 0000000..ffc6793
--- /dev/null
+++ b/extras.d/README
@@ -0,0 +1,14 @@
+The extras.d directory contains project initialization scripts to be
+sourced by stack.sh at the end of its run.  This is expected to be
+used by external projects that want to be configured, started and
+stopped with DevStack.
+
+Order is controlled by prefixing the script names with the a two digit
+sequence number.  Script names must end with '.sh'.  This provides a
+convenient way to disable scripts by simoy renaming them.
+
+DevStack reserves the sequence numbers 00 through 09 and 90 through 99
+for its own use.
+
+The scripts are called with an argument of 'stack' by stack.sh and
+with an argument of 'unstack' by unstack.sh.
diff --git a/lib/bigswitch_floodlight b/lib/bigswitch_floodlight
new file mode 100644
index 0000000..77aeb61
--- /dev/null
+++ b/lib/bigswitch_floodlight
@@ -0,0 +1,50 @@
+# Big Switch/FloodLight  OpenFlow Controller
+# ------------------------------------------
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
+BS_FL_OF_PORT=${BS_FL_OF_PORT:-6633}
+OVS_BRIDGE=${OVS_BRIDGE:-br-int}
+
+function configure_bigswitch_floodlight() {
+    :
+}
+
+function init_bigswitch_floodlight() {
+    install_quantum_agent_packages
+
+    echo -n "Installing OVS managed by the openflow controllers:"
+    echo ${BS_FL_CONTROLLERS_PORT}
+
+    # Create local OVS bridge and configure it
+    sudo ovs-vsctl --no-wait -- --if-exists del-br ${OVS_BRIDGE}
+    sudo ovs-vsctl --no-wait add-br ${OVS_BRIDGE}
+    sudo ovs-vsctl --no-wait br-set-external-id ${OVS_BRIDGE} bridge-id ${OVS_BRIDGE}
+
+    ctrls=
+    for ctrl in `echo ${BS_FL_CONTROLLERS_PORT} | tr ',' ' '`
+    do
+        ctrl=${ctrl%:*}
+        ctrls="${ctrls} tcp:${ctrl}:${BS_FL_OF_PORT}"
+    done
+    echo "Adding Network conttrollers: " ${ctrls}
+    sudo ovs-vsctl --no-wait set-controller ${OVS_BRIDGE} ${ctrls}
+}
+
+function install_bigswitch_floodlight() {
+    :
+}
+
+function start_bigswitch_floodlight() {
+    :
+}
+
+function stop_bigswitch_floodlight() {
+    :
+}
+
+# Restore xtrace
+$XTRACE
diff --git a/lib/cinder b/lib/cinder
index cbeb1d7..d9f8d63 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -37,6 +37,12 @@
 CINDER_CONF=$CINDER_CONF_DIR/cinder.conf
 CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini
 
+# Public facing bits
+CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
+CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
+CINDER_SERVICE_PORT_INT=${CINDER_SERVICE_PORT_INT:-18776}
+CINDER_SERVICE_PROTOCOL=${CINDER_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+
 # Support entry points installation of console scripts
 if [[ -d $CINDER_DIR/bin ]]; then
     CINDER_BIN_DIR=$CINDER_DIR/bin
@@ -169,6 +175,11 @@
     iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.openstack.volume.contrib.standard_extensions
     iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
 
+    if is_service_enabled tls-proxy; then
+        # Set the service port for a proxy to take the original
+        iniset $CINDER_CONF DEFAULT osapi_volume_listen_port $CINDER_SERVICE_PORT_INT
+    fi
+
     if [ "$SYSLOG" != "False" ]; then
         iniset $CINDER_CONF DEFAULT use_syslog True
     fi
@@ -241,9 +252,9 @@
             keystone endpoint-create \
                 --region RegionOne \
                 --service_id $CINDER_SERVICE \
-                --publicurl "http://$SERVICE_HOST:8776/v1/\$(tenant_id)s" \
-                --adminurl "http://$SERVICE_HOST:8776/v1/\$(tenant_id)s" \
-                --internalurl "http://$SERVICE_HOST:8776/v1/\$(tenant_id)s"
+                --publicurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
+                --adminurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s" \
+                --internalurl "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(tenant_id)s"
         fi
     fi
 }
@@ -340,6 +351,11 @@
     screen_it c-api "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-api --config-file $CINDER_CONF"
     screen_it c-vol "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-volume --config-file $CINDER_CONF"
     screen_it c-sch "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-scheduler --config-file $CINDER_CONF"
+
+    # Start proxies if enabled
+    if is_service_enabled c-api && is_service_enabled tls-proxy; then
+        start_tls_proxy '*' $CINDER_SERVICE_PORT $CINDER_SERVICE_HOST $CINDER_SERVICE_PORT_INT &
+    fi
 }
 
 # stop_cinder() - Stop running processes
diff --git a/lib/nova b/lib/nova
index 9803acb..8135bf1 100644
--- a/lib/nova
+++ b/lib/nova
@@ -432,8 +432,8 @@
     # Define extra nova conf flags by defining the array ``EXTRA_OPTS``.
     # For Example: ``EXTRA_OPTS=(foo=true bar=2)``
     for I in "${EXTRA_OPTS[@]}"; do
-        # Attempt to convert flags to options
-        iniset $NOVA_CONF DEFAULT ${I//=/ }
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset $NOVA_CONF DEFAULT ${I/=/ }
     done
 }
 
diff --git a/lib/quantum b/lib/quantum
index f081d9b..343e5a9 100644
--- a/lib/quantum
+++ b/lib/quantum
@@ -217,6 +217,8 @@
         iniset $NOVA_CONF DEFAULT libvirt_ovs_integration_bridge "$OVS_BRIDGE"
         iniset $NOVA_CONF DEFAULT linuxnet_ovs_ryu_api_host "$RYU_API_HOST:$RYU_API_PORT"
         iniset $NOVA_CONF DEFAULT libvirt_ovs_ryu_api_host "$RYU_API_HOST:$RYU_API_PORT"
+    elif [[ "$Q_PLUGIN" = "bigswitch_floodlight" ]]; then
+        NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver"}
     fi
     iniset $NOVA_CONF DEFAULT libvirt_vif_driver "$NOVA_VIF_DRIVER"
     iniset $NOVA_CONF DEFAULT linuxnet_interface_driver "$LINUXNET_VIF_DRIVER"
@@ -332,7 +334,7 @@
 
 function is_quantum_ovs_base_plugin() {
     local plugin=$1
-    if [[ ",openvswitch,ryu," =~ ,${plugin}, ]]; then
+    if [[ ",openvswitch,ryu,bigswitch_floodlight," =~ ,${plugin}, ]]; then
         return 0
     fi
     return 1
@@ -407,6 +409,13 @@
         Q_PLUGIN_CONF_FILENAME=ryu.ini
         Q_DB_NAME="ovs_quantum"
         Q_PLUGIN_CLASS="quantum.plugins.ryu.ryu_quantum_plugin.RyuQuantumPluginV2"
+    elif [[ "$Q_PLUGIN" = "bigswitch_floodlight" ]]; then
+        Q_PLUGIN_CONF_PATH=etc/quantum/plugins/bigswitch
+        Q_PLUGIN_CONF_FILENAME=restproxy.ini
+        Q_DB_NAME="restproxy_quantum"
+        Q_PLUGIN_CLASS="quantum.plugins.bigswitch.plugin.QuantumRestProxyV2"
+        BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
+        BS_FL_CONTROLLER_TIMEOUT=${BS_FL_CONTROLLER_TIMEOUT:-10}
     fi
 
     if [[ $Q_PLUGIN_CONF_PATH == '' || $Q_PLUGIN_CONF_FILENAME == '' || $Q_PLUGIN_CLASS == '' ]]; then
@@ -674,6 +683,9 @@
     elif [[ "$Q_PLUGIN" = "ryu" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE OVS openflow_controller $RYU_OFP_HOST:$RYU_OFP_PORT
         iniset /$Q_PLUGIN_CONF_FILE OVS openflow_rest_api $RYU_API_HOST:$RYU_API_PORT
+    elif [[ "$Q_PLUGIN" = "bigswitch_floodlight" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE RESTPROXY servers $BS_FL_CONTROLLERS_PORT
+        iniset /$Q_PLUGIN_CONF_FILE RESTPROXY servertimeout $BS_FL_CONTROLLER_TIMEOUT
     fi
 }
 
@@ -749,6 +761,8 @@
         iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
     elif [[ "$Q_PLUGIN" = "ryu" ]]; then
         iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.RyuInterfaceDriver
+    elif [[ "$Q_PLUGIN" = "bigswitch_floodlight" ]]; then
+        iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
     fi
 }
 
@@ -835,7 +849,7 @@
 # Quantum 3rd party programs
 #---------------------------
 # A comma-separated list of 3rd party programs
-QUANTUM_THIRD_PARTIES="ryu"
+QUANTUM_THIRD_PARTIES="ryu,bigswitch_floodlight"
 for third_party in ${QUANTUM_THIRD_PARTIES//,/ }; do
     source lib/$third_party
 done
diff --git a/lib/tls b/lib/tls
index 1e2a899..202edef 100644
--- a/lib/tls
+++ b/lib/tls
@@ -189,7 +189,7 @@
 " >$ca_dir/signing.conf
 }
 
-# Create root and intermediate CAs and an initial server cert
+# Create root and intermediate CAs
 # init_CA
 function init_CA {
     # Ensure CAs are built
@@ -198,7 +198,11 @@
 
     # Create the CA bundle
     cat $ROOT_CA_DIR/cacert.pem $INT_CA_DIR/cacert.pem >>$INT_CA_DIR/ca-chain.pem
+}
 
+# Create an initial server cert
+# init_cert
+function init_cert {
     if [[ ! -r $DEVSTACK_CERT ]]; then
         if [[ -n "$TLS_IP" ]]; then
             # Lie to let incomplete match routines work
diff --git a/stack.sh b/stack.sh
index 9b084be..5c071fc 100755
--- a/stack.sh
+++ b/stack.sh
@@ -324,7 +324,6 @@
 source $TOP_DIR/lib/ceilometer
 source $TOP_DIR/lib/heat
 source $TOP_DIR/lib/quantum
-source $TOP_DIR/lib/tempest
 source $TOP_DIR/lib/baremetal
 
 # Set the destination directories for OpenStack projects
@@ -779,9 +778,6 @@
     install_ceilometerclient
     install_ceilometer
 fi
-if is_service_enabled tempest; then
-    install_tempest
-fi
 
 
 # Initialization
@@ -842,6 +838,7 @@
 if is_service_enabled tls-proxy; then
     configure_CA
     init_CA
+    init_cert
     # Add name to /etc/hosts
     # don't be naive and add to existing line!
 fi
@@ -1326,16 +1323,6 @@
     screen_it baremetal "nova-baremetal-deploy-helper"
 fi
 
-# Configure Tempest last to ensure that the runtime configuration of
-# the various OpenStack services can be queried.
-if is_service_enabled tempest; then
-    echo_summary "Configuring Tempest"
-    configure_tempest
-    echo '**************************************************'
-    echo_summary "Finished Configuring Tempest"
-    echo '**************************************************'
-fi
-
 # Save some values we generated for later use
 CURRENT_RUN_TIME=$(date "+$TIMESTAMP_FORMAT")
 echo "# $CURRENT_RUN_TIME" >$TOP_DIR/.stackenv
@@ -1345,6 +1332,16 @@
 done
 
 
+# Run extras
+# ==========
+
+if [[ -d $TOP_DIR/extras.d ]]; then
+    for i in $TOP_DIR/extras.d/*.sh; do
+        [[ -r $i ]] && source $i stack
+    done
+fi
+
+
 # Run local script
 # ================
 
diff --git a/stackrc b/stackrc
index 96f0ee5..8d19440 100644
--- a/stackrc
+++ b/stackrc
@@ -111,7 +111,7 @@
 HEAT_BRANCH=master
 
 # python heat client library
-HEATCLIENT_REPO=${GIT_BASE}/heat-api/python-heatclient.git
+HEATCLIENT_REPO=${GIT_BASE}/openstack/python-heatclient.git
 HEATCLIENT_BRANCH=master
 
 # ryu service
diff --git a/tools/make_cert.sh b/tools/make_cert.sh
new file mode 100755
index 0000000..cb93e57
--- /dev/null
+++ b/tools/make_cert.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# **make_cert.sh**
+
+# Create a CA hierarchy (if necessary) and server certificate
+#
+# This mimics the CA structure that DevStack sets up when ``tls_proxy`` is enabled
+# but in the curent directory unless ``DATA_DIR`` is set
+
+ENABLE_TLS=True
+DATA_DIR=${DATA_DIR:-`pwd`/ca-data}
+
+ROOT_CA_DIR=$DATA_DIR/root
+INT_CA_DIR=$DATA_DIR/int
+
+# Import common functions
+source $TOP_DIR/functions
+
+# Import TLS functions
+source lib/tls
+
+function usage {
+    echo "$0 - Create CA and/or certs"
+    echo ""
+    echo "Usage: $0 commonName [orgUnit]"
+    exit 1
+}
+
+CN=$1
+if [ -z "$CN" ]]; then
+    usage
+fi
+ORG_UNIT_NAME=${2:-$ORG_UNIT_NAME}
+
+# Useful on OS/X
+if [[ `uname -s` == 'Darwin' && -d /usr/local/Cellar/openssl ]]; then
+    # set up for brew-installed modern OpenSSL
+    OPENSSL_CONF=/usr/local/etc/openssl/openssl.cnf
+    OPENSSL=/usr/local/Cellar/openssl/*/bin/openssl
+fi
+
+DEVSTACK_CERT_NAME=$CN
+DEVSTACK_HOSTNAME=$CN
+DEVSTACK_CERT=$DATA_DIR/$DEVSTACK_CERT_NAME.pem
+
+# Make sure the CA is set up
+configure_CA
+init_CA
+
+# Create the server cert
+make_cert $INT_CA_DIR $DEVSTACK_CERT_NAME $DEVSTACK_HOSTNAME
+
+# Create a cert bundle
+cat $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt $INT_CA_DIR/cacert.pem >$DEVSTACK_CERT
+
diff --git a/unstack.sh b/unstack.sh
index fd70916..1d4bfd5 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -39,6 +39,15 @@
     UNSTACK_ALL=${UNSTACK_ALL:-1}
 fi
 
+# Run extras
+# ==========
+
+if [[ -d $TOP_DIR/extras.d ]]; then
+    for i in $TOP_DIR/extras.d/*.sh; do
+        [[ -r $i ]] && source $i unstack
+    done
+fi
+
 if [[ "$Q_USE_DEBUG_COMMAND" == "True" ]]; then
     source $TOP_DIR/openrc
     teardown_quantum_debug