#!/usr/bin/python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.


# Creates a tunnel mesh across xenserver hosts
# Enforces broadcast drop rules on ingress GRE tunnels

import cloudstack_pluginlib as lib
import logging
import subprocess
import os
import sys
import subprocess
import time
import json
from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError

from time import localtime as _localtime, asctime as _asctime

def setup_ovs_bridge(bridge, key, cs_host_id):

    res = lib.check_switch()
    if res != "SUCCESS":
        #return "FAILURE:%s" % res
        return 'false'

    logging.debug("About to manually create the bridge:%s" % bridge)
    #set gre_key to bridge
    res = lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
                                     "other_config:gre_key=%s" % key])

    # enable stp
    lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge, "stp_enable=true"])

    logging.debug("Bridge has been manually created:%s" % res)
    if res:
#        result = "FAILURE:%s" % res
        result = 'false'
    else:
        # Verify the bridge actually exists, with the gre_key properly set
        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
                                          bridge, "other_config:gre_key"])
        if key in str(res):
#            result = "SUCCESS:%s" % bridge
            result = 'true'
        else:
#            result = "FAILURE:%s" % res
            result = 'false'

        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other_config:is-ovs-tun-network=True"])
	#get list of hosts using this bridge
        conf_hosts = lib.do_cmd([lib.VSCTL_PATH, "get","bridge", bridge,"other_config:ovs-host-setup"])
	#add cs_host_id to list of hosts using this bridge
        conf_hosts = cs_host_id + (conf_hosts and ',%s' % eval(conf_hosts) or '')
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
                   "other_config:ovs-host-setup=%s" % conf_hosts])

    logging.debug("Setup_ovs_bridge completed with result:%s" % result)
    return result

def setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id):

    res = lib.check_switch()
    if res != "SUCCESS":
        return "FAILURE:%s" % res

    logging.debug("About to manually create the bridge:%s" % bridge)
    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
    logging.debug("Bridge has been manually created:%s" % res)

    # Non empty result means something went wrong
    if res:
        result = "FAILURE:%s" % res
    else:
        # Verify the bridge actually exists
        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])

        res = lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other_config:is-ovs_vpc_distributed_vr_network=True"])
        conf_hosts = lib.do_cmd([lib.VSCTL_PATH, "get","bridge", bridge,"other:ovs-host-setup"])
        conf_hosts = cs_host_id + (conf_hosts and ',%s' % eval(conf_hosts) or '')
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
                   "other_config:ovs-host-setup=%s" % conf_hosts])

        # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
        lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
        lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')

        # add a default flow rule to send uni-cast traffic to L2 lookup table
        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')

        # add a default rule to send unknown mac address to L2 flooding table
        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')

        # add a default rule in L2 flood table to drop packet
        lib.add_flow(bridge, priority=0, table=2, actions='drop')

        # add a default rule in egress table to forward packet to L3 lookup table
        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')

        # add a default rule in L3 lookup table to forward packet to L2 lookup table
        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')

        # add a default rule in ingress table to drop in bound packets
        lib.add_flow(bridge, priority=0, table=5, actions='drop')

        result = "SUCCESS: successfully setup bridge with flow rules"

        logging.debug("Setup_ovs_bridge completed with result:%s" % result)

    return result

def destroy_ovs_bridge(bridge):

    res = lib.check_switch()
    if res != "SUCCESS":
#        return res
        return 'false'

    res = lib.do_cmd([lib.VSCTL_PATH, "del-br", bridge])
    logging.debug("Bridge has been manually removed:%s" % res)
    if res:
#        result = "FAILURE:%s" % res
        result = 'false'
    else:
#        result = "SUCCESS:%s" % bridge
        result = 'true'

    logging.debug("Destroy_ovs_bridge completed with result:%s" % result)
    return result

def create_tunnel(bridge, remote_ip, key, src_host, dst_host):

    logging.debug("Entering create_tunnel")

    res = lib.check_switch()
    if res != "SUCCESS":
        logging.debug("Openvswitch running: NO")
#        return "FAILURE:%s" % res
        return 'false'

    # We need to keep the name below 14 characters
    # src and target are enough - consider a fixed length hash
    name = "t%s-%s-%s" % (key, src_host, dst_host)

    # Verify the bridge to be created
    # NOTE: Timeout should not be necessary anymore
    wait = [lib.VSCTL_PATH, "--timeout=30", "wait-until", "bridge",
                    bridge, "--", "get", "bridge", bridge, "name"]
    res = lib.do_cmd(wait)
    if bridge not in str(res):
        logging.debug("WARNING:Can't find bridge %s for creating " +
                                  "tunnel!" % bridge)
#        return "FAILURE:NO_BRIDGE"
        return 'false'

    logging.debug("bridge %s for creating tunnel - VERIFIED" % bridge)
    tunnel_setup = False
    drop_flow_setup = False
    try:
        # Create a port and configure the tunnel interface for it
        add_tunnel = [lib.VSCTL_PATH, "add-port", bridge,
                                  name, "--", "set", "interface",
                                  name, "type=gre", "options:key=%s" % key,
                                  "options:remote_ip=%s" % remote_ip]
        lib.do_cmd(add_tunnel)
        tunnel_setup = True
        # verify port
        verify_port = [lib.VSCTL_PATH, "get", "port", name, "interfaces"]
        res = lib.do_cmd(verify_port)
        # Expecting python-style list as output
        iface_list = []
        if len(res) > 2:
            iface_list = res.strip()[1:-1].split(b',')
        if len(iface_list) != 1:
            logging.debug("WARNING: Unexpected output while verifying " +
                                      "port %s on bridge %s" % (name, bridge))
