Skip to content
Permalink
main
Switch branches/tags

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?
Go to file
Updates to support version 1.0.0 release
candidate 2.
1 contributor

Users who have contributed to this file

601 lines (505 sloc) 17.7 KB
#!/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
}