Uplift BGPVPN to Boron-SR1 and odl-netvirt feature

- Make the plugin use Boron SR1 when the bgpvpn features are used
- Make BGPVPN use the odl-netvirt feature
- Make EXPERIMENTAL_TARBALL_LOCATION point to SR1
- Remove the default gateway input for bgpvpn
- Unconditionally enable some features which were disabled for bgpvpn.
  Disable the bgpvpn specific environment configurations that were used
  in lieu of those features that were disabled for bgpvpn
- Make floating IP work for odl-netvirt-openstack. This is done by
  adding a provider_mapping to ovs between physnet1 and br-floating, which
  opendaylight uses to configure the networking setup accordingly.

Co-Authored-By: Romanos Skiadas <rski@intracom-telecom.com>
Change-Id: Icdb962dac83d0a68b25914285a0e7d8987daefdc
This commit is contained in:
Nikolas Hermanns 2016-08-23 15:18:23 +02:00 committed by Romanos Skiadas
parent 5db5332708
commit 5d1885b258
7 changed files with 26 additions and 317 deletions

View File

@ -8,15 +8,11 @@ $ovsdb_managers = odl_ovsdb_managers($opendaylight::odl_mgmt_ips)
if $use_neutron {
package {'python-networking-odl':
ensure => installed,
}
package {'python-networking-odl': ensure => installed }
unless $odl['enable_bgpvpn'] {
exec { 'ovs-set-manager':
command => "ovs-vsctl set-manager $ovsdb_managers",
path => '/usr/bin'
}
exec { 'ovs-set-manager':
command => "ovs-vsctl set-manager ${ovsdb_managers}",
path => '/usr/bin'
}
if $odl['enable_l3_odl'] or roles_include(['primary-controller', 'controller']) {
@ -107,9 +103,13 @@ if $use_neutron {
$net_role_property = 'neutron/mesh'
$tunneling_ip = get_network_role_property($net_role_property, 'ipaddr')
# With bgpvpn feature enabled the connectivity to the outside world
# is solved in another way.
unless $odl['enable_bgpvpn'] {
if $odl['enable_bgpvpn'] {
exec { 'ovs-set-provider-mapping':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config:provider_mappings=physnet1:br-floating",
path => '/usr/bin',
require => Exec['ovs-set-manager'],
}
} else {
if $ext_interface {
exec { 'ovs-set-provider-mapping':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config:provider_mappings=br-ex:${ext_interface}",
@ -117,26 +117,12 @@ if $use_neutron {
require => Exec['ovs-set-manager'],
}
}
exec { 'ovs-set-tunnel-endpoint':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config:local_ip=${tunneling_ip}",
path => '/usr/bin',
require => Exec['ovs-set-manager'],
}
}
# Setup the trunk end points. when the sdnvpn feature is activated this is needed.
if $odl['enable_bgpvpn'] {
$file_setupTEPs = '/tmp/setup_TEPs.py'
file { $file_setupTEPs:
ensure => file,
content => template('opendaylight/setup_TEPs.py'),
}
exec { 'setup_TEPs':
# At the moment the connection between ovs and ODL is no HA if vpnfeature is activated
command => "python $file_setupTEPs ${opendaylight::odl_mgmt_ips[0]} ${tunneling_ip} $ovsdb_managers",
require => File[$file_setupTEPs],
path => '/usr/local/bin:/usr/bin:/sbin:/bin:/usr/local/sbin:/usr/sbin',
}
}
exec { 'ovs-set-tunnel-endpoint':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config:local_ip=${tunneling_ip}",
path => '/usr/bin',
require => Exec['ovs-set-manager'],
}
}
$iface = get_network_role_property($net_role_property, 'phys_dev')

View File

@ -6,10 +6,11 @@ module Puppet::Parser::Functions
enabled_features = []
enabled_features << features_set['default']
enabled_features << features_set['odl-default']
enabled_features << features_set['ovs'] if not odl_settings['enable_bgpvpn']
# only enable the new netvirt features when bgpvpn is enabled
enabled_features << features_set['ovsdb'] unless odl_settings['enable_bgpvpn']
enabled_features << features_set['netvirt'] if odl_settings['enable_bgpvpn']
enabled_features << features_set['sfc'] if odl_settings['enable_sfc']
enabled_features << features_set[odl_settings['sfc_class']] if odl_settings['enable_sfc']
enabled_features << features_set['vpn'] if odl_settings['enable_bgpvpn']
enabled_features.join(',')
end

View File

@ -10,12 +10,7 @@ module Puppet::Parser::Functions
odl = function_hiera(['opendaylight'])
network_scheme = function_hiera(['network_scheme'])
if odl['enable_bgpvpn']
# If bgpvpn extensions are enabled br-ex is not needed
delete_bridges = ['br-prv', 'br-floating']
else
delete_bridges = ['br-prv']
end
delete_bridges = ['br-prv']
debug "ODL network before transformation: #{network_scheme}"
@ -57,11 +52,6 @@ module Puppet::Parser::Functions
end
else
debug "Changing network_scheme for the bgpvpn case"
roles = network_scheme['roles']
roles['neutron/floating'] = 'None' if roles.has_key?('neutron/floating')
if endpoints.has_key? 'br-floating'
endpoints.delete 'br-floating'
end
if endpoints.has_key? 'br-prv'
endpoints.delete 'br-prv'
end

View File

@ -8,16 +8,11 @@ class opendaylight::service {
$rest_port = $opendaylight::rest_api_port
if $odl['enable_bgpvpn'] {
$odl_up_testing_site = "ovsdb:1"
} else {
$odl_up_testing_site = "netvirt:1"
}
if roles_include(['primary-controller']) {
exec { 'wait-until-odl-ready':
command => join([
"curl -o /dev/null --fail --silent --head -u ${user}:${password}",
"http://${management_vip}:${rest_port}/restconf/operational/network-topology:network-topology/topology/${odl_up_testing_site}"
"http://${management_vip}:${rest_port}/restconf/operational/network-topology:network-topology/topology/netvirt:1"
], ' '),
path => '/bin:/usr/bin',
tries => 60,

View File

@ -1,252 +0,0 @@
'''
Created on Feb 19, 2016
This script created the tunnel endpoints in odl when vpnservice feature
is used
@author: enikher
'''
from subprocess import Popen, PIPE
import requests
import os
import yaml
import sys
import logging
import datetime
import urllib
import traceback
try:
from neutron.openstack.common import jsonutils
except ImportError:
from oslo_serialization import jsonutils
import json
Open_flow_version = 'Openflow13'
Astute_path = '/etc/astute.yaml'
LOG_PATH = '/var/log/odl_setup_tunnel_endpoints.log'
LOG = logging.getLogger(__name__)
LOG_LEVEL = logging.DEBUG
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
filename=LOG_PATH,
datefmt='%Y-%m-%dT:%H:%M:%s', level=LOG_LEVEL)
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
console.setFormatter(formatter)
LOG.addHandler(console)
def log_enter_exit(func):
def inner(self, *args, **kwargs):
LOG.debug(("Entering %(cls)s.%(method)s "
"args: %(args)s, kwargs: %(kwargs)s") %
{'cls': self.__class__.__name__,
'method': func.__name__,
'args': args,
'kwargs': kwargs})
start = datetime.datetime.now()
ret = func(self, *args, **kwargs)
end = datetime.datetime.now()
LOG.debug(("Exiting %(cls)s.%(method)s. "
"Spent %(duration)s sec. "
"Return %(return)s") %
{'cls': self.__class__.__name__,
'duration': end - start,
'method': func.__name__,
'return': ret})
return ret
return inner
class ODL_Client(object):
@log_enter_exit
def __init__(self, odl_ip, odl_port,
user, passw):
self.url = ("http://%(ip)s:%(port)s/restconf/config" %
{'ip': odl_ip,
'port': odl_port})
self.auth = (user, passw)
self.timeout = 10
@log_enter_exit
def sendjson(self, method, urlpath, obj=None):
"""Send json to the OpenDaylight controller."""
headers = {'Content-Type': 'application/json'}
data = jsonutils.dumps(obj, indent=2) if obj else None
url = '/'.join([self.url, urlpath])
LOG.debug("Sending METHOD (%(method)s) URL (%(url)s) JSON (%(obj)s)" %
{'method': method, 'url': url, 'obj': obj})
r = requests.request(method, url=url,
headers=headers, data=data,
auth=self.auth, timeout=self.timeout)
try:
r.raise_for_status()
except Exception as ex:
LOG.error("Error Sending METHOD (%(method)s) URL (%(url)s)"
"JSON (%(obj)s) return: %(r)s ex: %(ex)s; "
"Message: %(message)s" %
{'method': method, 'url': url, 'obj': obj, 'r': r,
'ex': ex, 'message': r.text})
raise ex
try:
return json.loads(r.content)
except Exception as ex:
LOG.debug("%s" % r)
# transport zone methods
@log_enter_exit
def create_transport_zone(self, name, tun_type,
prefix, vlanid, gateway):
tz = {'transport-zone': [
{'zone-name': name,
'tunnel-type': 'odl-interface:tunnel-type-'+tun_type,
'subnets': [{'prefix': prefix,
'vlan-id': vlanid,
'gateway-ip': gateway,
'vteps': []}]
}
]
}
return tz
@log_enter_exit
def add_tunnel_endpoint_post(self, tzn, prefix, dpnid, port, ip, gateway):
vteps = []
urlPath = 'itm:transport-zones'
transport_zone_available = True
try:
response = self.sendjson('GET', urlPath)
tz = response['transport-zones']
except Exception:
# Fixed cause deprecated
tunnel_typ = 'vxlan'
vlanid = 0
tz = self.create_transport_zone(tzn, tunnel_typ, prefix, vlanid,
gateway)
transport_zone_available = False
subnet = tz['transport-zone'][0]['subnets'][0]
if 'vteps' in subnet:
vteps = subnet['vteps']
already_included = False
vtep = {'dpn-id': dpnid, 'portname': port, 'ip-address': ip}
for i_vtep in vteps:
if i_vtep['ip-address'] == ip and not i_vtep['dpn-id'] == dpnid:
LOG.error("Local_ip already in use %s of DPN %s" %
(ip, i_vtep['dpn-id']))
sys.exit(11)
if i_vtep == vtep:
already_included = True
if already_included:
LOG.info("vTep: %s already included in the transport zone." % vtep)
return
vteps.append(vtep)
tz['transport-zone'][0]['subnets'][0]['vteps'] = vteps
if transport_zone_available:
prefixUrl = urllib.quote(prefix, safe='')
urlPath = ('itm:transport-zones/transport-zone/'
'%(tzn)s/subnets/%(prefixUrl)s/'
% {'tzn': tzn,
'prefixUrl': prefixUrl})
self.sendjson('PUT', urlPath,
{'subnets': tz['transport-zone'][0]['subnets']})
else:
self.sendjson('POST', urlPath, tz)
# HELPER function
@log_enter_exit
def execute(cmd, stdin="", rc_wanted=[0]):
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(stdin)
rc = p.returncode
if rc not in rc_wanted:
raise Exception("Command: %(cmd)s exit with rc: %(rc)s "
"Output: %(output)s err: %(err)s" %
{'cmd': cmd, 'rc': rc, 'output': output,
'err': err})
return output, err, rc
class ovs_client():
@log_enter_exit
def ovs_ofctl(self, args):
if Open_flow_version is not '':
args.append('-O')
args.append(Open_flow_version)
return execute(['ovs-ofctl'] + args)
@log_enter_exit
def ovs_vsctl(self, args):
return execute(['ovs-vsctl'] + args)
@log_enter_exit
def configure_bridge(self, br, odl_ctrl_ip, of_port):
self.ovs_vsctl(['--may-exist', 'add-br', br])
self.ovs_vsctl(['set', 'bridge', br, 'protocols=OpenFlow13'])
self.ovs_vsctl(['set-controller', br, 'tcp:'+odl_ctrl_ip+':'+of_port])
@log_enter_exit
def set_manager(self, ovsdb_managers):
self.ovs_vsctl(['set-manager'] + ovsdb_managers)
@log_enter_exit
def get_dpid(self, brname):
dpId = -1
result = self.ovs_vsctl(['get', 'Bridge', brname, 'datapath_id'])
if result[2] is 0:
hexDpId = result[0][1:-2]
dpId = int(hexDpId, 16)
# TODO: if dpId is negative, convert to unsigned
return dpId
def main():
if os.path.isfile(Astute_path):
with open(Astute_path, 'r') as f:
ASTUTE = yaml.load(f)
if len(sys.argv) < 4:
print("usage: %s <odl_ctrl_ip> <local_ip> <ovsdb_managers>"
% sys.argv[0])
sys.exit(10)
odl_ctrl_ip = sys.argv[1]
local_ip = sys.argv[2]
ovsdb_managers = []
for x in range(3, len(sys.argv)):
ovsdb_managers.append(sys.argv[x])
local_port = 'phy0'
of_port = '6633'
odl_user = ASTUTE['opendaylight']['metadata']['default_credentials']['user']
odl_passw = ASTUTE['opendaylight']['metadata']['default_credentials']['password']
odl_ha_ip = ASTUTE['network_metadata']['vips']['management']['ipaddr']
odl_rest_api_port = ASTUTE['opendaylight']['rest_api_port']
prefix = ASTUTE['private_network_range']
gateway = ASTUTE['opendaylight']['bgpvpn_gateway']
# Configure OVS
ovsc = ovs_client()
ovsc.configure_bridge('br-int', odl_ctrl_ip, of_port)
dpid = ovsc.get_dpid('br-int')
# Configure ODL
odlc = ODL_Client(odl_ha_ip, odl_rest_api_port, odl_user, odl_passw)
# There is only one transport zone at the moment
odlc.add_tunnel_endpoint_post('TZA', prefix, dpid, local_port,
local_ip, gateway)
ovsc.set_manager(ovsdb_managers)
if __name__ == '__main__':
try:
main()
except Exception as ex:
LOG.error(ex.message)
LOG.error(traceback.format_exc())
LOG.error("For more logs check: %(log_path)s"
% {'log_path': LOG_PATH})
sys.exit(1)

View File

@ -53,17 +53,6 @@ attributes:
- condition: "settings:opendaylight.enable_l3_odl.value == false"
strict: false
message: "OpenDayLight must be acting as the L3 controller for the bgpvpn features to be enabled."
bgpvpn_gateway:
weight: 50
type: "text"
value: "0.0.0.0"
description: "Define the default gateway for BGPVPN"
label: "Default Gateway"
restrictions:
- settings:opendaylight.enable_bgpvpn.value == false: Only needed if BGPVPN is enabled.
regex:
source: ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
error: 'Invalid ip number'
odl_v2:
weight: 60
type: "checkbox"
@ -100,16 +89,16 @@ attributes:
ncr:
- odl-ovsdb-sfc
- odl-ovsdb-sfc-rest
ovs:
ovsdb:
- odl-ovsdb-openstack
netvirt:
- odl-netvirt-openstack
sfc:
- odl-sfc-model
- odl-sfc-provider
- odl-sfc-provider-rest
- odl-sfc-ovs
- odl-sfc-openflow-renderer
vpn:
- odl-vpnservice-openstack
odl_deb: opendaylight
experimental_odl_deb: opendaylight-experimental
use_experimental_odl:

View File

@ -19,7 +19,7 @@ fi
# Where we can find odl karaf distribution tarball
# can be http(s) url or absolute path
ODL_TARBALL_LOCATION=${ODL_TARBALL_LOCATION:-https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.5.0-Boron/distribution-karaf-0.5.0-Boron.tar.gz}
ODL_EXPERIMENTAL_TARBALL_LOCATION=${ODL_EXPERIMENTAL_TARBALL_LOCATION:-https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/distribution-karaf/0.4.3-Beryllium-SR3/distribution-karaf-0.4.3-Beryllium-SR3.tar.gz}
ODL_EXPERIMENTAL_TARBALL_LOCATION=${ODL_EXPERIMENTAL_TARBALL_LOCATION:-https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/distribution-karaf/0.5.1-Boron-SR1/distribution-karaf-0.5.1-Boron-SR1.tar.gz}
ODL_EXPERIMENTAL_DEB_NAME=${ODL_EXPERIMENTAL_DEB_NAME:-opendaylight-experimental}
#ODL openflowjava NSH subtype patch related
@ -41,7 +41,7 @@ bdart=''
#Verion number used in deb/rpm package
ODL_VERSION_NUMBER=${ODL_VERSION_NUMBER:-0.5.0}
ODL_EXPERIMENTAL_VERSION_NUMBER=${ODL_EXPERIMENTAL_VERSION_NUMBER:-0.4.3}
ODL_EXPERIMENTAL_VERSION_NUMBER=${ODL_EXPERIMENTAL_VERSION_NUMBER:-0.5.1}
ODL_DESCRIPTION="OpenDaylight SDN Controller"
TMP_NAME="karaf-odl.tar.gz"