#!/usr/bin/env bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2021, OpenNebula Project, 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.                                             #
#--------------------------------------------------------------------------- #

#
# network module implementation
#

is_network_supported()
{
    if [ -e /etc/sysconfig/network-scripts/ifup ] || \
       [ -e /etc/sysconfig/network/ifup ] ;
    then
        return 0
    fi

    return 1
}

configure_network()
{
    gen_resolvconf
    gen_network_configuration
}

stop_network()
{
    service network stop
}

start_network()
{
    service network start
}

reload_network()
{
    service network restart
}

#
# helper functions
#

# TODO: remove global variables and get rid off exports
#
# to satisfy shellcheck SC2154:
export os_id
export ip
export network
export mask
export cidr
export ip6
export ip6_prefix_length
export ip6_ula
export mac
export dev
export mtu
export gateway
export gateway6
export method
export method6
export metric
export dns
export search_domains
export external
export detach
export all_nameservers
export all_search_domains

gen_iface_conf()
{
    cat <<EOT
BOOTPROTO=none
NETMASK="${mask}"
IPADDR="${ip}"
EOT

    if [ -n "${gateway}" ]; then
        if [ "${config_path}" = "/etc/sysconfig/network" ]; then
            echo "default ${gateway} - ${dev} ${metric:+metric ${metric}}" \
                >> "${config_path}/ifroute-${dev}"
        else
            echo "default via ${gateway} dev ${dev} ${metric:+metric ${metric}}" \
                >> "${config_path}/route-${dev}"
        fi
    fi

    if [ -n "${mtu}" ]; then
        echo "MTU=${mtu}"
    fi
}

gen_dhcp_conf()
{
    echo "BOOTPROTO=dhcp"
}

gen_alias_conf() {
    cat <<EOT
IPADDR${alias_num}="${ip}"
NETMASK${alias_num}="${mask}"
EOT
}

gen_iface6_conf()
{
    if [ "${config_path}" = "/etc/sysconfig/network" ]; then
        echo "IPADDR_6A=${ip6}/${ip6_prefix_length:-64}"

        cat <<EOT >> "/etc/sysconfig/network/ifsysctl-${dev}"
net.ipv6.conf.\$SYSCTL_IF.autoconf = 0
net.ipv6.conf.\$SYSCTL_IF.accept_ra = 0
EOT
    else
        cat <<EOT
IPV6INIT=yes
IPV6ADDR=${ip6}/${ip6_prefix_length:-64}
IPV6_AUTOCONF=no
EOT
    fi

    if [ -n "${ip6_ula}" ]; then
        if [ "${config_path}" = "/etc/sysconfig/network" ]; then
            echo "IPADDR_6B=${ip6_ula}/64"
        else
            ipv6addr_secondaries="${ipv6addr_secondaries} ${ip6_ula}/64"
        fi
    fi

    if [ -n "${gateway6}" ]; then
        if [ "${config_path}" = "/etc/sysconfig/network" ]; then
            echo "default ${gateway6} - ${dev}" >> "/etc/sysconfig/network/ifroute-${dev}"
        else
            echo "IPV6_DEFAULTGW=${gateway6}"
        fi
    fi

    if [ -n "${mtu}" ]; then
        echo "IPV6_MTU=${mtu}"
    fi
}

gen_dhcp6_conf()
{
    if [ "${method6}" = "auto" ] ; then
        cat <<EOT
IPV6INIT=yes
IPV6_AUTOCONF=yes
EOT
    else
        cat <<EOT
IPV6INIT=yes
IPV6_AUTOCONF=yes
DHCPV6C=yes
EOT
    fi
}

gen_alias6_conf()
{
    if [ "${config_path}" = "/etc/sysconfig/network" ]; then
        echo "IPADDR_A6A${alias_num}=${ip6}/${ip6_prefix_length:-64}"
    else
        ipv6addr_secondaries="${ipv6addr_secondaries} ${ip6}/${ip6_prefix_length:-64}"
    fi

    if [ -n "${ip6_ula}" ]; then
        if [ "${config_path}" = "/etc/sysconfig/network" ]; then
            echo "IPADDR_A6B${alias_num}=${ip6_ula}/64"
        else
            ipv6addr_secondaries="${ipv6addr_secondaries} ${ip6_ula}/64"
        fi
    fi
}

gen_network_configuration()
{
    if [ -d /etc/sysconfig/network-scripts ]; then
        config_path=/etc/sysconfig/network-scripts
    elif [ -d /etc/sysconfig/network ]; then
        config_path=/etc/sysconfig/network
    fi

    _context_interfaces=$(get_context_interfaces)

    for _iface in $_context_interfaces; do
        setup_iface_vars "$_iface"

        skip_interface && continue

        # cumulative variable
        ipv6addr_secondaries=''

        {
            rm -f "/etc/sysconfig/network-scripts/route-${dev}"
            rm -f "/etc/sysconfig/network/ifroute-${dev}"
            rm -f "/etc/sysconfig/network/ifsysctl-${dev}"

            cat <<EOT
DEVICE=${dev}
NM_CONTROLLED=no
TYPE=Ethernet
EOT
            if [ "${config_path}" = "/etc/sysconfig/network" ]; then
                echo "STARTMODE=auto"
            else
                echo "ONBOOT=yes"
            fi

            case "${method}" in
                ''|static)
                    [ -n "${ip}" ] && gen_iface_conf
                    ;;
                dhcp)
                    gen_dhcp_conf
                    ;;
            esac

            case "${method6}" in
                ''|static)
                    [ -n "${ip6}" ] && gen_iface6_conf
                    ;;
                auto|dhcp)
                    gen_dhcp6_conf
                    ;;
                disabled)
                    :
                    ;;
            esac

            _aliases=$(get_interface_alias "$_iface")
            alias_num=0

            for _nic_alias in $_aliases; do
                setup_ipadr_vars "$_nic_alias"
                setup_ip6adr_vars "$_nic_alias"
                setup_alias_vars "$_nic_alias"

                if [ -z "${detach}" ]; then
                    if ! is_true "${external}" ; then
                        [ -n "${ip}"  ] && gen_alias_conf
                        [ -n "${ip6}" ] && gen_alias6_conf

                        if [ -n "${ip}${ip6}" ]; then
                            alias_num=$((alias_num + 1))
                        fi
                    fi
                fi
            done

            # on Red Hats, we need just a single configuration
            # entry with all additional IPv6 addresses
            if [ -n "${ipv6addr_secondaries}" ]; then
                echo "IPV6ADDR_SECONDARIES='${ipv6addr_secondaries## }'"
            fi
        } > "${config_path}/ifcfg-${dev}"

        # TODO: do we want this here?
        ifup "${dev}"

    done
}
