deb-networking-cisco/devstack/csr1kv/cisco

828 lines
26 KiB
Plaintext

# Neutron Cisco plugin
# ---------------------------
# Save trace setting
CISCO_XTRACE=$(set +o | grep xtrace)
set +o xtrace
# Name of cisco router plugin
Q_CISCO_ROUTER_PLUGIN=${Q_CISCO_ROUTER_PLUGIN:-}
# Indicate if a VSM instance should be created
Q_CISCO_PLUGIN_DEVSTACK_VSM=${Q_CISCO_PLUGIN_DEVSTACK_VSM:-True}
# Specify the VSM image file
Q_CISCO_PLUGIN_VSM_ISO_IMAGE=${Q_CISCO_PLUGIN_VSM_ISO_IMAGE:-}
# Scecify the VSM parameters
Q_CISCO_PLUGIN_VSM_IP=${Q_CISCO_PLUGIN_VSM_IP:-192.168.168.2}
# Specify the VSM username
Q_CISCO_PLUGIN_VSM_USERNAME=${Q_CISCO_PLUGIN_VSM_USERNAME:-admin}
# Specify the VSM passward for above username
Q_CISCO_PLUGIN_VSM_PASSWORD=${Q_CISCO_PLUGIN_VSM_PASSWORD:-Sfish123}
# Specify the uVEM image/module
Q_CISCO_PLUGIN_UVEM_DEB_IMAGE=${Q_CISCO_PLUGIN_UVEM_DEB_IMAGE:-}
# Specify the uVEM integration bridge name
Q_CISCO_PLUGIN_INTEGRATION_BRIDGE=${Q_CISCO_PLUGIN_INTEGRATION_BRIDGE:-br-int}
# Specify the host management interface required by uVEM
Q_CISCO_PLUGIN_HOST_MGMT_INTF=${Q_CISCO_PLUGIN_HOST_MGMT_INTF:-eth0}
# Specify the upstream (public) interface required by uVEM
Q_CISCO_PLUGIN_UPSTREAM_INTF=${Q_CISCO_PLUGIN_UPSTREAM_INTF:-}
# Specify if tunneling is enabled
Q_CISCO_PLUGIN_ENABLE_TUNNELING=${Q_CISCO_PLUGIN_ENABLE_TUNNELING:-True}
# Specify the VXLAN range
Q_CISCO_PLUGIN_VXLAN_ID_RANGES=${Q_CISCO_PLUGIN_VXLAN_ID_RANGES:-5000:10000}
# Specify the VLAN range
Q_CISCO_PLUGIN_VLAN_RANGES=${Q_CISCO_PLUGIN_VLAN_RANGES:-vlan:1:4094}
# Specify if VSM should be restarted
Q_CISCO_PLUGIN_RESTART_VSM=${Q_CISCO_PLUGIN_RESTART_VSM:-no}
# Specify ncclient package information
NCCLIENT_DIR=$DEST/ncclient
NCCLIENT_VERSION=${NCCLIENT_VERSION:-0.3.1}
NCCLIENT_BRANCH=${NCCLIENT_BRANCH:-master}
# This routine put a prefix on an existing function name
function _prefix_function {
declare -F $1 > /dev/null || die "$1 doesn't exist"
eval "$(echo "${2}_${1}()"; declare -f ${1} | tail -n +2)"
}
function _has_cisco_router_plugin {
if [[ "$Q_CISCO_ROUTER_PLUGIN" != "" ]]; then
return 0
fi
return 1
}
# Prefix openvswitch plugin routines with "ovs" in order to differentiate from
# cisco plugin routines. This means, ovs plugin routines will coexist with cisco
# plugin routines in this script.
source $TOP_DIR/lib/neutron_plugins/openvswitch
#_prefix_function net_neutron_plugin_configure_plugin_agent ovs
#_prefix_function net_neutron_plugin_configure_service ovs
# Check the version of the installed ncclient package
function check_ncclient_version {
python << EOF
version = '$NCCLIENT_VERSION'
import sys
try:
import pkg_resources
import ncclient
module_version = pkg_resources.get_distribution('ncclient').version
if version != module_version:
sys.exit(1)
except:
sys.exit(1)
EOF
}
# Install the ncclient package
function install_ncclient {
sudo -E pip install ncclient
}
# Check if the required version of ncclient has been installed
function is_ncclient_installed {
# Check if the Cisco ncclient repository exists
if [[ ! -d $NCCLIENT_DIR ]]; then
return 1
fi
# Check if the ncclient is installed with the right version
if ! check_ncclient_version; then
return 1
fi
return 0
}
function _configure_cisco_router_plugin {
# Install a known compatible ncclient from the Cisco repository if necessary
if ! is_ncclient_installed; then
install_ncclient
fi
}
# Return the current VSM state
function _get_vsm_state {
sudo virsh list --all | awk '(NR > 2) {if ($2 == "DEVSTACK_VSM") {$1="";$2="";print;}}'
}
# This routine keeps contacting the VSM in 10s interval until it responds
function _wait_for_vsm_to_comeup {
echo "Wait for the VSM to come up; This may take a while"
sh -c "while ! http_proxy= curl -s -m 5 http://$2:$3@$1; do sleep 10; done" &> /dev/null
}
# Check if the VSM console is on
function _is_vsm_console_on {
local vnc_no=$(sudo virsh vncdisplay DEVSTACK_VSM 2> /dev/null)
local running=$(ps --no-headers -o cmd -C krdc | sed -n 's/krdc localhost\(:\d*\)/\1/p' | awk -v vno=$vnc_no '$1 == vno {print}')
if [[ -n $running ]]; then
return 0
else
return 1
fi
}
# Open the VSM console
function _open_vsm_console {
vnc_no=$(sudo virsh vncdisplay DEVSTACK_VSM)
krdc localhost$vnc_no&
# remove the process from the current job so that it's not killed at the
# completion of stack.sh
disown %%
}
# Close the VSM console
function _close_vsm_console {
local vnc_no=$(sudo virsh vncdisplay DEVSTACK_VSM 2> /dev/null)
local console_pid=$(ps --no-headers -o pid,cmd -C krdc | sed -n 's/\(\d*\) krdc localhost\(:\d*\)/\1 \2/p' | awk -v vno=$vnc_no '$2 == vno {print $1}')
if [[ -n $console_pid ]]; then
kill $console_pid
fi
}
function _repackage_iso_with_ovfenv {
local vsm_tap_ip=$1
local vsm_ip=$2
local vsm_iso_image=$3
local ovf_env_file=$DATA_DIR/neutron/cisco/ovf-env.xml
if [[ -f $ovf_env_file ]]; then
rm $ovf_env_file
fi
cat > $ovf_env_file <<-EOF
<?xml version="1.0" encoding="UTF-8"?>
<Environment
xmlns="http://schemas.dmtf.org/ovf/environment/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
xmlns:ve="http://www.vmware.com/schema/ovfenv"
oe:id="">
<PlatformSection>
<Kind>KVM</Kind>
<Locale>en</Locale>
</PlatformSection>
<PropertySection>
<Property oe:key="DomainId" oe:value="1"/>
<Property oe:key="EnableTelnet" oe:value="True"/>
<Property oe:key="GatewayIpV4" oe:value="$vsm_tap_ip"/>
<Property oe:key="HostName" oe:value="OSVSM"/>
<Property oe:key="ManagementIpV4" oe:value="$vsm_ip"/>
<Property oe:key="ManagementIpV4Subnet" oe:value="255.255.255.0"/>
<Property oe:key="OvfDeployment" oe:value="installer"/>
<Property oe:key="SvsMode" oe:value="L3"/>
<Property oe:key="Password" oe:value="$Q_CISCO_PLUGIN_VSM_PASSWORD"/>
<Property oe:key="HARole" oe:value="standalone"/>
</PropertySection> \n'
</Environment> \n'
EOF
local mntdir=$(mktemp -d)
local ddir=$(mktemp -d)
sudo /bin/mount -o loop -t iso9660 $Q_CISCO_PLUGIN_VSM_ISO_IMAGE $mntdir
cp -r $mntdir/* $ddir
sudo /bin/umount $mntdir
cp $ovf_env_file $ddir
if [[ -f $ddir/isolinux/isolinux.bin ]]; then
(cd $ddir; sudo /usr/bin/mkisofs -uid 0 -gid 0 -J -R -A Cisco_Nexus_1000V_VSM -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o $vsm_iso_image .)
else
(cd $ddir; sudo /usr/bin/mkisofs -uid 0 -gid 0 -J -R -A Cisco_Nexus_1000V_VSM -b boot/grub/iso9660_stage1_5 -no-emul-boot -boot-load-size 4 -boot-info-table -o $vsm_iso_image .)
fi
}
function _get_vsm_net {
first=$(echo $Q_CISCO_PLUGIN_VSM_IP | sed -n 's/^\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.[0-9]\{1,3\}$/\1/p')
second=$(echo $Q_CISCO_PLUGIN_VSM_IP | sed -n 's/^\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.[0-9]\{1,3\}$/\2/p')
third=$(echo $Q_CISCO_PLUGIN_VSM_IP | sed -n 's/^\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.[0-9]\{1,3\}$/\3/p')
if [[ -z $first || -z $second || -z $third ]]; then
die $LINENO "Incorrect network address: $Q_CISCO_PLUGIN_VSM_IP"
fi
declare -i f=$first
declare -i s=$second
declare -i t=$third
if (( $f > 255 || $s > 255 || $t > 255 )); then
die $LINENO "Incorrect network address: $Q_CISCO_PLUGIN_VSM_IP"
fi
echo $first.$second.$third
}
# This routine retrieves the domain id and the primary mac address from the VSM
function _get_vsm_info {
# Node: no code with output should be added here. The caller depends on the
# output from the below expect output
vsm_ip_addr=$1 user=$2 passwd=$3 expect -c '
spawn /usr/bin/telnet $env(vsm_ip_addr)
set timeout 240
expect {
-re "Trying.*Connected.*Escape.*Nexus .*login: " {
send "$env(user)\n"
exp_continue
#look for the password prompt
}
"*?assword:*" {
send "$env(passwd)\n"
}
}
expect {
-re ".*# " {
send "show interface control 0\n"
expect -indices -re ".*# "
puts [string range $expect_out(buffer) \
0 [expr $expect_out(0,start) - 1]]
send "show svs domain\n"
expect -indices -re ".*# "
puts [string range $expect_out(buffer) \
0 [expr $expect_out(0,start) - 1]]
}
}' | sed -n -e 's/ Hardware: Ethernet, address: \(..\)\(..\)\.\(..\)\(..\)\.\(..\)\(..\).*/\1:\2:\3:\4:\5:\6/p' -e 's/ Domain id: *\(\d*\)/\1/p'
# Node: no code with output should be added here. The caller depends on the
# output from the above expect output
}
function _configure_vsm {
install_package expect
vsm_ip_addr=$1 user=$2 passwd=$3 expect -c '
spawn /usr/bin/telnet $env(vsm_ip_addr)
expect {
-re "Trying.*Connected.*Escape.*Nexus .*login: " {
send "$env(user)\n"
exp_continue
#look for the password prompt
}
"*?assword:*" {
send "$env(passwd)\n"
}
}
expect -re ".*# "
send "config te\n"
expect -re ".*# "
send "feature http-server\n"
expect -re ".*# "
send "feature network-segmentation-manager\n"
expect -re ".*# "
send "feature segmentation\n"
expect -re ".*# "
send "port-profile test-profile\n"
expect -re ".*# "
send "no shut\n"
expect -re ".*# "
send "state enabled\n"
expect -re ".*# "
send "publish port-profile\n"
expect -re ".*# "
send "exit\n"
expect -re ".*# "
send "port-profile dhcp_pp\n"
expect -re ".*# "
send "no shut\n"
expect -re ".*# "
send "state enabled\n"
expect -re ".*# "
send "publish port-profile\n"
expect -re ".*# "
send "end\n"
expect -re ".*# "
send "exit\n"
'
}
function send_vsm_arp {
set +o xtrace
sudo sysctl -w net.ipv4.ip_nonlocal_bind=1
while true; do
sudo arping -U -A -c 3 -q -I $Q_CISCO_PLUGIN_HOST_MGMT_INTF $Q_CISCO_PLUGIN_VSM_IP
sleep 5
done
}
# This routine creates a virtual machine that runs VSM
function _create_devstack_vsm {
local vsm_image_file=$DATA_DIR/neutron/cisco/DEVSTACK_VSM.img
local vsm_iso_image
local vsm_xml_file=$DATA_DIR/neutron/cisco/DEVSTACK_VSM.xml
local vsm_arp_proc=$DATA_DIR/neutron/cisco/vsm_arp_proc
local vsm_ip
local vsm_tap_ip
local vsm_net
local vsm_state
local recreate=no
local config_vsm=False
# Intall krdc package. krdc is used to connect to the VSM desktop/console
install_package krdc
# Ignore all errors for this function (as latest DevStack will abort on any error)
set +o errexit
if [[ -z "$Q_CISCO_PLUGIN_VSM_ISO_IMAGE" ]]; then
die $LINENO "Please specify your VSM iso image in the localrc/local.conf file!"
fi
if [[ ! -f "$Q_CISCO_PLUGIN_VSM_ISO_IMAGE" ]]; then
die $LINENO "Can't find the VSM iso image file $Q_CISCO_PLUGIN_VSM_ISO_IMAGE!"
fi
vsm_iso_image=$DATA_DIR/neutron/cisco/$(basename $Q_CISCO_PLUGIN_VSM_ISO_IMAGE)
if [[ ! -d $DATA_DIR/neutron/cisco ]]; then
mkdir -p $DATA_DIR/neutron/cisco
fi
vsm_net=$(_get_vsm_net)
declare -i vsm_ip=${Q_CISCO_PLUGIN_VSM_IP/#$vsm_net./}
local vsm_tap_ip
if [[ $vsm_ip != 1 ]]; then
vsm_tap_ip=${vsm_net}.1
else
vsm_tap_ip=${vsm_net}.2
fi
vsm_state=$(_get_vsm_state)
# Check if the vsm image is changed
if [[ -f $vsm_xml_file ]]; then
matched=$(grep -c -m 1 "<source file='$vsm_iso_image'/>" $vsm_xml_file)
# The image file is changed; the VM needs to be recreated
if [[ "$matched" == "0" ]]; then
recreate=yes
fi
else
recreate=yes
fi
# In case of restart or recreate, kill the console and destroy the VM
if [[ ( "$vsm_state" == " running" && "$Q_CISCO_PLUGIN_RESTART_VSM" == "yes" ) || "$recreate" == "yes" ]]; then
_close_vsm_console
sudo virsh destroy DEVSTACK_VSM
if [[ "$recreate" == "yes" ]]; then
sudo virsh undefine DEVSTACK_VSM
rm -f $vsm_iso_image
rm -f $vsm_image_file
fi
fi
vsm_state=$(_get_vsm_state)
# VSM doesn't exist; create one
if [[ -z $vsm_state ]]; then
local vsm_uuid=$(uuidgen -t)
local libvirt_type=$LIBVIRT_TYPE
config_vsm=True
# Prepare for the iso image with ovf-env.xml inserted
if [[ ! -f $vsm_iso_image ]]; then
_repackage_iso_with_ovfenv $vsm_tap_ip $Q_CISCO_PLUGIN_VSM_IP $vsm_iso_image
fi
# Create the VSM disk image file
if [[ ! -f $vsm_image_file ]]; then
sudo qemu-img create $vsm_image_file 8G
fi
# Determine the libvirt type
if [[ "$libvirt_type" == "kvm" ]]; then
sudo modprobe kvm || true
if [ ! -e /dev/kvm ]; then
echo "WARNING: Switching to QEMU for VSM"
libvirt_type=qemu
fi
fi
# Note, mac addresses for NICs are hard-coded. VSM seems to take MAC
# addresses in certain ranges. Therefore, random-generated MAC addresses
# may not work.
cat > $vsm_xml_file <<-EOF
<domain type='$libvirt_type'>
<name>DEVSTACK_VSM</name>
<uuid>$vsm_uuid</uuid>
<memory unit='KiB'>2048000</memory>
<currentMemory unit='KiB'>1024000</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-1.0'>hvm</type>
<boot dev='cdrom'/>
<boot dev='hd'/>
</os>
<features> <acpi/> <pae/> </features>
<clock offset='localtime'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>destroy</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='$vsm_image_file'/>
<target dev='hda' bus='ide'/>
<alias name='ide0-0-0'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='$vsm_iso_image'/>
<target dev='hdb' bus='ide'/>
<readonly/>
<alias name='ide0-0-1'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0'>
<alias name='usb0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<alias name='ide0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<interface type='bridge'>
<mac address='0e:1f:35:ab:45:2e'/>
<source bridge='ds-vsm-bridge'/>
<target dev='ds-vsm-vnet0'/>
<model type='e1000'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</interface>
<interface type='bridge'>
<mac address='0e:1f:35:ab:45:3e'/>
<source bridge='ds-vsm-bridge'/>
<target dev='ds-vsm-vnet1'/>
<model type='e1000'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</interface>
<interface type='bridge'>
<mac address='0e:1f:35:ab:45:4e'/>
<source bridge='ds-vsm-bridge'/>
<target dev='ds-vsm-vnet2'/>
<model type='e1000'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0' keymap='en-us'>
<listen type='address' address='0.0.0.0'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</memballoon>
</devices>
</domain>
EOF
sudo virsh define $vsm_xml_file
vsm_state=$(_get_vsm_state)
fi
if [[ "$vsm_state" == " shut off" ]]; then
config_vsm=True
# Create the VSM bridge
sudo brctl addbr ds-vsm-bridge
sudo ip link set ds-vsm-bridge up
# Create a veth pair for communication between the host and the VSM
sudo ip link add tap-ds-vsm type veth peer name ds-vsm-veth
sudo ip link set tap-ds-vsm up
sudo ip link set tap-ds-vsm promisc on
sudo ip link set ds-vsm-veth up
sudo ip link set ds-vsm-veth promisc on
sudo brctl addif ds-vsm-bridge tap-ds-vsm
sudo ip -4 addr add $vsm_tap_ip/24 dev ds-vsm-veth
if sudo virsh start DEVSTACK_VSM; then
_open_vsm_console
fi
_wait_for_vsm_to_comeup $Q_CISCO_PLUGIN_VSM_IP $Q_CISCO_PLUGIN_VSM_USERNAME $Q_CISCO_PLUGIN_VSM_PASSWORD
# In multi-host environment, send gratuitous arp to the management
# network so that the compute nodes can reach the VSM
MULTI_HOST=`trueorfalse False $MULTI_HOST`
if [[ "$MULTI_HOST" == "True" ]]; then
local send_arp=True
if [[ -e $vsm_arp_proc ]]; then
local vsm_arp_proc_pid=$(cat $vsm_arp_proc | cut -d" " -f1)
local vsm_ipaddr=$(cat $vsm_arp_proc | cut -d" " -f2)
local cmd = $(ps --no-headers -p $vsm_arp_proc_pid -o cmd)
if [[ -n $cmd ]]; then
if [[ $vsm_ipaddr != $Q_CISCO_PLUGIN_VSM_IP ]]; then
kill $vsm_arp_proc_pid
else
send_arp=False
fi
fi
fi
if [[ $send_arp == "True" ]]; then
send_vsm_arp&
disown %%
echo "$! $Q_CISCO_PLUGIN_VSM_IP" > $vsm_arp_proc
fi
fi
else
if ! _is_vsm_console_on; then
_open_vsm_console
fi
fi
if [[ "$config_vsm" == "True" ]]; then
_configure_vsm $Q_CISCO_PLUGIN_VSM_IP $Q_CISCO_PLUGIN_VSM_USERNAME $Q_CISCO_PLUGIN_VSM_PASSWORD
fi
# Turn exit on error, back on
set -o errexit
}
function write_n1kv_conf {
local n1kv_cfg_file=$1
sudo cat > $n1kv_cfg_file <<-EOF
# This is a sample N1KV configurtion file.
# <n1kv.conf> file contains all the configuration parameters for UVEM operation.
# Please find below a brief explanation of these parameters and their meaning.
# Optional Parameters and Default Values of parameters are explicitly stated.
# Note:
# a) Mandatory parameters are needed for proper UVEM operation.
# N1KV DP/DPA should start even if these are not specified.
# But there will be functional impact. For eg: in VSM connectivity
# b)For most of the mandatory parameters, you can use 'vemcmd' configuration mode.
# But to be persistent, please edit this configuration file.
#
#<vsm-connection-params>
#
# TAG: switch-domain
# Description:
# Optional: No
# Default: 1
switch-domain 1
# TAG: l3control-ipaddr
# Description: IP Address of VSM's Control I/F
# Optional: No
# Default: n/a
l3control-ipaddr 1.2.3.4
# TAG: system-primary-mac
# Description: MAC address of VSM's Control I/F
# Optional: No
# Default: n/a
# system-primary-mac -INTF
# TAG: host-mgmt-intf
# Description: Management interface of the Host
# Optional: No (Even if not on N1KV, we need this
# for Host Identification on VSM).
# Default: n/a
host-mgmt-intf eth1
#
#<system-port-profile-Info>
# Description: System Port Profiles.
# Optional: Yes (If there are no System Interfaces: Mgmt I/F etc)
#
#Trunk Profile Format
#profile <name> trunk <vlan>
#profile <name> native-vlan <vlan>
#profile <name> mtu <mtu-size>
#
#Access Profile
#profile <name> access <vlan>
#profile <name> mtu <mtu-size>
#<Port-Profile Mapping>
# Description: Port-Profile mapping for all UVEM managed Interfaces.
# Optional: Uplinks: NO. System-Veth: NO.
# : Non-System Veth: YES. (Assume it will be populated by 'libvirt')
#
# Format:
# phys <port-name> profile <profile-name>
# virt <port-name> profile <profile-name>
# TBD: For uplinks UUID also need to be specified.
#phys eth1 profile sys-uplink
#phys eth2 profile uplink2
# <host-uuid>
# Description: Host UUID
# Optional : YES. If not specified UVEM would pick host UUID using 'dmidecode'.
# host-uuid <host-uuid>
# <dvswitch-uuid>
# Description: N1KV DVS UUID. Not to be confused with Open VSwitch UUID
# Optional : YES.
# dvswitch-uuid <sw-uuid>
# TBD
# <log-path>
# Description: Log Directory Path for DP/DPA
# Optional: YES.
# Default:
# Format:
# log-path:/opt/cisco/n1kv/logs
# <uvem-ovs-brname>
#
# Description: Default Open VSwitch Bridge Name
# Optional: YES.
# Default: n1kvdvs
# Format:
# uvem-ovs-brname n1kvdvs
uvem-ovs-brname br-int
EOF
}
function n1k_iniset {
local file=$1
local option=$2
local value=$3
if ! grep -q "^$option" "$file"; then
# Add at the end
echo "option does not exist-add to bottom"
echo -e "\n$option $value" >>"$file"
else
# Replace it
echo "n1k_iniset:Replace it $option $value $file"
sed -i "s/^$option.*/$option $value/" "$file"
fi
}
# Configure/Install the uVEM
function _configure_uvem {
# Specify uVEM configuration information
local N1KV_CONF_DIR=/etc/n1kv
local N1KV_CONF=$N1KV_CONF_DIR/n1kv.conf
local UVEM_LOCAL_DIR=$TOP_DIR/files/images/cisco
install_package expect
# Put config files in ``N1KV_CONF_DIR``
if [[ ! -d $N1KV_CONF_DIR ]]; then
sudo mkdir -p $N1KV_CONF_DIR
sudo chown $STACK_USER $N1KV_CONF_DIR
fi
local n1kv_temp_file=`mktemp`
if [[ ! -f $N1KV_CONF ]]; then
write_n1kv_conf $n1kv_temp_file
else
cp $N1KV_CONF $n1kv_temp_file
fi
# install a route to VSM on a compute node
if ! is_service_enabled q-svc ; then
local vsm_net=$(_get_vsm_net)
sudo ip route add ${vsm_net}.0/24 dev $Q_CISCO_PLUGIN_HOST_MGMT_INTF
if [[ $? != 0 && $? != 2 ]]; then
die $LINENO "Cannot add route to the VSM"
fi
fi
# Wait for VSM to come up before requesting information from it
_wait_for_vsm_to_comeup $Q_CISCO_PLUGIN_VSM_IP $Q_CISCO_PLUGIN_VSM_USERNAME $Q_CISCO_PLUGIN_VSM_PASSWORD
local vsm_info=($(_get_vsm_info $Q_CISCO_PLUGIN_VSM_IP $Q_CISCO_PLUGIN_VSM_USERNAME $Q_CISCO_PLUGIN_VSM_PASSWORD))
if [[ "${vsm_info[1]}" != "" ]]; then
n1k_iniset $n1kv_temp_file switch-domain ${vsm_info[1]}
fi
if [[ "$Q_CISCO_PLUGIN_VSM_IP" != "" ]]; then
n1k_iniset $n1kv_temp_file l3control-ipaddr $Q_CISCO_PLUGIN_VSM_IP
fi
if [[ "$Q_CISCO_PLUGIN_HOST_MGMT_INTF" != "" ]]; then
n1k_iniset $n1kv_temp_file host-mgmt-intf $Q_CISCO_PLUGIN_HOST_MGMT_INTF
fi
if [[ "$Q_CISCO_PLUGIN_UPSTREAM_INTF" != "" ]]; then
n1k_iniset $n1kv_temp_file phys "$Q_CISCO_PLUGIN_UPSTREAM_INTF profile sys-uplink"
# Make sure we add it to br-int as well, and force it up
sudo ovs-vsctl -- --may-exist add-port br-int $Q_CISCO_PLUGIN_UPSTREAM_INTF
sudo ifconfig $Q_CISCO_PLUGIN_UPSTREAM_INTF up
fi
if [[ "$Q_CISCO_PLUGIN_INTEGRATION_BRIDGE" != "" ]]; then
n1k_iniset $n1kv_temp_file uvem-ovs-brname $Q_CISCO_PLUGIN_INTEGRATION_BRIDGE
fi
sudo cp $n1kv_temp_file $N1KV_CONF
sudo chmod a+r $N1KV_CONF
rm $n1kv_temp_file
#copy the uVEM image
if [[ -z "$Q_CISCO_PLUGIN_UVEM_DEB_IMAGE" ]]; then
die $LINENO "Please specify your UVEM image in the localrc/local.conf file!"
fi
if [[ ! -f "$Q_CISCO_PLUGIN_UVEM_DEB_IMAGE" ]]; then
die $LINENO "Can't find the UVEM image file $Q_CISCO_PLUGIN_UVEM_DEB_IMAGE!"
fi
local uvem_image=`basename $Q_CISCO_PLUGIN_UVEM_DEB_IMAGE`
if [[ ! -f $UVEM_LOCAL_DIR/$uvem_image ]]; then
mkdir -p $UVEM_LOCAL_DIR
if sudo dpkg -s nexus1000v; then
sudo dpkg -r nexus1000v
fi
if [[ -e $UVEM_LOCAL_DIR/*.deb ]]; then
rm $UVEM_LOCAL_DIR/*deb
fi
cp $Q_CISCO_PLUGIN_UVEM_DEB_IMAGE $UVEM_LOCAL_DIR
#install the uVEM
install_package libnl1
sudo dpkg -i $UVEM_LOCAL_DIR/$uvem_image
else
#restart in case of change in the VSM configuration
sudo /etc/init.d/n1kv restart
fi
}
# Configure n1kv plugin
function _configure_n1kv_subplugin {
local cisco_cfg_file=$1
# if Embedded VSM is deployed, launch the VSM
if [[ "$Q_CISCO_PLUGIN_DEVSTACK_VSM" == "True" ]]; then
_create_devstack_vsm
fi
iniset $cisco_cfg_file CISCO_N1K default_policy_profile test-profile
iniset $cisco_cfg_file CISCO_N1K restrict_network_profiles False
# Configure uVEM on compute nodes
if is_service_enabled n-cpu; then
_configure_uvem
fi
}
function net_neutron_plugin_configure_plugin_agent {
# Assuming q-agt will be enabled on all the compute nodes
# uVEM is only configured/installed with q-agt enabled
_configure_uvem
}
function net_neutron_plugin_configure_service {
local cisco_cfg_file
cisco_cfg_file=/$Q_PLUGIN_CONF_FILE
if _has_n1kv_subplugin; then
_configure_n1kv_subplugin $cisco_cfg_file
fi
if _has_cisco_router_plugin; then
_configure_cisco_router_plugin
fi
}
function _has_n1kv_subplugin {
local subplugin
for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
if [[ "$subplugin" == "n1kv" ]]; then
return 0
fi
done
return 1
}
# Restore xtrace
$XTRACE