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:
parent
5db5332708
commit
5d1885b258
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue