yap/yap
2019-07-16 13:42:26 -07:00

1366 lines
31 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# yap - Yet Another Private WAN
#
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
export DATA_DIR="/var/lib/yap/data"
SALT_PILLARS="/etc/bondingadmin/salt-config/pillars"
SALT_PILLARS_TOP="$SALT_PILLARS/top.sls"
# check_args <name>,[skip],<value>...
#
# Check a list of arguments for presence. Each argument is supplied along with
# the name and requirements. eg:
#
# "foo,,$1" - first argument is named 'foo' and is required
# "bar,,$2" - second argument is named 'bar' and is required
# "baz,skip,$3" - third argument is named 'baz' and may be omitted (skip args
# must be at the end)
#
# Displays message and returns error status if requirements are not met
#
# If successful, pass output to eval to set args in local scope:
#
# args=$(check_args foo,,$1 bar,,$2) || return 1
# eval $args
#
function check_args() {
for arg_def in "$@" ; do
OLD_IFS="$IFS"
IFS=","
set $arg_def
IFS="$OLD_IFS"
name="$1"
skip="$2"
value="$3"
if [ -z $skip ] ; then
if [ -z "$value" ] ; then
echo "Argument '$name' is required" >&2
return 1
fi
fi
echo "declare $name=\"$value\""
done
}
# get_var <var> [default]
#
# Get variable from data store. If unset, return default
#
function get_var() {
varfile="${DATA_DIR}/$1"
if [ -f "$varfile" ] ; then
cat "$varfile"
else
echo "$2"
fi
}
# set_var <var> <value>
#
# Set variable in data store
#
function set_var() {
varfile="${DATA_DIR}/$1"
vardir=$(dirname "$varfile")
if [ ! -d "$vardir" ] ; then
install -d -m 0755 "$vardir"
fi
echo -n "$2" > "$varfile"
}
# set_var <var> <value>
#
# Set variable in data store
#
function set_var_from_file() {
varfile="${DATA_DIR}/$1"
vardir=$(dirname "$varfile")
if [ ! -d "$vardir" ] ; then
install -d -m 0755 "$vardir"
fi
cp "$2" "$varfile"
}
# del_var <var>
#
# Delete variable from data store
#
function del_var() {
varfile="${DATA_DIR}/$1"
vardir=$(dirname "$varfile")
rm -f "$varfile"
# Clean up empty dirs
find $DATA_DIR -depth -type d -empty -exec rmdir {} \;
}
# del_section <section>
#
# Delete section from data store
#
function del_section() {
if [ -z "$1" ] ; then
echo "Refusing to delete entire store"
return 1
fi
vardir="${DATA_DIR}/$1"
rm -rf "$vardir"
# Clean up empty dirs
find $DATA_DIR -depth -type d -empty -exec rmdir {} \;
}
# has_var <var>
#
# Check if variable exists
#
function has_var() {
test -f "${DATA_DIR}/$1"
}
# List variables in data store. If an argument is specified, list only
# variables under that root.
#
function all_vars() {
for var in $(find $DATA_DIR/$1 -type f | sort) ; do
echo "${var#$DATA_DIR}"
done
}
# Dump variables in data store. If an argument is specified, list only
# variables under that root.
#
function dump_vars() {
for var in $(find $DATA_DIR/$1 -type f | sort) ; do
echo "${var#$DATA_DIR} $(cat $var)"
done
}
# List immediate variables in data store. If an argument is specified, list
# only variables under that root.
#
function list_vars() {
if [ -d "$DATA_DIR/$1" ] ; then
for var in $(find $DATA_DIR/$1 -mindepth 1 -maxdepth 1 -type f | sort) ; do
echo ${var#$DATA_DIR}
done
fi
}
# Check if section exists
#
function has_section() {
test -d ${DATA_DIR}/$1
}
# Get section location on disk
#
function get_section_path() {
echo ${DATA_DIR}/$1
}
# List immediate sections in data store. If an argument is specified, list only
# sections under that section.
#
function list_sections() {
if [ -d $DATA_DIR/$1 ] ; then
for var in $(find $DATA_DIR/$1 -mindepth 1 -maxdepth 1 -type d | sort) ; do
echo ${var#$DATA_DIR/}
done
fi
}
function ip2dec() {
local a b c d ip=$@
IFS=. read -r a b c d <<< "$ip"
printf '%d\n' "$((a * 256 ** 3 + b * 256 ** 2 + c * 256 + d))"
}
function dec2ip() {
local delim ip dec=$@
for e in {3..0} ; do
((octet = dec / (256 ** e) ))
((dec -= octet * 256 ** e))
ip+=$delim$octet
delim=.
done
printf '%s' "$ip"
}
# Generate an IP for a VLAN interface based on the VLAN and and the YAP ID.
# The first octet will always be 100, while the other 3 octets are split into
# 3 sections of varying size to contain the IP type, the VLAN, and the YAP ID:
#
# type: 1-bit
# vlan ID: 12-bits
# YAP ID: 11-bits
#
# The resulting IP should be used with a prefix length of 21
#
function get_vlan_ip() {
vlan_id=$1
yap_id=$2
# Start at 100.0.0.0
local ip=$(ip2dec 100.0.0.0)
# Add the VLAN ID, shifted 11-bits
((ip += vlan_id << 11))
# Add the YAP ID
((ip += yap_id))
dec2ip $ip
}
function validate_ip() {
if ! [[ $1 =~ ^(0*(1?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))\.){3}0*(1?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))$ ]] ; then
return 1
fi
}
# Get resource from API
#
function api_get() {
args=$(check_args path,,$1) || return 1
eval $args
if ! has_var /auth/password ; then
echo "No bondingadmin auth set. Use $0 auth-set <email> <password> to set it."
return 1
fi
host=$(grep mgmt_server_url /etc/bondingadmin/bondingadmin.conf | cut -d ' ' -f 3)
email=$(get_var /auth/email)
password=$(get_var /auth/password)
curl --user "$email:$password" -k -s --fail https://$host$path
}
# Set the auth parameters for the API
#
function auth_set() {
args=$(check_args email,,$1 password,,$2) || return 1
eval $args
set_var /auth/email "$email"
set_var /auth/password "$password"
}
# Generate a table ID from the space ID of the given space
#
function get_table_id() {
args=$(check_args space,,$1) || return 1
eval $args
echo $(( $(get_var /spaces/$space/id) + 8192 ))
}
# Generate a unique ID for the YAP node, used in IP addresses
#
function get_next_yap_ip() {
local yap_id yap_id
if has_var last_yap_id ; then
yap_id=$(get_var last_yap_id)
else
yap_id=0
fi
((yap_id += 1))
set_var last_yap_id $yap_id
echo $yap_id
}
#
# Salt management
#
function get_full_nodelist() {
local nodelist=""
local vxr
for vxr in $(list_sections /vxrs) ; do
local name=$(basename $vxr)
nodelist="${nodelist} ${name}"
done
local aggregator
for aggregator in $(list_sections /aggregators) ; do
local id=$(basename $aggregator)
nodelist="${nodelist} node-${id}"
done
echo $(salt_nodelist $nodelist)
}
function get_vxr_nodelist() {
local nodelist=""
local vxr
for vxr in $(list_sections /vxrs) ; do
local name=$(basename $vxr)
nodelist="${nodelist} ${name}"
done
echo $(salt_nodelist $nodelist)
}
function get_region_nodelist() {
args=$(check_args region,,$1) || return 1
eval $args
local nodelist=""
local vxr
for vxr in $(list_sections /vxrs) ; do
local name=$(basename $vxr)
if [ "$(get_var $vxr/region)" = $region ] ; then
nodelist="${nodelist} ${name}"
fi
done
local aggregator
for aggregator in $(list_sections /aggregators) ; do
local id=$(basename $aggregator)
if [ "$(get_var $aggregator/region)" = $region ] ; then
nodelist="${nodelist} node-${id}"
fi
done
echo $(salt_nodelist $nodelist)
}
function salt_nodelist() {
local nodelist=''
local delim=''
for node in $@ ; do
nodelist="${nodelist}${delim}${node}"
delim=','
done
echo "L@$nodelist"
}
function salt_update() {
nodelist="$@"
install -d -m 0755 $SALT_PILLARS/yap/regions
install -d -m 0755 $SALT_PILLARS/yap/hosts
new_common_file=$(mktemp)
{
echo "yap:"
echo " ipsec_key: '$(get_var /ipsec/key)'"
} > $new_common_file
mv $new_common_file $SALT_PILLARS/yap/common.sls
chmod 0644 $SALT_PILLARS/yap/common.sls
local region
for region in $(list_sections /regions) ; do
pillar_file=$SALT_PILLARS/yap/regions/$(basename $region).sls
new_pillar_file=$(mktemp)
{
echo "yap:"
echo " spaces:"
local space
for space in $(list_sections $region/spaces) ; do
local space_name=$(basename $space)
local vlan=$(get_var $space/vlan)
local space_id=$(get_var /spaces/$space_name/id)
echo " $space_name:"
echo " vlan: $vlan"
echo " id: $space_id"
done
} > $new_pillar_file
mv $new_pillar_file $pillar_file
chmod 0644 $pillar_file
done
if [ ! -f $SALT_PILLARS_TOP ] ; then
echo "base:" > $SALT_PILLARS_TOP
fi
cp $SALT_PILLARS_TOP ${SALT_PILLARS_TOP}.prev
new_top=$(mktemp)
sed '/^### BEGIN YAP ###/,/### END YAP ###/d' $SALT_PILLARS_TOP > $new_top
echo "### BEGIN YAP ###" >> $new_top
local vxr
for vxr in $(list_sections /vxrs) ; do
new_host_file=$(mktemp)
local region=$(get_var $vxr/region)
local trunk=$(get_var $vxr/trunk)
local yap_id=$(get_var $vxr/yap_id)
local global=$(get_var $vxr/global false)
local name=$(basename $vxr)
local vxr_peers
{
echo -e "yap:"
echo -e " yap_id: $yap_id"
echo -e " trunk: $trunk"
echo -e " global: $global"
echo -e " global_interface_options:"
for option in $(list_vars $vxr/global_interface_options) ; do
echo -e " '$(basename $option)': '$(get_var $option)'"
done
echo -e " vxlan_peers:"
for peer_vxr in $(list_sections /vxrs) ; do
if [ "$peer_vxr" != "$vxr" ] ; then
echo -e " - $(get_var $peer_vxr/ip)"
fi
done
} > $new_host_file
mv $new_host_file $SALT_PILLARS/yap/hosts/$name.sls
chmod 0644 $SALT_PILLARS/yap/hosts/$name.sls
{
echo -e " '$name':"
echo -e " - yap.common"
echo -e " - yap.regions.$region"
echo -e " - yap.hosts.$name\n"
} >> $new_top
done
local aggregator
for aggregator in $(list_sections /aggregators) ; do
new_host_file=$(mktemp)
local id=$(basename $aggregator)
local yap_id=$(get_var $aggregator/yap_id)
local region=$(get_var $aggregator/region)
local trunk=$(get_var $aggregator/trunk)
{
echo -e "yap:"
echo -e " yap_id: $yap_id"
echo -e " trunk: $trunk"
} > $new_host_file
new_host_spaces_file=$(mktemp)
has_spaces=0
{
echo -e " spaces:"
for space in $(list_sections $aggregator/spaces) ; do
has_spaces=1
local space_name=$(basename $space)
{
echo -e " $space_name:"
local ip=$(get_var $space/ip)
if [ -n "$ip" ] ; then
echo -e " ip: $ip"
fi
local bird_config=$(get_var $space/bird_config)
if [ -n "$bird_config" ] ; then
echo -e " bird_config: |-"
echo -e "$bird_config" | sed -e 's/^/ /g'
fi
}
done
} > $new_host_spaces_file
if [ $has_spaces = 1 ] ; then
cat $new_host_spaces_file >> $new_host_file
fi
mv $new_host_file $SALT_PILLARS/yap/hosts/node-$id.sls
chmod 0644 $SALT_PILLARS/yap/hosts/node-$id.sls
{
echo -e " 'node-$id':"
echo -e " - yap.common"
echo -e " - yap.regions.$region"
echo -e " - yap.hosts.node-$id\n"
} >> $new_top
done
echo "### END YAP ###" >> $new_top
mv $new_top $SALT_PILLARS_TOP
chmod 0644 $SALT_PILLARS_TOP
# Update nodes if given
if [ -n "$nodelist" ] ; then
salt -C "$nodelist" state.sls yap
fi
}
function salt_exec() {
nodelist="$1"
shift
salt -C "$nodelist" "$@"
}
function upgrade() {
args=$(check_args region,skip,$1)
eval $args
if [ ! -z "$region" ] ; then
salt_update "$(get_region_nodelist $region)"
salt_exec "$(get_region_nodelist $region)" service.restart yap ||:
else
salt_update "$(get_full_nodelist)"
salt_exec "$(get_full_nodelist)" service.restart yap ||:
fi
}
#
# Region commands
#
function region_list() {
for region in $(list_sections /regions) ; do
basename "$region"
done
}
function region_show() {
args=$(check_args region,,$1) || return 1
eval $args
if ! has_section "/regions/$region" ; then
echo "Region does not exist"
return 1
fi
echo "name: $region"
echo
echo "Aggregators:"
for aggregator in $(list_sections "/aggregators") ; do
if [ "$(get_var $aggregator/region)" = $region ] ; then
echo " $(get_var $aggregator/name)"
fi
done
echo
echo "VLAN associations:"
for space in $(list_sections "/regions/$region/spaces") ; do
var="$space/vlan"
if has_var "$var" ; then
vlan_id=$(get_var $var)
echo " $(basename space) $vlan_id: $(get_vlan_ip $vlan_id 0)/21"
fi
done
}
function region_add() {
args=$(check_args region,,$1) || return 1
eval $args
if has_section "/regions/$region" ; then
echo "Region already exists"
return
fi
set_var "/regions/$region/name" "$region"
region_show $region
}
function region_delete() {
args=$(check_args region,,$1) || return 1
eval $args
del_section "/regions/$region"
}
#
# Space commands
#
function space_list() {
for space in $(list_sections /spaces) ; do
basename "$space"
done
}
function space_show() {
args=$(check_args space,,$1) || return 1
eval $args
if ! has_section "/spaces/$space" ; then
echo "Space does not exist"
return 1
fi
echo "key: $space"
echo "id: $(get_var /spaces/$space/id)"
echo "table id: $(get_table_id $space)"
echo
echo "VLAN associations:"
for region in $(list_sections /regions) ; do
var="$region/spaces/$space/vlan"
if has_var "$var" ; then
echo -e "$(basename $region)\t$(get_var $var)"
fi
done
}
function space_add() {
args=$(check_args space,,$1) || return 1
eval $args
if has_section "/spaces/$space" ; then
echo "Space already exists"
return 1
fi
if ! api_get "/api/v3/spaces/$space/" > /dev/null ; then
echo "Space not found in bondingadmin"
return 1
fi
space_json=$(api_get /api/v3/spaces/$space/)
private_wan_enabled=$(echo $space_json| jq .private_wan_enabled)
if ! $private_wan_enabled ; then
echo "Space ${space} does not have private WAN enabled."
return 1
fi
id=$(echo $space_json| jq .id)
set_var "/spaces/$space/id" "$id"
space_show $space
}
function space_delete() {
args=$(check_args space,,$1) || return 1
eval $args
for section in $(list_sections /regions/); do
for space_path in $(list_sections $section/spaces/); do
if [ "$(basename $space_path)" = "$space" ] ; then
echo "You must remove the VLAN for region $(basename $section) first. Use vlan-remove."
return 1
fi
done
done
# Clean up aggregator's space IP/custom configuration automatically
for agg_section in $(list_sections /aggregators/); do
for space_path in $(list_sections $agg_section/spaces/); do
if [ "$(basename $space_path)" = "$space" ] ; then
del_section "$space_path"
fi
done
done
del_section "/spaces/$space"
}
#
# Subnet commands
#
function subnet_get() {
args=$(check_args space,,$1, region,,$2, vlan_id,skip,$3) || return 1
eval $args
if ! has_section "/spaces/$space" ; then
echo "Space does not exist"
return 1
fi
if ! has_section "/regions/$region" ; then
echo "Region does not exist"
return 1
fi
if ! has_var "/regions/$region/spaces/$space/vlan"; then
if [ -z "$vlan_id" ] ; then
echo "No VLAN configured: argument 'vlan_id' is required"
return 1
fi
vlan_validate $space $region $vlan_id
else
vlan_id=$(get_var "/regions/$region/spaces/$space/vlan")
fi
echo "Subnet: $(get_vlan_ip $vlan_id 0)/21"
echo "Firewall: $(get_vlan_ip $vlan_id 1)"
echo "Aggregators:"
for aggregator in $(list_sections "/aggregators") ; do
if [ "$(get_var $aggregator/region)" = $region ] ; then
ip=$(get_vlan_ip $vlan_id $(get_var $aggregator/yap_id))
echo " $(get_var $aggregator/name): $ip"
fi
done
}
#
# Aggregator commands
#
function aggregator_list() {
for aggregator in $(list_sections /aggregators) ; do
basename "$aggregator"
done
}
function aggregator_show() {
args=$(check_args aggregator,,$1) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
echo "id: $aggregator"
echo "yap_id: $(get_var /aggregators/$aggregator/yap_id)"
echo "name: $(get_var /aggregators/$aggregator/name)"
echo "region: $(get_var /aggregators/$aggregator/region)"
echo "trunk: $(get_var /aggregators/$aggregator/trunk)"
}
function aggregator_add() {
args=$(check_args aggregator,,$1 region,,$2 trunk,,$3) || return 1
eval $args
if has_section "/aggregators/$aggregator" ; then
echo "Aggregator already exists"
return 1
fi
if ! has_section "/regions/$region" ; then
echo "Region does not exist"
return 1
fi
if ! api_get "/api/v3/aggregators/$aggregator/" > /dev/null ; then
echo "Aggregator not found in bondingadmin"
return 1
fi
name=$(api_get /api/v3/aggregators/$aggregator/ | jq -r .name)
set_var "/aggregators/$aggregator/name" "$name"
set_var "/aggregators/$aggregator/region" "$region"
set_var "/aggregators/$aggregator/trunk" "$trunk"
set_var "/aggregators/$aggregator/yap_id" "$(get_next_yap_ip)"
salt_update node-$aggregator ||:
aggregator_show $aggregator
}
function aggregator_trunk_set() {
args=$(check_args aggregator,,$1 trunk,,$2) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
set_var "/aggregators/$aggregator/trunk" "$trunk"
salt_update node-$aggregator ||:
salt_exec node-$aggregator service.restart yap ||:
aggregator_show $aggregator
}
function aggregator_set_space_ip() {
args=$(check_args aggregator,,$1 space,,$2 ip,,$3) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
if ! has_section "/spaces/$space" ; then
echo "Space does not exist"
return 1
fi
set_var "/aggregators/$aggregator/spaces/$space/ip" "$ip"
salt_update node-$aggregator ||:
salt_exec node-$aggregator cmd.run "yap restart $space" ||:
aggregator_show $aggregator
}
function aggregator_remove_space_ip() {
args=$(check_args aggregator,,$1 space,,$2) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
del_var "/aggregators/$aggregator/spaces/$space/ip"
salt_update node-$aggregator ||:
salt_exec node-$aggregator cmd.run "yap restart $space" ||:
aggregator_show $aggregator
}
function aggregator_set_space_bird_config() {
args=$(check_args aggregator,,$1 space,,$2 file,,$3) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
if ! has_section "/spaces/$space" ; then
echo "Space does not exist"
return 1
fi
if [ ! -f $file ] ; then
echo "File does not exist"
return 1
fi
set_var_from_file "/aggregators/$aggregator/spaces/$space/bird_config" $file
salt_update node-$aggregator ||:
salt_exec node-$aggregator cmd.run "yap restart $space" ||:
aggregator_show $aggregator
}
function aggregator_remove_space_bird_config() {
args=$(check_args aggregator,,$1 space,,$2) || return 1
eval $args
if ! has_section "/aggregators/$aggregator" ; then
echo "Aggregator does not exist"
return 1
fi
del_var "/aggregators/$aggregator/spaces/$space/bird_config"
salt_update node-$aggregator ||:
salt_exec node-$aggregator cmd.run "yap restart $space" ||:
aggregator_show $aggregator
}
function aggregator_delete() {
args=$(check_args aggregator,,$1) || return 1
eval $args
del_section "/aggregators/$aggregator"
for section in $(list_sections /regions/aggregators/) ; do
if [ "$(basename $section)" = "$aggregator" ] ; then
del_section "$section"
fi
done
salt_update node-$aggregator ||:
salt_exec node-$aggregator service.disable yap-check-policy-rules.timer ||:
salt_exec node-$aggregator service.stop yap-check-policy-rules.timer ||:
salt_exec node-$aggregator service.disable yap ||:
salt_exec node-$aggregator service.stop yap
}
#
# VXR commands
#
function vxr_list() {
for vxr in $(list_sections /vxrs) ; do
basename "$vxr"
done
}
function vxr_show() {
args=$(check_args vxr,,$1) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
echo "name: $vxr"
echo "yap_id: $(get_var /vxrs/$vxr/yap_id)"
echo "ip: $(get_var /vxrs/$vxr/ip)"
echo "region: $(get_var /vxrs/$vxr/region)"
echo "trunk: $(get_var /vxrs/$vxr/trunk)"
echo "global: $(get_var /vxrs/$vxr/global false)"
}
function vxr_add() {
args=$(check_args vxr,,$1 ip,,$2 region,,$3 trunk,,$4) || return 1
eval $args
if has_section "/vxrs/$vxr" ; then
echo "VXR already exists"
return 1
fi
if ! has_section "/regions/$region" ; then
echo "Region does not exist"
return 1
fi
if ! validate_ip $ip ; then
echo "IP is not valid"
return 1
fi
set_var "/vxrs/$vxr/ip" "$ip"
set_var "/vxrs/$vxr/region" "$region"
set_var "/vxrs/$vxr/trunk" "$trunk"
set_var "/vxrs/$vxr/yap_id" "$(get_next_yap_ip)"
# All VXRs need the IP
salt_update $(get_vxr_nodelist) ||:
# Additional apply for authorized keys, etc.
salt $vxr state.apply ||:
salt_exec $(get_vxr_nodelist) service.restart yap-firewall ||:
salt_exec $(get_vxr_nodelist) service.restart yap ||:
vxr_show $vxr
}
function vxr_trunk_set() {
args=$(check_args vxr,,$1 trunk,,$2) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
set_var "/vxrs/$vxr/trunk" "$trunk"
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr service.restart yap ||:
vxr_show $vxr
}
function vxr_ip_set() {
args=$(check_args vxr,,$1 ip,,$2) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
if ! validate_ip $ip ; then
echo "IP is not valid"
return 1
fi
set_var "/vxrs/$vxr/ip" "$ip"
salt_update $(get_vxr_nodelist) ||:
salt_exec $(get_vxr_nodelist) service.restart yap
vxr_show $vxr
}
function vxr_enable_global() {
args=$(check_args vxr,,$1) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
set_var "/vxrs/$vxr/global" true
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr cmd.run 'yap restart-global' ||:
vxr_show $vxr
}
function vxr_disable_global() {
args=$(check_args vxr,,$1) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
set_var "/vxrs/$vxr/global" false
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr cmd.run 'yap restart-global' ||:
vxr_show $vxr
}
function vxr_set_global_interface_option() {
args=$(check_args vxr,,$1 name,,$2 value,,$3) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
set_var "/vxrs/$vxr/global_interface_options/$name" "$value"
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr cmd.run 'yap restart-global' ||:
vxr_show $vxr
}
function vxr_delete_global_interface_option() {
args=$(check_args vxr,,$1 name,,$2) || return 1
eval $args
if ! has_section "/vxrs/$vxr" ; then
echo "VXR does not exist"
return 1
fi
del_var "/vxrs/$vxr/global_interface_options/$name"
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr cmd.run 'yap restart-global' ||:
vxr_show $vxr
}
function vxr_delete() {
args=$(check_args vxr,,$1) || return 1
eval $args
del_section "/vxrs/$vxr"
for section in $(list_sections /regions/vxrs/) ; do
if [ "$(basename $section)" = "$vxr" ] ; then
del_section "$section"
fi
done
salt_update $(get_vxr_nodelist) ||:
salt_exec $vxr service.disable yap ||:
salt_exec $vxr service.stop yap
}
#
# VLAN commands
#
function vlan_validate() {
args=$(check_args space,,$1 region,,$2 vlan_id,,$3) || return 1
eval $args
if ! [[ $vlan_id =~ [0-9]* ]] ; then
echo "VLAN must be numeric"
return 1
fi
if [[ $vlan_id -lt 2 ]] ; then
echo "VLAN must be greater than 1"
return 1
fi
if [[ $vlan_id -gt 4095 ]] ; then
echo "VLAN must be less than 4096"
return 1
fi
for space_path in $(list_sections /regions/$region/spaces); do
if [ "$(get_var $space_path/vlan)" = "$vlan_id" ] ; then
echo "VLAN ${vlan_id} conflicts with space $(basename $space_path) in region ${region}"
return 1
fi
done
}
function vlan_set() {
args=$(check_args space,,$1 region,,$2 vlan_id,,$3) || return 1
eval $args
if ! has_section /spaces/$space ; then
echo "Space does not exist"
return 1
fi
if ! has_section /regions/$region ; then
echo "Region does not exist"
return 1
fi
vlan_validate $space $region $vlan_id
set_var "/regions/$region/spaces/$space/vlan" "$vlan_id"
salt_update $(get_region_nodelist $region) ||:
salt_exec "$(get_region_nodelist $region)" cmd.run "yap restart $space"
}
function vlan_remove() {
args=$(check_args space,,$1 region,,$2) || return 1
eval $args
del_var "/regions/$region/spaces/$space/vlan"
salt_exec "$(get_region_nodelist $region)" cmd.run "yap stop $space" ||:
salt_update $(get_region_nodelist $region)
}
#
# IPSEC commands
#
function ipsec_enable() {
if has_var /ipsec/key ; then
echo "IPSEC is already enabled"
return 1
fi
key=$(hexdump -n 20 -e '5/4 "%08X"' /dev/urandom)
set_var /ipsec/key "0x$key"
nodelist="$(get_vxr_nodelist)"
if [ -n "$nodelist" ] ; then
salt_update $nodelist ||:
salt_exec "$nodelist" cmd.run "yap start-ipsec"
fi
}
function ipsec_disable() {
del_var /ipsec/key
nodelist="$(get_vxr_nodelist)"
if [ -n "$nodelist" ] ; then
salt_update $nodelist ||:
salt_exec "$nodelist" cmd.run "yap stop-ipsec"
fi
}
function usage() {
echo "$0 <action> [args]"
echo
echo "Actions:"
echo
echo "region-list"
echo "region-show <region>"
echo "region-add <region>"
echo "region-delete <region>"
echo
echo "space-list"
echo "space-show <spacekey>"
echo "space-add <spacekey>"
echo "space-delete <spacekey>"
echo
echo "subnet-get <spacekey> <region> [vlan_id]"
echo
echo "agg-list"
echo "agg-show <id>"
echo "agg-add <id> <region> <trunk>"
echo "agg-trunk-set <id> <trunk>"
echo "agg-delete <id>"
echo "agg-set-space-ip <id> <spacekey> <ip>"
echo "agg-remove-space-ip <id> <spacekey>"
echo "agg-set-space-bird-config <id> <spacekey> <filename>"
echo "agg-remove-space-bird-config <id> <spacekey>"
echo
echo "vxr-list"
echo "vxr-show <name>"
echo "vxr-add <name> <ip> <region> <trunk>"
echo "vxr-ip-set <name> <ip>"
echo "vxr-trunk-set <name> <trunk>"
echo "vxr-enable-global <name>"
echo "vxr-disable-global <name>"
echo "vxr-set-global-interface-option <name> <value>"
echo "vxr-delete-global-interface-option <name>"
echo "vxr-delete <name>"
echo
echo "vlan-set <spacekey> <region> <vlan_id>"
echo "vlan-remove <spacekey> <region>"
echo
echo "ipsec-enable"
echo "ipsec-disable"
echo "auth-set <email> <password>"
echo "dump-config"
echo "upgrade [region]"
echo
}
action=$1
shift
if [ -z "$action" ] ; then
usage
exit 0
fi
set -e
case "$action" in
auth-set)
auth_set "$@"
;;
dump-config)
dump_vars "$@"
;;
upgrade)
upgrade "$@"
;;
region-list)
region_list "$@"
;;
region-show)
region_show "$@"
;;
region-add)
region_add "$@"
;;
region-delete)
region_delete "$@"
;;
space-list)
space_list "$@"
;;
space-show)
space_show "$@"
;;
space-add)
space_add "$@"
;;
space-delete)
space_delete "$@"
;;
subnet-get)
subnet_get "$@"
;;
agg-list|aggregator-list)
aggregator_list "$@"
;;
agg-show|aggregator-show)
aggregator_show "$@"
;;
agg-add|aggregator-add)
aggregator_add "$@"
;;
agg-trunk-set|aggregator-trunk-set)
aggregator_trunk_set "$@"
;;
agg-delete|aggregator-delete)
aggregator_delete "$@"
;;
agg-set-space-ip|aggregator-set-space-ip)
aggregator_set_space_ip "$@"
;;
agg-remove-space-ip|aggregator-remove-space-ip)
aggregator_remove_space_ip "$@"
;;
agg-set-space-bird-config|aggregator-set-space-bird-config)
aggregator_set_space_bird_config "$@"
;;
agg-remove-space-bird-config|aggregator-remove-space-bird-config)
aggregator_remove_space_bird_config "$@"
;;
vxr-list)
vxr_list "$@"
;;
vxr-show)
vxr_show "$@"
;;
vxr-add)
vxr_add "$@"
;;
vxr-trunk-set)
vxr_trunk_set "$@"
;;
vxr-enable-global)
vxr_enable_global "$@"
;;
vxr-disable-global)
vxr_disable_global "$@"
;;
vxr-set-global-interface-option)
vxr_set_global_interface_option "$@"
;;
vxr-delete-global-interface-option)
vxr_delete_global_interface_option "$@"
;;
vxr-delete)
vxr_delete "$@"
;;
vlan-set)
vlan_set "$@"
;;
vlan-remove)
vlan_remove "$@"
;;
ipsec-enable)
ipsec_enable "$@"
;;
ipsec-disable)
ipsec_disable "$@"
;;
*)
usage
;;
esac