# Neutron Nicira NVP plugin
# ---------------------------

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

source $TOP_DIR/lib/neutron_plugins/ovs_base

function setup_integration_bridge() {
    _neutron_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_neutron_ovs_base_plugin() {
    # NVP uses OVS, but not the l3-agent
    return 0
}

function neutron_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 neutron_plugin_install_agent_packages() {
    # Nicira Plugin does not run q-agt, but it currently needs dhcp and metadata agents
    _neutron_ovs_base_install_agent_packages
}

function neutron_plugin_configure_common() {
    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nicira
    Q_PLUGIN_CONF_FILENAME=nvp.ini
    Q_DB_NAME="neutron_nvp"
    Q_PLUGIN_CLASS="neutron.plugins.nicira.NeutronPlugin.NvpPluginV2"
}

function neutron_plugin_configure_debug_command() {
    sudo ovs-vsctl --no-wait -- --may-exist add-br $PUBLIC_BRIDGE
    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT external_network_bridge "$PUBLIC_BRIDGE"
}

function neutron_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 neutron_plugin_configure_l3_agent() {
   # Nicira plugin does not run L3 agent
   die $LINENO "q-l3 should must not be executed with Nicira plugin!"
}

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

function neutron_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 metadata_mode access_network
    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 neutron_plugin_setup_interface_driver() {
    local conf_file=$1
    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
}

function has_neutron_plugin_security_group() {
    # 0 means True here
    return 0
}

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

# Restore xtrace
$MY_XTRACE