#            return "FAILURE:VERIFY_PORT_FAILED"
            return 'false'

        # verify interface
        iface_uuid = iface_list[0]
        verify_interface_key = [lib.VSCTL_PATH, "get", "interface",
                                iface_uuid, "options:key"]
        verify_interface_ip = [lib.VSCTL_PATH, "get", "interface",
                               iface_uuid, "options:remote_ip"]

        key_validation = lib.do_cmd(verify_interface_key)
        ip_validation = lib.do_cmd(verify_interface_ip)

        if not key in str(key_validation) or not remote_ip in str(ip_validation):
            logging.debug("WARNING: Unexpected output while verifying " +
                          "interface %s on bridge %s" % (name, bridge))
#            return "FAILURE:VERIFY_INTERFACE_FAILED"
            return 'false'

        logging.debug("Tunnel interface validated:%s" % verify_interface_ip)
        cmd_tun_ofport = [lib.VSCTL_PATH, "get", "interface",
                                          iface_uuid, "ofport"]
        tun_ofport = lib.do_cmd(cmd_tun_ofport)
        # Ensure no trailing LF
        if tun_ofport.endswith(b'\n'):
            tun_ofport = tun_ofport[:-1]

        try:
            ovs_tunnel_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other_config:is-ovs-tun-network"])
        except:
            ovs_tunnel_network = 'False'
        try:
            ovs_vpc_distributed_vr_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge,
                                                         "other_config:is-ovs_vpc_distributed_vr_network"])
        except:
            ovs_vpc_distributed_vr_network = 'False'

        if ovs_tunnel_network == 'True':
            # add flow entryies for dropping broadcast coming in from gre tunnel
            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                     nw_dst='224.0.0.0/24', actions='drop')
            drop_flow_setup = True

        if ovs_vpc_distributed_vr_network == 'True':
            # add flow rules for dropping broadcast coming in from tunnel ports
            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                     nw_dst='224.0.0.0/24', actions='drop')

            # add flow rule to send the traffic from tunnel ports to L2 switching table only
            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
            lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid])

        logging.debug("Broadcast drop rules added")
#        return "SUCCESS:%s" % name
        return 'true'
    except:
        logging.debug("An unexpected error occurred. Rolling back")
        if tunnel_setup:
            logging.debug("Deleting GRE interface")
            # Destroy GRE port and interface
            lib.del_port(bridge, name)
        if drop_flow_setup:
            # Delete flows
            logging.debug("Deleting flow entries from GRE interface")
            lib.del_flows(bridge, in_port=tun_ofport)
        # This will not cancel the original exception
        raise

def destroy_tunnel(bridge, iface_name):

    logging.debug("Destroying tunnel at port %s for bridge %s"
                            % (iface_name, bridge))
    ofport = get_field_of_interface(iface_name, "ofport")
    lib.del_flows(bridge, in_port=ofport)
    lib.del_port(bridge, iface_name)
#    return "SUCCESS"
    return 'true'

def get_field_of_interface(iface_name, field):
    get_iface_cmd = [lib.VSCTL_PATH, "get", "interface", iface_name, field]
    res = lib.do_cmd(get_iface_cmd)
    return res

if __name__ == '__main__':
    logging.basicConfig(filename="/var/log/cloudstack/agent/ovstunnel.log", format="%(asctime)s - %(message)s", level=logging.DEBUG)
    parser = OptionParser()
    parser.add_option("--key", dest="key")
    parser.add_option("--cs_host_id", dest="cs_host_id")
    parser.add_option("--bridge", dest="bridge")
    parser.add_option("--remote_ip", dest="remote_ip")
    parser.add_option("--src_host", dest="src_host")
    parser.add_option("--dst_host", dest="dst_host")
    parser.add_option("--iface_name", dest="iface_name")
    parser.add_option("--config", dest="config")
    (option, args) = parser.parse_args()
    if len(args) == 0:
        logging.debug("No command to execute")
        sys.exit(1)
    cmd = args[0]
    if cmd == "setup_ovs_bridge":
        setup_ovs_bridge(option.bridge, option.key, option.cs_host_id)
    elif cmd == "destroy_ovs_bridge":
        destroy_ovs_bridge(option.bridge)
    elif cmd == "create_tunnel":
        create_tunnel(option.bridge, option.remote_ip, option.key, option.src_host, option.dst_host)
    elif cmd == "destroy_tunnel":
        destroy_tunnel(option.bridge, option.iface_name)
    elif cmd == "setup_ovs_bridge_for_distributed_routing":
        setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id)
    elif cmd == "configure_ovs_bridge_for_network_topology":
        configure_bridge_for_network_topology(brdige, cs_host_id, config)
    elif cmd == "configure_ovs_bridge_for_routing_policies":
        configure_ovs_bridge_for_routing_policies(bridge, config)
    else:
        logging.debug("Unknown command: " + cmd)
        sys.exit(1)
