#!/bin/bash -x

# go in a directory everybody can access
# (postgresql commands usually have a 'could not change to "$PWD"' error
# message if the postgres user cannot have access to $PWD...)
cd /

. /etc/openstackquickstartrc
ADMIN_PASSWORD=$pw
SERVICE_HOST=$IP

echo "Setting up OpenStack demo controller..."

function install_packages () {
    test $# -gt 0 || return
    rpm -q $* > /dev/null || zypper -n in $* || exit 1
}

function run_as () {
    test $# -eq 2 || (echo "Bad usage of run_as function. Arguments: $*"; exit 1)
    su - $1 -s /bin/bash -c "$2"
}

function get_router_id () {
        eval `neutron router-show -f shell -F id public`
        echo $id
}

function get_service_tenant_id () {
	id=`keystone tenant-get service | awk '/id/  { print $4 } '`

	echo $id
}

function start_and_enable_service () {
    i=/etc/init.d/$1
    if [ -x $i ] ; then
        insserv $1
        if [ -n "$(type -p systemctl)" ]; then

            systemctl start ${1}.service
            systemctl enable ${1}.service
        else
            $i start
        fi
        $i status
        if [ $? -eq 3 ]; then
            journalctl -xn || :
            echo "Service $1 is not running"
            exit 1
        fi
    fi

}

function stop_and_disable_service () {
    i=/etc/init.d/$1
    if [ -x $i ] ; then
        $i stop
    fi
    chkconfig -d $1
}

function get_ext_bridge_name () {
    local id
    eval `neutron net-show -f shell -F id ext`
    echo "brq"${id:0:11}
}


function get_ext_bridge_ip () {
    local gateway_ip
    eval `neutron subnet-show -f shell -F gateway_ip ext`
    echo $gateway_ip
}

function get_ext_bridge_ip_prefix () {
    local cidr
    eval `neutron subnet-show -f shell -F cidr ext`
    echo $cidr | cut -f2 -d/
}

function get_ext_bridge_cidr () {
    local cidr
    eval `neutron subnet-show -f shell -F cidr ext`
    echo $cidr
}

function setup_ext_bridge_on_boot () {
    cat >/etc/sysconfig/network/ifcfg-$1 <<EOF
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_STP='off'
IPADDR='$2'
STARTMODE='onboot'
USERCONTROL='no'
POST_UP_SCRIPT='openstack-quickstart-neutron-$1'
EOF
    cat >/etc/sysconfig/network/scripts/openstack-quickstart-neutron-$1<<EOF
iptables -t nat -A POSTROUTING -s $3 -o $br -j MASQUERADE
EOF
    chmod 755 /etc/sysconfig/network/scripts/openstack-quickstart-neutron-$1
}

# iproute2 on 12.3 is broken, bnc#816215
function update_iproute2_on_opensuse_12_3 () {
     if grep -q 'openSUSE 12.3' /etc/SuSE-release; then
          OUT=`zypper lr -u | grep 'http://download.opensuse.org/update/12.3/'`
          echo $OUT | grep -q 'http://download.opensuse.org/update/12.3/'
          if [[ $? -ne 0 ]] ; then
               echo "Adding update repository"
               zypper ar http://download.opensuse.org/update/12.3/ update12.3
               # TODO: add netfilter repo until update iproute2 will not appear in update repo
               zypper ar http://download.opensuse.org/repositories/security:/netfilter/openSUSE_12.3/ netfilter12.3
          fi
          echo "Updating iproute2 package"
          zypper --gpg-auto-import-keys ref
          zypper --gpg-auto-import-keys install -f -y iproute2
     fi
}



update_iproute2_on_opensuse_12_3

grep -q bash.openstackrc /etc/bash.bashrc.local ||\
echo "export HOST_IP=$IP
. /etc/bash.openstackrc
setcreds admin $pw" >> /etc/bash.bashrc.local

install_packages patterns-OpenStack-controller patterns-OpenStack-compute-node patterns-OpenStack-clients patterns-OpenStack-network-node crudini psmisc

if [ "x$with_tempest" = "xyes" ]; then
    install_packages openstack-nova-objectstore openstack-neutron-lbaas-agent
fi

