Permalink
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
comanage-match/comanage-match-base/comanage_utils.sh
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updates to support version 1.0.0 release candidate 2.
601 lines (505 sloc)
17.7 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# COmanage Match bash shell utilities | |
# | |
# Portions licensed to the University Corporation for Advanced Internet | |
# Development, Inc. ("UCAID") under one or more contributor license agreements. | |
# See the NOTICE file distributed with this work for additional information | |
# regarding copyright ownership. | |
# | |
# UCAID licenses this file to you under the Apache License, Version 2.0 | |
# (the "License"); you may not use this file except in compliance with the | |
# License. You may obtain a copy of the License at: | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
if [ -n "$COMANAGE_DEBUG" ] | |
then | |
OUTPUT=/dev/stdout | |
else | |
OUTPUT=/dev/null | |
fi | |
########################################## | |
# Configure console (stdout) logging | |
# Globals: | |
# COMANAGE_MATCH_DIR | |
# OUTPUT | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::configure_console_logging() { | |
pushd "$COMANAGE_MATCH_DIR/app/config" > "$OUTPUT" 2>&1 | |
patch < /usr/local/src/comanage_match_console_logging.patch > "$OUTPUT" 2>&1 | |
popd > "$OUTPUT" 2>&1 | |
} | |
########################################## | |
# Configure TIER logging | |
# Globals: | |
# ENV | |
# USERTOKEN | |
# OUTPUT | |
# Arguments: | |
# NONE | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::configure_tier_logging() { | |
comanage_utils::manage_tier_environment | |
# Create pipes to use for COmanage Match instead of standard log files. | |
mkfifo -m 666 "$COMANAGE_MATCH_DIR/local/logs/error.log" > "$OUTPUT" 2>&1 | |
mkfifo -m 666 "$COMANAGE_MATCH_DIR/local/logs/debug.log" > "$OUTPUT" 2>&1 | |
# Format any output from COmanange Registry into standard TIER form. | |
(cat <> "$COMANAGE_MATCH_DIR/local/logs/error.log" | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "comanage_match;error.log;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe)& | |
(cat <> "$COMANAGE_MATCH_DIR/local/logs/debug.log" | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "comanage_match;debug.log;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe)& | |
} | |
########################################## | |
# Consume injected environment variables | |
# Globals: | |
# See function | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::consume_injected_environment() { | |
echo "Examining environment variables..." > "$OUTPUT" | |
# Configuration details that may be injected through environment | |
# variables or the contents of files. | |
local injectable_config_vars | |
injectable_config_vars=( | |
COMANAGE_MATCH_ADMIN_USERNAME | |
COMANAGE_MATCH_DATASOURCE | |
COMANAGE_MATCH_DATABASE | |
COMANAGE_MATCH_DATABASE_HOST | |
COMANAGE_MATCH_DATABASE_USER | |
COMANAGE_MATCH_DATABASE_USER_PASSWORD | |
COMANAGE_MATCH_SECURITY_SALT | |
COMANAGE_MATCH_SECURITY_SEED | |
COMANAGE_MATCH_VIRTUAL_HOST_FQDN | |
HTTPS_CERT_FILE | |
HTTPS_PRIVKEY_FILE | |
) | |
# If the file associated with a configuration variable is present then | |
# read the value from it into the appropriate variable. So for example | |
# if the variable COMANAGE_MATCH_DATASOURCE_FILE exists and its | |
# value points to a file on the file system then read the contents | |
# of that file into the variable COMANAGE_MATCH_DATASOURCE. | |
local config_var | |
for config_var in "${injectable_config_vars[@]}" | |
do | |
local file_name | |
eval file_name=\$"${config_var}_FILE"; | |
if [[ -e "$file_name" ]]; then | |
declare -g "${config_var}"=`cat $file_name` | |
echo "Set ${config_var} to be contents of ${file_name}" > "$OUTPUT" | |
fi | |
done | |
echo "Done examining environment variables" > "$OUTPUT" | |
} | |
########################################## | |
# Exec to start and become Apache HTTP Server | |
# Globals: | |
# None | |
# Arguments: | |
# Command and arguments to exec | |
# Returns: | |
# Does not return | |
########################################## | |
function comanage_utils::exec_apache_http_server() { | |
comanage_utils::consume_injected_environment | |
comanage_utils::configure_console_logging | |
comanage_utils::prepare_local_directory | |
comanage_utils::prepare_database_config | |
comanage_utils::prepare_email_config | |
comanage_utils::prepare_https_cert_key | |
comanage_utils::prepare_server_name | |
comanage_utils::wait_database_connectivity | |
comanage_utils::match_setup | |
comanage_utils::tmp_ownership | |
# first arg is `-f` or `--some-option` | |
if [ "${1#-}" != "$1" ]; then | |
set -- apache2-foreground "$@" | |
fi | |
exec "$@" | |
} | |
########################################## | |
# Manage TIER environment variables | |
# Globals: | |
# None | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::manage_tier_environment() { | |
# If ENV or USERTOKEN as injected by the deployer contain a semi-colon remove it. | |
if [[ ${ENV} =~ .*";".* ]]; then | |
ENV=`echo ${ENV} | tr -d ';'` | |
export ENV | |
fi | |
if [[ ${USERTOKEN} =~ .*";".* ]]; then | |
USERTOKEN=`echo ${USERTOKEN} | tr -d ';'` | |
export USERTOKEN | |
fi | |
# If ENV or USERTOKEN as injected by the deployer contain a space remove it. | |
if [[ ${ENV} =~ [[:space:]] ]]; then | |
ENV=`echo ${ENV} | tr -d [:space:]` | |
export ENV | |
fi | |
if [[ ${USERTOKEN} =~ [[:space:]] ]]; then | |
USERTOKEN=`echo ${USERTOKEN} | tr -d [:space:]` | |
export USERTOKEN | |
fi | |
} | |
########################################## | |
# Prepare database configuration | |
# Globals: | |
# COMANAGE_MATCH_DATABASE | |
# COMANAGE_MATCH_DATABASE_HOST | |
# COMANAGE_MATCH_DATABASE_USER | |
# COMANAGE_MATCH_DATABASE_USER_PASSWORD | |
# COMANAGE_MATCH_DATASOURCE | |
# COMANAGE_MATCH_DIR | |
# OUTPUT | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::prepare_database_config() { | |
# If the COmanage Match database configuration file does not exist | |
# then try to create it from injected information with reasonable defaults | |
# that aid simple evaluation deployments. | |
local database_config | |
database_config="$COMANAGE_MATCH_DIR/local/Config/database.php" | |
if [[ ! -e "$database_config" ]]; then | |
cat > "$database_config" <<EOF | |
<?php | |
return [ | |
'Datasources' => [ | |
'default' => [ | |
'className' => 'Cake\Database\Connection', | |
// Postgres is currently the only supported backend for COmanage Match | |
'driver' => 'Cake\Database\Driver\Postgres', | |
'host' => '${COMANAGE_MATCH_DATABASE_HOST:-comanage-match-database}', | |
'username' => '${COMANAGE_MATCH_DATABASE_USER:-match_user}', | |
'password' => '${COMANAGE_MATCH_DATABASE_USER_PASSWORD:-password}', | |
'database' => '${COMANAGE_MATCH_DATABASE:-match}', | |
] | |
] | |
]; | |
EOF | |
echo "Wrote new database configuration file ${database_config}" > "$OUTPUT" | |
fi | |
} | |
########################################## | |
# Prepare email configuration | |
# Globals: | |
# COMANAGE_MATCH_EMAIL_ACCOUNT | |
# COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD | |
# COMANAGE_MATCH_EMAIL_FROM | |
# COMANAGE_MATCH_EMAIL_HOST | |
# COMANAGE_MATCH_EMAIL_PORT | |
# COMANAGE_MATCH_EMAIL_TRANSPORT | |
# COMANAGE_MATCH_DIR | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::prepare_email_config() { | |
# If the COmanage Match email configuration file does not exist | |
# then try to create it from injected information with reasonable defaults | |
# that aid simple evaluation deployments. | |
local email_config | |
email_config="$COMANAGE_MATCH_DIR/local/Config/email.php" | |
# File already exists so return. | |
if [[ -e "$email_config" ]]; then | |
return | |
fi | |
# File does not exist so create it. | |
local php_string | |
read -r -d '' php_string <<'EOF' | |
<?php | |
return [ | |
'EmailTransport' => [ | |
'default' => [ | |
EOF | |
php_string+=$'\n\t\t' | |
if [[ -n "${COMANAGE_MATCH_EMAIL_CLASS_NAME}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'className' => '${COMANAGE_MATCH_EMAIL_CLASS_NAME}'," | |
fi | |
if [[ -n "${COMANAGE_MATCH_EMAIL_HOST}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'host' => '${COMANAGE_MATCH_EMAIL_HOST}'," | |
fi | |
# The value of port is an integer. | |
if [[ -n "${COMANAGE_MATCH_EMAIL_PORT}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'port' => ${COMANAGE_MATCH_EMAIL_PORT}," | |
fi | |
if [[ -n "${COMANAGE_MATCH_EMAIL_ACCOUNT}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'username' => '${COMANAGE_MATCH_EMAIL_ACCOUNT}'," | |
fi | |
if [[ -n "${COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'password' => '${COMANAGE_MATCH_EMAIL_ACCOUNT_PASSWORD}'," | |
fi | |
php_string+=$'\n\t\t' | |
php_string+="'tls' => true," | |
php_string+=$'\n\t' | |
php_string+="]," | |
php_string+=$'\n' | |
php_string+="]," | |
php_string+=$'\n' | |
php_string+="'Email' => [" | |
php_string+=$'\n\t' | |
php_string+="'default' => [" | |
php_string+=$'\n\t\t' | |
php_string+="'transport' => 'default'," | |
if [[ -n "${COMANAGE_MATCH_EMAIL_FROM_EMAIL}" ]]; then | |
php_string+=$'\n\t\t' | |
php_string+="'from' => '${COMANAGE_MATCH_EMAIL_FROM_EMAIL}'," | |
else | |
php_string+=$'\n\t\t' | |
php_string+="'from' => 'postmaster@organization.edu'," | |
fi | |
php_string+=$'\n\t\t],\n\t],\n];' | |
printf "%s" "$php_string" > $email_config | |
} | |
########################################## | |
# Prepare cert and key for HTTPS | |
# Globals: | |
# HTTPS_CERT_FILE | |
# HTTPS_PRIVKEY_FILE | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::prepare_https_cert_key() { | |
local cert_path | |
local privkey_path | |
local web_user | |
if [[ -e '/etc/debian_version' ]]; then | |
cert_path='/etc/apache2/cert.pem' | |
privkey_path='/etc/apache2/privkey.pem' | |
web_user='www-data' | |
elif [[ -e '/etc/centos-release' ]]; then | |
cert_path='/etc/httpd/cert.pem' | |
privkey_path='/etc/httpd/privkey.pem' | |
web_user='apache' | |
fi | |
# If defined use configured location of Apache HTTP Server | |
# HTTPS certificate and key files. The certificate file may also | |
# include intermediate CA certificates, sorted from leaf to root. | |
if [[ -n "${HTTPS_CERT_FILE}" ]]; then | |
rm -f "${cert_path}" | |
cp "${HTTPS_CERT_FILE}" "${cert_path}" | |
chown "${web_user}" "${cert_path}" | |
chmod 0644 "${cert_path}" | |
echo "Copied HTTPS certificate file ${HTTPS_CERT_FILE} to ${cert_path}" > "$OUTPUT" | |
echo "Set ownership of ${cert_path} to ${web_user}" > "$OUTPUT" | |
fi | |
if [[ -n "${HTTPS_PRIVKEY_FILE}" ]]; then | |
rm -f "${privkey_path}" | |
cp "${HTTPS_PRIVKEY_FILE}" "${privkey_path}" | |
chown "${web_user}" "${privkey_path}" | |
chmod 0600 "${privkey_path}" | |
echo "Copied HTTPS private key file ${HTTPS_PRIVKEY_FILE} to ${privkey_path}" > "$OUTPUT" | |
echo "Set ownership of ${privkey_path} to ${web_user}" > "$OUTPUT" | |
fi | |
} | |
########################################## | |
# Prepare local directory structure | |
# Globals: | |
# COMANAGE_MATCH_DIR | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::prepare_local_directory() { | |
# Make sure the directory structure we need is available | |
# in the data volume for $COMANAGE_MATCH_DIR/local | |
local directories | |
declare -a directories=("Config" | |
"logs" | |
"tmp" | |
) | |
local dir | |
local full_path | |
for dir in "${directories[@]}" | |
do | |
full_path="${COMANAGE_MATCH_DIR}/local/${dir}" | |
if [[ ! -d "${full_path}" ]]; then | |
mkdir -p "${full_path}" > "$OUTPUT" 2>&1 | |
echo "Created directory ${full_path}" | |
fi | |
done | |
} | |
########################################## | |
# Prepare web server name | |
# Globals: | |
# COMANAGE_MATCH_VIRTUAL_HOST_FQDN | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::prepare_server_name() { | |
# If COMANAGE_MATCH_VIRTUAL_HOST_FQDN has not been injected try to determine | |
# it from the HTTPS_CERT_FILE. | |
if [[ -z "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then | |
COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -text -noout | | |
sed -n '/X509v3 Subject Alternative Name:/ {n;p}' | | |
sed -E 's/.*DNS:(.*)\s*$/\1/') | |
if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then | |
echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using Subject Alternative Name from x509 certificate" > "$OUTPUT" | |
else | |
COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -subject -noout | | |
sed -E 's/subject=.*CN=(.*)\s*/\1/') | |
if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then | |
echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using CN from x509 certificate" > "$OUTPUT" | |
fi | |
fi | |
fi | |
# Configure Apache HTTP Server with the server name. | |
# This configures the server name for the default Debian | |
# Apache HTTP Server configuration but not the server name used | |
# by any virtual hosts. | |
if [[ -e '/etc/debian_version' ]]; then | |
cat > /etc/apache2/conf-available/server-name.conf <<EOF | |
ServerName ${COMANAGE_MATCH_VIRTUAL_HOST_FQDN:-unknown} | |
EOF | |
a2enconf server-name.conf > "$OUTPUT" 2>&1 | |
fi | |
# Export the server name so that it may be used by | |
# Apache HTTP Server virtual host configurations. | |
export COMANAGE_MATCH_VIRTUAL_HOST_FQDN | |
} | |
########################################## | |
# Clear CakePHP cache files | |
# Globals: | |
# None | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::match_clear_cache() { | |
pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1 | |
./bin/cake schema_cache clear > "$OUTPUT" 2>&1 | |
popd > "$OUTPUT" 2>&1 | |
} | |
########################################## | |
# Run COmanage Match setup shell command | |
# Globals: | |
# COMANAGE_MATCH_ADMIN_USERNAME | |
# COMANAGE_MATCH_DIR | |
# COMANAGE_MATCH_SECURITY_SALT | |
# COMANAGE_MATCH_SECURITY_SEED | |
# OUTPUT | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::match_setup() { | |
# We only want to run the setup script once since it creates | |
# state in the database. | |
local auto_generated_security | |
pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1 | |
echo "Testing if COmanage Match setup has been done previously..." > "$OUTPUT" | |
if ! ./bin/cake databaseSetupAlready > "$OUTPUT" 2>&1; then | |
echo "COmanage Match database is not setup yet..." > "$OUTPUT" | |
rm -f "$COMANAGE_MATCH_DIR/local/Config/security.salt" > "$OUTPUT" 2>&1 | |
echo "Running ./bin/cake setup..." > "$OUTPUT" | |
./bin/cake setup --admin-username "${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT" 2>&1 | |
echo "Set admin username ${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT" | |
auto_generated_security=1 | |
fi | |
popd > "$OUTPUT" 2>&1 | |
comanage_utils::match_clear_cache | |
# If COmanage Match CakePHP security salt has been | |
# injected and the files do not otherwise exist create them. | |
if [[ -n "$COMANAGE_MATCH_SECURITY_SALT" && | |
( -n "$auto_generated_security" || ! -e "$COMANAGE_MATCH_DIR/local/Config/security.salt" ) ]]; then | |
echo "$COMANAGE_MATCH_SECURITY_SALT" > "$COMANAGE_MATCH_DIR/local/Config/security.salt" | |
fi | |
} | |
########################################## | |
# Set tmp directory file ownership | |
# Globals: | |
# COMANAGE_MATCH_DIR | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::tmp_ownership() { | |
# Ensure that the web server user owns the tmp directory | |
# and all children. | |
local tmp_dir | |
local ownership | |
if [[ -e '/etc/debian_version' ]]; then | |
ownership='www-data:www-data' | |
elif [[ -e '/etc/centos-release' ]]; then | |
ownership='apache:apache' | |
fi | |
tmp_dir="${COMANAGE_MATCH_DIR}/local/tmp" | |
chown -R "${ownership}" "${tmp_dir}" | |
echo "Recursively set ownership of ${tmp_dir} to ${ownership}" > "$OUTPUT" | |
} | |
########################################## | |
# Set logs directory file ownership | |
# Globals: | |
# COMANAGE_MATCH_DIR | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::logs_ownership() { | |
# Ensure that the web server user owns the tmp directory | |
# and all children. | |
local logs_dir | |
local ownership | |
if [[ -e '/etc/debian_version' ]]; then | |
ownership='www-data:www-data' | |
elif [[ -e '/etc/centos-release' ]]; then | |
ownership='apache:apache' | |
fi | |
logs_dir="${COMANAGE_MATCH_DIR}/local/logs" | |
chown -R "${ownership}" "${logs_dir}" | |
echo "Recursively set ownership of ${logs_dir} to ${ownership}" > "$OUTPUT" | |
} | |
########################################## | |
# Wait until able to connect to database | |
# Globals: | |
# COMANAGE_MATCH_DIR | |
# OUTPUT | |
# Arguments: | |
# None | |
# Returns: | |
# None | |
########################################## | |
function comanage_utils::wait_database_connectivity() { | |
pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1 | |
# Loop until we are able to open a connection to the database. | |
echo "Testing database connectivity..." > "$OUTPUT" | |
until ./bin/cake databaseConnectivityTest > "$OUTPUT" 2>&1; do | |
>&2 echo "Database is unavailable - sleeping" | |
sleep 1 | |
done | |
echo "Database is available" > "$OUTPUT" | |
popd > "$OUTPUT" 2>&1 | |
} |