#!/usr/bin/python
# 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 commands
import os
import sys
import subprocess
import time
import XenAPIPlugin

sys.path.append("/opt/xensource/sm/")
import util

from time import localtime as _localtime, asctime as _asctime

xePath = "/opt/xensource/bin/xe"
lib.setup_logging("/var/log/cloud/ovstunnel.log")

def block_ipv6_v5(bridge):
    lib.add_flow(bridge, priority=65000, dl_type='0x86dd', actions='drop')


def block_ipv6_v6(bridge):
    lib.add_flow(bridge, priority=65000, proto='ipv6', actions='drop')


block_ipv6_handlers = {
        '5': block_ipv6_v5,
        '6': block_ipv6_v6}


def echo(fn):
    def wrapped(*v, **k):
        name = fn.__name__
        logging.debug("#### VMOPS enter  %s ####" % name)
        res = fn(*v, **k)
        logging.debug("#### VMOPS exit  %s ####" % name)
        return res
    return wrapped


@echo
def setup_ovs_bridge(session, args):
    bridge = args.pop("bridge")
    key = args.pop("key")
    xs_nw_uuid = args.pop("xs_nw_uuid")
    cs_host_id = args.pop("cs_host_id")

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

    logging.debug("About to manually create the bridge:%s" % bridge)
    # create a bridge with the same name as the xapi network
    # also associate gre key in other config attribute
    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
                                     "--", "set", "bridge", bridge,
                                     "other_config:gre_key=%s" % key])
    logging.debug("Bridge has been manually created:%s" % res)
    # TODO: Make sure xs-network-uuid is set into external_ids
    lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
                            "external_ids:xs-network-uuid=%s" % xs_nw_uuid])

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

    # Non empty result means something went wrong
    if res:
        result = "FAILURE:%s" % res
    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 res:
            result = "SUCCESS:%s" % bridge
        else:
            result = "FAILURE:%s" % res
        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                   "other-config:is-ovs-tun-network=True"])
        # Finally note in the xenapi network object that the network has
        # been configured
        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
                                "bridge=%s" % bridge, "--minimal"])
        conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get",
                                "uuid=%s" % xs_nw_uuid,
                                "param-name=other-config",
                                "param-key=ovs-host-setup"])
        host_found = False
        if conf_hosts:
            setup_hosts = conf_hosts.split(",")
            for host in setup_hosts:
                if host == cs_host_id:
                    host_found = True
        if not host_found:
            conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
            lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                       "other-config:ovs-host-setup=%s" % conf_hosts])

        # BLOCK IPv6 - Flow spec changes with ovs version
        # Temporarily no need BLOCK IPv6
#        host_list_cmd = [lib.XE_PATH, 'host-list', '--minimal']
#        host_list_str = lib.do_cmd(host_list_cmd)
#        host_uuid = host_list_str.split(',')[0].strip()
#        version_cmd = [lib.XE_PATH, 'host-param-get', 'uuid=%s' % host_uuid,
#                                   'param-name=software-version',
#                                   'param-key=product_version']
#        version = lib.do_cmd(version_cmd).split('.')[0]
#        block_ipv6_handlers[version](bridge)
    logging.debug("Setup_ovs_bridge completed with result:%s" % result)
    return result


@echo
def setup_ovs_bridge_for_distributed_routing(session, args):
    bridge = args.pop("bridge")
    key = args.pop("key")
    xs_nw_uuid = args.pop("xs_nw_uuid")
    cs_host_id = args.pop("cs_host_id")

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

    logging.debug("About to manually create the bridge:%s" % bridge)
    # create a bridge with the same name as the xapi network
    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])

    logging.debug("Bridge has been manually created:%s" % res)
    # TODO: Make sure xs-network-uuid is set into external_ids
    lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
                            "external_ids:xs-network-uuid=%s" % xs_nw_uuid])

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

        # Finally note in the xenapi network object that the network has
        # been configured
        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
                                "bridge=%s" % bridge, "--minimal"])
        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                   "other-config:is-ovs-vpc-distributed-vr-network=True"])
        conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get",
                                "uuid=%s" % xs_nw_uuid,
                                "param-name=other-config",
                                "param-key=ovs-host-setup"])
        host_found = False
        if conf_hosts:
            setup_hosts = conf_hosts.split(",")
            for host in setup_hosts:
                if host == cs_host_id:
                    host_found = True
        if not host_found:
            conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
            lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                       "other-config:ovs-host-setup=%s" % conf_hosts])

        # first clear the default rule (rule for 'NORMAL' processing which makes a bridge simple L2 learn & flood switch)
        lib.del_flows(bridge, table=0)

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

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

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

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

        # add a default rule in egress ACL table to forward packet to L3 lookup table
        lib.add_flow(bridge, priority=0, table=lib.EGRESS_ACL_TABLE, actions='resubmit(,%s)'%lib.L3_LOOKUP_TABLE)

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

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

        # initialize the sequence number for the bridge
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:topology-update-sequence-number=0"])
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other-config:route-policy-update-sequence-number=0"])

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

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