if [ "$DB" = "postgresql" ] ; then
    if grep -q "SUSE Linux Enterprise Server 11" /etc/SuSE-release; then
        install_packages postgresql91-server python-psycopg2
    else
        install_packages postgresql-server python-psycopg2
    fi
fi

# configure NTP, because we need synchronized time between nodes
grep -q ntp.org /etc/ntp.conf || echo server pool.ntp.org >> /etc/ntp.conf

# change libvirt to run qemu as user qemu
sed -i -e 's;.*user.*=.*;user = "qemu";' /etc/libvirt/qemu.conf
if [ -e /dev/kvm ]; then
    chown root:kvm /dev/kvm
    chmod 660 /dev/kvm
fi

# configure tgt for cinder
if [ -f /etc/tgt/targets.conf ]; then
    grep -q "include /var/lib/cinder/volumes" /etc/tgt/targets.conf || {
        echo "include /var/lib/cinder/volumes/*" >> /etc/tgt/targets.conf
        start_and_enable_service tgtd
    }
fi

# Set up the database
if [ "$DB" = "postgresql" ] ; then
    DATADIR=/var/lib/pgsql/data
    # No database exists? Start and Stop to create the initial files
    if  [ ! -f $DATADIR/PG_VERSION ]; then
        start_and_enable_service $DB
        stop_and_disable_service $DB
    fi
    if ! grep -q ::/0 $DATADIR/pg_hba.conf ; then
        sed -i "s/^\(host .*\) ident\(.*\)/\1 md5 \2/" "$DATADIR/pg_hba.conf"
        sed -i "s/^\(local \)/local horizon all md5 sameuser\n\1/" "$DATADIR/pg_hba.conf"
        # allow remote connections:
        echo "listen_addresses = '*'" >> $DATADIR/postgresql.conf
        echo "host all all 0.0.0.0/0 md5  sameuser" >> $DATADIR/pg_hba.conf
        echo "host all all      ::/0 md5  sameuser" >> $DATADIR/pg_hba.conf
        if ! rpm -q postgresql | grep -q postgresql-8 ; then
            sed -i 's/\s*sameuser$//' $DATADIR/pg_hba.conf # adapt config syntax to postgresql-9
        fi
    fi
else
    echo | mysql -u root || pwquery=-p
    for DBNAME in nova cinder keystone glance horizon neutron ; do
        echo "
        set global character_set_server=latin1;
        set session character_set_server=latin1;
        CREATE DATABASE IF NOT EXISTS $DBNAME;
        GRANT ALL PRIVILEGES ON $DBNAME.* TO '$DBNAME'@localhost IDENTIFIED BY '$mpw';
        GRANT ALL PRIVILEGES ON $DBNAME.* TO '$DBNAME'@'%' IDENTIFIED BY '$mpw';
        " | mysql -u root $pwquery
    done
fi


# start some initial services
for s in ntp libvirtd $DB tgtd memcached
do
    start_and_enable_service $s
done

start_and_enable_service open-iscsi || :


# Set up the database
if [ "$DB" = "postgresql" ] ; then
    sudo -u postgres dropdb keystone || true # needed for keystone_data.sh
    for DBNAME in nova cinder keystone glance horizon heat neutron ; do
        # use ALTER if CREATE fails: the role probably already exists
        # in that case
        sudo -u postgres psql -c "CREATE ROLE $DBNAME PASSWORD '$mpw' LOGIN;" || \
        sudo -u postgres psql -c "ALTER ROLE $DBNAME PASSWORD '$mpw' LOGIN;"
        sudo -u postgres createdb -O $DBNAME $DBNAME || true
    done
    sudo -u postgres createuser -s root || :
fi

grep -q -e vmx -e svm /proc/cpuinfo || MODE=lxc

