BCF P+V support

Change-Id: Idcd208188402e77b832021bb47b71a8b140b5209
This commit is contained in:
Kanzhe Jiang 2016-04-07 11:55:11 -07:00
parent a62bff2b66
commit de7743ea55
15 changed files with 933 additions and 35 deletions

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
notice('MODULAR: bigswitch reconfigure-keystone')
notice('MODULAR: bigswitch reconfigure-keystone')
# configure /etc/keystone/keystone.conf
ini_setting { 'keystone.conf notification driver':

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
notice('MODULAR: bigswitch reconfigure-neutron')
notice('MODULAR: bigswitch reconfigure-neutron')
include bcf::params
if $bcf::params::openstack::bcf_mode == 'P-Only' {
include bcf::p_only::reconfigure_neutron

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
notice('MODULAR: bigswitch restart-cluster-services')
notice('MODULAR: bigswitch restart-cluster-services')
include bcf::params
if $bcf::params::openstack::bcf_mode == 'P-Only' {
include bcf::p_only::restart_cluster_services

View File

@ -0,0 +1,318 @@
import argparse
import functools
import httplib
import json
import traceback
import sys
import yaml
HASH_HEADER = 'BCF-SETUP'
BCF_CONTROLLER_PORT = 8443
ANY = 'any'
ELEMENT_EXISTS = "List element already exists"
LOG_FILE = '/var/log/bsn.log'
def debug_func(*dargs, **dkwargs):
def wrapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
with open(LOG_FILE, "a") as log_file:
log_file.write(
"Function %s called with args [%s], kwargs %s\n" % (
func.func_name, ','.join(
["%s=%s" % (x, y) # this code gets the names of args
for (x, y) in zip(func.func_code.co_varnames, args)]
), kwargs
)
)
ret = func(*args, **kwargs)
if dkwargs.get('log_return'):
with open(LOG_FILE, "a") as log_file:
log_file.write("Function %s returning with value %s\n"
% (func.func_name, ret))
return ret
return inner
# this first case handles when the decorator is called without args
# (e.g. @debug_func) and the second is for when an arg is passed
# (e.g. @debug_func(log_return=True)
if dargs and callable(dargs[0]):
return wrapper(dargs[0])
return wrapper
class NodeConfig(object):
def __init__(self, yaml_file='/etc/astute.yaml'):
self.bridge_vlan_map = {}
with open(yaml_file, 'r') as myfile:
yaml_cfg = myfile.read()
try:
node_config = yaml.load(yaml_cfg)
except Exception as e:
with open(LOG_FILE, "a") as log_file:
log_file.write("Error parsing node yaml file:\n%(e)s\n"
% {'e': e})
return None
trans = node_config['network_scheme']['transformations']
# get the bridge where bond is connected
for tran in trans:
if (tran['action'] != 'add-patch'):
continue
if ('br-prv' not in tran['bridges']):
continue
bridges = list(tran['bridges'])
bridges.remove('br-prv')
bond_bridge = bridges[0]
break
# Get bond name
for tran in trans:
if (tran['action'] != 'add-bond'):
continue
if (bond_bridge != tran.get('bridge')):
continue
bond_name = tran['name']
break
for tran in trans:
if (tran['action'] == 'add-port' and
bond_name in tran['name'] and
'.' in tran['name']):
self.bridge_vlan_map[tran['bridge']] = (
int(tran['name'].split('.')[1]))
@debug_func(log_return=True)
def get_bridge_vlan_str(self):
return ["%s:%d" % (bridge.split('-')[1],vlan)
for bridge, vlan in self.bridge_vlan_map.items()]
class RestLib(object):
@staticmethod
def request(url, prefix="/api/v1/data/controller/", method='GET',
data='', hashPath=None, host="127.0.0.1:8443", cookie=None):
headers = {'Content-type': 'application/json'}
if cookie:
headers['Cookie'] = 'session_cookie=%s' % cookie
if hashPath:
headers[HASH_HEADER] = hashPath
connection = httplib.HTTPSConnection(host)
try:
connection.request(method, prefix + url, data, headers)
response = connection.getresponse()
ret = (response.status, response.reason, response.read(),
response.getheader(HASH_HEADER))
with open(LOG_FILE, "a") as log_file:
log_file.write('Controller REQUEST: %s %s:body=%r\n' %
(method, host + prefix + url, data))
log_file.write('Controller RESPONSE: status=%d reason=%r,'
'data=%r, hash=%r\n' % ret)
return ret
except Exception as e:
raise Exception("Controller REQUEST exception: %s" % e)
@staticmethod
def get(cookie, url, server, port, hashPath=None):
host = "%s:%d" % (server, port)
return RestLib.request(url, hashPath=hashPath, host=host,
cookie=cookie)
@staticmethod
def post(cookie, url, server, port, data, hashPath=None):
host = "%s:%d" % (server, port)
return RestLib.request(url, method='POST', hashPath=hashPath,
host=host, data=data, cookie=cookie)
@staticmethod
def patch(cookie, url, server, port, data, hashPath=None):
host = "%s:%d" % (server, port)
return RestLib.request(url, method='PATCH', hashPath=hashPath,
host=host, data=data, cookie=cookie)
@staticmethod
def put(cookie, url, server, port, data, hashPath=None):
host = "%s:%d" % (server, port)
return RestLib.request(url, method='PUT', hashPath=hashPath,
host=host, data=data, cookie=cookie)
@staticmethod
def delete(cookie, url, server, port, hashPath=None):
host = "%s:%d" % (server, port)
return RestLib.request(url, method='DELETE', hashPath=hashPath,
host=host, cookie=cookie)
@staticmethod
def auth_bcf(server, username, password, port=BCF_CONTROLLER_PORT):
login = {"user": username, "password": password}
host = "%s:%d" % (server, port)
ret = RestLib.request("/api/v1/auth/login", prefix='',
method='POST', data=json.dumps(login),
host=host)
session = json.loads(ret[2])
if ret[0] != 200:
raise Exception(ret)
if ("session_cookie" not in session):
raise Exception("Failed to authenticate: session cookie not set")
return session["session_cookie"]
@staticmethod
@debug_func
def logout_bcf(cookie, server, port=BCF_CONTROLLER_PORT):
url = "core/aaa/session[auth-token=\"%s\"]" % cookie
ret = RestLib.delete(cookie, url, server, port)
return ret
@staticmethod
@debug_func(log_return=True)
def get_active_bcf_controller(servers, username, password,
port=BCF_CONTROLLER_PORT):
for server in servers:
try:
cookie = RestLib.auth_bcf(server, username, password, port)
url = 'core/controller/role'
res = RestLib.get(cookie, url, server, port)[2]
if 'active' in res:
return server, cookie
except Exception:
continue
return None, None
@staticmethod
@debug_func(log_return=True)
def get_os_mgmt_segments(server, cookie, tenant,
port=BCF_CONTROLLER_PORT):
url = (r'''applications/bcf/info/endpoint-manager/segment'''
'''[tenant="%(tenant)s"]''' %
{'tenant': tenant})
ret = RestLib.get(cookie, url, server, port)
if ret[0] != 200:
raise Exception(ret)
res = json.loads(ret[2])
segments = []
for segment in res:
# 'management' or 'Management' segment does not matter
segments.append(segment['name'].lower())
return segments
@staticmethod
@debug_func(log_return=True)
def program_segment_and_membership_rule(
server, cookie, tenant, segment, internal_port, vlan,
port=BCF_CONTROLLER_PORT):
existing_segments = RestLib.get_os_mgmt_segments(
server, cookie, tenant, port)
if segment not in existing_segments:
with open(LOG_FILE, "a") as log_file:
msg = (r'''Warning: BCF controller does not have tenant '''
'''%(tenant)s segment %(segment)s\n''' %
{'tenant': tenant, 'segment': segment})
log_file.write(msg)
segment_url = (
r'''applications/bcf/tenant[name="%(tenant)s"]/segment''' %
{'tenant': tenant})
segment_data = {"name": segment}
try:
ret = RestLib.post(cookie, segment_url, server, port,
json.dumps(segment_data))
except Exception:
ret = RestLib.patch(cookie, segment_url, server, port,
json.dumps(segment_data))
if ret[0] != 204:
if (ret[0] != 409 or
ELEMENT_EXISTS not in ret[2]):
raise Exception(ret)
intf_rule_url = (r'''applications/bcf/tenant[name="%(tenant)s"]/'''
'''segment[name="%(segment)s"]/'''
'''switch-port-membership-rule''' %
{'tenant': tenant,
'segment': segment})
rule_data = {"interface": ANY, "switch": ANY, "vlan": vlan}
try:
ret = RestLib.post(cookie, intf_rule_url, server, port,
json.dumps(rule_data))
except Exception:
ret = RestLib.patch(cookie, intf_rule_url, server, port,
json.dumps(rule_data))
if ret[0] != 204:
if (ret[0] != 409 or
ELEMENT_EXISTS not in ret[2]):
raise Exception(ret)
pg_rule_url = (r'''applications/bcf/tenant[name="%(tenant)s"]/'''
'''segment[name="%(segment)s"]/'''
'''interface-group-membership-rule''' %
{'tenant': tenant,
'segment': segment})
rule_data = {"interface-group": ANY, "vlan": vlan}
try:
ret = RestLib.post(cookie, pg_rule_url, server, port,
json.dumps(rule_data))
except Exception:
ret = RestLib.patch(cookie, pg_rule_url, server, port,
json.dumps(rule_data))
if ret[0] != 204:
if (ret[0] != 409 or
ELEMENT_EXISTS not in ret[2]):
raise Exception(ret)
specific_rule_url = (r'''applications/bcf/tenant[name="%(tenant)s"]/'''
'''segment[name="%(segment)s"]/'''
'''switch-port-membership-rule''' %
{'tenant': tenant,
'segment': segment})
rule_data = {"interface": internal_port, "switch": ANY, "vlan": -1}
try:
ret = RestLib.post(cookie, specific_rule_url, server, port,
json.dumps(rule_data))
except Exception:
ret = RestLib.patch(cookie, specific_rule_url, server, port,
json.dumps(rule_data))
if ret[0] != 204:
if (ret[0] != 409 or
ELEMENT_EXISTS not in ret[2]):
raise Exception(ret)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--username", required=True,
help="username for bcf controller")
parser.add_argument("-p", "--password", required=True,
help="password for bcf controller")
parser.add_argument("-c", "--controllers", required=True,
help="ip addresses of controller cluster "
"separated by ,")
parser.add_argument("-m", "--management-tenant", required=True,
help="Openstack management tenant.")
parser.add_argument("-f", "--fuel-cluster-id", required=True,
help="The custer id of the fuel environment")
args = parser.parse_args()
ctrls = args.controllers.split(',')
try:
nodeCfg = NodeConfig()
segments = nodeCfg.get_bridge_vlan_str()
active_server, cookie = RestLib.get_active_bcf_controller(
ctrls, args.username, args.password,
port=BCF_CONTROLLER_PORT)
for segment in segments:
segment_name, vlan = segment.split(':')
internal_port = "%s%s" % (segment_name[:3], args.fuel_cluster_id)
seg_vlan = int(vlan)
RestLib.program_segment_and_membership_rule(
active_server, cookie, args.management_tenant,
segment_name, internal_port, seg_vlan)
sys.exit(0)
except Exception as e:
err = traceback.format_exc()
with open(LOG_FILE, "a") as log_file:
log_file.write('bcf_rest_client exception: %s\n' % err)
sys.exit(-1)

View File

@ -0,0 +1,104 @@
#!/bin/iash
IFS=,
declare -a bridges=($1)
bond_name=$2
# stop ovs agent, otherwise, ovs bridges cannot be removed
pkill neutron-openvswitch-agent
service neutron-plugin-openvswitch-agent stop
rm -f /etc/init/neutron-plugin-openvswitch-agent.conf
rm -f /usr/bin/neutron-openvswitch-agent
# remove ovs and linux bridge, example ("br-storage" "br-prv" "br-ex")
len=${#bridges[@]}
for (( i=0; i<$len; i++ )); do
ovs-vsctl del-br ${bridges[$i]}
brctl delbr ${bridges[$i]}
ip link del dev ${bridges[$i]}
done
# delete ovs br-int
while true; do
service neutron-plugin-openvswitch-agent stop
rm -f /etc/init/neutron-plugin-openvswitch-agent.conf
ovs-vsctl del-br br-int
ip link del dev br-int
sleep 1
ovs-vsctl show | grep br-int
if [[ $? != 0 ]]; then
break
fi
done
#bring down all bonds
if [[ $bond_name != "none" ]]; then
ip link del dev ${bond_name}
fi
exit 0
# /etc/network/interfaces
echo '' > /etc/network/interfaces
declare -a interfaces=("s0", "m0", "e0")
len=${#interfaces[@]}
for (( i=0; i<$len; i++ )); do
echo -e 'auto' ${interfaces[$i]} >>/etc/network/interfaces
echo -e 'iface' ${interfaces[$i]} 'inet manual' >>/etc/network/interfaces
echo ${interfaces[$i]} | grep '\.'
if [[ $? == 0 ]]; then
intf=$(echo ${interfaces[$i]} | cut -d \. -f 1)
echo -e 'vlan-raw-device ' $intf >> /etc/network/interfaces
fi
echo -e '\n' >> /etc/network/interfaces
done
echo -e 'auto br_fw_admin' >>/etc/network/interfaces
echo -e 'iface br_fw_admin inet static' >>/etc/network/interfaces
echo -e 'bridge_ports eth0' >>/etc/network/interfaces
echo -e 'address' >>/etc/network/interfaces
#reset uplinks to move them out of bond
uplinks=(%(uplinks)s)
len=${#uplinks[@]}
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} down
done
sleep 2
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} up
done
# assign ip to ivs internal ports
bash /etc/rc.local
echo 'Restart openstack-nova-compute and neutron-bsn-agent'
service nova-compute restart
service neutron-bsn-agent restart
set +e
# Make sure only root can run this script
if [[ "$(id -u)" != "0" ]]; then
echo -e "Please run as root"
exit 1
fi
apt-get install ubuntu-cloud-keyring
apt-get update -y
apt-get install -y linux-headers-$(uname -r) build-essential
apt-get install -y python-dev python-setuptools
apt-get install -y puppet dpkg
apt-get install -y vlan ethtool
apt-get install -y libssl-dev libffi6 libffi-dev
apt-get install -y libnl-genl-3-200
apt-get -f install -y
apt-get install -o Dpkg::Options::="--force-confold" --force-yes -y neutron-common
easy_install pip
puppet module install --force puppetlabs-inifile
puppet module install --force puppetlabs-stdlib
set -e
exit 0

View File

@ -0,0 +1,138 @@
#!/bin/bash
if [ "$#" -ne 6 ]; then
echo "Usage: $0 <management interface> <management ip> <uplinks> <all used interfaces> <bridges' ip>" >&2
exit 1
fi
mgmt_itf=$1
IFS='/'
declare -a mgmt_ip_attr=($2)
mgmt_ip=${mgmt_ip_attr[0]}
IFS=','
declare -a uplinks=($3)
declare -a interfaces=($4)
IFS='{}'
read -ra array1 <<< $5
deployment_id=$6
cdr2mask ()
{
# Number of args to shift, 255..255, first non-255 byte, zeroes
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
[ $1 -gt 1 ] && shift $1 || shift
echo ${1-0}.${2-0}.${3-0}.${4-0}
}
# install ivs
dpkg --force-all -i /etc/fuel/plugins/fuel-plugin-bigswitch-1.0/ivs_packages/ubuntu/ivs_3.5.0_amd64.deb
dpkg --force-all -i /etc/fuel/plugins/fuel-plugin-bigswitch-1.0/ivs_packages/ubuntu/ivs-dbg_3.5.0_amd64.deb
apt-get install -y libnl-genl-3-200
apt-get -f install -y
apt-get install -y apport
# full installation
if [[ -f /etc/init/neutron-plugin-openvswitch-agent.override ]]; then
cp /etc/init/neutron-plugin-openvswitch-agent.override /etc/init/neutron-bsn-agent.override
fi
echo '' > /etc/network/interfaces
# Process input arguments
IFS=','
declare -a array2=(${array1[0]})
#IFS='=>'
len=${#array2[@]}
for (( i=0; i<$len; i++ )); do
# entry = "br-storage"=>["192.168.1.3/24"]
entry=${array2[$i]}
IFS='=>'
declare -a bridge_ip=(${entry})
key=$(echo "${bridge_ip[0]}" | sed -e 's/"//' -e 's/"//')
itf_ip=$(echo "${bridge_ip[2]}" | sed -e 's/\[//' -e 's/"//' -e 's/"//' -e 's/]//')
IFS='/'
declare -a ip_address=(${itf_ip})
netmask=$( cdr2mask ${ip_address[1]} )
internal_interface=""
if [[ "$key" =~ "br-storage" ]]; then
internal_interface="s${deployment_id}"
elif [[ "$key" =~ "br-mgmt" ]]; then
internal_interface="m${deployment_id}"
elif [[ "$key" =~ "br-ex" ]]; then
internal_interface="e${deployment_id}"
fi
if [[ "$internal_interface" =~ "$deployment_id" ]]; then
echo -e 'auto' ${internal_interface} >> /etc/network/interfaces
echo -e 'iface' ${internal_interface} 'inet manual' >> /etc/network/interfaces
if [[ ! -z ${netmask} ]]; then
echo -e ' address' ${ip_address[0]} >> /etc/network/interfaces
echo -e ' netmask' ${netmask} >> /etc/network/interfaces
ifconfig $internal_interface up
ip link set $internal_interface up
ifconfig $internal_interface ${ip_address[0]} netmask ${netmask}
fi
echo -e '\n' >> /etc/network/interfaces
fi
done
# /etc/network/interfaces
len=${#interfaces[@]}
for (( i=0; i<$len; i++ )); do
echo -e 'auto' ${interfaces[$i]} >> /etc/network/interfaces
echo -e 'iface' ${interfaces[$i]} 'inet manual' >> /etc/network/interfaces
echo -e '\n' >> /etc/network/interfaces
done
echo -e 'auto br_fw_admin' >> /etc/network/interfaces
echo -e 'iface br_fw_admin inet static' >> /etc/network/interfaces
echo -e ' bridge_ports' ${mgmt_itf} >> /etc/network/interfaces
echo -e ' address' ${mgmt_ip} >> /etc/network/interfaces
echo -e '\n' >> /etc/network/interfaces
exit 0
#reset uplinks to move them out of bond
len=${#uplinks[@]}
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} down
done
sleep 2
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} up
done
# assign ip to ivs internal ports
#bash /etc/rc.local
echo 'Restart openstack-nova-compute and neutron-bsn-agent'
service nova-compute restart
service neutron-bsn-agent restart
set +e
# Make sure only root can run this script
if [[ "$(id -u)" != "0" ]]; then
echo -e "Please run as root"
exit 1
fi
apt-get install ubuntu-cloud-keyring
apt-get update -y
apt-get install -y linux-headers-$(uname -r) build-essential
apt-get install -y python-dev python-setuptools
apt-get install -y puppet dpkg
apt-get install -y vlan ethtool
apt-get install -y libssl-dev libffi6 libffi-dev
apt-get install -y libnl-genl-3-200
apt-get -f install -y
apt-get install -o Dpkg::Options::="--force-confold" --force-yes -y neutron-common
easy_install pip
puppet module install --force puppetlabs-inifile
puppet module install --force puppetlabs-stdlib
set -e
exit 0

View File

@ -0,0 +1,205 @@
#!/bin/bash
compute() {
if [[ $deploy_dhcp_agent == true ]]; then
dpkg -l neutron-dhcp-agent
if [[ $? != 0 ]]; then
apt-get install -o Dpkg::Options::="--force-confold" -y neutron-metadata-agent
apt-get install -o Dpkg::Options::="--force-confold" -y neutron-dhcp-agent
service neutron-metadata-agent stop
service neutron-dhcp-agent stop
fi
# patch linux/dhcp.py to make sure static host route is pushed to instances
dhcp_py=$(find /usr -name dhcp.py | grep linux)
dhcp_dir=$(dirname "${dhcp_py}")
sed -i 's/if (isolated_subnets\[subnet.id\] and/if (True and/g' $dhcp_py
find $dhcp_dir -name "*.pyc" | xargs rm
find $dhcp_dir -name "*.pyo" | xargs rm
fi
# install ivs
if [[ $install_ivs == true ]]; then
# check ivs version compatability
pass=true
ivs --version
if [[ $? == 0 ]]; then
old_version=$(ivs --version | awk '{print $2}')
old_version_numbers=(${old_version//./ })
new_version_numbers=(${ivs_version//./ })
if [[ "$old_version" != "${old_version%%$ivs_version*}" ]]; then
pass=true
elif [[ $old_version > $ivs_version ]]; then
pass=false
elif [[ $((${new_version_numbers[0]}-1)) -gt ${old_version_numbers[0]} ]]; then
pass=false
fi
fi
if [[ $pass == true ]]; then
dpkg --force-all -i %(dst_dir)s/%(ivs_pkg)s
if [[ -f %(dst_dir)s/%(ivs_debug_pkg)s ]]; then
modinfo openvswitch | grep "^version"
if [[ $? == 0 ]]; then
apt-get remove -y openvswitch-datapath-dkms && rmmod openvswitch && modprobe openvswitch
fi
apt-get install -y libnl-genl-3-200
apt-get -f install -y
dpkg --force-all -i %(dst_dir)s/%(ivs_debug_pkg)s
apt-get install -y apport
fi
elif [[ $skip_ivs_version_check == true ]]; then
dpkg --force-all -i %(dst_dir)s/%(ivs_pkg)s
if [[ -f %(dst_dir)s/%(ivs_debug_pkg)s ]]; then
modinfo openvswitch | grep "^version"
if [[ $? == 0 ]]; then
apt-get remove -y openvswitch-datapath-dkms && rmmod openvswitch && modprobe openvswitch
fi
apt-get install -y libnl-genl-3-200
apt-get -f install -y
dpkg --force-all -i %(dst_dir)s/%(ivs_debug_pkg)s
apt-get install -y apport
fi
else
echo "ivs upgrade fails version validation"
fi
fi
# full installation
if [[ $install_all == true ]]; then
if [[ -f /etc/init/neutron-plugin-openvswitch-agent.override ]]; then
cp /etc/init/neutron-plugin-openvswitch-agent.override /etc/init/neutron-bsn-agent.override
fi
# stop ovs agent, otherwise, ovs bridges cannot be removed
pkill neutron-openvswitch-agent
service neutron-plugin-openvswitch-agent stop
rm -f /etc/init/neutron-bsn-agent.conf
rm -f /etc/init/neutron-plugin-openvswitch-agent.conf
rm -f /usr/bin/neutron-openvswitch-agent
# remove ovs and linux bridge, example ("br-storage" "br-prv" "br-ex")
declare -a ovs_br=(%(ovs_br)s)
len=${#ovs_br[@]}
for (( i=0; i<$len; i++ )); do
ovs-vsctl del-br ${ovs_br[$i]}
brctl delbr ${ovs_br[$i]}
ip link del dev ${ovs_br[$i]}
done
# delete ovs br-int
while true; do
service neutron-plugin-openvswitch-agent stop
rm -f /etc/init/neutron-plugin-openvswitch-agent.conf
ovs-vsctl del-br %(br-int)s
ip link del dev %(br-int)s
sleep 1
ovs-vsctl show | grep %(br-int)s
if [[ $? != 0 ]]; then
break
fi
done
#bring down all bonds
declare -a bonds=(%(bonds)s)
len=${#bonds[@]}
for (( i=0; i<$len; i++ )); do
ip link del dev ${bonds[$i]}
done
# deploy bcf
puppet apply --modulepath /etc/puppet/modules %(dst_dir)s/%(hostname)s.pp
# /etc/network/interfaces
if [[ ${fuel_cluster_id} != 'None' ]]; then
echo '' > /etc/network/interfaces
declare -a interfaces=(%(interfaces)s)
len=${#interfaces[@]}
for (( i=0; i<$len; i++ )); do
echo -e 'auto' ${interfaces[$i]} >>/etc/network/interfaces
echo -e 'iface' ${interfaces[$i]} 'inet manual' >>/etc/network/interfaces
echo ${interfaces[$i]} | grep '\.'
if [[ $? == 0 ]]; then
intf=$(echo ${interfaces[$i]} | cut -d \. -f 1)
echo -e 'vlan-raw-device ' $intf >> /etc/network/interfaces
fi
echo -e '\n' >> /etc/network/interfaces
done
echo -e 'auto' %(br_fw_admin)s >>/etc/network/interfaces
echo -e 'iface' %(br_fw_admin)s 'inet static' >>/etc/network/interfaces
echo -e 'bridge_ports' %(pxe_interface)s >>/etc/network/interfaces
echo -e 'address' %(br_fw_admin_address)s >>/etc/network/interfaces
fi
#reset uplinks to move them out of bond
declare -a uplinks=(%(uplinks)s)
len=${#uplinks[@]}
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} down
done
sleep 2
for (( i=0; i<$len; i++ )); do
ip link set ${uplinks[$i]} up
done
# assign ip to ivs internal ports
bash /etc/rc.local
fi
if [[ $deploy_dhcp_agent == true ]]; then
echo 'Restart neutron-metadata-agent and neutron-dhcp-agent'
service neutron-metadata-agent restart
service neutron-dhcp-agent restart
fi
echo 'Restart openstack-nova-compute and neutron-bsn-agent'
service nova-compute restart
service neutron-bsn-agent restart
set +e
# Make sure only root can run this script
if [[ "$(id -u)" != "0" ]]; then
echo -e "Please run as root"
exit 1
fi
# prepare dependencies
cat /etc/apt/sources.list | grep "http://archive.ubuntu.com/ubuntu"
if [[ $? != 0 ]]; then
release=$(lsb_release -sc)
echo -e "\ndeb http://archive.ubuntu.com/ubuntu $release main\n" >> /etc/apt/sources.list
fi
apt-get install ubuntu-cloud-keyring
apt-get update -y
apt-get install -y linux-headers-$(uname -r) build-essential
apt-get install -y python-dev python-setuptools
apt-get install -y puppet dpkg
apt-get install -y vlan ethtool
apt-get install -y libssl-dev libffi6 libffi-dev
apt-get install -y libnl-genl-3-200
apt-get -f install -y
apt-get install -o Dpkg::Options::="--force-confold" --force-yes -y neutron-common
easy_install pip
puppet module install --force puppetlabs-inifile
puppet module install --force puppetlabs-stdlib
# install bsnstacklib
if [[ $install_bsnstacklib == true ]]; then
sleep 2
pip uninstall -y bsnstacklib
sleep 2
if [[ $pip_proxy == false ]]; then
pip install --upgrade "bsnstacklib>%(bsnstacklib_version_lower)s,<%(bsnstacklib_version_upper)s"
pip install --upgrade horizon-bsn
else
pip --proxy $pip_proxy install --upgrade "bsnstacklib>%(bsnstacklib_version_lower)s,<%(bsnstacklib_version_upper)s"
pip --proxy $pip_proxy install --upgrade horizon-bsn
fi
fi
set -e
exit 0

View File

@ -19,21 +19,26 @@ class bcf {
$sys_desc_lacp = '5c:16:c7:00:00:04'
$sys_desc_xor = '5c:16:c7:00:00:00'
$deployment_id = hiera('deployment_id')
# Network configuration
$network_scheme = hiera_hash('network_scheme', {})
$existing_bridges = $network_scheme['endpoints']
prepare_network_config($network_scheme)
$gw = get_default_gateways()
$phy_devs = get_network_role_property('neutron/private', 'phys_dev')
$mgmt_itf = get_network_role_property('admin/pxe', 'phys_dev')
$if_str = "${phy_devs}"
if $if_str =~ /^bond.*/ {
$ifaces = join($phy_devs, ',')
$bond = true
$bond_name = "${phy_devs[0]}"
$s = "${phy_devs[0]},"
$r = split("abc${ifaces}", $s)
$itfs = $r[1]
}
else {
$bond = false
$bond_name = 'none'
$itfs = $phy_devs
}
$network_metadata = hiera_hash('network_metadata', {})

View File

@ -13,10 +13,93 @@
# License for the specific language governing permissions and limitations
# under the License.
#
notice('MODULAR: bigswitch p_v compute')
class bcf::p_v::compute {
include bcf
include bcf::params
include bcf::params::openstack
$interfaces_dict = $bcf::network_scheme['interfaces']
notice("bigswitch interfaces_dict ${interfaces_dict}")
$bridge_ips = {}
$bridge_ips['br-aux'] = 'none'
$ivs_internal_ports = {}
$mgmt_ip = $bcf::existing_bridges['br-fw-admin']['IP']
if has_key($bcf::existing_bridges, 'br-storage') {
$bridge_ips['br-storage'] = $bcf::existing_bridges['br-storage']['IP']
$ivs_internal_ports['br-storage'] = "s${bcf::deployment_id}"
}
if has_key($bcf::existing_bridges, 'br-prv') {
$bridge_ips['br-prv'] = $bcf::existing_bridges['br-prv']['IP']
}
if has_key($bcf::existing_bridges, 'br-mgmt') {
$bridge_ips['br-mgmt'] = $bcf::existing_bridges['br-mgmt']['IP']
$ivs_internal_ports['br-mgmt'] = "m${bcf::deployment_id}"
}
if has_key($bcf::existing_bridges, 'br-ex') {
$bridge_ips['br-ex'] = $bcf::existing_bridges['br-ex']['IP']
$ivs_internal_ports['br-ex'] = "e${bcf::deployment_id}"
}
$bridge_list = split(inline_template("<%= @bridge_ips.keys.join(',') %>", ','))
$interfaces = split(inline_template("<%= @interfaces_dict.keys.join(',') %>", ','))
$internal_port_str = inline_template("<%= @ivs_internal_ports.values.join(' --internal-port=') %>")
$ivs_uplink_str = regsubst($bcf::itfs, ',', ' -u ', 'G')
notice("bigswitch bond_name ${bcf::bond_name}")
notice("bigswitch interfaces ${interfaces}")
package { 'python-pip':
ensure => 'installed',
}
exec { 'bsnstacklib':
command => 'pip install "bsnstacklib<2015.2"',
path => '/usr/local/bin/:/usr/bin/:/bin',
require => Package['python-pip']
}
# Install the cleanup script
file { '/etc/bigswitch':
ensure => 'directory',
require => Exec['bsnstacklib']
}
file { '/etc/bigswitch/bridge-cleanup.sh':
ensure => 'file',
source => 'puppet:///modules/bcf/p_v/bridge-cleanup.sh',
require => File['/etc/bigswitch']
}
exec { 'clean up ovs bridges':
command => "bash /etc/bigswitch/bridge-cleanup.sh ${bridge_list} ${bcf::bond_name}",
path => '/usr/local/bin/:/usr/bin/:/bin',
require => File['/etc/bigswitch/bridge-cleanup.sh']
}
file { '/etc/bigswitch/ivs-setup.sh':
ensure => 'file',
source => 'puppet:///modules/bcf/p_v/ivs-setup.sh',
require => EXEC['clean up ovs bridges']
}
exec { 'set up ivs':
command => "bash /etc/bigswitch/ivs-setup.sh ${bcf::mgmt_itf} ${mgmt_ip} ${bcf::itfs} ${interfaces} \'${bridge_ips}\' ${bcf::deployment_id}",
path => '/usr/local/bin/:/usr/bin/:/bin',
require => File['/etc/bigswitch/ivs-setup.sh']
}
file { '/etc/default/ivs':
ensure => file,
mode => '0644',
content => "DAEMON_ARGS=\"--hitless --inband-vlan 4092 -u ${ivs_uplink_str} --internal-port=${internal_port_str}\"",
require => Exec['set up ivs'],
notify => Service['ivs'],
}
service { 'ivs':
ensure => running,
enable => true,
}
# edit rc.local for cron job and default gw
file { '/etc/rc.local':
@ -59,7 +142,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'report_interval',
value => '60',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
ini_setting { 'neutron.conf agent_down_time':
ensure => present,
@ -68,7 +151,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'agent_down_time',
value => '150',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
ini_setting { 'neutron.conf service_plugins':
ensure => present,
@ -77,7 +160,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'service_plugins',
value => 'router',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
ini_setting { 'neutron.conf dhcp_agents_per_network':
ensure => present,
@ -86,7 +169,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'dhcp_agents_per_network',
value => '1',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
ini_setting { 'neutron.conf notification driver':
ensure => present,
@ -95,7 +178,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'notification_driver',
value => 'messaging',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
# set the correct properties in ml2_conf.ini on compute as well
@ -107,7 +190,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'type_drivers',
value => 'vlan',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
ini_setting { 'ml2 tenant network types':
ensure => present,
@ -116,7 +199,7 @@ class bcf::p_v::compute {
key_val_separator => '=',
setting => 'tenant_network_types',
value => 'vlan',
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
# change ml2 ownership
@ -124,23 +207,52 @@ class bcf::p_v::compute {
owner => neutron,
group => neutron,
recurse => true,
notify => Service['neutron-plugin-openvswitch-agent'],
notify => Service['neutron-bsn-agent'],
}
# ensure neutron-plugin-openvswitch-agent is running
file { '/etc/init/neutron-plugin-openvswitch-agent.conf':
ensure => file,
mode => '0644',
# config neutron-bsn-agent conf
file { '/etc/init/neutron-bsn-agent.conf':
ensure => present,
content => "
description \"Neutron BSN Agent\"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
exec /usr/local/bin/neutron-bsn-agent --config-file=/etc/neutron/neutron.conf --config-dir /etc/neutron/conf.d/common --log-file=/var/log/neutron/neutron-bsn-agent.log
end script
",
}
service { 'neutron-plugin-openvswitch-agent':
file { '/etc/init.d/neutron-bsn-agent':
ensure => link,
target => '/lib/init/upstart-job',
notify => Service['neutron-bsn-agent'],
}
service {'neutron-bsn-agent':
ensure => 'running',
enable => true,
provider => 'upstart',
hasrestart => true,
hasstatus => true,
subscribe => [File['/etc/init/neutron-plugin-openvswitch-agent.conf']],
subscribe => [File['/etc/init/neutron-bsn-agent.conf'], File['/etc/init.d/neutron-bsn-agent']],
}
# stop and disable neutron-plugin-openvswitch-agent
service { 'neutron-plugin-openvswitch-agent':
ensure => 'stopped',
enable => false,
provider => 'upstart',
}
# disable l3 agent
ini_setting { 'l3 agent disable metadata proxy':
ensure => present,
path => '/etc/neutron/l3_agent.ini',
section => 'DEFAULT',
key_val_separator => '=',
setting => 'enable_metadata_proxy',
value => 'False',
}
file { '/etc/neutron/dnsmasq-neutron.conf':
ensure => file,
content => 'dhcp-option-force=26,1400',

View File

@ -125,14 +125,6 @@ class bcf::p_v::reconfigure_neutron {
setting => 'enable_metadata_proxy',
value => 'False',
}
ini_setting { 'l3 agent handle_internal_only_routers':
ensure => present,
path => '/etc/neutron/l3_agent.ini',
section => 'DEFAULT',
key_val_separator => '=',
setting => 'handle_internal_only_routers',
value => 'True',
}
# config /etc/neutron/plugins/ml2/ml2_conf.ini
ini_setting { 'ml2 type dirvers':
@ -159,7 +151,7 @@ class bcf::p_v::reconfigure_neutron {
section => 'ml2',
key_val_separator => '=',
setting => 'mechanism_drivers',
value => 'openvswitch,bsn_ml2',
value => 'bsn_ml2',
notify => Service['neutron-server'],
}
ini_setting { 'ml2 restproxy ssl cert directory':
@ -171,11 +163,13 @@ class bcf::p_v::reconfigure_neutron {
value => '/etc/neutron/plugins/ml2',
notify => Service['neutron-server'],
}
if $bcf::params::openstack::bcf_controller_2 == ':8000' {
$server = $bcf::params::openstack::bcf_controller_1
if $bcf::params::openstack::bcf_controller_2 == '' {
$server = "${bcf::params::openstack::bcf_controller_1}:8000"
$rest_server = "${bcf::params::openstack::bcf_controller_1}"
}
else {
$server = "${bcf::params::openstack::bcf_controller_1},${bcf::params::openstack::bcf_controller_2}"
$server = "${bcf::params::openstack::bcf_controller_1}:8000,${bcf::params::openstack::bcf_controller_2}:8000"
$rest_server = "${bcf::params::openstack::bcf_controller_1},${bcf::params::openstack::bcf_controller_2}"
}
ini_setting { 'ml2 restproxy servers':
@ -282,4 +276,14 @@ class bcf::p_v::reconfigure_neutron {
ensure => running,
enable => true,
}
file { '/etc/bigswitch/bcf_rest_client.py':
ensure => 'file',
source => 'puppet:///modules/bcf/p_v/bcf_rest_client.py',
}
exec { 'Openstack segment membership':
command => "python /etc/bigswitch/bcf_rest_client.py -u ${bcf::params::openstack::bcf_username} -p ${bcf::params::openstack::bcf_password} -c ${rest_server} -m ${bcf::params::openstack::bcf_os_mgmt_tenant} -f ${bcf::params::openstack::deployment_id}",
path => '/usr/local/bin/:/usr/bin/:/bin',
require => FILE['/etc/bigswitch/bcf_rest_client.py']
}
}

View File

@ -35,8 +35,12 @@ class bcf::p_v::restart_cluster_services {
command => 'crm resource stop p_neutron-l3-agent',
path => '/usr/local/bin/:/bin/:/usr/sbin',
} ->
exec { 'clean up neutron-l3-agent':
command => 'crm resource cleanup p_neutron-l3-agent',
path => '/usr/local/bin/:/bin/:/usr/sbin',
} ->
exec { 'disable neutron-l3-agent':
command => 'crm resource disable p_neutron-l3-agent',
command => 'crm configure delete p_neutron-l3-agent',
path => '/usr/local/bin/:/bin/:/usr/sbin',
} ->
exec { 'restart neutron-plugin-openvswitch-agent':

View File

@ -18,6 +18,7 @@ class bcf::params::openstack {
$virtual_cluster_name = 'OpenStackCluster'
$ceph_virtual_cluster_name = 'CephCluster'
$deployment_id = hiera('deployment_id')
$quantum_settings = hiera('quantum_settings')
$keystone_vip = hiera('management_vip')
$auth_user = 'neutron'
@ -38,11 +39,11 @@ class bcf::params::openstack {
$rabbit_hash = hiera('rabbit')
$bcf_mode = $bcf_hash['bcf_mode']
$bcf_controller_1 = "${bcf_hash['bcf_controller_1']}:8000"
$bcf_controller_2 = "${bcf_hash['bcf_controller_2']}:8000"
$bcf_controller_1 = "${bcf_hash['bcf_controller_1']}"
$bcf_controller_2 = "${bcf_hash['bcf_controller_2']}"
$bcf_username = $bcf_hash['bcf_controller_username']
$bcf_password = $bcf_hash['bcf_controller_password']
$bcf_instance_id = $bcf_hash['openstack_instance_id']
$bcf_controller_mgmt = $bcf_hash['bcf_controller_os_mgmt']
$bcf_os_mgmt_tenant = $bcf_hash['openstack_mgmt_tenant']
$access_tenant = 'services'
}

View File

@ -68,7 +68,7 @@
type: puppet
role: [compute]
required_for: [post_deployment_end]
requires: [restart-cluster-services]
requires: [restart-cluster-services, configure_default_route]
parameters:
puppet_manifest: puppet/manifests/compute-config.pp
puppet_modules: puppet/modules:/etc/puppet/modules

View File

@ -57,3 +57,10 @@ attributes:
description: "The Openstack instance ID that is unique within the BCF fabric"
weight: 30
type: "text"
openstack_mgmt_tenant:
value: ""
label: "Management Tenant"
description: "The BCF Management Tenant"
weight: 40
type: "text"