# Quantum Open vSwtich plugin
# ---------------------------

# Save trace setting
MY_XTRACE=$(set +o | grep xtrace)
set +o xtrace

source $TOP_DIR/lib/quantum_plugins/ovs_base

function quantum_plugin_create_nova_conf() {
    _quantum_ovs_base_configure_nova_vif_driver
    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $FLAT_NETWORK_BRIDGE
    fi
}

function quantum_plugin_install_agent_packages() {
    _quantum_ovs_base_install_agent_packages
}

function quantum_plugin_configure_common() {
    Q_PLUGIN_CONF_PATH=etc/quantum/plugins/openvswitch
    Q_PLUGIN_CONF_FILENAME=ovs_quantum_plugin.ini
    Q_DB_NAME="ovs_quantum"
    Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
}

function quantum_plugin_configure_debug_command() {
    _quantum_ovs_base_configure_debug_command
}

function quantum_plugin_configure_dhcp_agent() {
    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager quantum.agent.dhcp_agent.DhcpAgentWithStateReport
}

function quantum_plugin_configure_l3_agent() {
    _quantum_ovs_base_configure_l3_agent
    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager quantum.agent.l3_agent.L3NATAgentWithStateReport
}

function quantum_plugin_configure_plugin_agent() {
    # Setup integration bridge
    _quantum_ovs_base_setup_bridge $OVS_BRIDGE
    _quantum_ovs_base_configure_firewall_driver

    # Setup agent for tunneling
    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
        # Verify tunnels are supported
        # REVISIT - also check kernel module support for GRE and patch ports
        OVS_VERSION=`ovs-vsctl --version | head -n 1 | awk '{print $4;}'`
        if [ $OVS_VERSION \< "1.4" ] && ! is_service_enabled q-svc ; then
            die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
        fi
        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
        iniset /$Q_PLUGIN_CONF_FILE OVS local_ip $HOST_IP
    fi

    # Setup physical network bridge mappings.  Override
    # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
    # complex physical network configurations.
    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
        OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE

        # Configure bridge manually with physical interface as port for multi-node
        sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
    fi
    if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings $OVS_BRIDGE_MAPPINGS
    fi
    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-openvswitch-agent"

    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
        Q_RR_DOM0_COMMAND="$QUANTUM_DIR/bin/quantum-rootwrap-xen-dom0 $Q_RR_CONF_FILE"

        # For now, duplicate the xen configuration already found in nova.conf
        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_url "$XENAPI_CONNECTION_URL"
        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_username "$XENAPI_USER"
        iniset $Q_RR_CONF_FILE XENAPI xenapi_connection_password "$XENAPI_PASSWORD"

        # Under XS/XCP, the ovs agent needs to target the dom0
        # integration bridge.  This is enabled by using a root wrapper
        # that executes commands on dom0 via a XenAPI plugin.
        iniset /$Q_PLUGIN_CONF_FILE AGENT root_helper "$Q_RR_DOM0_COMMAND"

        # FLAT_NETWORK_BRIDGE is the dom0 integration bridge.  To
        # ensure the bridge lacks direct connectivity, set
        # VM_VLAN=-1;VM_DEV=invalid in localrc
        iniset /$Q_PLUGIN_CONF_FILE OVS integration_bridge $FLAT_NETWORK_BRIDGE

        # The ovs agent needs to ensure that the ports associated with
        # a given network share the same local vlan tag.  On
        # single-node XS/XCP, this requires monitoring both the dom0
        # bridge, where VM's are attached, and the domU bridge, where
        # dhcp servers are attached.
        if is_service_enabled q-dhcp; then
            iniset /$Q_PLUGIN_CONF_FILE OVS domu_integration_bridge $OVS_BRIDGE
            # DomU will use the regular rootwrap
            iniset /$Q_PLUGIN_CONF_FILE AGENT domu_root_helper "$Q_RR_COMMAND"
            # Plug the vm interface into the domU integration bridge.
            sudo ip addr flush dev $GUEST_INTERFACE_DEFAULT
            sudo ip link set $OVS_BRIDGE up
            # Assign the VM IP only if it has been set explicitly
            if [[ "$VM_IP" != "" ]]; then
                sudo ip addr add $VM_IP dev $OVS_BRIDGE
            fi
            sudo ovs-vsctl add-port $OVS_BRIDGE $GUEST_INTERFACE_DEFAULT
        fi
    fi
}

function quantum_plugin_configure_service() {
    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type gre
        iniset /$Q_PLUGIN_CONF_FILE OVS tunnel_id_ranges $TENANT_TUNNEL_RANGES
    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type vlan
    else
        echo "WARNING - The openvswitch plugin is using local tenant networks, with no connectivity between hosts."
    fi

    # Override ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc``
    # for more complex physical network configurations.
    if [[ "$OVS_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
        OVS_VLAN_RANGES=$PHYSICAL_NETWORK
        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
            OVS_VLAN_RANGES=$OVS_VLAN_RANGES:$TENANT_VLAN_RANGE
        fi
    fi
    if [[ "$OVS_VLAN_RANGES" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS network_vlan_ranges $OVS_VLAN_RANGES
    fi

    # Enable tunnel networks if selected
    if [[ $OVS_ENABLE_TUNNELING = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
    fi
}

function quantum_plugin_setup_interface_driver() {
    local conf_file=$1
    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
}

function has_quantum_plugin_security_group() {
    return 0
}

function quantum_plugin_check_adv_test_requirements() {
    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
}

# Restore xtrace
$MY_XTRACE