# use lxc or qemu, if kvm is unavailable
if rpm -q openstack-nova-compute >/dev/null ; then
    if [ "$MODE" = lxc ] ; then
        crudini --set /etc/nova/nova.conf DEFAULT libvirt_type lxc
        install_packages lxc
        # not sure what this is good for, cgroups is and should be mounted under /sys/fs/cgroup
        #echo mount -t cgroup none /cgroup >> /etc/init.d/boot.local
        #mkdir /cgroup
        #mount -t cgroup none /cgroup
    else
        modprobe kvm-intel ; modprobe kvm-amd
        sed -i -e 's/\(MODULES_LOADED_ON_BOOT="\)/\1kvm-intel kvm-amd\ /' /etc/sysconfig/kernel
    fi
    modprobe nbd
    sed -i -e 's/\(MODULES_LOADED_ON_BOOT="\)/\1nbd\ /' /etc/sysconfig/kernel
fi

# disable firewall before playing with ip_forward stuff

rm -f /var/lock/SuSEfirewall2.booting # workaround openSUSE bug
if test -e /sbin/SuSEfirewall2; then
    SuSEfirewall2 stop        # interferes with openstack's network/firewall
    stop_and_disable_service SuSEfirewall2_setup
    stop_and_disable_service SuSEfirewall2_init
fi

# activate ip-forwarding
[ -e /etc/sysconfig/sysctl ] && sed -i -e 's;IP_FORWARD="no";IP_FORWARD="yes";' /etc/sysconfig/sysctl

if grep -q 'net.ipv4.ip_forward' /etc/sysctl.conf; then
     sed -i -e 's;net.ipv4.ip_forward.*;net.ipv4.ip_forward = 1;' /etc/sysctl.conf
else
     #sysctl file may not have ending new line
     echo  >> /etc/sysctl.conf
     echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
fi
echo 1 > /proc/sys/net/ipv4/ip_forward

set -e

# configure bridge
if [ ! -e /etc/sysconfig/network/ifcfg-$br ] ; then
    echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf
    /etc/init.d/network stop
    ifdown eth0 # because systemd ignores the above
    sed -i -e "s/\(BOOTPROTO\).*/\1='static'/"     \
           -e "s|^\(IPADDR\).*|\1='0.0.0.0\\/32'|" /etc/sysconfig/network/ifcfg-eth0
    cat >/etc/sysconfig/network/scripts/openstack-quickstart-neutron-$br<<EOF
ip link add name vefr type veth peer name vefq
ip link set vefr up
ip link set vefq up
brctl addif $br vefr
EOF
chmod 755 /etc/sysconfig/network/scripts/openstack-quickstart-neutron-$br
    cat >/etc/sysconfig/network/ifcfg-$br <<EOF
BOOTPROTO='dhcp4'
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth0'
BRIDGE_STP='off'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR=''
MTU=''
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='onboot'
USERCONTROL='no'
POST_UP_SCRIPT='openstack-quickstart-neutron-$br'
EOF
    /etc/init.d/network start
fi

#-----------------------------------------
# setup OpenStack Dashboard (optional)
#-----------------------------------------


if [ "x$with_horizon" = "xyes" ]; then
    # configure dashboard/apache sample configuration from the package:
    install -m 644 /etc/apache2/conf.d/openstack-dashboard.conf{.sample,}
    a2enmod rewrite
    a2enmod ssl
    a2enmod wsgi
    a2enmod socache_shmcb
    a2enflag SSL

    DASHBOARD_LOCAL_SET=/srv/www/openstack-dashboard/openstack_dashboard/local/local_settings.py
    if grep -q "^\s*CACHE_BACKEND" $DASHBOARD_LOCAL_SET ; then
        sed -i "s|^\s*CACHE_BACKEND.*$|CACHE_BACKEND = 'memcached://127.0.0.1:11211/'|" $DASHBOARD_LOCAL_SET
    else
        echo "CACHE_BACKEND = 'memcached://127.0.0.1:11211/'" >> $DASHBOARD_LOCAL_SET
    fi

    if [ "$DB" = "postgresql" ] ; then
    cat >> $DASHBOARD_LOCAL_SET <<EODASHDB
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'HOST': '$IP',
        'NAME': 'horizon',
        'USER': 'horizon',
        'PASSWORD': '$mpw',
    }
}
EODASHDB
    fi

    if grep -q "^USE_SSL =" $DASHBOARD_LOCAL_SET; then
        sed -i -e "s/^USE_SSL =.*/USE_SSL = True/" $DASHBOARD_LOCAL_SET
    else
        echo "USE_SSL = True" >> $DASHBOARD_LOCAL_SET
    fi
    # Use 'secure' session and CSRF cookies (bnc#753582):
    cat >> $DASHBOARD_LOCAL_SET <<EOSEC
