Merge "Allow deploying keystone with SSL certificates"
diff --git a/lib/cinder b/lib/cinder
index 96d2505..9288685 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -209,6 +209,7 @@
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_host
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_port
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_protocol
+ inicomment $CINDER_API_PASTE_INI filter:authtoken cafile
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_tenant_name
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_user
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_password
@@ -219,6 +220,7 @@
iniset $CINDER_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $CINDER_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $CINDER_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ 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
diff --git a/lib/glance b/lib/glance
index f40b1a7..2e29a8f 100644
--- a/lib/glance
+++ b/lib/glance
@@ -82,6 +82,7 @@
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $GLANCE_REGISTRY_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_user glance
@@ -99,6 +100,7 @@
iniset $GLANCE_API_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $GLANCE_API_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $GLANCE_API_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $GLANCE_API_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $GLANCE_API_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $GLANCE_API_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $GLANCE_API_CONF keystone_authtoken admin_user glance
diff --git a/lib/heat b/lib/heat
index 7a9ef0d..e44a618 100644
--- a/lib/heat
+++ b/lib/heat
@@ -96,6 +96,7 @@
iniset $HEAT_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $HEAT_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
+ 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
diff --git a/lib/ironic b/lib/ironic
index 9f86e84..099746a 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -98,6 +98,7 @@
iniset $IRONIC_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $IRONIC_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $IRONIC_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $IRONIC_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
diff --git a/lib/keystone b/lib/keystone
index c1fa0af..6d0c1cd 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -4,6 +4,7 @@
# Dependencies:
#
# - ``functions`` file
+# - ``tls`` file
# - ``DEST``, ``STACK_USER``
# - ``IDENTITY_API_VERSION``
# - ``BASE_SQL_CONN``
@@ -79,6 +80,13 @@
# valid assignment backends as per dir keystone/identity/backends
KEYSTONE_VALID_ASSIGNMENT_BACKENDS=kvs,ldap,sql
+# if we are running with SSL use https protocols
+if is_ssl_enabled_service "key"; then
+ KEYSTONE_AUTH_PROTOCOL="https"
+ KEYSTONE_SERVICE_PROTOCOL="https"
+fi
+
+
# Functions
# ---------
# cleanup_keystone() - Remove residual data files, anything left over from previous
@@ -172,6 +180,15 @@
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/"
+ # Register SSL certificates if provided
+ if is_ssl_enabled_service key; then
+ ensure_certificates KEYSTONE
+
+ iniset $KEYSTONE_CONF ssl enable True
+ iniset $KEYSTONE_CONF ssl certfile $KEYSTONE_SSL_CERT
+ iniset $KEYSTONE_CONF ssl keyfile $KEYSTONE_SSL_KEY
+ fi
+
if is_service_enabled tls-proxy; then
# Set the service ports for a proxy to take the originals
iniset $KEYSTONE_CONF DEFAULT public_port $KEYSTONE_SERVICE_PORT_INT
@@ -386,7 +403,7 @@
fi
echo "Waiting for keystone to start..."
- if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s http://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
+ if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
die $LINENO "keystone did not start"
fi
diff --git a/lib/nova b/lib/nova
index 6ab2000..5fd0beb 100644
--- a/lib/nova
+++ b/lib/nova
@@ -225,6 +225,7 @@
inicomment $NOVA_API_PASTE_INI filter:authtoken auth_host
inicomment $NOVA_API_PASTE_INI filter:authtoken auth_protocol
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_tenant_name
+ inicomment $NOVA_API_PASTE_INI filter:authtoken cafile
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_user
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_password
fi
@@ -399,6 +400,7 @@
iniset $NOVA_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $NOVA_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
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
fi
diff --git a/lib/swift b/lib/swift
index 40722ab..8a1489b 100644
--- a/lib/swift
+++ b/lib/swift
@@ -316,6 +316,7 @@
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
@@ -339,6 +340,7 @@
auth_port = ${KEYSTONE_AUTH_PORT}
auth_host = ${KEYSTONE_AUTH_HOST}
auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
+cafile = ${KEYSTONE_SSL_CA}
auth_token = ${SERVICE_TOKEN}
admin_token = ${SERVICE_TOKEN}
diff --git a/lib/tls b/lib/tls
index a1a7fdd..6134fa1 100644
--- a/lib/tls
+++ b/lib/tls
@@ -22,7 +22,8 @@
# - make_int_ca
# - new_cert $INT_CA_DIR int-server "abc"
# - start_tls_proxy HOST_IP 5000 localhost 5000
-
+# - ensure_certificates
+# - is_ssl_enabled_service
# Defaults
# --------
@@ -309,6 +310,53 @@
}
+# Certificate Input Configuration
+# ===============================
+
+# check to see if the service(s) specified are to be SSL enabled.
+#
+# Multiple services specified as arguments are ``OR``'ed together; the test
+# is a short-circuit boolean, i.e it returns on the first match.
+#
+# Uses global ``SSL_ENABLED_SERVICES``
+function is_ssl_enabled_service() {
+ services=$@
+ for service in ${services}; do
+ [[ ,${SSL_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
+ done
+ return 1
+}
+
+
+# Ensure that the certificates for a service are in place. This function does
+# not check that a service is SSL enabled, this should already have been
+# completed.
+#
+# 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.
+function ensure_certificates() {
+ local service=$1
+
+ local cert_var="${service}_SSL_CERT"
+ local key_var="${service}_SSL_KEY"
+ local ca_var="${service}_SSL_CA"
+
+ local cert=${!cert_var}
+ local key=${!key_var}
+ local ca=${!ca_var}
+
+ if [[ !($cert && $key && $ca) ]]; then
+ die $LINENO "Missing either the ${cert_var} ${key_var} or ${ca_var}" \
+ "variable to enable SSL for ${service}"
+ fi
+
+ cat $ca >> $SSL_BUNDLE_FILE
+}
+
+
# Proxy Functions
# ===============
diff --git a/lib/trove b/lib/trove
index c40006b..5ba4de5 100644
--- a/lib/trove
+++ b/lib/trove
@@ -29,7 +29,6 @@
TROVECLIENT_DIR=$DEST/python-troveclient
TROVE_CONF_DIR=/etc/trove
TROVE_LOCAL_CONF_DIR=$TROVE_DIR/etc/trove
-TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT//v$IDENTITY_API_VERSION
TROVE_AUTH_CACHE_DIR=${TROVE_AUTH_CACHE_DIR:-/var/cache/trove}
TROVE_BIN_DIR=/usr/local/bin
@@ -102,6 +101,7 @@
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_host $KEYSTONE_AUTH_HOST
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_port $KEYSTONE_AUTH_PORT
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $TROVE_API_PASTE_INI filter:tokenauth cafile $KEYSTONE_SSL_CA
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_tenant_name $SERVICE_TENANT_NAME
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_user trove
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_password $SERVICE_PASSWORD
@@ -123,6 +123,8 @@
# (Re)create trove taskmanager conf file if needed
if is_service_enabled tr-tmgr; then
+ TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT//v$IDENTITY_API_VERSION
+
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT rabbit_password $RABBIT_PASSWORD
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT sql_connection `database_connection_url trove`
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT taskmanager_manager trove.taskmanager.manager.Manager
diff --git a/openrc b/openrc
index 804bb3f..784b00e 100644
--- a/openrc
+++ b/openrc
@@ -58,6 +58,7 @@
HOST_IP=${HOST_IP:-127.0.0.1}
SERVICE_HOST=${SERVICE_HOST:-$HOST_IP}
SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
+KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-$SERVICE_PROTOCOL}
# Some exercises call glance directly. On a single-node installation, Glance
# should be listening on HOST_IP. If its running elsewhere, it can be set here
@@ -71,10 +72,10 @@
# the user/tenant has access to - including nova, glance, keystone, swift, ...
# We currently recommend using the 2.0 *identity api*.
#
-export OS_AUTH_URL=$SERVICE_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
+export OS_AUTH_URL=$KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
# Set the pointer to our CA certificate chain. Harmless if TLS is not used.
-export OS_CACERT=$INT_CA_DIR/ca-chain.pem
+export OS_CACERT=${OS_CACERT:-$INT_CA_DIR/ca-chain.pem}
# Currently novaclient needs you to specify the *compute api* version. This
# needs to match the config of your catalog returned by Keystone.
diff --git a/stack.sh b/stack.sh
index 825373e..a2ef679 100755
--- a/stack.sh
+++ b/stack.sh
@@ -290,6 +290,10 @@
# Service startup timeout
SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
+# Reset the bundle of CA certificates
+SSL_BUNDLE_FILE="$DATA_DIR/ca-bundle.pem"
+rm -f $SSL_BUNDLE_FILE
+
# Configure Projects
# ==================
@@ -799,6 +803,17 @@
restart_rpc_backend
+# Export Certicate Authority Bundle
+# ---------------------------------
+
+# If certificates were used and written to the SSL bundle file then these
+# should be exported so clients can validate their connections.
+
+if [ -f $SSL_BUNDLE_FILE ]; then
+ export OS_CACERT=$SSL_BUNDLE_FILE
+fi
+
+
# Configure database
# ------------------
@@ -1146,6 +1161,7 @@
start_trove
fi
+
# Create account rc files
# =======================
@@ -1154,7 +1170,13 @@
# which is helpful in image bundle steps.
if is_service_enabled nova && is_service_enabled key; then
- $TOP_DIR/tools/create_userrc.sh -PA --target-dir $TOP_DIR/accrc
+ USERRC_PARAMS="-PA --target-dir $TOP_DIR/accrc"
+
+ if [ -f $SSL_BUNDLE_FILE ]; then
+ USERRC_PARAMS="$USERRC_PARAMS --os-cacert $SSL_BUNDLE_FILE"
+ fi
+
+ $TOP_DIR/tools/create_userrc.sh $USERRC_PARAMS
fi
@@ -1230,7 +1252,7 @@
CURRENT_RUN_TIME=$(date "+$TIMESTAMP_FORMAT")
echo "# $CURRENT_RUN_TIME" >$TOP_DIR/.stackenv
for i in BASE_SQL_CONN ENABLED_SERVICES HOST_IP LOGFILE \
- SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP; do
+ SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP KEYSTONE_AUTH_PROTOCOL OS_CACERT; do
echo $i=${!i} >>$TOP_DIR/.stackenv
done
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index 8383fe7..5f4c486 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -43,6 +43,7 @@
--os-tenant-name <tenant_name>
--os-tenant-id <tenant_id>
--os-auth-url <auth_url>
+--os-cacert <cert file>
--target-dir <target_directory>
--skip-tenant <tenant-name>
--debug
@@ -53,7 +54,7 @@
EOF
}
-if ! options=$(getopt -o hPAp:u:r:C: -l os-username:,os-password:,os-tenant-name:,os-tenant-id:,os-auth-url:,target-dir:,skip-tenant:,help,debug -- "$@")
+if ! options=$(getopt -o hPAp:u:r:C: -l os-username:,os-password:,os-tenant-name:,os-tenant-id:,os-auth-url:,target-dir:,skip-tenant:,os-cacert:,help,debug -- "$@")
then
#parse error
display_help
@@ -80,6 +81,7 @@
--os-tenant-id) export OS_TENANT_ID=$2; shift ;;
--skip-tenant) SKIP_TENANT="$SKIP_TENANT$2,"; shift ;;
--os-auth-url) export OS_AUTH_URL=$2; shift ;;
+ --os-cacert) export OS_CACERT=$2; shift ;;
--target-dir) ACCOUNT_DIR=$2; shift ;;
--debug) set -o xtrace ;;
-u) MODE=${MODE:-one}; USER_NAME=$2; shift ;;
@@ -201,6 +203,7 @@
# Openstack Tenant ID = $tenant_id
export OS_TENANT_NAME="$tenant_name"
export OS_AUTH_URL="$OS_AUTH_URL"
+export OS_CACERT="$OS_CACERT"
export EC2_CERT="$ec2_cert"
export EC2_PRIVATE_KEY="$ec2_private_key"
export EC2_USER_ID=42 #not checked by nova (can be a 12-digit id)