#!/bin/bash

UBUNTU_USER="ubuntu"
UBUNTU_IMAGE_NAME="Ubuntu Server 14.04 (amd64) - Ferry Image"

#
# Ferry configuration
#
FERRY_INSTANCE="Ferry"
FERRY_IMAGE="Ferry Server"

#
# Global vars
#
FLOATING_IP="127.0.0.1"
TOKEN=""

function start_ubuntu_image {
    # 
    # Start the base image and attach a floating IP so that
    # we can interact with it.
    #
    nova boot --flavor "${OS_FLAVOR}" --image "${BASE_IMAGE}" --key-name "${OS_KEY_NAME}" --security-groups "${OS_SEC}" $FERRY_INSTANCE

    # Wait for the instance to boot up
    STATUS=""
    while [[ $STATUS != "ACTIVE" ]]; do
	STATUS=$(nova show --minimal $FERRY_INSTANCE | grep status | awk '{print $4}')
	sleep 2
    done

    # Create a floating IP and then associate the instance with it. 
    FLOATING_IP=$(neutron --os-token $TOKEN floatingip-create $EXT_NET -f value | sed -n 3p )
    nova floating-ip-associate $FERRY_INSTANCE $FLOATING_IP
}

function check_openstack_credentials {
    #
    # Check if the user has specified the various OpenStack credentials
    # 
    : ${OS_USERNAME?"Please set OS_USERNAME to your username"}
    : ${OS_PASSWORD?"Please set OS_PASSWORD to your password"}
    : ${OS_TENANT_ID?"Please set OS_TENANT_ID to your tenant ID"}
    : ${OS_TENANT_NAME?"Please set OS_TENANT_NAME to your tenant name"}
    : ${OS_AUTH_URL?"Please set OS_AUTH_URL to the Keystone URL"}
    : ${OS_REGION_NAME?"Please set OS_REGION_NAME to the OpenStack region"}
}

function check_install_credentials {
    #
    # Check if the user has specified the various OpenStack credentials
    # 
    check_openstack_credentials
    : ${OS_FLAVOR?"Please set OS_FLAVOR to the default flavor name (e.g., standard.xsmall)"}
    : ${OS_KEY_NAME?"Pleas set OS_KEY_NAME to the name of the ssh key (e.g., my-key)"}
    : ${OS_KEY_LOCATION?"Please set OS_KEY_LOCATION to the location of the private key"}
    : ${OS_SEC?"Please set OS_SEC to your default security group"}
    : ${OS_EXT_NET?"Please set OS_EXT_NET to the ID of your external network"}
}

function get_keystone_token {
    #
    # Download a token from keystone. Used by other ClI tools (Neutron, etc.). 
    # 
    TOKEN=$(keystone token-get 2> /dev/null | sed -n '5p' | awk '{print $4}')
}

function save_ferry_image {
    #
    # Save the running instance as a new image. 
    #
    nova image-create $FERRY_INSTANCE $FERRY_IMAGE
}

function import_ubuntu_image {
    # 
    # Download and import a base Ubuntu image
    # into the OpenStack cluster. 
    #

    if [[ -z $UBUNTU_IMAGE ]]; then
	echo -e "Ubuntu image not found. Importing..."

	# First need to download the Ubuntu 14.04 image and
	# untar it so that we can get to the image.
	wget https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img

	# Now upload to Glance. 
	glance image-create --name $UBUNTU_IMAGE_NAME --disk-format=raw --container-format=bare --file=./trusty-server-cloudimg-amd64-disk1.img
    fi
}

function install_on_openstack {
    # Check for OpenStack credentials
    echo -e "Checking OpenStack install credentials"
    check_install_credentials
    get_keystone_token

    # We need to check if the user has specified
    # a base Ubuntu image. If not, we need to import one. 
    echo -e "Checking for Ubuntu image"
    import_ubuntu_image

    # Now instantiate a new Ubuntu instance and associate
    # a floating IP with that instance. 
    echo -e "Starting Ubuntu instance"
    start_ubuntu_image

    # Now we'll need to install Ferry on that instance.
    echo -e "Installing Ferry"
    install_ferry $UBUNTU_USER $FLOATING_IP

    # Finally save the new Ferry image. 
    echo -e "Saving Ferry image"
    save_ferry_image
}

function install_ferry {
    #
    # Install Ferry on the remote instance. 
    #
    USER=$1
    SERVER=$2

    # Cmds to run. 
    Cmds[0] = "apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9"
    Cmds[1] = "sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\""
    Cmds[2] = "apt-get --yes install xfsprogs python-pip python-dev git lxc-docker-0.8.1"
    Cmds[3] = "cd /root;git clone https://github.com/opencore/ferry.git"
    Cmds[4] = "cd /root/ferry;python setup.py install"
    Cmds[5] = "adduser --disabled-password --gecos \"\" ferry"
    Cmds[6] = "usermod -a -G sudo ferry"
    Cmds[7] = "usermod -a -G docker ferry"
    Cmds[8] = "mkdir -p /ferry/master"
    Cmds[9] = "export FERRY_DIR=/ferry/master"
    Cmds[10] = "ferry -u install"
    Cmds[11] = "ferry server"
    Cmds[12] = "ferry pull image://ferry/heatserver"
    Cmds[13] = "rm -rf /root/ferry"

    for cmd in "${Cmds[@]}"
    do
	if [[ $SERVER == "localhost" ]]; then
	    # Just execute the command locally.
	    cmd
	else
	    # Execute the command via ssh. This assumes that the user
	    # has password-less access to the external machine.
	    ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${OS_KEY_LOCATION}/${OS_KEY}.pem -t -t ${SERVER} '${cmd}'
        fi
    done
}


function print_net_info {
    echo ""    
    echo "Networks:"
    neutron --os-token $TOKEN --os-url $1 net-list 2> /dev/null

    echo ""
    echo "Routers:"
    neutron --os-token $TOKEN --os-url $1 router-list 2> /dev/null
}

# 
# Check the arguments so that we know what the user wants to do. 
# 
if [[ $# == 0 ]]; then
    # The user just wants to install Ferry on some
    # Ubuntu-based machine. 
    echo -e "Installing Ferry on localhost..."
    echo -e "Please ensure that localhost is running Ubuntu 14.04"
    install_ferry "root" "localhost"
elif [[ $1 == "os-info" ]]; then
    check_openstack_credentials
    get_keystone_token

    # Now find out the list of servers, etc. 
    echo "====US West===="
    print_net_info "https://region-a.geo-1.network.hpcloudsvc.com"

    echo ""
    echo "====US East===="
    print_net_info "https://region-b.geo-1.network.hpcloudsvc.com"
elif [[ $1 == "naked" ]]; then
    # The user just wants to install Ferry on some
    # Ubuntu-based machine. 
    echo -e "Installing Ferry on ${2}@${3}..."
    echo -e "Please ensure that ${3} is running Ubuntu 14.04"
    install_ferry $2 $3
elif [[ $2 == "openstack" ]]; then
    echo -e "Installing Ferry on OpenStack..."
    install_on_openstack
fi