@echo
def destroy_ovs_bridge(session, args):
    bridge = args.pop("bridge")
    this_host_id = args.pop("cs_host_id")
    res = lib.check_switch()
    if res != "SUCCESS":
        return res
    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
    else:
        # Note that the bridge has been removed on xapi network object
        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
                                "bridge=%s" % bridge, "--minimal"])
        conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get",
                                "uuid=%s" % xs_nw_uuid,
                                "param-name=other-config",
                                "param-key=ovs-host-setup"])
        new_conf_hosts = ""
        hosts = conf_hosts.split(',')
        for host in hosts:
            if str(host) == str(this_host_id):
                continue
            new_conf_hosts = host + "," + new_conf_hosts
        new_conf_hosts = new_conf_hosts[:-1]
        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
                   "other-config:ovs-host-setup=%s" % new_conf_hosts])
        result = "SUCCESS:%s" % bridge

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


@echo
def create_tunnel(session, args):
    bridge = args.pop("bridge")
    remote_ip = args.pop("remote_ip")
    gre_key = args.pop("key")
    src_host = args.pop("from")
    dst_host = args.pop("to")
    network_uuid = args.pop("cloudstack-network-id")

    return lib.create_tunnel(bridge, remote_ip, gre_key, src_host, dst_host, network_uuid)

@echo
def destroy_tunnel(session, args):
    bridge = args.pop("bridge")
    iface_name = args.pop("in_port")
    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"


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

def is_xcp(session, args):
    host_list_cmd = [lib.XE_PATH, 'host-list', '--minimal']
    host_list_str = lib.do_cmd(host_list_cmd)
    host_uuid = host_list_str.split(',')[0].strip()

    status, output = commands.getstatusoutput("xe host-param-list uuid="+host_uuid+" | grep platform_name")
    if (status != 0):
       return "FALSE"

    platform_cmd = [lib.XE_PATH, 'host-param-get', 'uuid=%s' % host_uuid,
                               'param-name=software-version',
                               'param-key=platform_name']
    platform = lib.do_cmd(platform_cmd).split('.')[0]
    return platform

def getLabel(session, args):
    i = 0
    pif_list_cmd = [lib.XE_PATH, 'pif-list', '--minimal']
    pif_list_str = lib.do_cmd(pif_list_cmd)
    while True:
	pif_uuid = pif_list_str.split(',')[i].strip()
	network_cmd = [lib.XE_PATH, 'pif-param-get', 'uuid=%s' % pif_uuid, 'param-name=network-uuid']
	network_uuid = lib.do_cmd(network_cmd).split('.')[0]
	iface_cmd = [lib.XE_PATH, 'network-param-get', 'uuid=%s' % network_uuid, 'param-name=bridge']
	iface = lib.do_cmd(iface_cmd)
	status,output = commands.getstatusoutput("ifconfig "+iface+" | grep inet")
	if (status != 0):
		i += 1
		continue
    	label_cmd = [lib.XE_PATH, 'network-param-get', 'uuid=%s' % network_uuid, 'param-name=name-label']
    	label = lib.do_cmd(label_cmd).split('.')[0]
    	return label
    return False

@echo
def configure_ovs_bridge_for_network_topology(session, args):
    bridge = args.pop("bridge")
    json_config = args.pop("config")
    this_host_id = args.pop("host-id")
    sequence_no = args.pop("seq-no")

    # get the last update sequence number
    last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other-config:topology-update-sequence-number"])
    last_seq_no = last_seq_no[1:-1]
    if long(sequence_no) > long(last_seq_no):
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
                    "other-config:topology-update-sequence-number=%s"%sequence_no])
        return lib.configure_vpc_bridge_for_network_topology(bridge, this_host_id, json_config, sequence_no)
    else:
        return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \
                " update received and applied with sequence number %s" %last_seq_no

@echo
def configure_ovs_bridge_for_routing_policies(session, args):
    bridge = args.pop("bridge")
    json_config = args.pop("config")
    sequence_no = args.pop("seq-no")

    # get the last update sequence number
    last_seq_no = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge,
                              "other-config:route-policy-update-sequence-number"])
    last_seq_no = last_seq_no[1:-1]
    if long(sequence_no) > long(last_seq_no):
        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
                    "other-config:route-policy-update-sequence-number=%s"%sequence_no])
        return lib.configure_vpc_bridge_for_routing_policies(bridge, json_config, sequence_no)
    else:
        return "SUCCESS: Ignoring the update with the sequence number %s" %sequence_no + " as there is already recent" \
                " update received and applied with sequence number %s" %last_seq_no

if __name__ == "__main__":
    XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,
                           "destroy_tunnel": destroy_tunnel,
                           "setup_ovs_bridge": setup_ovs_bridge,
                           "destroy_ovs_bridge": destroy_ovs_bridge,
                           "is_xcp": is_xcp,
                           "getLabel": getLabel,
                           "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing,
                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology,
                           "configure_ovs_bridge_for_routing_policies": configure_ovs_bridge_for_routing_policies})