# Use 'secure' cookies when we use SSL, see https://docs.djangoproject.com/en/1.4/topics/security/:
SESSION_COOKIE_SECURE = CSRF_COOKIE_SECURE = USE_SSL
EOSEC
    # sync dashboard DB "after" the database is created
    run_as wwwrun "cd /srv/www/openstack-dashboard; umask 0027; python -m 'manage' syncdb --noinput"
fi

KEYSTONE_AUTH_HOST=${KEYSTONE_AUTH_HOST:-$SERVICE_HOST}
KEYSTONE_AUTH_PORT=${KEYSTONE_AUTH_PORT:-35357}
KEYSTONE_SERVICE_PORT=${KEYSTONE_AUTH_PORT:-5000}
KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-http}
KEYSTONE_PUBLIC_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_SERVICE_PORT/v2.0
KEYSTONE_PUBLIC_ENDPOINT_V3=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_SERVICE_PORT/v3

#-----------------------------------------
# setup keystone client endpoint configuration
#-----------------------------------------

for c in /etc/glance/glance-api.conf /etc/glance/glance-registry.conf \
    /etc/neutron/neutron.conf /etc/cinder/cinder.conf \
    /etc/heat/heat.conf /etc/nova/nova.conf ; do
    crudini --set $c keystone_authtoken auth_host $IP
    crudini --set $c keystone_authtoken auth_port 35357
    crudini --set $c keystone_authtoken auth_protocol http
    crudini --set $c keystone_authtoken auth_uri $KEYSTONE_PUBLIC_ENDPOINT
    crudini --set $c keystone_authtoken admin_tenant_name service
    crudini --set $c keystone_authtoken admin_user '%SERVICE_USER%'
    crudini --set $c keystone_authtoken admin_password '%SERVICE_PASSWORD%'
done

#-----------------------------------------
## setup glance configuration
#-----------------------------------------

sed -i "s%sql_connection =.*%sql_connection = $DB://glance:$mpw@$IP/glance%" /etc/glance/glance-registry.conf /etc/glance/glance-api.conf # db_sync is broken for postgresql

#-----------------------------------------
## setup nova configuration
#-----------------------------------------

crudini --set /etc/nova/nova.conf database connection "$DB://nova:$mpw@$IP/nova"
crudini --set /etc/nova/nova.conf DEFAULT glance_api_servers "$IP:9292"
crudini --set /etc/nova/nova.conf DEFAULT novncproxy_base_url "http://$IP:6080/vnc_auto.html"
crudini --set /etc/nova/nova.conf DEFAULT allow_resize_to_same_host True
crudini --set /etc/nova/nova.conf DEFAULT default_floating_pool ext
crudini --set /etc/nova/nova.conf DEFAULT my_ip "$IP"
metadata_secret=$(uuidgen)
crudini --set /etc/nova/nova.conf DEFAULT neutron_metadata_proxy_shared_secret $metadata_secret

extensions_path=$(ls -d /usr/lib*/python*/site-packages/extensions 2> /dev/null | head -n 1)
if [ -n "$extensions_path" ]; then
    crudini --set /etc/nova/nova.conf DEFAULT osapi_extensions_path "$extensions_path"
fi

# configure cinder
crudini --set /etc/cinder/cinder.conf DEFAULT my_ip "$IP"
crudini --set /etc/cinder/cinder.conf database connection "$DB://cinder:${mpw}@${IP}/cinder"

