#!/bin/bash
#ECS IPv6 - debian

#****************************global*****************************
tool_name=$0
SYS_TYPE=""
SYS_VERSION=""

#***************************end_value***************************
end_value=0


#*****************************error*****************************
ERROR_NON_INTERFACES=100 #interfaces do not exist
ERROR_INVAILD_OPTION=101 #invalid option
ERROR_DEV_NO_EXIST=102   #specified device does not exist


function modify_conf_forDebian() {
    local conf_file=$1
    local eth=$2
    local str1="iface ${eth} inet dhcp"
    local str2="iface ${eth} inet6 dhcp\n    pre-up sleep 3"

    if [ "$(cat "$conf_file" | grep "${str1}")" ] && [ ! "$(cat "$conf_file" | grep "${str2}")" ];then
        sed -i "/${str1}/a${str2}" "$conf_file"
    fi
}

function modify_conf_forUbuntu() {
    local conf_file1=$1
    local conf_file18=$2
    local conf_file2=$3
    local eth=$4
    local str1="iface ${eth} inet dhcp"
    local str2="iface ${eth} inet6 dhcp"
    
    if [[ ${SYS_VERSION} == "16" ]];then
        if [ "$(cat "${conf_file1}" | grep "${str1}")" ] && [ ! "$(cat "${conf_file1}" | grep "${str2}")" ];then
            sed -i "/${str1}/a${str2}" "$conf_file1"
        fi
    elif [[ ${SYS_VERSION} == "18" ]];then
        if [ "$(cat "${conf_file18}" | grep "dhcp6:*")" ];then
            sed -i "/dhcp6: no/d" "$conf_file18"
        fi
        if [ "$(cat "${conf_file18}" | grep  "$eth")" ] && [ ! "$(cat "${conf_file18}" | grep -A1 "$eth" | grep "dhcp6:*")" ];then
            sed -i "/${eth}/a\            dhcp6: yes" "$conf_file18"
        fi
    fi

    if [ -n "$(cat "${conf_file2}")" ] && [ 0 -ne ${num=$(cat ${conf_file2} | grep -n "network" | awk -F: '{print $1}')} ];then
        NUM=`expr $num + 1`
        sed -i "${NUM}s/config:.*$/config: disabled/g" "${conf_file2}"
    fi
}

function check_interface(){
    local interface=$1
    local interface_dir="/sys/class/net/$interface"

    if [ -d $interface_dir ];then
        echo 1
    else 
        echo 0
    fi
}

function get_interfaces(){
    local interfaces=""
    local net_dir="/sys/class/net/"

    if [ ! -d $net_dir ];then
        echo ""
        return
    fi
    interfaces=$(ls $net_dir | grep '^eth[0-9]\+$')
    echo "$interfaces"
}

function network_restart () {
    local eth=$1

    if [[ ${SYS_TYPE} = "debian" ]];then
        service networking restart
    elif [[ ${SYS_TYPE}${SYS_VERSION} = "ubuntu16" ]];then
        ifdown $eth; ifup $eth
    elif [[ ${SYS_TYPE}${SYS_VERSION} = "ubuntu18" ]];then
        netplan apply
    fi
}

function ipv6_dhcp(){
    local inf=$1
    local ifcfg_file="/etc/network/interfaces"
    local ifcfg_file18="/etc/netplan/01-netcfg.yaml"
    local cloud_cfg="/etc/cloud/cloud.cfg"

    echo "Set up dynamic ipv6 for $inf"
    if [[ ${SYS_TYPE} = "debian" ]] && [ -f "$ifcfg_file" ];then
        modify_conf_forDebian "$ifcfg_file" "$inf"
    elif [[ ${SYS_TYPE} = "ubuntu" ]] && [ -f "${ifcfg_file}" ];then
        modify_conf_forUbuntu "${ifcfg_file}" "${ifcfg_file18}" "${cloud_cfg}" "$inf"
    else
        echo "$ifcfg_file does not exist" 
    fi
    network_restart "$inf"
}

function config_ipv6() {
    local interfaces=""
    interfaces=$(get_interfaces)
    if [ -z "$interfaces" ];then
        echo "[error] interfaces do not exist"
        end_value=$ERROR_NON_INTERFACES
        exit $end_value
    fi
    for inf in $interfaces;do
        if [ $(check_interface $inf) -eq 1 ];then
            ipv6_dhcp "$inf"
        fi
    done
}

function show_usage(){
    cat <<EOF
    Usage: $tool_name [OPTION...]
    Examples:
    $tool_name --help                            # show usage
    $tool_name --dev [dev]                       # specified device to config ipv6
        e.g. $tool_name --dev eth0
    $tool_name                                   # auto config all device ipv6
EOF

}

function get_opt(){
    if [ "$#" == 0 ];then
        echo "Set up dynamic ipv6 for all devs"
        config_ipv6
    else
        local option=$1
        case $option in
            --help)
                show_usage;;
            --dev)
                dev_arg=$2
                if [ -z $dev_arg ];then
                    echo "[error] dev parameter is empty"
                    exit $ERROR_INVAILD_OPTION
                fi
                if [ $(check_interface $dev_arg) -eq 1 ];then
                    ipv6_dhcp $dev_arg
                else
                   echo "[error] $dev does not exist"
                   exit $ERROR_DEV_NO_EXIST
                fi;;
            *)
                echo "Invalid option !"
                show_usage
                exit $ERROR_INVAILD_OPTION;;
        esac
    fi

}

function get_osversion() {
    local os_file="/etc/debian_version"
    local lsb_release="/etc/lsb-release"
    
    if [ -e ${os_file} ];then
        SYS_TYPE='debian'
    fi    
    
    if [ -e "${lsb_release}" ] && [ -n "$(grep -i 'ubuntu' "${lsb_release}")" ];then
        SYS_TYPE='ubuntu'
        if [ -n "$(grep '14\.[0-9]' ${lsb_release})" ];then
            SYS_VERSION=14
            exit
        elif [ -n "$(grep '16\.[0-9]' ${lsb_release})" ];then 
            SYS_VERSION=16
        elif [ -n "$(grep '18\.[0-9]' ${lsb_release})" ];then
            SYS_VERSION=18
        fi
    fi
}

get_osversion
get_opt "$@"
