# lib/horizon
# Functions to control the configuration and operation of the horizon service

# Dependencies:
#
# - ``functions`` file
# - ``apache`` file
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined

# ``stack.sh`` calls the entry points in this order:
#
# - install_horizon
# - configure_horizon
# - init_horizon
# - start_horizon
# - stop_horizon
# - cleanup_horizon

# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

# Set up default directories
HORIZON_DIR=$DEST/horizon

# local_settings.py is used to customize Dashboard settings.
# The example file in Horizon repo is used by default.
HORIZON_SETTINGS=${HORIZON_SETTINGS:-$HORIZON_DIR/openstack_dashboard/local/local_settings.py.example}

# Tell Tempest this project is present
TEMPEST_SERVICES+=,horizon


# Functions
# ---------

# utility method of setting python option
function _horizon_config_set {
    local file=$1
    local section=$2
    local option=$3
    local value=$4

    if grep -q "^$section" $file; then
        line=$(sed -ne "/^$section/,/^}/ { /^ *'$option':/ p; }" $file)
        if [ -n "$line" ]; then
            sed -i -e "/^$section/,/^}/ s/^\( *'$option'\) *:.*$/\1: $value,/" $file
        else
            sed -i -e "/^$section/a\    '$option': $value," $file
        fi
    else
        echo -e "\n\n$section = {\n    '$option': $value,\n}" >> $file
    fi
}



# Entry Points
# ------------

# cleanup_horizon() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_horizon {
    if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
        # If ``/usr/bin/node`` points into ``$DEST``
        # we installed it via ``install_nodejs``
        if [[ $(readlink -f /usr/bin/node) =~ ($DEST) ]]; then
            sudo rm /usr/bin/node
        fi
    fi
}

# configure_horizon() - Set config files, create data dirs, etc
function configure_horizon {
    setup_develop $HORIZON_DIR
}

# init_horizon() - Initialize databases, etc.
function init_horizon {
    # ``local_settings.py`` is used to override horizon default settings.
    local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
    cp $HORIZON_SETTINGS $local_settings

    if is_service_enabled neutron; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_security_group $Q_USE_SECGROUP
    fi
    # enable loadbalancer dashboard in case service is enabled
    if is_service_enabled q-lbaas; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_lb True
    fi

    # enable firewall dashboard in case service is enabled
    if is_service_enabled q-fwaas; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_firewall True
    fi

    # enable VPN dashboard in case service is enabled
    if is_service_enabled q-vpn; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_vpn True
    fi

    # Create an empty directory that apache uses as docroot
    sudo mkdir -p $HORIZON_DIR/.blackhole

    # Apache 2.4 uses mod_authz_host for access control now (instead of "Allow")
    HORIZON_REQUIRE=''
    if check_apache_version "2.4" ; then
        HORIZON_REQUIRE='Require all granted'
    fi

    local horizon_conf=/etc/$APACHE_NAME/$APACHE_CONF_DIR/horizon.conf
    if is_ubuntu; then
        # Clean up the old config name
        sudo rm -f /etc/apache2/sites-enabled/000-default
        # Be a good citizen and use the distro tools here
        sudo touch $horizon_conf
        sudo a2ensite horizon.conf
    elif is_fedora; then
        sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
    elif is_suse; then
        : # nothing to do
    else
        exit_distro_not_supported "horizon apache configuration"
    fi

    # Remove old log files that could mess with how devstack detects whether Horizon
    # has been successfully started (see start_horizon() and functions::screen_it())
    sudo rm -f /var/log/$APACHE_NAME/horizon_*

    # Configure apache to run horizon
    sudo sh -c "sed -e \"
        s,%USER%,$APACHE_USER,g;
        s,%GROUP%,$APACHE_GROUP,g;
        s,%HORIZON_DIR%,$HORIZON_DIR,g;
        s,%APACHE_NAME%,$APACHE_NAME,g;
        s,%DEST%,$DEST,g;
        s,%HORIZON_REQUIRE%,$HORIZON_REQUIRE,g;
    \" $FILES/apache-horizon.template >$horizon_conf"
}

# install_horizon() - Collect source and prepare
function install_horizon {
    # Apache installation, because we mark it NOPRIME
    install_apache_wsgi

    git_clone $HORIZON_REPO $HORIZON_DIR $HORIZON_BRANCH $HORIZON_TAG
}

# start_horizon() - Start running processes, including screen
function start_horizon {
    restart_apache_server
    screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
}

# stop_horizon() - Stop running processes (non-screen)
function stop_horizon {
    stop_apache_server
}


# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