for m in cinder heat nova glance neutron ; do
    sed -i -e 's/%SERVICE_TENANT_NAME%/service/' \
           -e "s/%SERVICE_USER%/$m/" \
           -e "s/%SERVICE_PASSWORD%/$ADMIN_PASSWORD/" \
               /etc/$m/*.ini /etc/$m/$m*.conf
done


# keystone demo setup, based on devstack.sh

sed -i -e 's/kvs/sql/' -e "s,^.*connection =.*,connection = $DB://keystone:$mpw@$IP/keystone," /etc/keystone/keystone.conf
rm -f /var/lib/keystone/keystone.sqlite # cleanup DB as devstack's script fails otherwise

crudini --set /etc/keystone/keystone.conf DEFAULT admin_token "$SERVICE_TOKEN"

/etc/init.d/openstack-keystone restart
keystone_data=/usr/lib/devstack/keystone_data.sh
ENABLED_SERVICES="g-api,g-reg,key,n-api,n-cpu,n-net,n-vol,c-api,n-sch,n-novnc,n-xvnc,q-svc,heat,mysql,rabbit"
if [ "x$with_horizon" = "xyes" ]; then
    ENABLED_SERVICES+=",horizon"
fi
if [ "x$with_tempest" = "xyes" ]; then
    ENABLED_SERVICES+=",tempest"
fi
SERVICE_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0

ADMIN_PASSWORD=$ADMIN_PASSWORD KEYSTONE_CATALOG_BACKEND=sql SERVICE_HOST=$SERVICE_HOST \
    SERVICE_TOKEN=$SERVICE_TOKEN SERVICE_ENDPOINT=$SERVICE_ENDPOINT DEVSTACK_DIR=/root \
    ENABLED_SERVICES=$ENABLED_SERVICES bash $keystone_data

. /etc/bash.bashrc.local

if which aa-complain >&/dev/null; then
    aa-complain /etc/apparmor.d/usr.sbin.libvirtd
fi
if [ -e /etc/init.d/boot.apparmor ]; then
    stop_and_disable_service boot.apparmor
fi
if [ -e /etc/init.d/dnsmasq ]; then
    stop_and_disable_service dnsmasq
fi

#-----------------------------------------
## setup neutron configuration
#-----------------------------------------

crudini --set /etc/neutron/neutron.conf database connection $DB://neutron:$mpw@$IP/neutron

crudini --set /etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini linux_bridge physical_interface_mappings root-bridge:vefq,physnet1:eth0
crudini --set /etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini securitygroup firewall_driver neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
# crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vlan
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_vlan network_vlan_ranges root-bridge,physnet1
crudini --set /etc/neutron/dhcp_agent.ini DEFAULT use_namespaces true
crudini --set /etc/neutron/l3_agent.ini DEFAULT use_namespaces true
crudini --set /etc/neutron/neutron.conf DEFAULT allow_overlapping_ips true
crudini --set /etc/neutron/metadata_agent.ini DEFAULT metadata_proxy_shared_secret $metadata_secret

if [ "x$with_tempest" = "xyes" ]; then
    crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins "neutron.services.loadbalancer.plugin.LoadBalancerPlugin, neutron.services.l3_router.l3_router_plugin.L3RouterPlugin, neutron.services.vpn.plugin.VPNDriverPlugin"
fi

start_and_enable_service rabbitmq-server

# Start Keystone and Neutron
for s in openstack-keystone \
    openstack-neutron openstack-neutron-linuxbridge-agent openstack-neutron-dhcp-agent \
    openstack-neutron-l3-agent openstack-neutron-metadata-agent
do
    start_and_enable_service $s
done

if [ "x$with_tempest" = "xyes" ]; then
    start_and_enable_service openstack-neutron-lbaas-agent
    crudini --set /etc/neutron/lbaas_agent.ini DEFAULT interface_driver neutron.agent.linux.interface.BridgeInterfaceDriver

fi

### wait until neutron will start
cnt=0
while : ; do
	if [[ $cnt -gt 6 ]] ; then
		echo "Can't reach neutron server. Exiting !!!" >&2
		exit 1
	fi
        neutron net-list
        if [[ $? -eq 0 ]] ; then
                break
        fi
	cnt=$(($cnt+1))
        sleep 2
done
### create subnets
## fixed
SERVICE_TENANT_ID=`get_service_tenant_id`
neutron net-create fixed --tenant-id $SERVICE_TENANT_ID --shared --provider:network_type flat --provider:physical_network root-bridge
neutron subnet-create --name fixed --dns-nameserver 8.8.8.8 --dns-nameserver 8.8.4.4 fixed $testnet
neutron router-create --tenant-id $SERVICE_TENANT_ID public
neutron router-interface-add public fixed

## floating/external
neutron net-create ext --tenant-id $SERVICE_TENANT_ID --provider:network_type local --router:external True

ext_network_id=$(neutron net-list | grep ' ext '  | cut -d' ' -f2)
neutron subnet-create --name ext --disable-dhcp --tenant-id $SERVICE_TENANT_ID ext $floatingnet
neutron router-gateway-set public ext
# create four floatingip pools
for i in 1 2 3 4; do
neutron floatingip-create ext
done
### create routing configuration for external bridge
ext_bridge_name=`get_ext_bridge_name`
ext_bridge_ip=`get_ext_bridge_ip`/`get_ext_bridge_ip_prefix`
ext_bridge_cidr=`get_ext_bridge_cidr`
setup_ext_bridge_on_boot $ext_bridge_name $ext_bridge_ip $ext_bridge_cidr
ifup $ext_bridge_name
#-----------------------------------------
## end neutron setup configuration
#---------------------------------------

# Start glance and nova
for s in openstack-glance-api openstack-glance-registry \
    openstack-nova-api openstack-nova-conductor openstack-nova-scheduler openstack-nova-compute openstack-novncproxy \
    openstack-nova-consoleauth
do
    start_and_enable_service $s
done

if [ "x$with_tempest" = "xyes" ]; then
    start_and_enable_service openstack-nova-objectstore
fi

#-----------------------------------------
## setup heat configuration
#-----------------------------------------

crudini --set /etc/heat/heat.conf DEFAULT sql_connection $DB://heat:$mpw@$IP/heat

for s in openstack-heat-engine openstack-heat-api-cfn openstack-heat-api; do
    start_and_enable_service $s
done

#-----------------------------------------
## setup loopback LVM configuration
#-----------------------------------------


openstack_loopback_lvm=/usr/sbin/openstack-loopback-lvm
$openstack_loopback_lvm
if [ "$?" -ne "0" ]; then
    # setup failed, so do not use
    for s in api scheduler volume ; do
        insserv -r openstack-cinder-$s
    done
else
    grep -q openstack-loopback-lvm /etc/init.d/boot.local || echo $openstack_loopback_lvm >> /etc/init.d/boot.local
    # SLE11 and other old distros need boot.lvm enabled
    if [ -z "$(type -p systemctl)" ]; then
        insserv boot.lvm
        /etc/init.d/boot.lvm start
    fi
    start_and_enable_service openstack-cinder-volume
    start_and_enable_service openstack-cinder-scheduler
    start_and_enable_service openstack-cinder-api
fi

setcreds admin $pw
nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0 # to allow ping
nova secgroup-add-rule default tcp 22 22 0.0.0.0/0 # to allow only SSH or do
nova secgroup-add-rule default tcp 1 65535 0.0.0.0/0 # to allow all TCP
nova secgroup-add-rule default udp 1 65535 0.0.0.0/0 # and all UDP
nova secgroup-list-rules default # lists the rules


#-----------------------------------------
# setup tempest configuration
#-----------------------------------------

if [ "x$with_tempest" = "xyes" -a -e /etc/tempest/tempest.conf ]; then
    c=/etc/tempest/tempest.conf
    crudini --set $c identity uri $KEYSTONE_PUBLIC_ENDPOINT
    crudini --set $c identity uri_v3 $KEYSTONE_PUBLIC_ENDPOINT_V3
    crudini --set $c identity admin_username admin
    crudini --set $c identity admin_password $pw
    crudini --set $c identity alt_password $pw
    crudini --set $c identity password $pw
    #crudini --set $c compute allow_tenant_isolation true
    crudini --set $c compute allow_tenant_isolation false
    crudini --set $c compute fixed_network_name fixed
    crudini --set $c compute network_for_ssh ext
    # broken in tempest testsuite on havana :/
    crudini --set $c compute run_ssh false
    crudini --set $c compute-admin password $pw
    crudini --set $c network public_network_id $ext_network_id
    crudini --set $c network public_router_id $(get_router_id)
    crudini --set $c service_available neutron True
    crudini --set $c service_available swift False
    crudini --set $c stress max_instances 2
    crudini --set $c service_available horizon $with_horizon
fi
