Pull from nova-cloud-controller-ha-support.
This commit is contained in:
commit
37585336da
10
config.yaml
10
config.yaml
@ -128,3 +128,13 @@ options:
|
||||
description: |
|
||||
Default multicast port number that will be used to communicate between
|
||||
HA Cluster nodes.
|
||||
ssl_cert:
|
||||
type: string
|
||||
description: |
|
||||
SSL certificate to install and use for API ports. Setting this value
|
||||
and ssl_key will enable reverse proxying, point Glance's entry in the
|
||||
Keystone catalog to use https, and override any certficiate and key
|
||||
issued by Keystone (if it is configured to do so).
|
||||
ssl_key:
|
||||
type: string
|
||||
description: SSL key to use with certificate specified as ssl_cert.
|
||||
|
1
hooks/cluster-relation-changed
Symbolic link
1
hooks/cluster-relation-changed
Symbolic link
@ -0,0 +1 @@
|
||||
nova-cloud-controller-relations
|
1
hooks/cluster-relation-departed
Symbolic link
1
hooks/cluster-relation-departed
Symbolic link
@ -0,0 +1 @@
|
||||
nova-cloud-controller-relations
|
1
hooks/ha-relation-changed
Symbolic link
1
hooks/ha-relation-changed
Symbolic link
@ -0,0 +1 @@
|
||||
nova-cloud-controller-relations
|
1
hooks/ha-relation-joined
Symbolic link
1
hooks/ha-relation-joined
Symbolic link
@ -0,0 +1 @@
|
||||
nova-cloud-controller-relations
|
@ -165,8 +165,9 @@ get_os_codename_install_source() {
|
||||
fi
|
||||
|
||||
# have a guess based on the deb string provided
|
||||
if [[ "${rel:0:3}" == "deb" ]]; then
|
||||
CODENAMES="diablo essex folsom grizzly"
|
||||
if [[ "${rel:0:3}" == "deb" ]] || \
|
||||
[[ "${rel:0:3}" == "ppa" ]] ; then
|
||||
CODENAMES="diablo essex folsom grizzly havana"
|
||||
for cname in $CODENAMES; do
|
||||
if echo $rel | grep -q $cname; then
|
||||
codename=$cname
|
||||
@ -178,11 +179,13 @@ get_os_codename_install_source() {
|
||||
|
||||
get_os_codename_package() {
|
||||
local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }') || echo "none"
|
||||
pkg_vers=$(echo $pkg_vers | cut -d: -f2) # epochs
|
||||
case "${pkg_vers:0:6}" in
|
||||
"2011.2") echo "diablo" ;;
|
||||
"2012.1") echo "essex" ;;
|
||||
"2012.2") echo "folsom" ;;
|
||||
"2013.1") echo "grizzly" ;;
|
||||
"2013.2") echo "havana" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -191,7 +194,8 @@ get_os_version_codename() {
|
||||
"diablo") echo "2011.2" ;;
|
||||
"essex") echo "2012.1" ;;
|
||||
"folsom") echo "2012.2" ;;
|
||||
"grizzly") echo "2012.3" ;;
|
||||
"grizzly") echo "2013.1" ;;
|
||||
"havana") echo "2013.2" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -315,57 +319,20 @@ function get_block_device() {
|
||||
return 0
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Creates an rc file exporting environment variables to a
|
||||
# script_path local to the charm's installed directory.
|
||||
# Any charm scripts run outside the juju hook environment can source this
|
||||
# scriptrc to obtain updated config information necessary to perform health
|
||||
# checks or service changes
|
||||
#
|
||||
# Parameters:
|
||||
# An array of '=' delimited ENV_VAR:value combinations to export.
|
||||
# If optional script_path key is not provided in the array, script_path
|
||||
# defaults to scripts/scriptrc
|
||||
##########################################################################
|
||||
function save_script_rc {
|
||||
if [ ! -n "$JUJU_UNIT_NAME" ]; then
|
||||
echo "Error: Missing JUJU_UNIT_NAME environment variable"
|
||||
exit 1
|
||||
fi
|
||||
# our default unit_path
|
||||
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/scripts/scriptrc"
|
||||
echo $unit_path
|
||||
tmp_rc="/tmp/${JUJU_UNIT_NAME/\//-}rc"
|
||||
|
||||
echo "#!/bin/bash" > $tmp_rc
|
||||
for env_var in "${@}"
|
||||
do
|
||||
if `echo $env_var | grep -q script_path`; then
|
||||
# well then we need to reset the new unit-local script path
|
||||
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/${env_var/script_path=/}"
|
||||
else
|
||||
echo "export $env_var" >> $tmp_rc
|
||||
fi
|
||||
done
|
||||
chmod 755 $tmp_rc
|
||||
mv $tmp_rc $unit_path
|
||||
}
|
||||
|
||||
|
||||
HAPROXY_CFG=/etc/haproxy/haproxy.cfg
|
||||
HAPROXY_DEFAULT=/etc/default/haproxy
|
||||
|
||||
##########################################################################
|
||||
# Description: Configures HAProxy services for Openstack API's
|
||||
# Parameters:
|
||||
# Space delimited list of service:port combinations for which
|
||||
# Parameters:
|
||||
# Space delimited list of service:port:mode combinations for which
|
||||
# haproxy service configuration should be generated for. The function
|
||||
# assumes the name of the peer relation is 'cluster' and that every
|
||||
# service unit in the peer relation is running the same services.
|
||||
#
|
||||
# The HAProxy service will listen on port + 10000.
|
||||
# Example:
|
||||
# configure_haproxy cinder_api:12345 nova_api:9999
|
||||
# Services that do not specify :mode in parameter will default to http.
|
||||
#
|
||||
# Example
|
||||
# configure_haproxy cinder_api:8776:8756:tcp nova_api:8774:8764:http
|
||||
##########################################################################
|
||||
configure_haproxy() {
|
||||
local address=`unit-get private-address`
|
||||
@ -387,8 +354,8 @@ defaults
|
||||
retries 3
|
||||
timeout queue 1000
|
||||
timeout connect 1000
|
||||
timeout client 10000
|
||||
timeout server 10000
|
||||
timeout client 30000
|
||||
timeout server 30000
|
||||
|
||||
listen stats :8888
|
||||
mode http
|
||||
@ -401,14 +368,21 @@ listen stats :8888
|
||||
EOF
|
||||
for service in $@; do
|
||||
local service_name=$(echo $service | cut -d : -f 1)
|
||||
local api_listen_port=$(echo $service | cut -d : -f 2)
|
||||
local haproxy_listen_port=$(($api_listen_port + 10000))
|
||||
local haproxy_listen_port=$(echo $service | cut -d : -f 2)
|
||||
local api_listen_port=$(echo $service | cut -d : -f 3)
|
||||
local mode=$(echo $service | cut -d : -f 4)
|
||||
[[ -z "$mode" ]] && mode="http"
|
||||
juju-log "Adding haproxy configuration entry for $service "\
|
||||
"($haproxy_listen_port -> $api_listen_port)"
|
||||
cat >> $HAPROXY_CFG << EOF
|
||||
listen $service_name 0.0.0.0:$haproxy_listen_port
|
||||
balance roundrobin
|
||||
option tcplog
|
||||
mode $mode
|
||||
option ${mode}log
|
||||
server $name $address:$api_listen_port check
|
||||
EOF
|
||||
local r_id=""
|
||||
local unit=""
|
||||
for r_id in `relation-ids cluster`; do
|
||||
for unit in `relation-list -r $r_id`; do
|
||||
local unit_name=${unit////-}
|
||||
@ -421,6 +395,7 @@ EOF
|
||||
done
|
||||
done
|
||||
echo "ENABLED=1" > $HAPROXY_DEFAULT
|
||||
service haproxy restart
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
@ -428,18 +403,20 @@ EOF
|
||||
# Returns: 0 if configured, 1 if not configured
|
||||
##########################################################################
|
||||
is_clustered() {
|
||||
local r_id=""
|
||||
local unit=""
|
||||
for r_id in $(relation-ids ha); do
|
||||
if [ -n "$r_id" ]; then
|
||||
for unit in $(relation-list -r $r_id); do
|
||||
clustered=$(relation-get -r $r_id clustered $unit)
|
||||
if [ -n "$clustered" ]; then
|
||||
echo "Unit is clustered"
|
||||
juju-log "Unit is haclustered"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo "Unit is not clustered"
|
||||
juju-log "Unit is not haclustered"
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -448,6 +425,7 @@ is_clustered() {
|
||||
##########################################################################
|
||||
peer_units() {
|
||||
local peers=""
|
||||
local r_id=""
|
||||
for r_id in $(relation-ids cluster); do
|
||||
peers="$peers $(relation-list -r $r_id)"
|
||||
done
|
||||
@ -466,11 +444,11 @@ oldest_peer() {
|
||||
echo "Comparing $JUJU_UNIT_NAME with peers: $peers"
|
||||
local r_unit_no=$(echo $peer | cut -d / -f 2)
|
||||
if (($r_unit_no<$l_unit_no)); then
|
||||
echo "Not oldest peer; deferring"
|
||||
juju-log "Not oldest peer; deferring"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
echo "Oldest peer; might take charge?"
|
||||
juju-log "Oldest peer; might take charge?"
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -484,13 +462,13 @@ oldest_peer() {
|
||||
eligible_leader() {
|
||||
if is_clustered; then
|
||||
if ! is_leader $1; then
|
||||
echo 'Deferring action to CRM leader'
|
||||
juju-log 'Deferring action to CRM leader'
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
peers=$(peer_units)
|
||||
if [ -n "$peers" ] && ! oldest_peer "$peers"; then
|
||||
echo 'Deferring action to oldest service unit.'
|
||||
juju-log 'Deferring action to oldest service unit.'
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
@ -502,14 +480,14 @@ eligible_leader() {
|
||||
# Returns: 0 if peered, 1 if not peered
|
||||
##########################################################################
|
||||
is_peered() {
|
||||
r_id=$(relation-ids cluster)
|
||||
local r_id=$(relation-ids cluster)
|
||||
if [ -n "$r_id" ]; then
|
||||
if [ -n "$(relation-list -r $r_id)" ]; then
|
||||
echo "Unit peered"
|
||||
juju-log "Unit peered"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
echo "Unit not peered"
|
||||
juju-log "Unit not peered"
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -522,14 +500,209 @@ is_leader() {
|
||||
hostname=`hostname`
|
||||
if [ -x /usr/sbin/crm ]; then
|
||||
if crm resource show $1 | grep -q $hostname; then
|
||||
echo "$hostname is cluster leader"
|
||||
juju-log "$hostname is cluster leader."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
echo "$hostname is not cluster leader"
|
||||
juju-log "$hostname is not cluster leader."
|
||||
return 1
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Determines whether enough data has been provided in
|
||||
# configuration or relation data to configure HTTPS.
|
||||
# Parameters: None
|
||||
# Returns: 0 if HTTPS can be configured, 1 if not.
|
||||
##########################################################################
|
||||
https() {
|
||||
local r_id=""
|
||||
if [[ -n "$(config-get ssl_cert)" ]] &&
|
||||
[[ -n "$(config-get ssl_key)" ]] ; then
|
||||
return 0
|
||||
fi
|
||||
for r_id in $(relation-ids identity-service) ; do
|
||||
for unit in $(relation-list -r $r_id) ; do
|
||||
if [[ "$(relation-get -r $r_id https_keystone $unit)" == "True" ]] &&
|
||||
[[ -n "$(relation-get -r $r_id ssl_cert $unit)" ]] &&
|
||||
[[ -n "$(relation-get -r $r_id ssl_key $unit)" ]] &&
|
||||
[[ -n "$(relation-get -r $r_id ca_cert $unit)" ]] ; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: For a given number of port mappings, configures apache2
|
||||
# HTTPs local reverse proxying using certficates and keys provided in
|
||||
# either configuration data (preferred) or relation data. Assumes ports
|
||||
# are not in use (calling charm should ensure that).
|
||||
# Parameters: Variable number of proxy port mappings as
|
||||
# $internal:$external.
|
||||
# Returns: 0 if reverse proxy(s) have been configured, 0 if not.
|
||||
##########################################################################
|
||||
enable_https() {
|
||||
local port_maps="$@"
|
||||
local http_restart=""
|
||||
juju-log "Enabling HTTPS for port mappings: $port_maps."
|
||||
|
||||
# allow overriding of keystone provided certs with those set manually
|
||||
# in config.
|
||||
local cert=$(config-get ssl_cert)
|
||||
local key=$(config-get ssl_key)
|
||||
local ca_cert=""
|
||||
if [[ -z "$cert" ]] || [[ -z "$key" ]] ; then
|
||||
juju-log "Inspecting identity-service relations for SSL certificate."
|
||||
local r_id=""
|
||||
cert=""
|
||||
key=""
|
||||
ca_cert=""
|
||||
for r_id in $(relation-ids identity-service) ; do
|
||||
for unit in $(relation-list -r $r_id) ; do
|
||||
[[ -z "$cert" ]] && cert="$(relation-get -r $r_id ssl_cert $unit)"
|
||||
[[ -z "$key" ]] && key="$(relation-get -r $r_id ssl_key $unit)"
|
||||
[[ -z "$ca_cert" ]] && ca_cert="$(relation-get -r $r_id ca_cert $unit)"
|
||||
done
|
||||
done
|
||||
[[ -n "$cert" ]] && cert=$(echo $cert | base64 -di)
|
||||
[[ -n "$key" ]] && key=$(echo $key | base64 -di)
|
||||
[[ -n "$ca_cert" ]] && ca_cert=$(echo $ca_cert | base64 -di)
|
||||
else
|
||||
juju-log "Using SSL certificate provided in service config."
|
||||
fi
|
||||
|
||||
[[ -z "$cert" ]] || [[ -z "$key" ]] &&
|
||||
juju-log "Expected but could not find SSL certificate data, not "\
|
||||
"configuring HTTPS!" && return 1
|
||||
|
||||
apt-get -y install apache2
|
||||
a2enmod ssl proxy proxy_http | grep -v "To activate the new configuration" &&
|
||||
http_restart=1
|
||||
|
||||
mkdir -p /etc/apache2/ssl/$CHARM
|
||||
echo "$cert" >/etc/apache2/ssl/$CHARM/cert
|
||||
echo "$key" >/etc/apache2/ssl/$CHARM/key
|
||||
if [[ -n "$ca_cert" ]] ; then
|
||||
juju-log "Installing Keystone supplied CA cert."
|
||||
echo "$ca_cert" >/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
|
||||
update-ca-certificates --fresh
|
||||
|
||||
# XXX TODO: Find a better way of exporting this?
|
||||
if [[ "$CHARM" == "nova-cloud-controller" ]] ; then
|
||||
[[ -e /var/www/keystone_juju_ca_cert.crt ]] &&
|
||||
rm -rf /var/www/keystone_juju_ca_cert.crt
|
||||
ln -s /usr/local/share/ca-certificates/keystone_juju_ca_cert.crt \
|
||||
/var/www/keystone_juju_ca_cert.crt
|
||||
fi
|
||||
|
||||
fi
|
||||
for port_map in $port_maps ; do
|
||||
local ext_port=$(echo $port_map | cut -d: -f1)
|
||||
local int_port=$(echo $port_map | cut -d: -f2)
|
||||
juju-log "Creating apache2 reverse proxy vhost for $port_map."
|
||||
cat >/etc/apache2/sites-available/${CHARM}_${ext_port} <<END
|
||||
Listen $ext_port
|
||||
NameVirtualHost *:$ext_port
|
||||
<VirtualHost *:$ext_port>
|
||||
ServerName $(unit-get private-address)
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/apache2/ssl/$CHARM/cert
|
||||
SSLCertificateKeyFile /etc/apache2/ssl/$CHARM/key
|
||||
ProxyPass / http://localhost:$int_port/
|
||||
ProxyPassReverse / http://localhost:$int_port/
|
||||
ProxyPreserveHost on
|
||||
</VirtualHost>
|
||||
<Proxy *>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Proxy>
|
||||
<Location />
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Location>
|
||||
END
|
||||
a2ensite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
|
||||
http_restart=1
|
||||
done
|
||||
if [[ -n "$http_restart" ]] ; then
|
||||
service apache2 restart
|
||||
fi
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Ensure HTTPS reverse proxying is disabled for given port
|
||||
# mappings.
|
||||
# Parameters: Variable number of proxy port mappings as
|
||||
# $internal:$external.
|
||||
# Returns: 0 if reverse proxy is not active for all portmaps, 1 on error.
|
||||
##########################################################################
|
||||
disable_https() {
|
||||
local port_maps="$@"
|
||||
local http_restart=""
|
||||
juju-log "Ensuring HTTPS disabled for $port_maps."
|
||||
( [[ ! -d /etc/apache2 ]] || [[ ! -d /etc/apache2/ssl/$CHARM ]] ) && return 0
|
||||
for port_map in $port_maps ; do
|
||||
local ext_port=$(echo $port_map | cut -d: -f1)
|
||||
local int_port=$(echo $port_map | cut -d: -f2)
|
||||
if [[ -e /etc/apache2/sites-available/${CHARM}_${ext_port} ]] ; then
|
||||
juju-log "Disabling HTTPS reverse proxy for $CHARM $port_map."
|
||||
a2dissite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
|
||||
http_restart=1
|
||||
fi
|
||||
done
|
||||
if [[ -n "$http_restart" ]] ; then
|
||||
service apache2 restart
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Description: Ensures HTTPS is either enabled or disabled for given port
|
||||
# mapping.
|
||||
# Parameters: Variable number of proxy port mappings as
|
||||
# $internal:$external.
|
||||
# Returns: 0 if HTTPS reverse proxy is in place, 1 if it is not.
|
||||
##########################################################################
|
||||
setup_https() {
|
||||
# configure https via apache reverse proxying either
|
||||
# using certs provided by config or keystone.
|
||||
[[ -z "$CHARM" ]] &&
|
||||
error_out "setup_https(): CHARM not set."
|
||||
if ! https ; then
|
||||
disable_https $@
|
||||
else
|
||||
enable_https $@
|
||||
fi
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Determine correct API server listening port based on
|
||||
# existence of HTTPS reverse proxy and/or haproxy.
|
||||
# Paremeters: The standard public port for given service.
|
||||
# Returns: The correct listening port for API service.
|
||||
##########################################################################
|
||||
determine_api_port() {
|
||||
local public_port="$1"
|
||||
local i=0
|
||||
( [[ -n "$(peer_units)" ]] || is_clustered >/dev/null 2>&1 ) && i=$[$i + 1]
|
||||
https >/dev/null 2>&1 && i=$[$i + 1]
|
||||
echo $[$public_port - $[$i * 10]]
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Determine correct proxy listening port based on public IP +
|
||||
# existence of HTTPS reverse proxy.
|
||||
# Paremeters: The standard public port for given service.
|
||||
# Returns: The correct listening port for haproxy service public address.
|
||||
##########################################################################
|
||||
determine_haproxy_port() {
|
||||
local public_port="$1"
|
||||
local i=0
|
||||
https >/dev/null 2>&1 && i=$[$i + 1]
|
||||
echo $[$public_port - $[$i * 10]]
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Print the value for a given config option in an OpenStack
|
||||
# .ini style configuration file.
|
||||
@ -558,3 +731,39 @@ if value.startswith('%'): exit(0)
|
||||
print value
|
||||
"
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Creates an rc file exporting environment variables to a
|
||||
# script_path local to the charm's installed directory.
|
||||
# Any charm scripts run outside the juju hook environment can source this
|
||||
# scriptrc to obtain updated config information necessary to perform health
|
||||
# checks or service changes
|
||||
#
|
||||
# Parameters:
|
||||
# An array of '=' delimited ENV_VAR:value combinations to export.
|
||||
# If optional script_path key is not provided in the array, script_path
|
||||
# defaults to scripts/scriptrc
|
||||
##########################################################################
|
||||
function save_script_rc {
|
||||
if [ ! -n "$JUJU_UNIT_NAME" ]; then
|
||||
echo "Error: Missing JUJU_UNIT_NAME environment variable"
|
||||
exit 1
|
||||
fi
|
||||
# our default unit_path
|
||||
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/scripts/scriptrc"
|
||||
echo $unit_path
|
||||
tmp_rc="/tmp/${JUJU_UNIT_NAME/\//-}rc"
|
||||
|
||||
echo "#!/bin/bash" > $tmp_rc
|
||||
for env_var in "${@}"
|
||||
do
|
||||
if `echo $env_var | grep -q script_path`; then
|
||||
# well then we need to reset the new unit-local script path
|
||||
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/${env_var/script_path=/}"
|
||||
else
|
||||
echo "export $env_var" >> $tmp_rc
|
||||
fi
|
||||
done
|
||||
chmod 755 $tmp_rc
|
||||
mv $tmp_rc $unit_path
|
||||
}
|
||||
|
@ -95,17 +95,19 @@ function determine_quantum_config {
|
||||
function configure_quantum_networking {
|
||||
determine_quantum_config
|
||||
if [ "$(config-get conf-ext-net)" != "no" ] &&
|
||||
[ "$QUANTUM_PLUGIN" == "ovs" ] &&
|
||||
[ -f /etc/quantum/novarc ] &&
|
||||
[ -n "$(relation-ids amqp)" ] &&
|
||||
[ -n "$(relation-ids shared-db)" ]; then
|
||||
juju-log "Configuring external networking for quantum"
|
||||
# Use helper to create external network gateway
|
||||
# and router using generated credentials
|
||||
. /etc/quantum/novarc
|
||||
quantum-ext-net -g $(config-get ext-net-gateway) \
|
||||
-c $(config-get ext-net-cidr) \
|
||||
-f $(config-get pool-floating-start):$(config-get pool-floating-end) \
|
||||
$(config-get ext-net-name)
|
||||
if eligible_leader "res_nova_vip"; then
|
||||
# Use helper to create external network gateway
|
||||
# and router using generated credentials
|
||||
. /etc/quantum/novarc
|
||||
quantum-ext-net -g $(config-get ext-net-gateway) \
|
||||
-c $(config-get ext-net-cidr) \
|
||||
-f $(config-get pool-floating-start):$(config-get pool-floating-end) \
|
||||
$(config-get ext-net-name)
|
||||
fi
|
||||
set_or_update "default_floating_pool" "$(config-get ext-net-name)"
|
||||
fi
|
||||
}
|
||||
@ -219,3 +221,73 @@ function ssh_compute {
|
||||
known_hosts="$(base64 /etc/nova/compute_ssh/$sunit/known_hosts)" \
|
||||
authorized_keys="$(base64 /etc/nova/compute_ssh/$sunit/authorized_keys)"
|
||||
}
|
||||
|
||||
configure_https() {
|
||||
# setup https termination for all api services, depending on what is running
|
||||
# and topology of current deployment.
|
||||
local clustered=""
|
||||
( [[ -n "$(peer_units)" ]] || is_clustered ) && clustered="1"
|
||||
local services=""
|
||||
local ssl_port_maps=""
|
||||
local haproxy_port_maps=""
|
||||
local next_server=""
|
||||
local api_port=""
|
||||
|
||||
# upstartService:defaultPort:configOption
|
||||
local svcs="nova-api-ec2:8773:ec2_listen_port
|
||||
nova-api-os-compute:8774:osapi_compute_listen_port
|
||||
nova-objectstore:3333:s3_listen_port"
|
||||
[[ "$NET_MANAGER" == "Quantum" ]] &&
|
||||
svcs="$svcs quantum-server:9696:bind_port"
|
||||
|
||||
for s in $svcs ; do
|
||||
local service=$(echo $s | cut -d: -f1)
|
||||
local port=$(echo $s | cut -d: -f2)
|
||||
local opt=$(echo $s | cut -d: -f3)
|
||||
if [[ -n "$clustered" ]] ; then
|
||||
next_server="$(determine_haproxy_port $port)"
|
||||
api_port="$(determine_api_port $port)"
|
||||
haproxy_port_maps="$haproxy_port_maps $service:$next_server:$api_port"
|
||||
else
|
||||
api_port="$(determine_api_port $port)"
|
||||
next_server="$api_port"
|
||||
fi
|
||||
if [[ "$service" == "quantum-server" ]] ; then
|
||||
set_or_update "$opt" "$api_port" "$QUANTUM_CONF"
|
||||
else
|
||||
set_or_update "$opt" "$api_port"
|
||||
fi
|
||||
ssl_port_maps="$ssl_port_maps $port:$next_server"
|
||||
done
|
||||
|
||||
# make sure all backend api servers are bound to new backend port
|
||||
# before setting up any frontends.
|
||||
for s in $svcs ; do
|
||||
local service=$(echo $s | cut -d: -f1)
|
||||
service_ctl $service restart
|
||||
done
|
||||
|
||||
[[ -n "$haproxy_port_maps" ]] && configure_haproxy $haproxy_port_maps
|
||||
setup_https $ssl_port_maps
|
||||
|
||||
# another restart to ensure api servers are now bound to frontend ports
|
||||
# that may have just been disabled.
|
||||
for s in $svcs ; do
|
||||
local service=$(echo $s | cut -d: -f1)
|
||||
service_ctl $service restart
|
||||
done
|
||||
|
||||
local r_id=""
|
||||
# (re)configure ks endpoint accordingly
|
||||
for r_id in $(relation-ids identity-service) ; do
|
||||
keystone_joined "$r_id"
|
||||
done
|
||||
# pass on possibly updated quantum URL + ca_cert to compute nodes.
|
||||
for r_id in $(relation-ids cloud-compute) ; do
|
||||
compute_joined "$r_id"
|
||||
done
|
||||
# update the quantum relation, as well.
|
||||
for r_id in $(relation-ids quantum-network-service) ; do
|
||||
quantum_joined "$r_id"
|
||||
done
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ function install_hook {
|
||||
cp files/create_tenant_net.py /usr/bin/quantum-tenant-net
|
||||
|
||||
service_ctl all stop
|
||||
configure_https
|
||||
}
|
||||
|
||||
function upgrade_charm {
|
||||
@ -69,9 +70,7 @@ function config_changed {
|
||||
|
||||
set_config_flags
|
||||
|
||||
if [ "$NET_MANAGER" == "Quantum" ] && \
|
||||
is_clustered && is_leader 'res_nova_vip' || \
|
||||
! is_clustered; then
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
configure_quantum_networking
|
||||
fi
|
||||
|
||||
@ -88,6 +87,7 @@ function config_changed {
|
||||
'OPENSTACK_SERVICE_OBJECTSTORE=nova-objectstore'
|
||||
'OPENSTACK_SERVICE_SCHEDULER=nova-scheduler')
|
||||
save_script_rc ${env_vars[@]}
|
||||
configure_https
|
||||
}
|
||||
|
||||
function amqp_joined {
|
||||
@ -142,6 +142,10 @@ function amqp_changed {
|
||||
fi
|
||||
|
||||
determine_services && service_ctl all restart
|
||||
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
configure_quantum_networking
|
||||
fi
|
||||
}
|
||||
|
||||
function db_joined {
|
||||
@ -159,7 +163,7 @@ function db_joined {
|
||||
}
|
||||
|
||||
function db_changed {
|
||||
local db_host=`relation-get private-address`
|
||||
local db_host=`relation-get db_host`
|
||||
local db_password=`relation-get nova_password`
|
||||
|
||||
if [[ -z $db_host ]] || [[ -z $db_password ]] ; then
|
||||
@ -181,11 +185,15 @@ function db_changed {
|
||||
fi
|
||||
determine_services
|
||||
service_ctl all stop
|
||||
/usr/bin/nova-manage db sync
|
||||
|
||||
eligible_leader 'res_nova_vip' && /usr/bin/nova-manage db sync
|
||||
|
||||
service_ctl all start
|
||||
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
configure_quantum_networking
|
||||
fi
|
||||
|
||||
trigger_remote_service_restarts
|
||||
}
|
||||
|
||||
@ -202,28 +210,37 @@ function keystone_joined {
|
||||
# we need to get two entries into keystone's catalog, nova + ec2
|
||||
# group, them by prepending $service_ to each setting. the keystone
|
||||
# charm will assemble settings into corresponding catalog entries
|
||||
if is_clustered && is_leader 'res_nova_vip'; then
|
||||
address=$(config-get vip)
|
||||
nova_port=18774
|
||||
ec2_port=18773
|
||||
s3_port=13333
|
||||
quantum_port=19696
|
||||
vol_port=18776
|
||||
elif ! is_clustered; then
|
||||
address=$(unit-get private-address)
|
||||
nova_port=8774
|
||||
ec2_port=8773
|
||||
s3_port=3333
|
||||
quantum_port=9696
|
||||
vol_port=8776
|
||||
eligible_leader 'res_nova_vip' || return 0
|
||||
|
||||
is_clustered && local host=$(config-get vip) ||
|
||||
local host=$(unit-get private-address)
|
||||
|
||||
if [[ "$arg0" == "identity-service-relation-joined" ]] ; then
|
||||
# determine https status based only on config at this point,
|
||||
# insepcting KS relation is not reliable. if KS has mulitple
|
||||
# units, multiple relation-joineds are fired, resulting in the
|
||||
# endpoint being configured in catalog as https before https
|
||||
# is actually setup on this end. ends with failure to configure
|
||||
# quantum network, if its enabled.
|
||||
# if specified in config, https will have already been setup in
|
||||
# install or config-changed.
|
||||
if [[ -n "$(config-get ssl_cert)" ]] &&
|
||||
[[ -n "$(config-get ssl_key)" ]] ; then
|
||||
local scheme="https"
|
||||
else
|
||||
local scheme="http"
|
||||
fi
|
||||
else
|
||||
# Not the leader and clustered - no action required
|
||||
return 0
|
||||
# this function is called from other hook contexts, use normal method
|
||||
# for determining https
|
||||
https && scheme="https" || scheme="http"
|
||||
fi
|
||||
nova_url="http://$address:$nova_port/v1.1/\$(tenant_id)s"
|
||||
ec2_url="http://$address:$ec2_port/services/Cloud"
|
||||
s3_url="http://$address:$s3_port"
|
||||
region="$(config-get region)"
|
||||
|
||||
local nova_url="$scheme://$host:8774/v1.1/\$(tenant_id)s"
|
||||
local ec2_url="$scheme://$host:8773/services/Cloud"
|
||||
local s3_url="$scheme://$host:3333"
|
||||
local region="$(config-get region)"
|
||||
local quantum_url="$scheme://$host:9696"
|
||||
|
||||
# these are the default endpoints
|
||||
relation-set nova_service="nova" \
|
||||
@ -243,7 +260,6 @@ function keystone_joined {
|
||||
s3_internal_url="$s3_url"
|
||||
|
||||
if [ "$(config-get network-manager)" == "Quantum" ]; then
|
||||
quantum_url="http://$address:$quantum_port"
|
||||
relation-set quantum_service="quantum" \
|
||||
quantum_region="$region" \
|
||||
quantum_public_url="$quantum_url" \
|
||||
@ -253,7 +269,7 @@ function keystone_joined {
|
||||
|
||||
# tack on an endpoint for nova-volume a relation exists.
|
||||
if [[ -n "$(relation-ids nova-volume-service)" ]] ; then
|
||||
nova_vol_url="http://$address:$vol_port/v1/\$(tenant_id)s"
|
||||
nova_vol_url="$scheme://$host:$vol_port/v1/\$(tenant_id)s"
|
||||
relation-set nova-volume_service="nova-volume" \
|
||||
nova-volume_region="$region" \
|
||||
nova-volume_public_url="$nova_vol_url" \
|
||||
@ -292,6 +308,13 @@ function keystone_changed {
|
||||
sed -i '/--use_deprecated_auth/d' $NOVA_CONF
|
||||
fi
|
||||
|
||||
local clustered=""
|
||||
is_clustered && clustered="1"
|
||||
|
||||
[[ -n "$clustered" ]] && local host=$(config-get vip) ||
|
||||
local host=$(unit-get private-address)
|
||||
https && local scheme="https" || local scheme="http"
|
||||
|
||||
# update keystone authtoken settings accordingly
|
||||
set_or_update "service_host" "$service_host" "$API_CONF"
|
||||
set_or_update "service_port" "$service_port" "$API_CONF"
|
||||
@ -307,7 +330,7 @@ function keystone_changed {
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
# Configure Nova for quantum
|
||||
keystone_url="http://${auth_host}:${auth_port}/v2.0"
|
||||
set_or_update "quantum_url" "http://$(unit-get private-address):9696"
|
||||
set_or_update "quantum_url" "$scheme://$host:9696"
|
||||
set_or_update "quantum_admin_tenant_name" "${service_tenant}"
|
||||
set_or_update "quantum_admin_username" "${service_username}"
|
||||
set_or_update "quantum_admin_password" "${service_password}"
|
||||
@ -331,11 +354,13 @@ EOF
|
||||
determine_services && service_ctl all restart
|
||||
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
# if first time here, config quantum before setting up
|
||||
# https.
|
||||
configure_quantum_networking
|
||||
# ripple out changes to identity to connected services
|
||||
# which use cloud-controller as source of information for
|
||||
# keystone
|
||||
r_ids="$(relation-ids cloud-compute) $(relation-ids quantum-network-service)"
|
||||
local r_ids="$(relation-ids cloud-compute) $(relation-ids quantum-network-service)"
|
||||
for id in $r_ids ; do
|
||||
relation-set -r $id \
|
||||
keystone_host=$auth_host \
|
||||
@ -350,6 +375,14 @@ EOF
|
||||
|
||||
done
|
||||
fi
|
||||
configure_https
|
||||
|
||||
# if this changed event happens as a result of clustered VIP
|
||||
# reconfigure, configure_https needs to update VIP certificate
|
||||
# before quantumclient is used.
|
||||
if [[ "$NET_MANAGER" == "Quantum" ]]; then
|
||||
configure_quantum_networking
|
||||
fi
|
||||
}
|
||||
|
||||
volume_joined() {
|
||||
@ -401,19 +434,19 @@ volume_joined() {
|
||||
}
|
||||
|
||||
compute_joined() {
|
||||
if is_clustered && ! is_leader 'res_nova_vip'; then
|
||||
# Clustered and not current leader - do nothing
|
||||
return 0
|
||||
fi
|
||||
|
||||
relation-set network_manager=$(config-get network-manager)
|
||||
relation-set ec2_host=$(unit-get private-address)
|
||||
local r_id="$1"
|
||||
[[ -n "$r_id" ]] && r_id="-r $r_id"
|
||||
eligible_leader 'res_nova_vip' || return 0
|
||||
relation-set $r_id network_manager=$(config-get network-manager)
|
||||
# XXX Should point to VIP if clustered, or this may not even be needed.
|
||||
relation-set $r_id ec2_host=$(unit-get private-address)
|
||||
|
||||
local sect="filter:authtoken"
|
||||
keystone_host=$(local_config_get $API_CONF auth_host $sect)
|
||||
|
||||
if [ "$NET_MANAGER" == "Quantum" ]; then
|
||||
if [ -n "$keystone_host" ]; then
|
||||
relation-set \
|
||||
if [[ -n "$keystone_host" ]]; then
|
||||
relation-set $r_id \
|
||||
keystone_host=$keystone_host \
|
||||
auth_port=$(local_config_get $API_CONF auth_port $sect) \
|
||||
service_port=$(local_config_get $API_CONF service_port $sect) \
|
||||
@ -421,19 +454,24 @@ compute_joined() {
|
||||
service_password=$(local_config_get $API_CONF admin_password $sect) \
|
||||
service_tenant=$(local_config_get $API_CONF admin_tenant_name $sect) \
|
||||
auth_uri=$(local_config_get $API_CONF auth_uri $sect)
|
||||
fi
|
||||
|
||||
if is_clustered; then
|
||||
quantum_host=$(config-get vip)
|
||||
quantum_port=19696
|
||||
else
|
||||
quantum_host=$(unit-get private-address)
|
||||
quantum_port=9696
|
||||
fi
|
||||
is_clustered && local host=$(config-get vip) ||
|
||||
local host=$(unit-get private-address)
|
||||
https && local scheme="https" || local scheme="http"
|
||||
local quantum_url="$scheme://$host:9696"
|
||||
|
||||
relation-set quantum_host=$quantum_host \
|
||||
quantum_port=$quantum_port \
|
||||
quantum_plugin=$(config-get quantum-plugin)
|
||||
relation-set $r_id quantum_url=$quantum_url \
|
||||
quantum_plugin=$(config-get quantum-plugin) \
|
||||
region=$(config-get region)
|
||||
|
||||
fi
|
||||
|
||||
# must pass on the keystone CA certficiate, if it exists.
|
||||
cert="/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
|
||||
if [[ -n "$keystone_host" ]] && [[ -e $cert ]] ; then
|
||||
cert=$(cat $cert | base64)
|
||||
relation-set $r_id ca_cert="$cert"
|
||||
fi
|
||||
|
||||
# volume driver is dependent on os version, or presence
|
||||
@ -445,11 +483,10 @@ compute_joined() {
|
||||
vol_drv="nova-volume"
|
||||
;;
|
||||
"folsom")
|
||||
local r_ids=$(relation-ids cinder-volume-service)
|
||||
[[ -z "$r_ids" ]] && vol_drv="nova-volume"
|
||||
[[ -z "$(relation-ids cinder-volume-service)" ]] && vol_drv="nova-volume"
|
||||
;;
|
||||
esac
|
||||
relation-set volume_service="$vol_drv"
|
||||
relation-set $r_id volume_service="$vol_drv"
|
||||
}
|
||||
|
||||
compute_changed() {
|
||||
@ -469,15 +506,14 @@ compute_departed() {
|
||||
|
||||
function quantum_joined() {
|
||||
# Tell quantum service about keystone
|
||||
if is_clustered && ! is_leader 'res_nova_vip'; then
|
||||
# Clustered and not current leader - do nothing
|
||||
return 0
|
||||
fi
|
||||
eligible_leader || return 0
|
||||
local r_id="$1"
|
||||
[[ -n "$r_id" ]] && r_id="-r $r_id"
|
||||
|
||||
local sect="filter:authtoken"
|
||||
keystone_host=$(local_config_get $API_CONF auth_host $sect)
|
||||
if [ -n "$keystone_host" ]; then
|
||||
relation-set \
|
||||
relation-set $r_id \
|
||||
keystone_host=$keystone_host \
|
||||
auth_port=$(local_config_get $API_CONF auth_port $sect) \
|
||||
service_port=$(local_config_get $API_CONF service_port $sect) \
|
||||
@ -487,24 +523,51 @@ function quantum_joined() {
|
||||
auth_uri=$(local_config_get $API_CONF auth_uri $sect)
|
||||
fi
|
||||
|
||||
if is_clustered; then
|
||||
quantum_host=$(config-get vip)
|
||||
quantum_port=19696
|
||||
else
|
||||
quantum_host=$(unit-get private-address)
|
||||
quantum_port=9696
|
||||
# must pass on the keystone CA certficiate, if it exists.
|
||||
cert="/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
|
||||
if [[ -n "$keystone_host" ]] && [[ -e $cert ]] ; then
|
||||
cert=$(cat $cert | base64)
|
||||
relation-set $r_id ca_cert="$cert"
|
||||
fi
|
||||
|
||||
relation-set quantum_host=$quantum_host \
|
||||
quantum_port=$quantum_port \
|
||||
quantum_plugin=$(config-get quantum-plugin) \
|
||||
region=$(config-get region)
|
||||
is_clustered && local host=$(config-get vip) ||
|
||||
local host=$(unit-get private-address)
|
||||
https && local scheme="https" || local scheme="http"
|
||||
local quantum_url="$scheme://$host:9696"
|
||||
|
||||
relation-set $r_id quantum_host="$host" quantum_port="9696" \
|
||||
quantum_url=$quantum_url \
|
||||
quantum_plugin=$(config-get quantum-plugin) \
|
||||
region=$(config-get region)
|
||||
|
||||
}
|
||||
|
||||
function cluster_changed() {
|
||||
configure_haproxy "quantum_api:9696" "nova_api:8774" \
|
||||
"ec2_api:8773" "s3_api:3333" \
|
||||
"volume_api:8776"
|
||||
[[ -z "$(peer_units)" ]] &&
|
||||
juju-log "cluster_changed() with no peers." && exit 0
|
||||
# upstartService:defaultPort:configOption
|
||||
local svcs="nova-api-ec2:8773:ec2_listen_port
|
||||
nova-api-os-compute:8774:osapi_compute_listen_port
|
||||
nova-objectstore:3333:s3_listen_port"
|
||||
[[ "$NET_MANAGER" == "Quantum" ]] &&
|
||||
svcs="$svcs quantum-server:9696:bind_port"
|
||||
|
||||
for s in $svcs ; do
|
||||
local service=$(echo $s | cut -d: -f1)
|
||||
local port=$(echo $s | cut -d: -f2)
|
||||
local opt=$(echo $s | cut -d: -f3)
|
||||
local next_server="$(determine_haproxy_port $port)"
|
||||
local api_port="$(determine_api_port $port)"
|
||||
local haproxy_port_maps="$haproxy_port_maps $service:$next_server:$api_port:http"
|
||||
if [[ "$service" == "quantum-server" ]] ; then
|
||||
set_or_update "$opt" "$api_port" "$QUANTUM_CONF"
|
||||
else
|
||||
set_or_update "$opt" "$api_port"
|
||||
fi
|
||||
|
||||
service_ctl $service restart
|
||||
done
|
||||
configure_haproxy $haproxy_port_maps
|
||||
}
|
||||
|
||||
function ha_relation_joined() {
|
||||
@ -529,13 +592,13 @@ function ha_relation_joined() {
|
||||
init_services="{
|
||||
'res_nova_haproxy':'haproxy'
|
||||
}"
|
||||
groups="{
|
||||
'grp_nova_haproxy':'res_nova_vip res_nova_haproxy'
|
||||
clones="{
|
||||
'cl_nova_haproxy':'res_nova_haproxy'
|
||||
}"
|
||||
relation-set corosync_bindiface=$corosync_bindiface \
|
||||
corosync_mcastport=$corosync_mcastport \
|
||||
resources="$resources" resource_params="$resource_params" \
|
||||
init_services="$init_services" groups="$groups"
|
||||
init_services="$init_services" clones="$clones"
|
||||
else
|
||||
juju-log "Insufficient configuration data to configure hacluster"
|
||||
exit 1
|
||||
@ -545,45 +608,58 @@ function ha_relation_joined() {
|
||||
function ha_relation_changed() {
|
||||
local clustered=`relation-get clustered`
|
||||
if [ -n "$clustered" ] && is_leader 'res_nova_vip'; then
|
||||
https && local scheme="https" || local scheme="http"
|
||||
for r_id in `relation-ids identity-service`; do
|
||||
address=$(config-get vip)
|
||||
nova_url="http://$address:18774/v1.1/\$(tenant_id)s"
|
||||
ec2_url="http://$address:18773/services/Cloud"
|
||||
s3_url="http://$address:13333"
|
||||
local address=$(config-get vip)
|
||||
local region=$(config-get region)
|
||||
local nova_url="$scheme://$address:8774/v1.1/\$(tenant_id)s"
|
||||
local ec2_url="$scheme://$address:8773/services/Cloud"
|
||||
local s3_url="$scheme://$address:3333"
|
||||
local quantum_url="$scheme://$address:9696"
|
||||
local nova_vol_url="$scheme://$address:8776/v1/\$(tenant_id)s"
|
||||
|
||||
relation-set -r $r_id \
|
||||
nova_service="nova" \
|
||||
nova_region="$region" \
|
||||
nova_public_url="$nova_url" \
|
||||
nova_admin_url="$nova_url" \
|
||||
nova_internal_url="$nova_url" \
|
||||
ec2_service="ec2" \
|
||||
ec2_region="$region" \
|
||||
ec2_public_url="$ec2_url" \
|
||||
ec2_admin_url="$ec2_url" \
|
||||
ec2_internal_url="$ec2_url" \
|
||||
s3_service="s3" \
|
||||
s3_region="$region" \
|
||||
s3_public_url="$s3_url" \
|
||||
s3_admin_url="$s3_url" \
|
||||
s3_internal_url="$s3_url"
|
||||
|
||||
if [ "$(config-get network-manager)" == "Quantum" ]; then
|
||||
quantum_url="http://$address:19696"
|
||||
relation-set -r $r_id \
|
||||
quantum_service="quantum" \
|
||||
quantum_region="$region" \
|
||||
quantum_public_url="$quantum_url" \
|
||||
quantum_admin_url="$quantum_url" \
|
||||
quantum_internal_url="$quantum_url"
|
||||
fi
|
||||
|
||||
if [[ -n "$(relation-ids nova-volume-service)" ]] ; then
|
||||
nova_vol_url="http://$address:18776/v1/\$(tenant_id)s"
|
||||
relation-set -r $r_id \
|
||||
nova-volume_service="nova-volume" \
|
||||
nova-volume_region="$region" \
|
||||
nova-volume_public_url="$nova_vol_url" \
|
||||
nova-volume_admin_url="$nova_vol_url" \
|
||||
nova-volume_internal_url="$nova_vol_url"
|
||||
fi
|
||||
done
|
||||
if [ "$(config-get network-manager)" == "Quantum" ]; then
|
||||
# Let gateway nodes use the new HA address for the
|
||||
# Let gateway nodes use the new HA address for the
|
||||
# quantum API server
|
||||
for r_id in `relation-ids quantum-network-service`; do
|
||||
relation-set -r $r_id \
|
||||
quantum_host=$address
|
||||
quantum_port=19696
|
||||
quantum_host="$address" quantum_port="9696" \
|
||||
quantum_url="$quantum_url" region="$region"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
2
revision
2
revision
@ -1 +1 @@
|
||||
216
|
||||
239
|
||||
|
Loading…
x
Reference in New Issue
Block a user