#!/bin/bash

inventory="inventories/testing.erb"
group="ands"

usage() { 
    cat << END
Usage: $0 [-i inventory] [-g group] <action> [extra-args-to-ansible]

Parameters:
    inventory           - specifies name of inventory to use (testing, staging, production)
    group               - specifies node group to use if role is considered in action
    
Actions:
    -h                  - show help and exit

 Initial system installation
    all                 - full install, all the following steps in sequence:
    local               - configure local ssh client
    network             - configure network interfaces
    prepare             - perform all required pre-configuration before setting openshift
    openshift           - setup OpenShift cluster
    gluster             - configure gluster software and volumes
    configure           - configures OpenShift cluster (Storage, Users, OpenVPN tunnels)
    projects            - installs configuration files and OpenShift resources for KaaS and other configured projects

 Additional services
    cifs                - install plugin for mounting Samba/CIFS volumes in pods
    ganesha             - provide external nfs access to gluster volumes

 Maintenance
    health              - cluster health checks
    maintain            - check and fix running configuration
    upgrade             - upgrade to a new version (Dangerous)
    migrate <from> <to> - migrate GlusterFS bricks to a new server

 Scaling the cluster
    masters             - complete action: prepares the masters/nodes, scales up the cluster, and reconfigures storage (if necessary)
    nodes               - complete action: prepares the nodes, scales up the cluster, and reconfigures storage (if necessary)
    prepare             - prepares the new nodes
    openshift-masters   - scales OpenShift cluster with additional masters & nodes
    openshift-nodes     - scales OpenShift cluster with additional nodes
    openshift-etcd      - scales etcd cluster (if for some reason it was not performed during master/nodes scale-up)
    openshift-gluster   - scale gluster pods and adapts heketi topology (if not performed during master/nodes scale-up)
    configure           - Configures new nodes (Storage, Users, OpenVPN tunnels)
 
 Configuration of new resources, etc.
    users               - configure user roles & passwords
    storage             - reconfigures Gluster and OpenShift volumes
    projects            - reconfigures OpenShift resources if necessary
    add_project <name>  - add a new OpenShift namespace
    project <name>      - reconfigures a single OpenShift namespace
    project_groups <n>  - reconfigures fs groups for a single OpenShift namespace (required for Ganesha)
    apps <prj> [app]    - only re-generates templates for the specific namespaces (or even only specific application)
    templates           - Regenerate global templates (roles, etc.)
    templates <prj> [t] - Regenerate specified templates, i.e. 'setup.sh templates adei 01-webdav-secret.yml'
    vpn                 - reconfigure VPN tunnels
    certs               - re-generate OpenShift x509 certificates
    check               - check current setup and report if any maintenace should be peformed
    setup <type>        - executes specific configuration task from ands-openshift
                          Tasks: users, ssh, storage, heketi
 ADEI configuration
    adei_template       - Regenerate ADEI template

 Host system managment
    software            - Install additionaly configured software
    monitor             - Install monitoring scripts
    backup              - Install backup scripts
    current             - Current managmenet playbook with various temorary actions

 Custom actions
    playbook.yml        - execute the specified playbook (after ands_facts)
    role                - generates temporary playbook and executes the role

 Ansible option
    --limit <host>      - only execute rules on the specified host
    
END
    echo
    [ -n "$1" ] && echo "Error: $1"
    exit
}

apply() {
    export ANSIBLE_HOST_KEY_CHECKING=False

    [ -n "$1" ] || usage "No action specified"

    action=$1
    shift 1

    if [ -f "$action" ]; then
        if [[ "$action" == anslib/* ]]; then
            echo "Executing a library playbook '$action'"
            cat <<END  > playbooks/tmp_play.yml
- name: Common setup procedures
  hosts: $group
  remote_user: root
  roles:
    - { role: ands_facts }
    - { role: ands_network, action: install_pre }

- import_playbook: ../anslib/openshift-ansible/playbooks/prerequisites.yml
- import_playbook: ../$action

- name: Common setup procedures
  hosts: $group
  remote_user: root
  roles:
    - { role: ands_network, action: install_post }
END
            playbook="playbooks/tmp_play.yml"
            clean="playbooks/tmp_play.*"
        else
            playbook=$action
        fi
    elif [ -d "roles/$action" ]; then
        role=$action
    else
        usage "Role '$action' is not existing"
    fi

    clean=""
    if [ -z "$playbook" ]; then
        echo "Executing a specific role '$role' on '$group'"
        playbook="playbooks/tmp_role.yml"
        clean="playbooks/tmp_role.*"
    
        cat <<END  > playbooks/tmp_role.yml
- name: Common setup procedures
  hosts: $group
  remote_user: root
  roles:
    - ands_facts
    - $role
END
    fi
    
#    ansible-playbook -vvv --vault-password-file .vault-pass -i $inventory $playbook $@
    ansible-playbook --vault-password-file .vault-pass -i $inventory $playbook "$@"
    
    if [ -n "$clean" ]; then
        rm -rf "$clean"
    fi

    return $?
}

while getopts ":i:g:h" o; do
    case "${o}" in
        h)
            usage
            ;;
        i)
            inventory=${OPTARG}
            [ -f $inventory ] || [ -f inventories/${inventory}.erb ] || usage "Specified inventory '$inventory' is not found"
            [ -f $inventory ] || inventory=inventories/${inventory}.erb 
            ;;
        g)
            group=${OPTARG}
            ;;
        \?)
            usage "Invalid option: -$OPTARG"
            ;;
        :)
            usage "Option -$OPTARG requires an argument"
            ;;
        *)
            usage
            ;;
    esac
done

shift $((OPTIND-1))
