diff --git a/config.yaml b/config.yaml index 6934c9da..52dc5482 100644 --- a/config.yaml +++ b/config.yaml @@ -22,3 +22,13 @@ options: default: glance type: string description: Glance database name. + 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. diff --git a/hooks/glance-common b/hooks/glance-common index e74aa38e..3cee9ed5 100755 --- a/hooks/glance-common +++ b/hooks/glance-common @@ -119,3 +119,23 @@ do_openstack_upgrade() { keystone_changed $r_id fi } + + +configure_https() { + # request openstack-common setup reverse proxy mapping for API and registry + # servers + service_ctl all stop + if setup_https 9191:9181 9292:9282 ; then + juju-log "$CHARM: Configuring glance for HTTPS reverse proxying." + # configure servers to listen on new ports accordingly. + set_or_update bind_port "9181" "registry" + set_or_update bind_port "9282" "api" + set_or_update registry_port "9181" "api" + juju-log "$CHARM: Reverse proxy in place, updating Keystone catalog via "\ + "identiy-service relation (if it exists)." + for r_id in "$(relation-ids identity-service)" ; do + keystone_joined "$r_id" + done + fi + service_ctl all start +} diff --git a/hooks/glance-relations b/hooks/glance-relations index 0e78e403..b352198a 100755 --- a/hooks/glance-relations +++ b/hooks/glance-relations @@ -25,6 +25,8 @@ function install_hook { set_or_update debug True api set_or_update verbose True registry set_or_update debug True registry + + configure_https } function db_joined { @@ -182,9 +184,12 @@ EOF } function keystone_joined { + local r_id="$1" + [[ -n "$r_id" ]] && r_id=" -r $r_id" # advertise our API endpoint to keystone - url="http://$(unit-get private-address):9292/v1" - relation-set service="glance" \ + https && scheme="https" || scheme="http" + url="$scheme://$(unit-get private-address):9292/v1" + relation-set $r_id service="glance" \ region="RegionOne" public_url=$url admin_url=$url internal_url=$url } @@ -243,6 +248,9 @@ function keystone_changed { if [[ -n "$(relation-ids object-store)" ]] ; then object-store_joined fi + + # possibly configure HTTPS for API and registry + configure_https } function config_changed() { @@ -260,7 +268,7 @@ function config_changed() { do_openstack_upgrade "$install_src" $PACKAGES fi fi - + configure_https service_ctl all restart } diff --git a/hooks/lib/openstack-common b/hooks/lib/openstack-common index ecc16164..5fe52067 100644 --- a/hooks/lib/openstack-common +++ b/hooks/lib/openstack-common @@ -314,3 +314,98 @@ function get_block_device() { echo "$found" return 0 } + +https() { + # determine whether enough data exists in config or relation to satisfy + # https configuration. + local r_id="$1" + [[ -n "$r_id" ]] && r_id="-r $r_id" + if [[ -n "$(config-get ssl_cert)" ]] && + [[ -n "$(config-get ssl_key)" ]] ; then + return 0 + elif [[ -n "$(relation-get $r_id ssl_cert)" ]] && + [[ -n "$(relation-get $r_id ssl_key)" ]] && + [[ -n "$(relation-get $r_id ca_cert)" ]] ; then + return 0 + else + return 1 + fi +} + +setup_https() { + # configure https via apache reverse proxying either + # using certs provided by config or keystone. + local cert="" + local key="" + local port_maps="$@" + local http_restart="" + + [[ -z "$CHARM" ]] && + error_out "setup_https(): CHARM not set." + + # look for ssl certs in service config first, then keystone. + # allows per-service overriding of auto-created certs from keystone. + cert=$(config-get ssl_cert) + key=$(config-get ssl_key) + if [[ -z "$cert" ]] || [[ -z "$key" ]] ; then + juju-log "Inspecting identity-service relations for SSL certificate." + local r_ids=$(relation-ids identity-service) + for r_id in $r_ids ; do + cert="$(relation-get -r $r_id ssl_cert)" + key="$(relation-get -r $r_id ssl_key)" + ca_cert="$(relation-get -r $r_id ca_cert)" + 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 "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 + 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} < + 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 + + + Order deny,allow + Allow from all + + + Order allow,deny + Allow from all + +END + a2ensite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" && + http_restart=1 + done + [[ -n "$http_restart" ]] && service apache2 restart +} diff --git a/revision b/revision index 85322d0b..5595fa46 100644 --- a/revision +++ b/revision @@ -1 +1 @@ -79 +95