# lib/ironic
# Functions to control the configuration and operation of the **Ironic** service

# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
# - ``SERVICE_HOST``
# - ``KEYSTONE_TOKEN_FORMAT`` must be defined

# ``stack.sh`` calls the entry points in this order:
#
# - install_ironic
# - install_ironicclient
# - init_ironic
# - start_ironic
# - stop_ironic
# - cleanup_ironic

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


# Defaults
# --------

# Set up default directories
IRONIC_DIR=$DEST/ironic
IRONICCLIENT_DIR=$DEST/python-ironicclient
IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json

# Support entry points installation of console scripts
IRONIC_BIN_DIR=$(get_python_exec_prefix)

# Ironic connection info.  Note the port must be specified.
IRONIC_SERVICE_PROTOCOL=http
IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:6385}

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


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

# Test if any Ironic services are enabled
# is_ironic_enabled
function is_ironic_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"ir-" ]] && return 0
    return 1
}

# install_ironic() - Collect source and prepare
function install_ironic() {
    git_clone $IRONIC_REPO $IRONIC_DIR $IRONIC_BRANCH
    setup_develop $IRONIC_DIR
}

# install_ironicclient() - Collect sources and prepare
function install_ironicclient() {
    git_clone $IRONICCLIENT_REPO $IRONICCLIENT_DIR $IRONICCLIENT_BRANCH
    setup_develop $IRONICCLIENT_DIR
}

# cleanup_ironic() - Remove residual data files, anything left over from previous
# runs that would need to clean up.
function cleanup_ironic() {
    sudo rm -rf $IRONIC_AUTH_CACHE_DIR
}

# configure_ironic() - Set config files, create data dirs, etc
function configure_ironic() {
    if [[ ! -d $IRONIC_CONF_DIR ]]; then
        sudo mkdir -p $IRONIC_CONF_DIR
    fi
    sudo chown $STACK_USER $IRONIC_CONF_DIR

    # Copy over ironic configuration file and configure common parameters.
    cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
    iniset $IRONIC_CONF_FILE DEFAULT debug True
    inicomment $IRONIC_CONF_FILE DEFAULT log_file
    iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
    iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG

    # Configure Ironic conductor, if it was enabled.
    if is_service_enabled ir-cond; then
        configure_ironic_conductor
    fi

    # Configure Ironic API, if it was enabled.
    if is_service_enabled ir-api; then
        configure_ironic_api
    fi
}

# configure_ironic_api() - Is used by configure_ironic(). Performs
# API specific configuration.
function configure_ironic_api() {
    iniset $IRONIC_CONF_FILE DEFAULT auth_strategy keystone
    iniset $IRONIC_CONF_FILE DEFAULT policy_file $IRONIC_POLICY_JSON
    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
    iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
    iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
    iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api

    cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
}

# configure_ironic_conductor() - Is used by configure_ironic().
# Sets conductor specific settings.
function configure_ironic_conductor() {
    cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
    cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR

    iniset $IRONIC_CONF DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
}

# create_ironic_cache_dir() - Part of the init_ironic() process
function create_ironic_cache_dir() {
    # Create cache dir
    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/api
    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/api
    rm -f $IRONIC_AUTH_CACHE_DIR/api/*
    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/registry
    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/registry
    rm -f $IRONIC_AUTH_CACHE_DIR/registry/*
}

# create_ironic_accounts() - Set up common required ironic accounts

# Tenant               User       Roles
# ------------------------------------------------------------------
# service              ironic     admin        # if enabled
create_ironic_accounts() {

    SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")

    # Ironic
    if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
        IRONIC_USER=$(openstack user create \
            ironic \
            --password "$SERVICE_PASSWORD" \
            --project $SERVICE_TENANT \
            --email ironic@example.com \
            | grep " id " | get_field 2)
        openstack role add \
            $ADMIN_ROLE \
            --project $SERVICE_TENANT \
            --user $IRONIC_USER
        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
            IRONIC_SERVICE=$(openstack service create \
                ironic \
                --type=baremetal \
                --description="Ironic baremetal provisioning service" \
                | grep " id " | get_field 2)
            openstack endpoint create \
                $IRONIC_SERVICE \
                --region RegionOne \
                --publicurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
                --adminurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
                --internalurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT"
        fi
    fi
}


# init_ironic() - Initialize databases, etc.
function init_ironic() {
    # (Re)create  ironic database
    recreate_database ironic utf8

    # Migrate ironic database
    $IRONIC_BIN_DIR/ironic-dbsync

    create_ironic_cache_dir

    # Create keystone artifacts for Ironic.
    create_ironic_accounts
}

# start_ironic() - Start running processes, including screen
function start_ironic() {
    # Start Ironic API server, if enabled.
    if is_service_enabled ir-api; then
        start_ironic_api
    fi

    # Start Ironic conductor, if enabled.
    if is_service_enabled ir-cond; then
        start_ironic_conductor
    fi
}

# start_ironic_api() - Used by start_ironic().
# Starts Ironic API server.
function start_ironic_api() {
    screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
    echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
        die $LINENO "ir-api did not start"
    fi
}

# start_ironic_conductor() - Used by start_ironic().
# Starts Ironic conductor.
function start_ironic_conductor() {
    screen_it ir-cond "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
    # TODO(romcheg): Find a way to check whether the conductor has started.
}

# stop_ironic() - Stop running processes
function stop_ironic() {
    # Kill the Ironic screen windows
    screen -S $SCREEN_NAME -p ir-api -X kill
    screen -S $SCREEN_NAME -p ir-cond -X kill
}


# Restore xtrace
$XTRACE

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