#!/bin/bash

# debops: run ansible-playbook with some customization
# Copyright (C) 2014 Maciej Delmanowski <drybjed@gmail.com>
# Part of the DebOps project - http://debops.org/


# This program is free software; you can redistribute
# it and/or modify it under the terms of the
# GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General
# Public License along with this program; if not,
# write to the Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# An on-line copy of the GNU General Public License can
# be downloaded from the FSF web page at:
# http://www.gnu.org/copyleft/gpl.html


set -e

# ---- Variable definitions ----

# Set some global constants
declare -r DEBOPS_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/debops"
declare -r DEBOPS_CONFIG=".debops.cfg"
declare -r SCRIPT_NAME="$(basename ${0})"

# Don't check SSH fingerprint on connection (to enable, set INSECURE=1 on the
# command line)
[ -z "${INSECURE}" ] && INSECURE=0

# Paths to look through if '.debops.cfg' is found in local directory
DEBOPS_PLAYBOOKS_PWD_PATHS=(
  "${PWD}/debops-playbooks/playbooks"
)

# Paths to look through if local install is not found
DEBOPS_PLAYBOOKS_INSTALL_PATHS=(
  "${DEBOPS_DATA_HOME}/debops-playbooks/playbooks"
  "/usr/local/share/debops/debops-playbooks/playbooks"
  "/usr/share/debops/debops-playbooks/playbooks"
)

ANSIBLE_INVENTORY_PWD_PATHS=(
  "${PWD}/ansible/inventory"
  "${PWD}/inventory"
)


# ---- Main script ----

# Check if we are in DebOps project directory
if [ ! -f ${PWD}/${DEBOPS_CONFIG} ] ; then
  echo >&2 "${SCRIPT_NAME}: Fatal: not a DebOps project directory" ; exit 1
fi

# Check if ansible-playbook is available
if ! type ansible-playbook > /dev/null 2>&1 ; then
  echo >&2 "${SCRIPT_NAME}: Error: ansible-playbook: command not found" ; exit 1
fi

# Check if playbooks are installed in local directory
if [ -f ${PWD}/${DEBOPS_CONFIG} ] ; then
  for playbook_path in "${DEBOPS_PLAYBOOKS_PWD_PATHS[@]}" ; do
    if [ -f ${playbook_path}/site.yml ] ; then
      debops_playbooks="${playbook_path}"
      break
    fi
  done
fi

# If playbooks have not been found in local directory, look for them in known
# locations
if [ -z "${debops_playbooks}" ] ; then
  for playbook_path in "${DEBOPS_PLAYBOOKS_INSTALL_PATHS[@]}" ; do
    if [ -f ${playbook_path}/site.yml ] ; then
      debops_playbooks="${playbook_path}"
      break
    fi
  done
fi

# Check if Ansible inventory can be found in local directory
if [ -f ${PWD}/${DEBOPS_CONFIG} ] ; then
  for inventory_path in "${ANSIBLE_INVENTORY_PWD_PATHS[@]}" ; do
    if [ -d ${inventory_path} ] ; then
      ansible_inventory="${inventory_path}"
      break
    fi
  done
fi

# Playbooks have not been found, there's no point in going further
if [ -z "${debops_playbooks}" ] ; then
  echo >&2 "${SCRIPT_NAME}: Error: DebOps playbooks not installed" ; exit 1
else

  # If inventory haven't been found, there's no point in going even further
  if [ -z "${ansible_inventory}" ] ; then
    echo >&2 "${SCRIPT_NAME}: Error: Ansible inventory not found" ; exit 1
  else

    # Check if user specified a potential playbook name as the first argument. If
    # yes, use it as the playbook name and remove it from the argument list
    maybe_play="${1}"
    if [ -f ${debops_playbooks}/${maybe_play}.yml ] ; then
      play="${maybe_play}.yml" ; shift
    else
      play="site.yml"
    fi

    export ANSIBLE_HOSTS="${ansible_inventory}"

    # Allow insecure SSH connections if requested
    if [ ${INSECURE} -gt 0 ] ; then
      export ANSIBLE_HOST_KEY_CHECKING=False
    fi

    # Run ansible-playbook with custom environment
    echo "Running Ansible playbook from:"
    echo "${debops_playbooks}/${play} ..."
    ansible-playbook ${debops_playbooks}/${play} "${@}"
  fi
fi

