#!/usr/bin/env bash

# -------------------------------------------------------------------------- #
# Copyright 2010-2016, OpenNebula Systems                                    #
#                                                                            #
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
# not use this file except in compliance with the License. You may obtain    #
# a copy of the License at                                                   #
#                                                                            #
# http://www.apache.org/licenses/LICENSE-2.0                                 #
#                                                                            #
# Unless required by applicable law or agreed to in writing, software        #
# distributed under the License is distributed on an "AS IS" BASIS,          #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
# See the License for the specific language governing permissions and        #
# limitations under the License.                                             #
#--------------------------------------------------------------------------- #

get_context_interfaces() {
    env | grep -E "^ETH[0-9]+_VROUTER_IP=" | sed 's/_.*$//' | sort
}

downcase() {
    tr 'ETH' 'eth'
}

get_ip() {
    ip=$(get_iface_var "$1" "IP")

    echo $ip
}

get_vrouter_id() {
    vrouter_id="$VROUTER_KEEPALIVED_ID"

    if [ -z "$vrouter_id" ]; then
        vrouter_id="0"
    fi

    # vrouter_id is a byte
    vrouter_id=$(( $vrouter_id & 255 ))

    if [ $? != 0 ]; then
        vrouter_id="0"
    fi

    echo $vrouter_id
}

get_vrouter_password() {
    password="$VROUTER_KEEPALIVED_PASSWORD"

    echo $password
}

get_check_script() {
    script="$VROUTER_KEEPALIVED_CHECK_SCRIPT"

    echo $script
}

get_iface_var() {
    var_name="$1_$2"
    var=$(eval "echo \"\${$var_name}\"")

    echo $var
}

gen_group() {
    cat <<EOT
vrrp_sync_group router {
  group {
EOT

	for interface in $(get_context_interfaces); do
        vrouter_ip=$(get_iface_var $interface VROUTER_IP)

        if [ -n $vrouter_ip ]; then
            echo "    $interface"
        fi
    done

	cat <<EOT
  }
}

EOT
}

gen_check_script() {
    script="$(get_check_script)"

    if [ -n "$script" ]; then
        cat <<EOT
vrrp_script chk_script {
  script "$script"
  interval 2
  fall 2
  rise 2
}

EOT
    fi
}

gen_auth() {
    password=$(get_vrouter_password)

    if [ -n "$password" ]; then
        cat <<EOT
authentication {
    auth_type PASS
    auth_pass $password
  }
EOT
    fi
}

gen_track() {
    script="$(get_check_script)"

    if [ -n "$script" ]; then
        cat <<EOT
track_script {
    chk_script
  }
EOT
    fi
}

gen_preempt() {
    script="$(get_check_script)"

    if [ -z "$script" ]; then
        echo nopreempt
    fi
}

gen_instances() {
    for interface in $(get_context_interfaces); do
        vrouter_ip=$(get_iface_var $interface VROUTER_IP)
        interface_downcase=$(echo $interface | downcase)

        if [ -n $vrouter_ip ]; then
            cat <<EOT
vrrp_instance $interface {
  state master
  interface $interface_downcase
  virtual_router_id $(get_vrouter_id)
  priority 101
  advert_int 1
  virtual_ipaddress {
    $vrouter_ip
  }
  $(gen_auth)
  $(gen_track)
  $(gen_preempt)
}

EOT
        fi
    done
}

reload_service() {
    service keepalived reload
}

#####

# skip the script if instance is not Virtual Router
if [ -z "${VROUTER_ID}${VROUTER_KEEPALIVED_ID}" ]; then
    exit 0
fi

(

gen_group
gen_check_script
gen_instances

) > /etc/keepalived/keepalived.conf

if [ "$1" == "reconfigure" ]; then
    reload_service
else
    rc-update add keepalived boot
fi
