Enable BGPVPN_extension/SDNVPN_feature
To enable SDNVPN feature we have to do: - setup the transport endpoint that it has the correct ip in ovs and ODL - Add br-int - Configure ODL as the controller for br-int - disable ovsdb feature and enable sdnpvpn feature - fuel network setup has to be changed to stick to sdnvpn network concept Change-Id: I320c9597b4b760f3a7d273aad710b5e43f4ba754
This commit is contained in:
parent
f4dd004249
commit
c6573ae567
|
@ -1,3 +1,7 @@
|
|||
*.rpm
|
||||
*.deb
|
||||
.build/
|
||||
.cache/
|
||||
.project
|
||||
.pydevproject
|
||||
tmp/
|
||||
|
|
|
@ -86,12 +86,17 @@ if $use_neutron {
|
|||
$net_role_property = 'neutron/mesh'
|
||||
$iface = get_network_role_property($net_role_property, 'phys_dev')
|
||||
$tunneling_ip = get_network_role_property($net_role_property, 'ipaddr')
|
||||
$odl_settings = hiera('opendaylight')
|
||||
|
||||
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}",
|
||||
path => '/usr/bin',
|
||||
require => Exec['ovs-set-manager'],
|
||||
# With bgpvpn feature enabled the connectivity to the outside world
|
||||
# is solved in another way.
|
||||
unless $odl_settings['enable_bgpvpn'] {
|
||||
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}",
|
||||
path => '/usr/bin',
|
||||
require => Exec['ovs-set-manager'],
|
||||
}
|
||||
}
|
||||
}
|
||||
exec { 'ovs-set-tunnel-endpoint':
|
||||
|
@ -100,6 +105,22 @@ if $use_neutron {
|
|||
require => Exec['ovs-set-manager'],
|
||||
}
|
||||
|
||||
# Setup the trunk end points. when the sdnvpn feature is activated this is needed.
|
||||
if $odl_settings['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}",
|
||||
require => File[$file_setupTEPs],
|
||||
path => '/usr/local/bin:/usr/bin:/sbin:/bin:/usr/local/sbin:/usr/sbin',
|
||||
}
|
||||
}
|
||||
|
||||
$physical_net_mtu = pick(get_transformation_property('mtu', $iface[0]), '1500')
|
||||
|
||||
if $segmentation_type == 'gre' {
|
||||
|
|
|
@ -45,7 +45,11 @@ module Puppet::Parser::Functions
|
|||
# override neutron_config/quantum_settings
|
||||
neutron_config = function_hiera(['neutron_config'])
|
||||
neutron_config['L2']['mechanism_drivers'] = 'opendaylight'
|
||||
neutron_config['L2']['phys_nets']['physnet1']['bridge'] = 'br-ex'
|
||||
if odl['enable_bgpvpn']
|
||||
neutron_config['L2']['phys_nets']['physnet1']['bridge'] = 'br-ex'
|
||||
else
|
||||
neutron_config['L2']['phys_nets']['physnet1']['bridge'] = 'br-int'
|
||||
end
|
||||
hiera_overrides['neutron_config'] = neutron_config
|
||||
hiera_overrides['quantum_settings'] = neutron_config
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
module Puppet::Parser::Functions
|
||||
newfunction(:odl_karaf_features, :type => :rvalue) do |args|
|
||||
odl_settings = function_hiera(['opendaylight'])
|
||||
bgpvpn = function_hiera(['bgpvpn', false])
|
||||
features_set = odl_settings['metadata']['odl_features']
|
||||
|
||||
enabled_features = []
|
||||
enabled_features << features_set['default']
|
||||
enabled_features << features_set['ovs']
|
||||
enabled_features << features_set['odl-default']
|
||||
enabled_features << features_set['ovs'] if not odl_settings['enable_bgpvpn']
|
||||
enabled_features << features_set['sfc'] if odl_settings['enable_sfc']
|
||||
enabled_features << features_set['gbp'] if odl_settings['enable_gbp']
|
||||
enabled_features << features_set['vpn'] if bgpvpn
|
||||
enabled_features << features_set['vpn'] if odl_settings['enable_bgpvpn']
|
||||
|
||||
enabled_features.join(',')
|
||||
end
|
||||
|
|
|
@ -11,7 +11,13 @@ module Puppet::Parser::Functions
|
|||
odl = function_hiera(['opendaylight'])
|
||||
network_scheme = function_hiera(['network_scheme'])
|
||||
management_vrouter_vip = function_hiera(['management_vrouter_vip'])
|
||||
delete_bridges = ['br-prv']
|
||||
|
||||
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
|
||||
|
||||
debug "ODL network before transformation: #{network_scheme}"
|
||||
|
||||
|
@ -21,32 +27,46 @@ module Puppet::Parser::Functions
|
|||
transformations.delete_if { |action| action['action'] == 'add-patch' and not (action['bridges'] & delete_bridges).empty? }
|
||||
transformations.delete_if { |action| action['action'] == 'add-port' and delete_bridges.include?(action['bridge']) }
|
||||
|
||||
# Modify only once
|
||||
if not endpoints.has_key? 'br-ex-lnx'
|
||||
transformations.each { |action| action['name'] = 'br-ex-lnx' if (action['action'] == 'add-br' and action['name'] == 'br-ex') }
|
||||
transformations.each { |action| action['bridge'] = 'br-ex-lnx' if (action['action'] == 'add-port' and action['bridge'] == 'br-ex') }
|
||||
if not odl['enable_bgpvpn']
|
||||
debug "Changing network_scheme for the non bgpvpn case."
|
||||
# Modify only once
|
||||
if not endpoints.has_key? 'br-ex-lnx'
|
||||
transformations.each { |action| action['name'] = 'br-ex-lnx' if (action['action'] == 'add-br' and action['name'] == 'br-ex') }
|
||||
transformations.each { |action| action['bridge'] = 'br-ex-lnx' if (action['action'] == 'add-port' and action['bridge'] == 'br-ex') }
|
||||
end
|
||||
|
||||
transformations.each { |action| action['name'] = 'br-ex' if (action['action'] == 'add-br' and action['name'] == 'br-floating') }
|
||||
transformations.each { |action| action['bridge'] = 'br-ex' if (action['action'] == 'add-port' and action['bridge'] == 'br-floating') }
|
||||
|
||||
transformations.each { |action| action['bridges'] = ['br-ex', 'br-ex-lnx'] if (action['action'] == 'add-patch' and action['bridges'] == ['br-floating', 'br-ex']) }
|
||||
|
||||
roles = network_scheme['roles']
|
||||
roles.each { |role,bridge| roles[role] = 'br-ex-lnx' if bridge == 'br-ex' }
|
||||
roles['neutron/private'] = 'br-aux' if roles.has_key?('neutron/private')
|
||||
roles['neutron/floating'] = 'br-ex' if roles.has_key?('neutron/floating')
|
||||
|
||||
if endpoints.has_key? 'br-ex' and not endpoints.has_key? 'br-ex-lnx'
|
||||
endpoints['br-ex-lnx'] = endpoints.delete 'br-ex'
|
||||
end
|
||||
|
||||
if endpoints.has_key? 'br-floating'
|
||||
endpoints['br-ex'] = endpoints.delete 'br-floating'
|
||||
end
|
||||
|
||||
if endpoints.has_key? 'br-prv'
|
||||
endpoints['br-aux'] = endpoints.delete 'br-prv'
|
||||
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
|
||||
end
|
||||
|
||||
transformations.each { |action| action['name'] = 'br-ex' if (action['action'] == 'add-br' and action['name'] == 'br-floating') }
|
||||
transformations.each { |action| action['bridge'] = 'br-ex' if (action['action'] == 'add-port' and action['bridge'] == 'br-floating') }
|
||||
|
||||
transformations.each { |action| action['bridges'] = ['br-ex', 'br-ex-lnx'] if (action['action'] == 'add-patch' and action['bridges'] == ['br-floating', 'br-ex']) }
|
||||
|
||||
roles = network_scheme['roles']
|
||||
roles.each { |role,bridge| roles[role] = 'br-ex-lnx' if bridge == 'br-ex' }
|
||||
roles['neutron/private'] = 'br-aux' if roles.has_key?('neutron/private')
|
||||
roles['neutron/floating'] = 'br-ex' if roles.has_key?('neutron/floating')
|
||||
|
||||
if endpoints.has_key? 'br-ex' and not endpoints.has_key? 'br-ex-lnx'
|
||||
endpoints['br-ex-lnx'] = endpoints.delete 'br-ex'
|
||||
end
|
||||
if endpoints.has_key? 'br-floating'
|
||||
endpoints['br-ex'] = endpoints.delete 'br-floating'
|
||||
end
|
||||
if endpoints.has_key? 'br-prv'
|
||||
endpoints['br-aux'] = endpoints.delete 'br-prv'
|
||||
end
|
||||
|
||||
debug "ODL network after transformation: #{network_scheme}"
|
||||
network_scheme
|
||||
end
|
||||
|
|
|
@ -5,9 +5,14 @@ class opendaylight::service {
|
|||
$odl = hiera('opendaylight')
|
||||
$rest_port = $odl['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 => "curl -o /dev/null --fail --silent --head -u admin:admin http://${management_vip}:${rest_port}/restconf/operational/network-topology:network-topology/topology/netvirt:1",
|
||||
command => "curl -o /dev/null --fail --silent --head -u admin:admin http://${management_vip}:${rest_port}/restconf/operational/network-topology:network-topology/topology/${odl_up_testing_site}",
|
||||
path => '/bin:/usr/bin',
|
||||
tries => 60,
|
||||
try_sleep => 20,
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
'''
|
||||
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
|
||||
|
||||
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'
|
||||
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)
|
||||
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
|
||||
|
||||
# There is a bug in ODL that a put does not update the tunel
|
||||
# endpoints. So we need to delete it and post it again.
|
||||
# If new blades are added into an running env that could break
|
||||
# the other end points
|
||||
# https://bugs.opendaylight.org/show_bug.cgi?id=5422
|
||||
try:
|
||||
self.sendjson('DELETE', urlPath)
|
||||
except Exception:
|
||||
pass
|
||||
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 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) < 3:
|
||||
print("usage: %s <odl_ctrl_ip> <local_ip>" % sys.argv[0])
|
||||
sys.exit(10)
|
||||
odl_ctrl_ip = sys.argv[1]
|
||||
local_ip = sys.argv[2]
|
||||
local_port = 'phy0'
|
||||
of_port = '6633'
|
||||
|
||||
# FIXME: That should come from fuel at some point in time
|
||||
odl_user = 'admin'
|
||||
odl_passw = 'admin'
|
||||
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
@ -17,6 +17,35 @@ attributes:
|
|||
type: "checkbox"
|
||||
value: false
|
||||
label: "SFC features"
|
||||
enable_bgpvpn:
|
||||
weight: 13
|
||||
type: "checkbox"
|
||||
value: false
|
||||
label: "BGPVPN extensions"
|
||||
description:
|
||||
>
|
||||
This enables the bgpvpn extension of neutron togethere with the
|
||||
corresponding sdnvpn features in odl. This feature will disable
|
||||
the standart ovsdb feature from ODL.
|
||||
restrictions:
|
||||
- condition: "settings:bgpvpn == null or settings:bgpvpn.metadata.enabled == false"
|
||||
strict: false
|
||||
message: "BGPVPN (fuel-plugin-bgpvpn) plugin must be installed and enabled."
|
||||
- networking_parameters:segmentation_type == 'vlan': This feature works only with segmentation_type != vlan
|
||||
- condition: "settings:fuel-plugin-ovs == null or settings:fuel-plugin-ovs.metadata.enabled == false"
|
||||
strict: false
|
||||
message: "Openvswitch with NSH support (fuel-plugin-ovs) must be installed and enabled."
|
||||
bgpvpn_gateway:
|
||||
weight: 13
|
||||
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'
|
||||
metadata:
|
||||
restrictions:
|
||||
- "cluster:net_provider != 'neutron'": "Only neutron is supported by OpenDaylight"
|
||||
|
@ -29,14 +58,15 @@ attributes:
|
|||
- kar
|
||||
- ssh
|
||||
- management
|
||||
odl-default:
|
||||
- odl-restconf-all
|
||||
- odl-aaa-authn
|
||||
- odl-dlux-all
|
||||
gbp:
|
||||
- odl-groupbasedpolicy-neutronmapper
|
||||
- odl-groupbasedpolicy-ofoverlay
|
||||
ovs:
|
||||
- odl-ovsdb-openstack
|
||||
- odl-restconf-all
|
||||
- odl-aaa-authn
|
||||
- odl-dlux-all
|
||||
sfc:
|
||||
- odl-sfc-model
|
||||
- odl-sfc-provider
|
||||
|
@ -47,11 +77,6 @@ attributes:
|
|||
- odl-sfc-ovs
|
||||
- odl-sfcofl2
|
||||
vpn:
|
||||
- odl-vpnservice-api
|
||||
- odl-vpnservice-impl
|
||||
- odl-vpnservice-impl-rest
|
||||
- odl-vpnservice-impl-ui
|
||||
- odl-vpnservice-core
|
||||
- odl-vpnservice-openstack
|
||||
rest_api_port:
|
||||
value: '8282'
|
||||
|
|
|
@ -3,7 +3,7 @@ name: opendaylight
|
|||
# Human-readable name for your plugin
|
||||
title: OpenDaylight plugin
|
||||
# Plugin version
|
||||
version: '0.8.0'
|
||||
version: '0.8.1'
|
||||
# Description
|
||||
description: 'This plugin provides OpenDaylight as a backend for neutron.
|
||||
Use the same IP address as for OpenStack Horizon and port 8181 to reach dlux web ui.
|
||||
|
|
Loading…
Reference in New Issue