# Quantum Nicira NVP plugin
# ---------------------------

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

source $TOP_DIR/lib/quantum_plugins/ovs_base

function setup_integration_bridge() {
    _quantum_ovs_base_setup_bridge $OVS_BRIDGE
    # Set manager to NVP controller (1st of list)
    if [[ "$NVP_CONTROLLERS" != "" ]]; then
        # Get the first controller
        controllers=(${NVP_CONTROLLERS//,/ })
        OVS_MGR_IP=${controllers[0]}
    else
        die $LINENO "Error - No controller specified. Unable to set a manager for OVS"
    fi
    sudo ovs-vsctl set-manager ssl:$OVS_MGR_IP
}

function is_quantum_ovs_base_plugin() {
    # NVP uses OVS, but not the l3-agent
    return 0
}

function quantum_plugin_create_nova_conf() {
    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtOpenVswitchDriver"}
    # if n-cpu is enabled, then setup integration bridge
    if is_service_enabled n-cpu; then
        setup_integration_bridge
    fi
}

function quantum_plugin_install_agent_packages() {
    # Nicira Plugin does not run q-agt, but it currently needs dhcp and metadata agents
    _quantum_ovs_base_install_agent_packages
}

function quantum_plugin_configure_common() {
    Q_PLUGIN_CONF_PATH=etc/quantum/plugins/nicira
    Q_PLUGIN_CONF_FILENAME=nvp.ini
    Q_DB_NAME="quantum_nvp"
    Q_PLUGIN_CLASS="quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2"
}

function quantum_plugin_configure_debug_command() {
    sudo ovs-vsctl --no-wait -- --may-exist add-br $PUBLIC_BRIDGE
}

function quantum_plugin_configure_dhcp_agent() {
    setup_integration_bridge
    iniset $Q_DHCP_CONF_FILE DEFAULT enable_isolated_metadata True
    iniset $Q_DHCP_CONF_FILE DEFAULT enable_metadata_network True
    iniset $Q_DHCP_CONF_FILE DEFAULT ovs_use_veth True
}

function quantum_plugin_configure_l3_agent() {
   # Nicira plugin does not run L3 agent
   die $LINENO "q-l3 should must not be executed with Nicira plugin!"
}

function quantum_plugin_configure_plugin_agent() {
   # Nicira plugin does not run L2 agent
   die $LINENO "q-agt must not be executed with Nicira plugin!"
}

function quantum_plugin_configure_service() {
    if [[ "$MAX_LP_PER_BRIDGED_LS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE NVP max_lp_per_bridged_ls $MAX_LP_PER_BRIDGED_LS
    fi
    if [[ "$MAX_LP_PER_OVERLAY_LS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE NVP max_lp_per_overlay_ls $MAX_LP_PER_OVERLAY_LS
    fi
    if [[ "$FAILOVER_TIME" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE NVP failover_time $FAILOVER_TIME
    fi
    if [[ "$CONCURRENT_CONNECTIONS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE NVP concurrent_connections $CONCURRENT_CONNECTIONS
    fi

    if [[ "$DEFAULT_TZ_UUID" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_tz_uuid $DEFAULT_TZ_UUID
    else
        die $LINENO "The nicira plugin won't work without a default transport zone."
    fi
    if [[ "$DEFAULT_L3_GW_SVC_UUID" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_l3_gw_service_uuid $DEFAULT_L3_GW_SVC_UUID
        Q_L3_ENABLED=True
        Q_L3_ROUTER_PER_TENANT=True
        iniset /$Q_PLUGIN_CONF_FILE NVP enable_metadata_access_network True
    fi
    if [[ "$DEFAULT_L2_GW_SVC_UUID" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_l2_gw_service_uuid $DEFAULT_L2_GW_SVC_UUID
    fi
    # NVP_CONTROLLERS must be a comma separated string
    if [[ "$NVP_CONTROLLERS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_controllers $NVP_CONTROLLERS
    else
        die $LINENO "The nicira plugin needs at least an NVP controller."
    fi
    if [[ "$NVP_USER" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_user $NVP_USER
    fi
    if [[ "$NVP_PASSWORD" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_password $NVP_PASSWORD
    fi
    if [[ "$NVP_REQ_TIMEOUT" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT req_timeout $NVP_REQ_TIMEOUT
    fi
    if [[ "$NVP_HTTP_TIMEOUT" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT http_timeout $NVP_HTTP_TIMEOUT
    fi
    if [[ "$NVP_RETRIES" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT retries $NVP_RETRIES
    fi
    if [[ "$NVP_REDIRECTS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE DEFAULT redirects $NVP_REDIRECTS
    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() {
    # 0 means True here
    return 0
}

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

# Restore xtrace
$MY_XTRACE
