Rename Router related methods for VMware NSX plugin
This is another step for the renaming/refactoring of nvplib and related modules. This is about routers. Partial-implements blueprint: nicira-plugin-renaming Change-Id: Ic69b2777fa1ae3125b8adf23943360e3fe18e4c2
This commit is contained in:
parent
06fafcb82b
commit
72c058f45a
@ -77,6 +77,7 @@ from neutron.plugins.nicira.extensions import maclearning as mac_ext
|
||||
from neutron.plugins.nicira.extensions import nvp_networkgw as networkgw
|
||||
from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
|
||||
from neutron.plugins.nicira.nsxlib import queue as queuelib
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
|
||||
@ -257,7 +258,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
port_data['fixed_ips'],
|
||||
subnet_ids))
|
||||
try:
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
cluster, nsx_router_id, port_data.get('tenant_id', 'fake'),
|
||||
port_data.get('id', 'fake'), port_data.get('name', 'fake'),
|
||||
port_data.get('admin_state_up', True), ip_addresses,
|
||||
@ -314,7 +315,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# Be safe and concede NAT rules might not exist.
|
||||
# Therefore use min_num_expected=0
|
||||
for cidr in cidrs:
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "SourceNatRule",
|
||||
max_num_expected=1, min_num_expected=0,
|
||||
source_ip_addresses=cidr)
|
||||
@ -324,7 +325,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# Set the SNAT rule for each subnet (only first IP)
|
||||
for cidr in cidrs:
|
||||
cidr_prefix = int(cidr.split('/')[1])
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.cluster, nsx_router_id,
|
||||
ip_addresses[0].split('/')[0],
|
||||
ip_addresses[0].split('/')[0],
|
||||
@ -333,34 +334,34 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
|
||||
def _update_router_port_attachment(self, cluster, context,
|
||||
nsx_router_id, port_data,
|
||||
nvp_router_port_id,
|
||||
nsx_router_port_id,
|
||||
attachment_type,
|
||||
attachment,
|
||||
attachment_vlan=None):
|
||||
if not nvp_router_port_id:
|
||||
nvp_router_port_id = self._find_router_gw_port(context, port_data)
|
||||
if not nsx_router_port_id:
|
||||
nsx_router_port_id = self._find_router_gw_port(context, port_data)
|
||||
try:
|
||||
nvplib.plug_router_port_attachment(cluster, nsx_router_id,
|
||||
nvp_router_port_id,
|
||||
attachment,
|
||||
attachment_type,
|
||||
attachment_vlan)
|
||||
routerlib.plug_router_port_attachment(cluster, nsx_router_id,
|
||||
nsx_router_port_id,
|
||||
attachment,
|
||||
attachment_type,
|
||||
attachment_vlan)
|
||||
LOG.debug(_("Attached %(att)s to NVP router port %(port)s"),
|
||||
{'att': attachment, 'port': nvp_router_port_id})
|
||||
{'att': attachment, 'port': nsx_router_port_id})
|
||||
except NvpApiClient.NvpApiException:
|
||||
# Must remove NVP logical port
|
||||
nvplib.delete_router_lport(cluster, nsx_router_id,
|
||||
nvp_router_port_id)
|
||||
routerlib.delete_router_lport(cluster, nsx_router_id,
|
||||
nsx_router_port_id)
|
||||
LOG.exception(_("Unable to plug attachment in NVP logical "
|
||||
"router port %(r_port_id)s, associated with "
|
||||
"Neutron %(q_port_id)s"),
|
||||
{'r_port_id': nvp_router_port_id,
|
||||
{'r_port_id': nsx_router_port_id,
|
||||
'q_port_id': port_data.get('id')})
|
||||
raise nvp_exc.NvpPluginException(
|
||||
err_msg=(_("Unable to plug attachment in router port "
|
||||
"%(r_port_id)s for neutron port id %(q_port_id)s "
|
||||
"on router %(router_id)s") %
|
||||
{'r_port_id': nvp_router_port_id,
|
||||
{'r_port_id': nsx_router_port_id,
|
||||
'q_port_id': port_data.get('id'),
|
||||
'router_id': nsx_router_id}))
|
||||
|
||||
@ -525,9 +526,9 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# Delete logical router port
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, port_data['device_id'])
|
||||
nvp_switch_id, nvp_port_id = nsx_utils.get_nsx_switch_and_port_id(
|
||||
nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
|
||||
context.session, self.cluster, port_data['id'])
|
||||
if not nvp_port_id:
|
||||
if not nsx_port_id:
|
||||
LOG.warn(_("Neutron port %(port_id)s not found on NVP backend. "
|
||||
"Terminating delete operation. A dangling router port "
|
||||
"might have been left on router %(router_id)s"),
|
||||
@ -535,17 +536,17 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
'router_id': nsx_router_id})
|
||||
return
|
||||
try:
|
||||
nvplib.delete_peer_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
nvp_switch_id,
|
||||
nvp_port_id)
|
||||
routerlib.delete_peer_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
nsx_switch_id,
|
||||
nsx_port_id)
|
||||
except NvpApiClient.NvpApiException:
|
||||
# Do not raise because the issue might as well be that the
|
||||
# router has already been deleted, so there would be nothing
|
||||
# to do here
|
||||
LOG.exception(_("Ignoring exception as this means the peer "
|
||||
"for port '%s' has already been deleted."),
|
||||
nvp_port_id)
|
||||
nsx_port_id)
|
||||
|
||||
# Delete logical switch port
|
||||
self._nvp_delete_port(context, port_data)
|
||||
@ -599,8 +600,8 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
port_data['network_id'])
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
lr_port = nvplib.find_router_gw_port(context, self.cluster,
|
||||
nsx_router_id)
|
||||
lr_port = routerlib.find_router_gw_port(context, self.cluster,
|
||||
nsx_router_id)
|
||||
if not lr_port:
|
||||
raise nvp_exc.NvpPluginException(
|
||||
err_msg=(_("The gateway port for the NSX router %s "
|
||||
@ -624,14 +625,14 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# regardless of what the user specifies in neutron
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, port_data['device_id'])
|
||||
nvplib.update_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
lr_port['uuid'],
|
||||
port_data['tenant_id'],
|
||||
port_data['id'],
|
||||
port_data['name'],
|
||||
True,
|
||||
ip_addresses)
|
||||
routerlib.update_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
lr_port['uuid'],
|
||||
port_data['tenant_id'],
|
||||
port_data['id'],
|
||||
port_data['name'],
|
||||
True,
|
||||
ip_addresses)
|
||||
ext_network = self.get_network(context, port_data['network_id'])
|
||||
if ext_network.get(pnet.NETWORK_TYPE) == NetworkTypes.L3_EXT:
|
||||
# Update attachment
|
||||
@ -662,14 +663,14 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
router_id = port_data['device_id']
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
nvplib.update_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
lr_port['uuid'],
|
||||
port_data['tenant_id'],
|
||||
port_data['id'],
|
||||
port_data['name'],
|
||||
True,
|
||||
['0.0.0.0/31'])
|
||||
routerlib.update_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
lr_port['uuid'],
|
||||
port_data['tenant_id'],
|
||||
port_data['id'],
|
||||
port_data['name'],
|
||||
True,
|
||||
['0.0.0.0/31'])
|
||||
# Reset attachment
|
||||
self._update_router_port_attachment(
|
||||
self.cluster, context, nsx_router_id, port_data,
|
||||
@ -1036,7 +1037,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
'device_owner': ['network:router_interface']}
|
||||
router_iface_ports = self.get_ports(context, filters=port_filter)
|
||||
for port in router_iface_ports:
|
||||
nvp_switch_id, nvp_port_id = nsx_utils.get_nsx_switch_and_port_id(
|
||||
nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
|
||||
context.session, self.cluster, id)
|
||||
# Before removing entry from Neutron DB, retrieve NSX switch
|
||||
# identifiers for removing them from backend
|
||||
@ -1047,13 +1048,13 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# clean up network owned ports
|
||||
for port in router_iface_ports:
|
||||
try:
|
||||
if nvp_port_id:
|
||||
if nsx_port_id:
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, port['device_id'])
|
||||
nvplib.delete_peer_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
nvp_switch_id,
|
||||
nvp_port_id)
|
||||
routerlib.delete_peer_router_lport(self.cluster,
|
||||
nsx_router_id,
|
||||
nsx_switch_id,
|
||||
nsx_port_id)
|
||||
else:
|
||||
LOG.warning(_("A nvp lport identifier was not found for "
|
||||
"neutron port '%s'. Unable to remove "
|
||||
@ -1068,7 +1069,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# to do here
|
||||
LOG.warning(_("Ignoring exception as this means the peer for "
|
||||
"port '%s' has already been deleted."),
|
||||
nvp_port_id)
|
||||
nsx_port_id)
|
||||
|
||||
# Do not go to NVP for external networks
|
||||
if not external:
|
||||
@ -1395,7 +1396,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
tenant_id = self._get_tenant_id_for_create(context, router)
|
||||
distributed = router.get('distributed')
|
||||
try:
|
||||
lrouter = nvplib.create_lrouter(
|
||||
lrouter = routerlib.create_lrouter(
|
||||
self.cluster, router['id'],
|
||||
tenant_id, router['name'], nexthop,
|
||||
distributed=attr.is_attr_set(distributed) and distributed)
|
||||
@ -1424,7 +1425,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
'def_l3_gw_svc':
|
||||
self.cluster.default_l3_gw_service_uuid})
|
||||
# Try and remove logical router from NVP
|
||||
nvplib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
routerlib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
# Return user a 500 with an apter message
|
||||
raise nvp_exc.NvpPluginException(
|
||||
err_msg=(_("Unable to create router %s on NSX backend") %
|
||||
@ -1517,14 +1518,14 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
def _update_lrouter(self, context, router_id, name, nexthop, routes=None):
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
return nvplib.update_lrouter(
|
||||
return routerlib.update_lrouter(
|
||||
self.cluster, nsx_router_id, name,
|
||||
nexthop, routes=routes)
|
||||
|
||||
def _update_lrouter_routes(self, context, router_id, routes):
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
nvplib.update_explicit_routes_lrouter(
|
||||
routerlib.update_explicit_routes_lrouter(
|
||||
self.cluster, nsx_router_id, routes)
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
@ -1591,7 +1592,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
def _delete_lrouter(self, context, router_id, nsx_router_id):
|
||||
# The neutron router id (router_id) is ignored in this routine,
|
||||
# but used in plugins deriving from this one
|
||||
nvplib.delete_lrouter(self.cluster, nsx_router_id)
|
||||
routerlib.delete_lrouter(self.cluster, nsx_router_id)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
with context.session.begin(subtransactions=True):
|
||||
@ -1660,7 +1661,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
cidr_prefix = int(subnet['cidr'].split('/')[1])
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router['id'])
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.cluster, nsx_router_id, snat_ip, snat_ip,
|
||||
order=NVP_EXTGW_NAT_RULES_ORDER - cidr_prefix,
|
||||
match_criteria={'source_ip_addresses': subnet['cidr']})
|
||||
@ -1670,7 +1671,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
if router.gw_port:
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router['id'])
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "SourceNatRule",
|
||||
max_num_expected=1, min_num_expected=1,
|
||||
source_ip_addresses=subnet['cidr'])
|
||||
@ -1701,7 +1702,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# Fetch router from DB
|
||||
router = self._get_router(context, router_id)
|
||||
self._add_subnet_snat_rule(context, router, subnet)
|
||||
nvplib.create_lrouter_nosnat_rule(
|
||||
routerlib.create_lrouter_nosnat_rule(
|
||||
self.cluster, nsx_router_id,
|
||||
order=NVP_NOSNAT_RULES_ORDER,
|
||||
match_criteria={'destination_ip_addresses': subnet['cidr']})
|
||||
@ -1768,7 +1769,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# do not exist in 2.x deployments
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "NoSourceNatRule",
|
||||
max_num_expected=1, min_num_expected=0,
|
||||
destination_ip_addresses=subnet['cidr'])
|
||||
@ -1790,19 +1791,19 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
# but used by derived classes
|
||||
try:
|
||||
# Remove DNAT rule for the floating IP
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "DestinationNatRule",
|
||||
max_num_expected=1,
|
||||
min_num_expected=min_num_rules_expected,
|
||||
destination_ip_addresses=floating_ip_address)
|
||||
|
||||
# Remove SNAT rules for the floating IP
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "SourceNatRule",
|
||||
max_num_expected=1,
|
||||
min_num_expected=min_num_rules_expected,
|
||||
source_ip_addresses=internal_ip)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.cluster, nsx_router_id, "SourceNatRule",
|
||||
max_num_expected=1,
|
||||
min_num_expected=min_num_rules_expected,
|
||||
@ -1824,17 +1825,17 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
router_id = fip_db.router_id
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self.cluster, router_id)
|
||||
nvp_gw_port_id = nvplib.find_router_gw_port(
|
||||
nsx_gw_port_id = routerlib.find_router_gw_port(
|
||||
context, self.cluster, nsx_router_id)['uuid']
|
||||
ext_neutron_port_db = self._get_port(context.elevated(),
|
||||
fip_db.floating_port_id)
|
||||
nvp_floating_ips = self._build_ip_address_list(
|
||||
nsx_floating_ips = self._build_ip_address_list(
|
||||
context.elevated(), ext_neutron_port_db['fixed_ips'])
|
||||
nvplib.update_lrouter_port_ips(self.cluster,
|
||||
nsx_router_id,
|
||||
nvp_gw_port_id,
|
||||
ips_to_add=[],
|
||||
ips_to_remove=nvp_floating_ips)
|
||||
routerlib.update_lrouter_port_ips(self.cluster,
|
||||
nsx_router_id,
|
||||
nsx_gw_port_id,
|
||||
ips_to_add=[],
|
||||
ips_to_remove=nsx_floating_ips)
|
||||
|
||||
def _get_fip_assoc_data(self, context, fip, floatingip_db):
|
||||
if (('fixed_ip_address' in fip and fip['fixed_ip_address']) and
|
||||
@ -1895,22 +1896,22 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
'port_id': floatingip_db.fixed_port_id,
|
||||
'fixed_ip_address': floatingip_db.fixed_ip_address,
|
||||
'tenant_id': floatingip_db.tenant_id})
|
||||
nvp_gw_port_id = nvplib.find_router_gw_port(
|
||||
nsx_gw_port_id = routerlib.find_router_gw_port(
|
||||
context, self.cluster, nsx_old_router_id)['uuid']
|
||||
self._retrieve_and_delete_nat_rules(
|
||||
context, floating_ip, old_internal_ip, nsx_old_router_id)
|
||||
nvplib.update_lrouter_port_ips(
|
||||
self.cluster, nsx_old_router_id, nvp_gw_port_id,
|
||||
routerlib.update_lrouter_port_ips(
|
||||
self.cluster, nsx_old_router_id, nsx_gw_port_id,
|
||||
ips_to_add=[], ips_to_remove=nvp_floating_ips)
|
||||
|
||||
if router_id:
|
||||
nvp_gw_port_id = nvplib.find_router_gw_port(
|
||||
nsx_gw_port_id = routerlib.find_router_gw_port(
|
||||
context, self.cluster, nsx_router_id)['uuid']
|
||||
# Re-create NAT rules only if a port id is specified
|
||||
if fip.get('port_id'):
|
||||
try:
|
||||
# Setup DNAT rules for the floating IP
|
||||
nvplib.create_lrouter_dnat_rule(
|
||||
routerlib.create_lrouter_dnat_rule(
|
||||
self.cluster, nsx_router_id, internal_ip,
|
||||
order=NVP_FLOATINGIP_NAT_RULES_ORDER,
|
||||
match_criteria={'destination_ip_addresses':
|
||||
@ -1928,7 +1929,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
internal_subnet_cidr = self._build_ip_address_list(
|
||||
context, internal_port['fixed_ips'],
|
||||
subnet_ids=subnet_ids)[0]
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.cluster, nsx_router_id, floating_ip, floating_ip,
|
||||
order=NVP_NOSNAT_RULES_ORDER - 1,
|
||||
match_criteria={'source_ip_addresses':
|
||||
@ -1937,17 +1938,15 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
internal_ip})
|
||||
# setup snat rule such that src ip of a IP packet when
|
||||
# using floating is the floating ip itself.
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.cluster, nsx_router_id, floating_ip, floating_ip,
|
||||
order=NVP_FLOATINGIP_NAT_RULES_ORDER,
|
||||
match_criteria={'source_ip_addresses': internal_ip})
|
||||
|
||||
# Add Floating IP address to router_port
|
||||
nvplib.update_lrouter_port_ips(self.cluster,
|
||||
nsx_router_id,
|
||||
nvp_gw_port_id,
|
||||
ips_to_add=nvp_floating_ips,
|
||||
ips_to_remove=[])
|
||||
routerlib.update_lrouter_port_ips(
|
||||
self.cluster, nsx_router_id, nsx_gw_port_id,
|
||||
ips_to_add=nvp_floating_ips, ips_to_remove=[])
|
||||
except NvpApiClient.NvpApiException:
|
||||
LOG.exception(_("An error occurred while creating NAT "
|
||||
"rules on the NVP platform for floating "
|
||||
|
@ -36,6 +36,7 @@ from neutron.plugins.nicira.dbexts import vcns_db
|
||||
from neutron.plugins.nicira.dbexts import vcns_models
|
||||
from neutron.plugins.nicira.extensions import servicerouter as sr
|
||||
from neutron.plugins.nicira import NeutronPlugin
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
from neutron.plugins.nicira.vshield.common import (
|
||||
@ -425,7 +426,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
neutron_port_id = ''
|
||||
pname = name[:36] + '-lp'
|
||||
admin_status_enabled = True
|
||||
lr_port = nvplib.create_router_lport(
|
||||
lr_port = routerlib.create_router_lport(
|
||||
self.cluster, lrouter['uuid'], tenant_id,
|
||||
neutron_port_id, pname, admin_status_enabled,
|
||||
[vcns_const.INTEGRATION_LR_IPADDRESS])
|
||||
@ -464,7 +465,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
msg = _("Unable to create integration logic switch "
|
||||
"for router %s") % name
|
||||
LOG.exception(msg)
|
||||
nvplib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
routerlib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
raise q_exc.NeutronException(message=msg)
|
||||
|
||||
try:
|
||||
@ -474,7 +475,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
msg = _("Unable to add router interface to integration lswitch "
|
||||
"for router %s") % name
|
||||
LOG.exception(msg)
|
||||
nvplib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
routerlib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
raise q_exc.NeutronException(message=msg)
|
||||
|
||||
try:
|
||||
@ -484,7 +485,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
msg = (_("Unable to create advance service router for %s") % name)
|
||||
LOG.exception(msg)
|
||||
self.vcns_driver.delete_lswitch(lswitch('uuid'))
|
||||
nvplib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
routerlib.delete_lrouter(self.cluster, lrouter['uuid'])
|
||||
raise q_exc.NeutronException(message=msg)
|
||||
|
||||
lrouter['status'] = service_constants.PENDING_CREATE
|
||||
@ -516,7 +517,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
self.vcns_driver.delete_edge(router_id, edge_id, jobdata=jobdata)
|
||||
|
||||
# delete NSX logical router
|
||||
nvplib.delete_lrouter(self.cluster, nsx_router_id)
|
||||
routerlib.delete_lrouter(self.cluster, nsx_router_id)
|
||||
|
||||
if id in self._router_type:
|
||||
del self._router_type[router_id]
|
||||
@ -563,7 +564,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
|
||||
def _get_nvp_lrouter_status(self, id):
|
||||
try:
|
||||
lrouter = nvplib.get_lrouter(self.cluster, id)
|
||||
lrouter = routerlib.get_lrouter(self.cluster, id)
|
||||
lr_status = lrouter["_relations"]["LogicalRouterStatus"]
|
||||
if lr_status["fabric_status"]:
|
||||
nvp_status = RouterStatus.ROUTER_STATUS_ACTIVE
|
||||
@ -587,9 +588,9 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||
|
||||
def _get_all_nvp_lrouters_statuses(self, tenant_id, fields):
|
||||
# get nvp lrouters status
|
||||
nvp_lrouters = nvplib.get_lrouters(self.cluster,
|
||||
tenant_id,
|
||||
fields)
|
||||
nvp_lrouters = routerlib.get_lrouters(self.cluster,
|
||||
tenant_id,
|
||||
fields)
|
||||
|
||||
nvp_status = {}
|
||||
for nvp_lrouter in nvp_lrouters:
|
||||
|
@ -18,6 +18,7 @@
|
||||
from neutron.openstack.common import log
|
||||
from neutron.plugins.nicira.dbexts import nicira_db
|
||||
from neutron.plugins.nicira import nsx_cluster
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
|
||||
@ -155,7 +156,7 @@ def get_nsx_router_id(session, cluster, neutron_router_id):
|
||||
# Find logical router from backend.
|
||||
# This is a rather expensive query, but it won't be executed
|
||||
# more than once for each router in Neutron's lifetime
|
||||
nsx_routers = nvplib.query_lrouters(
|
||||
nsx_routers = routerlib.query_lrouters(
|
||||
cluster, '*',
|
||||
filters={'tag': neutron_router_id,
|
||||
'tag_scope': 'q_router_id'})
|
||||
|
@ -27,6 +27,7 @@ from neutron.openstack.common import loopingcall
|
||||
from neutron.openstack.common import timeutils
|
||||
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||
from neutron.plugins.nicira.common import nsx_utils
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
|
||||
@ -191,7 +192,7 @@ class NvpSynchronizer():
|
||||
nvplib.LSWITCH_RESOURCE, fields='uuid,tags,fabric_status',
|
||||
relations='LogicalSwitchStatus')
|
||||
LR_URI = nvplib._build_uri_path(
|
||||
nvplib.LROUTER_RESOURCE, fields='uuid,tags,fabric_status',
|
||||
routerlib.LROUTER_RESOURCE, fields='uuid,tags,fabric_status',
|
||||
relations='LogicalRouterStatus')
|
||||
LP_URI = nvplib._build_uri_path(
|
||||
nvplib.LSWITCHPORT_RESOURCE,
|
||||
@ -319,7 +320,7 @@ class NvpSynchronizer():
|
||||
# This query will return the logical router status too
|
||||
nsx_router_id = nsx_utils.get_nsx_router_id(
|
||||
context.session, self._cluster, neutron_router_data['id'])
|
||||
lrouter = nvplib.get_lrouter(
|
||||
lrouter = routerlib.get_lrouter(
|
||||
self._cluster, nsx_router_id)
|
||||
except exceptions.NotFound:
|
||||
# NOTE(salv-orlando): We should be catching
|
||||
|
@ -1,16 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 VMware, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
676
neutron/plugins/nicira/nsxlib/router.py
Normal file
676
neutron/plugins/nicira/nsxlib/router.py
Normal file
@ -0,0 +1,676 @@
|
||||
# Copyright 2014 VMware, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.common import exceptions as exception
|
||||
from neutron.openstack.common import excutils
|
||||
from neutron.openstack.common import jsonutils
|
||||
from neutron.openstack.common import log
|
||||
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||
from neutron.plugins.nicira.common import utils
|
||||
from neutron.plugins.nicira.nsxlib.versioning import DEFAULT_VERSION
|
||||
from neutron.plugins.nicira.nsxlib.versioning import versioned
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira.nvplib import _build_uri_path
|
||||
from neutron.plugins.nicira.nvplib import do_request
|
||||
from neutron.plugins.nicira.nvplib import get_all_query_pages
|
||||
from neutron.plugins.nicira.nvplib import get_port
|
||||
|
||||
HTTP_GET = "GET"
|
||||
HTTP_POST = "POST"
|
||||
HTTP_DELETE = "DELETE"
|
||||
HTTP_PUT = "PUT"
|
||||
|
||||
LROUTER_RESOURCE = "lrouter"
|
||||
LROUTER_RESOURCE = "lrouter"
|
||||
LROUTERPORT_RESOURCE = "lport/%s" % LROUTER_RESOURCE
|
||||
LROUTERRIB_RESOURCE = "rib/%s" % LROUTER_RESOURCE
|
||||
LROUTERNAT_RESOURCE = "nat/lrouter"
|
||||
# Constants for NAT rules
|
||||
MATCH_KEYS = ["destination_ip_addresses", "destination_port_max",
|
||||
"destination_port_min", "source_ip_addresses",
|
||||
"source_port_max", "source_port_min", "protocol"]
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def _prepare_lrouter_body(name, neutron_router_id, tenant_id,
|
||||
router_type, distributed=None, **kwargs):
|
||||
body = {
|
||||
"display_name": utils.check_and_truncate(name),
|
||||
"tags": utils.get_tags(os_tid=tenant_id,
|
||||
q_router_id=neutron_router_id),
|
||||
"routing_config": {
|
||||
"type": router_type
|
||||
},
|
||||
"type": "LogicalRouterConfig"
|
||||
}
|
||||
# add the distributed key only if not None (ie: True or False)
|
||||
if distributed is not None:
|
||||
body['distributed'] = distributed
|
||||
if kwargs:
|
||||
body["routing_config"].update(kwargs)
|
||||
return body
|
||||
|
||||
|
||||
def _create_implicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed=None):
|
||||
implicit_routing_config = {
|
||||
"default_route_next_hop": {
|
||||
"gateway_ip_address": nexthop,
|
||||
"type": "RouterNextHop"
|
||||
},
|
||||
}
|
||||
lrouter_obj = _prepare_lrouter_body(
|
||||
display_name, neutron_router_id, tenant_id,
|
||||
"SingleDefaultRouteImplicitRoutingConfig",
|
||||
distributed=distributed,
|
||||
**implicit_routing_config)
|
||||
return do_request(HTTP_POST, _build_uri_path(LROUTER_RESOURCE),
|
||||
jsonutils.dumps(lrouter_obj), cluster=cluster)
|
||||
|
||||
|
||||
def create_implicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop):
|
||||
"""Create a NSX logical router on the specified cluster.
|
||||
|
||||
:param cluster: The target NSX cluster
|
||||
:param tenant_id: Identifier of the Openstack tenant for which
|
||||
the logical router is being created
|
||||
:param display_name: Descriptive name of this logical router
|
||||
:param nexthop: External gateway IP address for the logical router
|
||||
:raise NvpApiException: if there is a problem while communicating
|
||||
with the NSX controller
|
||||
"""
|
||||
return _create_implicit_routing_lrouter(
|
||||
cluster, neutron_router_id, tenant_id, display_name, nexthop)
|
||||
|
||||
|
||||
def create_implicit_routing_lrouter_with_distribution(
|
||||
cluster, neutron_router_id, tenant_id, display_name,
|
||||
nexthop, distributed=None):
|
||||
"""Create a NSX logical router on the specified cluster.
|
||||
|
||||
This function also allows for creating distributed lrouters
|
||||
:param cluster: The target NSX cluster
|
||||
:param tenant_id: Identifier of the Openstack tenant for which
|
||||
the logical router is being created
|
||||
:param display_name: Descriptive name of this logical router
|
||||
:param nexthop: External gateway IP address for the logical router
|
||||
:param distributed: True for distributed logical routers
|
||||
:raise NvpApiException: if there is a problem while communicating
|
||||
with the NSX controller
|
||||
"""
|
||||
return _create_implicit_routing_lrouter(
|
||||
cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed)
|
||||
|
||||
|
||||
def create_explicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed=None):
|
||||
lrouter_obj = _prepare_lrouter_body(
|
||||
display_name, neutron_router_id, tenant_id,
|
||||
"RoutingTableRoutingConfig", distributed=distributed)
|
||||
router = do_request(HTTP_POST, _build_uri_path(LROUTER_RESOURCE),
|
||||
jsonutils.dumps(lrouter_obj), cluster=cluster)
|
||||
default_gw = {'prefix': '0.0.0.0/0', 'next_hop_ip': nexthop}
|
||||
create_explicit_route_lrouter(cluster, router['uuid'], default_gw)
|
||||
return router
|
||||
|
||||
|
||||
def delete_lrouter(cluster, lrouter_id):
|
||||
do_request(HTTP_DELETE, _build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=lrouter_id),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def get_lrouter(cluster, lrouter_id):
|
||||
return do_request(HTTP_GET,
|
||||
_build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=lrouter_id,
|
||||
relations='LogicalRouterStatus'),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def query_lrouters(cluster, fields=None, filters=None):
|
||||
return get_all_query_pages(
|
||||
_build_uri_path(LROUTER_RESOURCE,
|
||||
fields=fields,
|
||||
relations='LogicalRouterStatus',
|
||||
filters=filters),
|
||||
cluster)
|
||||
|
||||
|
||||
def get_lrouters(cluster, tenant_id, fields=None, filters=None):
|
||||
# FIXME(salv-orlando): Fields parameter is ignored in this routine
|
||||
actual_filters = {}
|
||||
if filters:
|
||||
actual_filters.update(filters)
|
||||
if tenant_id:
|
||||
actual_filters['tag'] = tenant_id
|
||||
actual_filters['tag_scope'] = 'os_tid'
|
||||
lrouter_fields = "uuid,display_name,fabric_status,tags"
|
||||
return query_lrouters(cluster, lrouter_fields, actual_filters)
|
||||
|
||||
|
||||
def update_implicit_routing_lrouter(cluster, r_id, display_name, nexthop):
|
||||
lrouter_obj = get_lrouter(cluster, r_id)
|
||||
if not display_name and not nexthop:
|
||||
# Nothing to update
|
||||
return lrouter_obj
|
||||
# It seems that this is faster than the doing an if on display_name
|
||||
lrouter_obj["display_name"] = (utils.check_and_truncate(display_name) or
|
||||
lrouter_obj["display_name"])
|
||||
if nexthop:
|
||||
nh_element = lrouter_obj["routing_config"].get(
|
||||
"default_route_next_hop")
|
||||
if nh_element:
|
||||
nh_element["gateway_ip_address"] = nexthop
|
||||
return do_request(HTTP_PUT, _build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=r_id),
|
||||
jsonutils.dumps(lrouter_obj),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def get_explicit_routes_lrouter(cluster, router_id, protocol_type='static'):
|
||||
static_filter = {'protocol': protocol_type}
|
||||
existing_routes = do_request(
|
||||
HTTP_GET,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
filters=static_filter,
|
||||
fields="*",
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)['results']
|
||||
return existing_routes
|
||||
|
||||
|
||||
def delete_explicit_route_lrouter(cluster, router_id, route_id):
|
||||
do_request(HTTP_DELETE,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
resource_id=route_id,
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def create_explicit_route_lrouter(cluster, router_id, route):
|
||||
next_hop_ip = route.get("nexthop") or route.get("next_hop_ip")
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
uuid = do_request(
|
||||
HTTP_POST,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
parent_resource_id=router_id),
|
||||
jsonutils.dumps({
|
||||
"action": "accept",
|
||||
"next_hop_ip": next_hop_ip,
|
||||
"prefix": prefix,
|
||||
"protocol": "static"
|
||||
}),
|
||||
cluster=cluster)['uuid']
|
||||
return uuid
|
||||
|
||||
|
||||
def update_explicit_routes_lrouter(cluster, router_id, routes):
|
||||
# Update in bulk: delete them all, and add the ones specified
|
||||
# but keep track of what is been modified to allow roll-backs
|
||||
# in case of failures
|
||||
nsx_routes = get_explicit_routes_lrouter(cluster, router_id)
|
||||
try:
|
||||
deleted_routes = []
|
||||
added_routes = []
|
||||
# omit the default route (0.0.0.0/0) from the processing;
|
||||
# this must be handled through the nexthop for the router
|
||||
for route in nsx_routes:
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
if prefix != '0.0.0.0/0':
|
||||
delete_explicit_route_lrouter(cluster,
|
||||
router_id,
|
||||
route['uuid'])
|
||||
deleted_routes.append(route)
|
||||
for route in routes:
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
if prefix != '0.0.0.0/0':
|
||||
uuid = create_explicit_route_lrouter(cluster,
|
||||
router_id, route)
|
||||
added_routes.append(uuid)
|
||||
except NvpApiClient.NvpApiException:
|
||||
LOG.exception(_('Cannot update NSX routes %(routes)s for '
|
||||
'router %(router_id)s'),
|
||||
{'routes': routes, 'router_id': router_id})
|
||||
# Roll back to keep NSX in consistent state
|
||||
with excutils.save_and_reraise_exception():
|
||||
if nsx_routes:
|
||||
if deleted_routes:
|
||||
for route in deleted_routes:
|
||||
create_explicit_route_lrouter(cluster,
|
||||
router_id, route)
|
||||
if added_routes:
|
||||
for route_id in added_routes:
|
||||
delete_explicit_route_lrouter(cluster,
|
||||
router_id, route_id)
|
||||
return nsx_routes
|
||||
|
||||
|
||||
def get_default_route_explicit_routing_lrouter_v33(cluster, router_id):
|
||||
static_filter = {"protocol": "static",
|
||||
"prefix": "0.0.0.0/0"}
|
||||
default_route = do_request(
|
||||
HTTP_GET,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
filters=static_filter,
|
||||
fields="*",
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)["results"][0]
|
||||
return default_route
|
||||
|
||||
|
||||
def get_default_route_explicit_routing_lrouter_v32(cluster, router_id):
|
||||
# Scan all routes because 3.2 does not support query by prefix
|
||||
all_routes = get_explicit_routes_lrouter(cluster, router_id)
|
||||
for route in all_routes:
|
||||
if route['prefix'] == '0.0.0.0/0':
|
||||
return route
|
||||
|
||||
|
||||
def update_default_gw_explicit_routing_lrouter(cluster, router_id, next_hop):
|
||||
default_route = get_default_route_explicit_routing_lrouter(cluster,
|
||||
router_id)
|
||||
if next_hop != default_route["next_hop_ip"]:
|
||||
new_default_route = {"action": "accept",
|
||||
"next_hop_ip": next_hop,
|
||||
"prefix": "0.0.0.0/0",
|
||||
"protocol": "static"}
|
||||
do_request(HTTP_PUT,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
resource_id=default_route['uuid'],
|
||||
parent_resource_id=router_id),
|
||||
jsonutils.dumps(new_default_route),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def update_explicit_routing_lrouter(cluster, router_id,
|
||||
display_name, next_hop, routes=None):
|
||||
update_implicit_routing_lrouter(cluster, router_id, display_name, next_hop)
|
||||
if next_hop:
|
||||
update_default_gw_explicit_routing_lrouter(cluster,
|
||||
router_id, next_hop)
|
||||
if routes is not None:
|
||||
return update_explicit_routes_lrouter(cluster, router_id, routes)
|
||||
|
||||
|
||||
def query_lrouter_lports(cluster, lr_uuid, fields="*",
|
||||
filters=None, relations=None):
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, parent_resource_id=lr_uuid,
|
||||
fields=fields, filters=filters, relations=relations)
|
||||
return do_request(HTTP_GET, uri, cluster=cluster)['results']
|
||||
|
||||
|
||||
def create_router_lport(cluster, lrouter_uuid, tenant_id, neutron_port_id,
|
||||
display_name, admin_status_enabled, ip_addresses,
|
||||
mac_address=None):
|
||||
"""Creates a logical port on the assigned logical router."""
|
||||
lport_obj = dict(
|
||||
admin_status_enabled=admin_status_enabled,
|
||||
display_name=display_name,
|
||||
tags=utils.get_tags(os_tid=tenant_id, q_port_id=neutron_port_id),
|
||||
ip_addresses=ip_addresses,
|
||||
type="LogicalRouterPortConfig"
|
||||
)
|
||||
# Only add the mac_address to lport_obj if present. This is because
|
||||
# when creating the fake_ext_gw there is no mac_address present.
|
||||
if mac_address:
|
||||
lport_obj['mac_address'] = mac_address
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE,
|
||||
parent_resource_id=lrouter_uuid)
|
||||
result = do_request(HTTP_POST, path, jsonutils.dumps(lport_obj),
|
||||
cluster=cluster)
|
||||
|
||||
LOG.debug(_("Created logical port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': result['uuid'],
|
||||
'lrouter_uuid': lrouter_uuid})
|
||||
return result
|
||||
|
||||
|
||||
def update_router_lport(cluster, lrouter_uuid, lrouter_port_uuid,
|
||||
tenant_id, neutron_port_id, display_name,
|
||||
admin_status_enabled, ip_addresses):
|
||||
"""Updates a logical port on the assigned logical router."""
|
||||
lport_obj = dict(
|
||||
admin_status_enabled=admin_status_enabled,
|
||||
display_name=display_name,
|
||||
tags=utils.get_tags(os_tid=tenant_id, q_port_id=neutron_port_id),
|
||||
ip_addresses=ip_addresses,
|
||||
type="LogicalRouterPortConfig"
|
||||
)
|
||||
# Do not pass null items to NSX
|
||||
for key in lport_obj.keys():
|
||||
if lport_obj[key] is None:
|
||||
del lport_obj[key]
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE,
|
||||
lrouter_port_uuid,
|
||||
parent_resource_id=lrouter_uuid)
|
||||
result = do_request(HTTP_PUT, path,
|
||||
jsonutils.dumps(lport_obj),
|
||||
cluster=cluster)
|
||||
LOG.debug(_("Updated logical port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': lrouter_port_uuid, 'lrouter_uuid': lrouter_uuid})
|
||||
return result
|
||||
|
||||
|
||||
def delete_router_lport(cluster, lrouter_uuid, lport_uuid):
|
||||
"""Creates a logical port on the assigned logical router."""
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE, lport_uuid, lrouter_uuid)
|
||||
do_request(HTTP_DELETE, path, cluster=cluster)
|
||||
LOG.debug(_("Delete logical router port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': lport_uuid,
|
||||
'lrouter_uuid': lrouter_uuid})
|
||||
|
||||
|
||||
def delete_peer_router_lport(cluster, lr_uuid, ls_uuid, lp_uuid):
|
||||
nsx_port = get_port(cluster, ls_uuid, lp_uuid,
|
||||
relations="LogicalPortAttachment")
|
||||
relations = nsx_port.get('_relations')
|
||||
if relations:
|
||||
att_data = relations.get('LogicalPortAttachment')
|
||||
if att_data:
|
||||
lrp_uuid = att_data.get('peer_port_uuid')
|
||||
if lrp_uuid:
|
||||
delete_router_lport(cluster, lr_uuid, lrp_uuid)
|
||||
|
||||
|
||||
def find_router_gw_port(context, cluster, router_id):
|
||||
"""Retrieves the external gateway port for a NSX logical router."""
|
||||
|
||||
# Find the uuid of nsx ext gw logical router port
|
||||
# TODO(salvatore-orlando): Consider storing it in Neutron DB
|
||||
results = query_lrouter_lports(
|
||||
cluster, router_id,
|
||||
relations="LogicalPortAttachment")
|
||||
for lport in results:
|
||||
if '_relations' in lport:
|
||||
attachment = lport['_relations'].get('LogicalPortAttachment')
|
||||
if attachment and attachment.get('type') == 'L3GatewayAttachment':
|
||||
return lport
|
||||
|
||||
|
||||
def plug_router_port_attachment(cluster, router_id, port_id,
|
||||
attachment_uuid, nsx_attachment_type,
|
||||
attachment_vlan=None):
|
||||
"""Attach a router port to the given attachment.
|
||||
|
||||
Current attachment types:
|
||||
- PatchAttachment [-> logical switch port uuid]
|
||||
- L3GatewayAttachment [-> L3GatewayService uuid]
|
||||
For the latter attachment type a VLAN ID can be specified as well.
|
||||
"""
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, port_id, router_id,
|
||||
is_attachment=True)
|
||||
attach_obj = {}
|
||||
attach_obj["type"] = nsx_attachment_type
|
||||
if nsx_attachment_type == "PatchAttachment":
|
||||
attach_obj["peer_port_uuid"] = attachment_uuid
|
||||
elif nsx_attachment_type == "L3GatewayAttachment":
|
||||
attach_obj["l3_gateway_service_uuid"] = attachment_uuid
|
||||
if attachment_vlan:
|
||||
attach_obj['vlan_id'] = attachment_vlan
|
||||
else:
|
||||
raise nvp_exc.NvpInvalidAttachmentType(
|
||||
attachment_type=nsx_attachment_type)
|
||||
return do_request(
|
||||
HTTP_PUT, uri, jsonutils.dumps(attach_obj), cluster=cluster)
|
||||
|
||||
|
||||
def _create_nat_match_obj(**kwargs):
|
||||
nat_match_obj = {'ethertype': 'IPv4'}
|
||||
delta = set(kwargs.keys()) - set(MATCH_KEYS)
|
||||
if delta:
|
||||
raise Exception(_("Invalid keys for NAT match: %s"), delta)
|
||||
nat_match_obj.update(kwargs)
|
||||
return nat_match_obj
|
||||
|
||||
|
||||
def _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj):
|
||||
LOG.debug(_("Creating NAT rule: %s"), nat_rule_obj)
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, parent_resource_id=router_id)
|
||||
return do_request(HTTP_POST, uri, jsonutils.dumps(nat_rule_obj),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj):
|
||||
return {"to_source_ip_address_min": min_src_ip,
|
||||
"to_source_ip_address_max": max_src_ip,
|
||||
"type": "SourceNatRule",
|
||||
"match": nat_match_obj}
|
||||
|
||||
|
||||
def create_lrouter_nosnat_rule_v2(cluster, _router_id, _match_criteria=None):
|
||||
LOG.info(_("No SNAT rules cannot be applied as they are not available in "
|
||||
"this version of the NSX platform"))
|
||||
|
||||
|
||||
def create_lrouter_nodnat_rule_v2(cluster, _router_id, _match_criteria=None):
|
||||
LOG.info(_("No DNAT rules cannot be applied as they are not available in "
|
||||
"this version of the NSX platform"))
|
||||
|
||||
|
||||
def create_lrouter_snat_rule_v2(cluster, router_id,
|
||||
min_src_ip, max_src_ip, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj)
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_dnat_rule_v2(cluster, router_id, dst_ip,
|
||||
to_dst_port=None, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"to_destination_ip_address_min": dst_ip,
|
||||
"to_destination_ip_address_max": dst_ip,
|
||||
"type": "DestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if to_dst_port:
|
||||
nat_rule_obj['to_destination_port'] = to_dst_port
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_nosnat_rule_v3(cluster, router_id, order=None,
|
||||
match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"type": "NoSourceNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_nodnat_rule_v3(cluster, router_id, order=None,
|
||||
match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"type": "NoDestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_snat_rule_v3(cluster, router_id, min_src_ip, max_src_ip,
|
||||
order=None, match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj)
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_dnat_rule_v3(cluster, router_id, dst_ip, to_dst_port=None,
|
||||
order=None, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"to_destination_ip_address": dst_ip,
|
||||
"type": "DestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if to_dst_port:
|
||||
nat_rule_obj['to_destination_port'] = to_dst_port
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def delete_nat_rules_by_match(cluster, router_id, rule_type,
|
||||
max_num_expected,
|
||||
min_num_expected=0,
|
||||
**kwargs):
|
||||
# remove nat rules
|
||||
nat_rules = query_nat_rules(cluster, router_id)
|
||||
to_delete_ids = []
|
||||
for r in nat_rules:
|
||||
if (r['type'] != rule_type):
|
||||
continue
|
||||
|
||||
for key, value in kwargs.iteritems():
|
||||
if not (key in r['match'] and r['match'][key] == value):
|
||||
break
|
||||
else:
|
||||
to_delete_ids.append(r['uuid'])
|
||||
if not (len(to_delete_ids) in
|
||||
range(min_num_expected, max_num_expected + 1)):
|
||||
raise nvp_exc.NvpNatRuleMismatch(actual_rules=len(to_delete_ids),
|
||||
min_rules=min_num_expected,
|
||||
max_rules=max_num_expected)
|
||||
|
||||
for rule_id in to_delete_ids:
|
||||
delete_router_nat_rule(cluster, router_id, rule_id)
|
||||
|
||||
|
||||
def delete_router_nat_rule(cluster, router_id, rule_id):
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, rule_id, router_id)
|
||||
do_request(HTTP_DELETE, uri, cluster=cluster)
|
||||
|
||||
|
||||
def query_nat_rules(cluster, router_id, fields="*", filters=None):
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, parent_resource_id=router_id,
|
||||
fields=fields, filters=filters)
|
||||
return get_all_query_pages(uri, cluster)
|
||||
|
||||
|
||||
# NOTE(salvatore-orlando): The following FIXME applies in general to
|
||||
# each operation on list attributes.
|
||||
# FIXME(salvatore-orlando): need a lock around the list of IPs on an iface
|
||||
def update_lrouter_port_ips(cluster, lrouter_id, lport_id,
|
||||
ips_to_add, ips_to_remove):
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, lport_id, lrouter_id)
|
||||
try:
|
||||
port = do_request(HTTP_GET, uri, cluster=cluster)
|
||||
# TODO(salvatore-orlando): Enforce ips_to_add intersection with
|
||||
# ips_to_remove is empty
|
||||
ip_address_set = set(port['ip_addresses'])
|
||||
ip_address_set = ip_address_set - set(ips_to_remove)
|
||||
ip_address_set = ip_address_set | set(ips_to_add)
|
||||
# Set is not JSON serializable - convert to list
|
||||
port['ip_addresses'] = list(ip_address_set)
|
||||
do_request(HTTP_PUT, uri, jsonutils.dumps(port), cluster=cluster)
|
||||
except exception.NotFound as e:
|
||||
# FIXME(salv-orlando):avoid raising different exception
|
||||
data = {'lport_id': lport_id, 'lrouter_id': lrouter_id}
|
||||
msg = (_("Router Port %(lport_id)s not found on router "
|
||||
"%(lrouter_id)s") % data)
|
||||
LOG.exception(msg)
|
||||
raise nvp_exc.NvpPluginException(err_msg=msg)
|
||||
except NvpApiClient.NvpApiException as e:
|
||||
msg = _("An exception occurred while updating IP addresses on a "
|
||||
"router logical port:%s") % str(e)
|
||||
LOG.exception(msg)
|
||||
raise nvp_exc.NvpPluginException(err_msg=msg)
|
||||
|
||||
|
||||
ROUTER_FUNC_DICT = {
|
||||
'create_lrouter': {
|
||||
2: {DEFAULT_VERSION: create_implicit_routing_lrouter, },
|
||||
3: {DEFAULT_VERSION: create_implicit_routing_lrouter,
|
||||
1: create_implicit_routing_lrouter_with_distribution,
|
||||
2: create_explicit_routing_lrouter, }, },
|
||||
'update_lrouter': {
|
||||
2: {DEFAULT_VERSION: update_implicit_routing_lrouter, },
|
||||
3: {DEFAULT_VERSION: update_implicit_routing_lrouter,
|
||||
2: update_explicit_routing_lrouter, }, },
|
||||
'create_lrouter_dnat_rule': {
|
||||
2: {DEFAULT_VERSION: create_lrouter_dnat_rule_v2, },
|
||||
3: {DEFAULT_VERSION: create_lrouter_dnat_rule_v3, }, },
|
||||
'create_lrouter_snat_rule': {
|
||||
2: {DEFAULT_VERSION: create_lrouter_snat_rule_v2, },
|
||||
3: {DEFAULT_VERSION: create_lrouter_snat_rule_v3, }, },
|
||||
'create_lrouter_nosnat_rule': {
|
||||
2: {DEFAULT_VERSION: create_lrouter_nosnat_rule_v2, },
|
||||
3: {DEFAULT_VERSION: create_lrouter_nosnat_rule_v3, }, },
|
||||
'create_lrouter_nodnat_rule': {
|
||||
2: {DEFAULT_VERSION: create_lrouter_nodnat_rule_v2, },
|
||||
3: {DEFAULT_VERSION: create_lrouter_nodnat_rule_v3, }, },
|
||||
'get_default_route_explicit_routing_lrouter': {
|
||||
3: {DEFAULT_VERSION: get_default_route_explicit_routing_lrouter_v32,
|
||||
2: get_default_route_explicit_routing_lrouter_v32, }, },
|
||||
}
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def create_lrouter(cluster, *args, **kwargs):
|
||||
if kwargs.get('distributed', None):
|
||||
v = cluster.api_client.get_nvp_version()
|
||||
if (v.major, v.minor) < (3, 1):
|
||||
raise nvp_exc.NvpInvalidVersion(version=v)
|
||||
return v
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def get_default_route_explicit_routing_lrouter(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def update_lrouter(cluster, *args, **kwargs):
|
||||
if kwargs.get('routes', None):
|
||||
v = cluster.api_client.get_nvp_version()
|
||||
if (v.major, v.minor) < (3, 2):
|
||||
raise nvp_exc.NvpInvalidVersion(version=v)
|
||||
return v
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def create_lrouter_dnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def create_lrouter_snat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def create_lrouter_nosnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@versioned(ROUTER_FUNC_DICT)
|
||||
def create_lrouter_nodnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
66
neutron/plugins/nicira/nsxlib/versioning.py
Normal file
66
neutron/plugins/nicira/nsxlib/versioning.py
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 2014 VMware, Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import inspect
|
||||
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
|
||||
DEFAULT_VERSION = -1
|
||||
|
||||
|
||||
def versioned(func_table):
|
||||
|
||||
def versioned_function(wrapped_func):
|
||||
func_name = wrapped_func.__name__
|
||||
|
||||
def dispatch_versioned_function(cluster, *args, **kwargs):
|
||||
# Call the wrapper function, in case we need to
|
||||
# run validation checks regarding versions. It
|
||||
# should return the NVP version
|
||||
v = (wrapped_func(cluster, *args, **kwargs) or
|
||||
cluster.api_client.get_nvp_version())
|
||||
func = get_function_by_version(func_table, func_name, v)
|
||||
func_kwargs = kwargs
|
||||
arg_spec = inspect.getargspec(func)
|
||||
if not arg_spec.keywords and not arg_spec.varargs:
|
||||
# drop args unknown to function from func_args
|
||||
arg_set = set(func_kwargs.keys())
|
||||
for arg in arg_set - set(arg_spec.args):
|
||||
del func_kwargs[arg]
|
||||
# NOTE(salvatore-orlando): shall we fail here if a required
|
||||
# argument is not passed, or let the called function raise?
|
||||
return func(cluster, *args, **func_kwargs)
|
||||
|
||||
return dispatch_versioned_function
|
||||
return versioned_function
|
||||
|
||||
|
||||
def get_function_by_version(func_table, func_name, ver):
|
||||
if ver:
|
||||
if ver.major not in func_table[func_name]:
|
||||
major = max(func_table[func_name].keys())
|
||||
minor = max(func_table[func_name][major].keys())
|
||||
if major > ver.major:
|
||||
raise NotImplementedError(_("Operation may not be supported"))
|
||||
else:
|
||||
major = ver.major
|
||||
minor = ver.minor
|
||||
if ver.minor not in func_table[func_name][major]:
|
||||
minor = DEFAULT_VERSION
|
||||
return func_table[func_name][major][minor]
|
||||
else:
|
||||
msg = _('NSX version is not set. Unable to complete request '
|
||||
'correctly. Check log for NSX communication errors.')
|
||||
raise NvpApiClient.ServiceUnavailable(message=msg)
|
@ -21,14 +21,12 @@
|
||||
|
||||
|
||||
import hashlib
|
||||
import inspect
|
||||
import json
|
||||
|
||||
#FIXME(danwent): I'd like this file to get to the point where it has
|
||||
# no neutron-specific logic in it
|
||||
from neutron.common import constants
|
||||
from neutron.common import exceptions as exception
|
||||
from neutron.openstack.common import excutils
|
||||
from neutron.openstack.common import log
|
||||
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||
from neutron.plugins.nicira.common import utils
|
||||
@ -47,23 +45,10 @@ URI_PREFIX = "/ws.v1"
|
||||
# Resources exposed by NVP API
|
||||
LSWITCH_RESOURCE = "lswitch"
|
||||
LSWITCHPORT_RESOURCE = "lport/%s" % LSWITCH_RESOURCE
|
||||
LROUTER_RESOURCE = "lrouter"
|
||||
LROUTERPORT_RESOURCE = "lport/%s" % LROUTER_RESOURCE
|
||||
LROUTERRIB_RESOURCE = "rib/%s" % LROUTER_RESOURCE
|
||||
LROUTERNAT_RESOURCE = "nat/lrouter"
|
||||
LQUEUE_RESOURCE = "lqueue"
|
||||
GWSERVICE_RESOURCE = "gateway-service"
|
||||
# Current neutron version
|
||||
NEUTRON_VERSION = version_info.release_string()
|
||||
# Constants for NAT rules
|
||||
MATCH_KEYS = ["destination_ip_addresses", "destination_port_max",
|
||||
"destination_port_min", "source_ip_addresses",
|
||||
"source_port_max", "source_port_min", "protocol"]
|
||||
|
||||
SNAT_KEYS = ["to_src_port_min", "to_src_port_max", "to_src_ip_min",
|
||||
"to_src_ip_max"]
|
||||
|
||||
DNAT_KEYS = ["to_dst_port", "to_dst_ip_min", "to_dst_ip_max"]
|
||||
# Maximum page size for a single request
|
||||
# NOTE(salv-orlando): This might become a version-dependent map should the
|
||||
# limit be raised in future versions
|
||||
@ -91,30 +76,6 @@ def device_id_to_vm_id(device_id, obfuscate=False):
|
||||
return device_id
|
||||
|
||||
|
||||
def version_dependent(wrapped_func):
|
||||
func_name = wrapped_func.__name__
|
||||
|
||||
def dispatch_version_dependent_function(cluster, *args, **kwargs):
|
||||
# Call the wrapper function, in case we need to
|
||||
# run validation checks regarding versions. It
|
||||
# should return the NVP version
|
||||
v = (wrapped_func(cluster, *args, **kwargs) or
|
||||
cluster.api_client.get_nvp_version())
|
||||
func = get_function_by_version(func_name, v)
|
||||
func_kwargs = kwargs
|
||||
arg_spec = inspect.getargspec(func)
|
||||
if not arg_spec.keywords and not arg_spec.varargs:
|
||||
# drop args unknown to function from func_args
|
||||
arg_set = set(func_kwargs.keys())
|
||||
for arg in arg_set - set(arg_spec.args):
|
||||
del func_kwargs[arg]
|
||||
# NOTE(salvatore-orlando): shall we fail here if a required
|
||||
# argument is not passed, or let the called function raise?
|
||||
return func(cluster, *args, **func_kwargs)
|
||||
|
||||
return dispatch_version_dependent_function
|
||||
|
||||
|
||||
def _build_uri_path(resource,
|
||||
resource_id=None,
|
||||
parent_resource_id=None,
|
||||
@ -317,122 +278,12 @@ def create_l2_gw_service(cluster, tenant_id, display_name, devices):
|
||||
json.dumps(gwservice_obj), cluster=cluster)
|
||||
|
||||
|
||||
def _prepare_lrouter_body(name, neutron_router_id, tenant_id, router_type,
|
||||
distributed=None, **kwargs):
|
||||
body = {
|
||||
"display_name": utils.check_and_truncate(name),
|
||||
"tags": [{"tag": tenant_id, "scope": "os_tid"},
|
||||
{"tag": neutron_router_id, "scope": "q_router_id"},
|
||||
{"tag": NEUTRON_VERSION, "scope": "quantum"}],
|
||||
"routing_config": {
|
||||
"type": router_type
|
||||
},
|
||||
"type": "LogicalRouterConfig"
|
||||
}
|
||||
# add the distributed key only if not None (ie: True or False)
|
||||
if distributed is not None:
|
||||
body['distributed'] = distributed
|
||||
if kwargs:
|
||||
body["routing_config"].update(kwargs)
|
||||
return body
|
||||
|
||||
|
||||
def _create_implicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed=None):
|
||||
implicit_routing_config = {
|
||||
"default_route_next_hop": {
|
||||
"gateway_ip_address": nexthop,
|
||||
"type": "RouterNextHop"
|
||||
},
|
||||
}
|
||||
lrouter_obj = _prepare_lrouter_body(
|
||||
display_name, neutron_router_id, tenant_id,
|
||||
"SingleDefaultRouteImplicitRoutingConfig",
|
||||
distributed=distributed,
|
||||
**implicit_routing_config)
|
||||
return do_request(HTTP_POST, _build_uri_path(LROUTER_RESOURCE),
|
||||
json.dumps(lrouter_obj), cluster=cluster)
|
||||
|
||||
|
||||
def create_implicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop):
|
||||
"""Create a NVP logical router on the specified cluster.
|
||||
|
||||
:param cluster: The target NVP cluster
|
||||
:param tenant_id: Identifier of the Openstack tenant for which
|
||||
the logical router is being created
|
||||
:param display_name: Descriptive name of this logical router
|
||||
:param nexthop: External gateway IP address for the logical router
|
||||
:raise NvpApiException: if there is a problem while communicating
|
||||
with the NVP controller
|
||||
"""
|
||||
return _create_implicit_routing_lrouter(
|
||||
cluster, neutron_router_id, tenant_id, display_name, nexthop)
|
||||
|
||||
|
||||
def create_implicit_routing_lrouter_with_distribution(
|
||||
cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed=None):
|
||||
"""Create a NVP logical router on the specified cluster.
|
||||
|
||||
This function also allows for creating distributed lrouters
|
||||
:param cluster: The target NVP cluster
|
||||
:param tenant_id: Identifier of the Openstack tenant for which
|
||||
the logical router is being created
|
||||
:param display_name: Descriptive name of this logical router
|
||||
:param nexthop: External gateway IP address for the logical router
|
||||
:param distributed: True for distributed logical routers
|
||||
:raise NvpApiException: if there is a problem while communicating
|
||||
with the NVP controller
|
||||
"""
|
||||
return _create_implicit_routing_lrouter(
|
||||
cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop, distributed)
|
||||
|
||||
|
||||
def create_explicit_routing_lrouter(cluster, neutron_router_id, tenant_id,
|
||||
display_name, nexthop,
|
||||
distributed=None):
|
||||
lrouter_obj = _prepare_lrouter_body(
|
||||
display_name, neutron_router_id,
|
||||
tenant_id, "RoutingTableRoutingConfig",
|
||||
distributed=distributed)
|
||||
router = do_request(HTTP_POST, _build_uri_path(LROUTER_RESOURCE),
|
||||
json.dumps(lrouter_obj), cluster=cluster)
|
||||
default_gw = {'prefix': '0.0.0.0/0', 'next_hop_ip': nexthop}
|
||||
create_explicit_route_lrouter(cluster, router['uuid'], default_gw)
|
||||
return router
|
||||
|
||||
|
||||
@version_dependent
|
||||
def create_lrouter(cluster, *args, **kwargs):
|
||||
if kwargs.get('distributed', None):
|
||||
v = cluster.api_client.get_nvp_version()
|
||||
if (v.major, v.minor) < (3, 1):
|
||||
raise nvp_exc.NvpInvalidVersion(version=v)
|
||||
return v
|
||||
|
||||
|
||||
def delete_lrouter(cluster, lrouter_id):
|
||||
do_request(HTTP_DELETE, _build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=lrouter_id),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def delete_l2_gw_service(cluster, gateway_id):
|
||||
do_request("DELETE", _build_uri_path(GWSERVICE_RESOURCE,
|
||||
resource_id=gateway_id),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def get_lrouter(cluster, lrouter_id):
|
||||
return do_request(HTTP_GET,
|
||||
_build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=lrouter_id,
|
||||
relations='LogicalRouterStatus'),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def get_l2_gw_service(cluster, gateway_id):
|
||||
return do_request(
|
||||
"GET", _build_uri_path(GWSERVICE_RESOURCE,
|
||||
@ -440,27 +291,6 @@ def get_l2_gw_service(cluster, gateway_id):
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def query_lrouters(cluster, fields=None, filters=None):
|
||||
return get_all_query_pages(
|
||||
_build_uri_path(LROUTER_RESOURCE,
|
||||
fields=fields,
|
||||
relations='LogicalRouterStatus',
|
||||
filters=filters),
|
||||
cluster)
|
||||
|
||||
|
||||
def get_lrouters(cluster, tenant_id, fields=None, filters=None):
|
||||
# FIXME(salv-orlando): Fields parameter is ignored in this routine
|
||||
actual_filters = {}
|
||||
if filters:
|
||||
actual_filters.update(filters)
|
||||
if tenant_id:
|
||||
actual_filters['tag'] = tenant_id
|
||||
actual_filters['tag_scope'] = 'os_tid'
|
||||
lrouter_fields = "uuid,display_name,fabric_status,tags"
|
||||
return query_lrouters(cluster, lrouter_fields, actual_filters)
|
||||
|
||||
|
||||
def get_l2_gw_services(cluster, tenant_id=None,
|
||||
fields=None, filters=None):
|
||||
actual_filters = dict(filters or {})
|
||||
@ -485,164 +315,6 @@ def update_l2_gw_service(cluster, gateway_id, display_name):
|
||||
json.dumps(gwservice_obj), cluster=cluster)
|
||||
|
||||
|
||||
def update_implicit_routing_lrouter(cluster, r_id, display_name, nexthop):
|
||||
lrouter_obj = get_lrouter(cluster, r_id)
|
||||
if not display_name and not nexthop:
|
||||
# Nothing to update
|
||||
return lrouter_obj
|
||||
# It seems that this is faster than the doing an if on display_name
|
||||
lrouter_obj["display_name"] = (utils.check_and_truncate(display_name) or
|
||||
lrouter_obj["display_name"])
|
||||
if nexthop:
|
||||
nh_element = lrouter_obj["routing_config"].get(
|
||||
"default_route_next_hop")
|
||||
if nh_element:
|
||||
nh_element["gateway_ip_address"] = nexthop
|
||||
return do_request(HTTP_PUT, _build_uri_path(LROUTER_RESOURCE,
|
||||
resource_id=r_id),
|
||||
json.dumps(lrouter_obj),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def get_explicit_routes_lrouter(cluster, router_id, protocol_type='static'):
|
||||
static_filter = {'protocol': protocol_type}
|
||||
existing_routes = do_request(
|
||||
HTTP_GET,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
filters=static_filter,
|
||||
fields="*",
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)['results']
|
||||
return existing_routes
|
||||
|
||||
|
||||
def delete_explicit_route_lrouter(cluster, router_id, route_id):
|
||||
do_request(HTTP_DELETE,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
resource_id=route_id,
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def create_explicit_route_lrouter(cluster, router_id, route):
|
||||
next_hop_ip = route.get("nexthop") or route.get("next_hop_ip")
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
uuid = do_request(
|
||||
HTTP_POST,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
parent_resource_id=router_id),
|
||||
json.dumps({
|
||||
"action": "accept",
|
||||
"next_hop_ip": next_hop_ip,
|
||||
"prefix": prefix,
|
||||
"protocol": "static"
|
||||
}),
|
||||
cluster=cluster)['uuid']
|
||||
return uuid
|
||||
|
||||
|
||||
def update_explicit_routes_lrouter(cluster, router_id, routes):
|
||||
# Update in bulk: delete them all, and add the ones specified
|
||||
# but keep track of what is been modified to allow roll-backs
|
||||
# in case of failures
|
||||
nvp_routes = get_explicit_routes_lrouter(cluster, router_id)
|
||||
try:
|
||||
deleted_routes = []
|
||||
added_routes = []
|
||||
# omit the default route (0.0.0.0/0) from the processing;
|
||||
# this must be handled through the nexthop for the router
|
||||
for route in nvp_routes:
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
if prefix != '0.0.0.0/0':
|
||||
delete_explicit_route_lrouter(cluster,
|
||||
router_id,
|
||||
route['uuid'])
|
||||
deleted_routes.append(route)
|
||||
for route in routes:
|
||||
prefix = route.get("destination") or route.get("prefix")
|
||||
if prefix != '0.0.0.0/0':
|
||||
uuid = create_explicit_route_lrouter(cluster,
|
||||
router_id, route)
|
||||
added_routes.append(uuid)
|
||||
except NvpApiClient.NvpApiException:
|
||||
LOG.exception(_('Cannot update NVP routes %(routes)s for '
|
||||
'router %(router_id)s'),
|
||||
{'routes': routes, 'router_id': router_id})
|
||||
# Roll back to keep NVP in consistent state
|
||||
with excutils.save_and_reraise_exception():
|
||||
if nvp_routes:
|
||||
if deleted_routes:
|
||||
for route in deleted_routes:
|
||||
create_explicit_route_lrouter(cluster,
|
||||
router_id, route)
|
||||
if added_routes:
|
||||
for route_id in added_routes:
|
||||
delete_explicit_route_lrouter(cluster,
|
||||
router_id, route_id)
|
||||
return nvp_routes
|
||||
|
||||
|
||||
@version_dependent
|
||||
def get_default_route_explicit_routing_lrouter(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def get_default_route_explicit_routing_lrouter_v33(cluster, router_id):
|
||||
static_filter = {"protocol": "static",
|
||||
"prefix": "0.0.0.0/0"}
|
||||
default_route = do_request(
|
||||
HTTP_GET,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
filters=static_filter,
|
||||
fields="*",
|
||||
parent_resource_id=router_id),
|
||||
cluster=cluster)["results"][0]
|
||||
return default_route
|
||||
|
||||
|
||||
def get_default_route_explicit_routing_lrouter_v32(cluster, router_id):
|
||||
# Scan all routes because 3.2 does not support query by prefix
|
||||
all_routes = get_explicit_routes_lrouter(cluster, router_id)
|
||||
for route in all_routes:
|
||||
if route['prefix'] == '0.0.0.0/0':
|
||||
return route
|
||||
|
||||
|
||||
def update_default_gw_explicit_routing_lrouter(cluster, router_id, next_hop):
|
||||
default_route = get_default_route_explicit_routing_lrouter(cluster,
|
||||
router_id)
|
||||
if next_hop != default_route["next_hop_ip"]:
|
||||
new_default_route = {"action": "accept",
|
||||
"next_hop_ip": next_hop,
|
||||
"prefix": "0.0.0.0/0",
|
||||
"protocol": "static"}
|
||||
do_request(HTTP_PUT,
|
||||
_build_uri_path(LROUTERRIB_RESOURCE,
|
||||
resource_id=default_route['uuid'],
|
||||
parent_resource_id=router_id),
|
||||
json.dumps(new_default_route),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def update_explicit_routing_lrouter(cluster, router_id,
|
||||
display_name, next_hop, routes=None):
|
||||
update_implicit_routing_lrouter(cluster, router_id, display_name, next_hop)
|
||||
if next_hop:
|
||||
update_default_gw_explicit_routing_lrouter(cluster,
|
||||
router_id, next_hop)
|
||||
if routes is not None:
|
||||
return update_explicit_routes_lrouter(cluster, router_id, routes)
|
||||
|
||||
|
||||
@version_dependent
|
||||
def update_lrouter(cluster, *args, **kwargs):
|
||||
if kwargs.get('routes', None):
|
||||
v = cluster.api_client.get_nvp_version()
|
||||
if (v.major, v.minor) < (3, 2):
|
||||
raise nvp_exc.NvpInvalidVersion(version=v)
|
||||
return v
|
||||
|
||||
|
||||
def delete_network(cluster, net_id, lswitch_id):
|
||||
delete_networks(cluster, net_id, [lswitch_id])
|
||||
|
||||
@ -669,13 +341,6 @@ def query_lswitch_lports(cluster, ls_uuid, fields="*",
|
||||
return do_request(HTTP_GET, uri, cluster=cluster)['results']
|
||||
|
||||
|
||||
def query_lrouter_lports(cluster, lr_uuid, fields="*",
|
||||
filters=None, relations=None):
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, parent_resource_id=lr_uuid,
|
||||
fields=fields, filters=filters, relations=relations)
|
||||
return do_request(HTTP_GET, uri, cluster=cluster)['results']
|
||||
|
||||
|
||||
def delete_port(cluster, switch, port):
|
||||
uri = "/ws.v1/lswitch/" + switch + "/lport/" + port
|
||||
try:
|
||||
@ -884,129 +549,6 @@ def create_lport(cluster, lswitch_uuid, tenant_id, neutron_port_id,
|
||||
return result
|
||||
|
||||
|
||||
def create_router_lport(cluster, lrouter_uuid, tenant_id, neutron_port_id,
|
||||
display_name, admin_status_enabled, ip_addresses,
|
||||
mac_address=None):
|
||||
"""Creates a logical port on the assigned logical router."""
|
||||
tags = [dict(scope='os_tid', tag=tenant_id),
|
||||
dict(scope='q_port_id', tag=neutron_port_id),
|
||||
dict(scope='quantum', tag=NEUTRON_VERSION)]
|
||||
|
||||
lport_obj = dict(
|
||||
admin_status_enabled=admin_status_enabled,
|
||||
display_name=display_name,
|
||||
tags=tags,
|
||||
ip_addresses=ip_addresses,
|
||||
type="LogicalRouterPortConfig"
|
||||
)
|
||||
# Only add the mac_address to lport_obj if present. This is because
|
||||
# when creating the fake_ext_gw there is no mac_address present.
|
||||
if mac_address:
|
||||
lport_obj['mac_address'] = mac_address
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE,
|
||||
parent_resource_id=lrouter_uuid)
|
||||
result = do_request(HTTP_POST, path, json.dumps(lport_obj),
|
||||
cluster=cluster)
|
||||
|
||||
LOG.debug(_("Created logical port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': result['uuid'],
|
||||
'lrouter_uuid': lrouter_uuid})
|
||||
return result
|
||||
|
||||
|
||||
def update_router_lport(cluster, lrouter_uuid, lrouter_port_uuid,
|
||||
tenant_id, neutron_port_id, display_name,
|
||||
admin_status_enabled, ip_addresses):
|
||||
"""Updates a logical port on the assigned logical router."""
|
||||
lport_obj = dict(
|
||||
admin_status_enabled=admin_status_enabled,
|
||||
display_name=display_name,
|
||||
tags=[dict(scope='os_tid', tag=tenant_id),
|
||||
dict(scope='q_port_id', tag=neutron_port_id),
|
||||
dict(scope='quantum', tag=NEUTRON_VERSION)],
|
||||
ip_addresses=ip_addresses,
|
||||
type="LogicalRouterPortConfig"
|
||||
)
|
||||
# Do not pass null items to NVP
|
||||
for key in lport_obj.keys():
|
||||
if lport_obj[key] is None:
|
||||
del lport_obj[key]
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE,
|
||||
lrouter_port_uuid,
|
||||
parent_resource_id=lrouter_uuid)
|
||||
result = do_request(HTTP_PUT, path,
|
||||
json.dumps(lport_obj),
|
||||
cluster=cluster)
|
||||
LOG.debug(_("Updated logical port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': lrouter_port_uuid, 'lrouter_uuid': lrouter_uuid})
|
||||
return result
|
||||
|
||||
|
||||
def delete_router_lport(cluster, lrouter_uuid, lport_uuid):
|
||||
"""Creates a logical port on the assigned logical router."""
|
||||
path = _build_uri_path(LROUTERPORT_RESOURCE, lport_uuid, lrouter_uuid)
|
||||
do_request(HTTP_DELETE, path, cluster=cluster)
|
||||
LOG.debug(_("Delete logical router port %(lport_uuid)s on "
|
||||
"logical router %(lrouter_uuid)s"),
|
||||
{'lport_uuid': lport_uuid,
|
||||
'lrouter_uuid': lrouter_uuid})
|
||||
|
||||
|
||||
def delete_peer_router_lport(cluster, lr_uuid, ls_uuid, lp_uuid):
|
||||
nvp_port = get_port(cluster, ls_uuid, lp_uuid,
|
||||
relations="LogicalPortAttachment")
|
||||
relations = nvp_port.get('_relations')
|
||||
if relations:
|
||||
att_data = relations.get('LogicalPortAttachment')
|
||||
if att_data:
|
||||
lrp_uuid = att_data.get('peer_port_uuid')
|
||||
if lrp_uuid:
|
||||
delete_router_lport(cluster, lr_uuid, lrp_uuid)
|
||||
|
||||
|
||||
def find_router_gw_port(context, cluster, router_id):
|
||||
"""Retrieves the external gateway port for a NVP logical router."""
|
||||
|
||||
# Find the uuid of nvp ext gw logical router port
|
||||
# TODO(salvatore-orlando): Consider storing it in Neutron DB
|
||||
results = query_lrouter_lports(
|
||||
cluster, router_id,
|
||||
relations="LogicalPortAttachment")
|
||||
for lport in results:
|
||||
if '_relations' in lport:
|
||||
attachment = lport['_relations'].get('LogicalPortAttachment')
|
||||
if attachment and attachment.get('type') == 'L3GatewayAttachment':
|
||||
return lport
|
||||
|
||||
|
||||
def plug_router_port_attachment(cluster, router_id, port_id,
|
||||
attachment_uuid, nvp_attachment_type,
|
||||
attachment_vlan=None):
|
||||
"""Attach a router port to the given attachment.
|
||||
|
||||
Current attachment types:
|
||||
- PatchAttachment [-> logical switch port uuid]
|
||||
- L3GatewayAttachment [-> L3GatewayService uuid]
|
||||
For the latter attachment type a VLAN ID can be specified as well.
|
||||
"""
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, port_id, router_id,
|
||||
is_attachment=True)
|
||||
attach_obj = {}
|
||||
attach_obj["type"] = nvp_attachment_type
|
||||
if nvp_attachment_type == "PatchAttachment":
|
||||
attach_obj["peer_port_uuid"] = attachment_uuid
|
||||
elif nvp_attachment_type == "L3GatewayAttachment":
|
||||
attach_obj["l3_gateway_service_uuid"] = attachment_uuid
|
||||
if attachment_vlan:
|
||||
attach_obj['vlan_id'] = attachment_vlan
|
||||
else:
|
||||
raise nvp_exc.NvpInvalidAttachmentType(
|
||||
attachment_type=nvp_attachment_type)
|
||||
return do_request(HTTP_PUT, uri, json.dumps(attach_obj), cluster=cluster)
|
||||
|
||||
|
||||
def get_port_status(cluster, lswitch_id, port_id):
|
||||
"""Retrieve the operational status of the port."""
|
||||
try:
|
||||
@ -1176,243 +718,3 @@ def delete_security_profile(cluster, spid):
|
||||
LOG.warn(_("Unable to find security profile %s on NSX backend"),
|
||||
spid)
|
||||
raise
|
||||
|
||||
|
||||
def _create_nat_match_obj(**kwargs):
|
||||
nat_match_obj = {'ethertype': 'IPv4'}
|
||||
delta = set(kwargs.keys()) - set(MATCH_KEYS)
|
||||
if delta:
|
||||
raise Exception(_("Invalid keys for NAT match: %s"), delta)
|
||||
nat_match_obj.update(kwargs)
|
||||
return nat_match_obj
|
||||
|
||||
|
||||
def _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj):
|
||||
LOG.debug(_("Creating NAT rule: %s"), nat_rule_obj)
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, parent_resource_id=router_id)
|
||||
return do_request(HTTP_POST, uri, json.dumps(nat_rule_obj),
|
||||
cluster=cluster)
|
||||
|
||||
|
||||
def _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj):
|
||||
return {"to_source_ip_address_min": min_src_ip,
|
||||
"to_source_ip_address_max": max_src_ip,
|
||||
"type": "SourceNatRule",
|
||||
"match": nat_match_obj}
|
||||
|
||||
|
||||
def create_lrouter_nosnat_rule_v2(cluster, _router_id, _match_criteria=None):
|
||||
LOG.info(_("No SNAT rules cannot be applied as they are not available in "
|
||||
"this version of the NVP platform"))
|
||||
|
||||
|
||||
def create_lrouter_nodnat_rule_v2(cluster, _router_id, _match_criteria=None):
|
||||
LOG.info(_("No DNAT rules cannot be applied as they are not available in "
|
||||
"this version of the NVP platform"))
|
||||
|
||||
|
||||
def create_lrouter_snat_rule_v2(cluster, router_id,
|
||||
min_src_ip, max_src_ip, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj)
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_dnat_rule_v2(cluster, router_id, dst_ip,
|
||||
to_dst_port=None, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"to_destination_ip_address_min": dst_ip,
|
||||
"to_destination_ip_address_max": dst_ip,
|
||||
"type": "DestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if to_dst_port:
|
||||
nat_rule_obj['to_destination_port'] = to_dst_port
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_nosnat_rule_v3(cluster, router_id, order=None,
|
||||
match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"type": "NoSourceNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_nodnat_rule_v3(cluster, router_id, order=None,
|
||||
match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"type": "NoDestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_snat_rule_v3(cluster, router_id, min_src_ip, max_src_ip,
|
||||
order=None, match_criteria=None):
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = _build_snat_rule_obj(min_src_ip, max_src_ip, nat_match_obj)
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
def create_lrouter_dnat_rule_v3(cluster, router_id, dst_ip, to_dst_port=None,
|
||||
order=None, match_criteria=None):
|
||||
|
||||
nat_match_obj = _create_nat_match_obj(**match_criteria)
|
||||
nat_rule_obj = {
|
||||
"to_destination_ip_address": dst_ip,
|
||||
"type": "DestinationNatRule",
|
||||
"match": nat_match_obj
|
||||
}
|
||||
if to_dst_port:
|
||||
nat_rule_obj['to_destination_port'] = to_dst_port
|
||||
if order:
|
||||
nat_rule_obj['order'] = order
|
||||
return _create_lrouter_nat_rule(cluster, router_id, nat_rule_obj)
|
||||
|
||||
|
||||
@version_dependent
|
||||
def create_lrouter_dnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@version_dependent
|
||||
def create_lrouter_snat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@version_dependent
|
||||
def create_lrouter_nosnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@version_dependent
|
||||
def create_lrouter_nodnat_rule(cluster, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def delete_nat_rules_by_match(cluster, router_id, rule_type,
|
||||
max_num_expected,
|
||||
min_num_expected=0,
|
||||
**kwargs):
|
||||
# remove nat rules
|
||||
nat_rules = query_nat_rules(cluster, router_id)
|
||||
to_delete_ids = []
|
||||
for r in nat_rules:
|
||||
if (r['type'] != rule_type):
|
||||
continue
|
||||
|
||||
for key, value in kwargs.iteritems():
|
||||
if not (key in r['match'] and r['match'][key] == value):
|
||||
break
|
||||
else:
|
||||
to_delete_ids.append(r['uuid'])
|
||||
if not (len(to_delete_ids) in
|
||||
range(min_num_expected, max_num_expected + 1)):
|
||||
raise nvp_exc.NvpNatRuleMismatch(actual_rules=len(to_delete_ids),
|
||||
min_rules=min_num_expected,
|
||||
max_rules=max_num_expected)
|
||||
|
||||
for rule_id in to_delete_ids:
|
||||
delete_router_nat_rule(cluster, router_id, rule_id)
|
||||
|
||||
|
||||
def delete_router_nat_rule(cluster, router_id, rule_id):
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, rule_id, router_id)
|
||||
do_request(HTTP_DELETE, uri, cluster=cluster)
|
||||
|
||||
|
||||
def query_nat_rules(cluster, router_id, fields="*", filters=None):
|
||||
uri = _build_uri_path(LROUTERNAT_RESOURCE, parent_resource_id=router_id,
|
||||
fields=fields, filters=filters)
|
||||
return get_all_query_pages(uri, cluster)
|
||||
|
||||
|
||||
# NOTE(salvatore-orlando): The following FIXME applies in general to
|
||||
# each operation on list attributes.
|
||||
# FIXME(salvatore-orlando): need a lock around the list of IPs on an iface
|
||||
def update_lrouter_port_ips(cluster, lrouter_id, lport_id,
|
||||
ips_to_add, ips_to_remove):
|
||||
uri = _build_uri_path(LROUTERPORT_RESOURCE, lport_id, lrouter_id)
|
||||
try:
|
||||
port = do_request(HTTP_GET, uri, cluster=cluster)
|
||||
# TODO(salvatore-orlando): Enforce ips_to_add intersection with
|
||||
# ips_to_remove is empty
|
||||
ip_address_set = set(port['ip_addresses'])
|
||||
ip_address_set = ip_address_set - set(ips_to_remove)
|
||||
ip_address_set = ip_address_set | set(ips_to_add)
|
||||
# Set is not JSON serializable - convert to list
|
||||
port['ip_addresses'] = list(ip_address_set)
|
||||
do_request(HTTP_PUT, uri, json.dumps(port), cluster=cluster)
|
||||
except exception.NotFound as e:
|
||||
# FIXME(salv-orlando):avoid raising different exception
|
||||
data = {'lport_id': lport_id, 'lrouter_id': lrouter_id}
|
||||
msg = (_("Router Port %(lport_id)s not found on router "
|
||||
"%(lrouter_id)s") % data)
|
||||
LOG.exception(msg)
|
||||
raise nvp_exc.NvpPluginException(err_msg=msg)
|
||||
except NvpApiClient.NvpApiException as e:
|
||||
msg = _("An exception occurred while updating IP addresses on a "
|
||||
"router logical port:%s") % str(e)
|
||||
LOG.exception(msg)
|
||||
raise nvp_exc.NvpPluginException(err_msg=msg)
|
||||
|
||||
|
||||
DEFAULT = -1
|
||||
NVPLIB_FUNC_DICT = {
|
||||
'create_lrouter': {
|
||||
2: {DEFAULT: create_implicit_routing_lrouter, },
|
||||
3: {DEFAULT: create_implicit_routing_lrouter,
|
||||
1: create_implicit_routing_lrouter_with_distribution,
|
||||
2: create_explicit_routing_lrouter, }, },
|
||||
'update_lrouter': {
|
||||
2: {DEFAULT: update_implicit_routing_lrouter, },
|
||||
3: {DEFAULT: update_implicit_routing_lrouter,
|
||||
2: update_explicit_routing_lrouter, }, },
|
||||
'create_lrouter_dnat_rule': {
|
||||
2: {DEFAULT: create_lrouter_dnat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_dnat_rule_v3, }, },
|
||||
'create_lrouter_snat_rule': {
|
||||
2: {DEFAULT: create_lrouter_snat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_snat_rule_v3, }, },
|
||||
'create_lrouter_nosnat_rule': {
|
||||
2: {DEFAULT: create_lrouter_nosnat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_nosnat_rule_v3, }, },
|
||||
'create_lrouter_nodnat_rule': {
|
||||
2: {DEFAULT: create_lrouter_nodnat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_nodnat_rule_v3, }, },
|
||||
'get_default_route_explicit_routing_lrouter': {
|
||||
3: {DEFAULT: get_default_route_explicit_routing_lrouter_v32,
|
||||
2: get_default_route_explicit_routing_lrouter_v32, }, },
|
||||
}
|
||||
|
||||
|
||||
def get_function_by_version(func_name, nvp_ver):
|
||||
if nvp_ver:
|
||||
if nvp_ver.major not in NVPLIB_FUNC_DICT[func_name]:
|
||||
major = max(NVPLIB_FUNC_DICT[func_name].keys())
|
||||
minor = max(NVPLIB_FUNC_DICT[func_name][major].keys())
|
||||
if major > nvp_ver.major:
|
||||
raise NotImplementedError(_("Operation may not be supported"))
|
||||
else:
|
||||
major = nvp_ver.major
|
||||
minor = nvp_ver.minor
|
||||
if nvp_ver.minor not in NVPLIB_FUNC_DICT[func_name][major]:
|
||||
minor = DEFAULT
|
||||
return NVPLIB_FUNC_DICT[func_name][major][minor]
|
||||
else:
|
||||
msg = _('NVP version is not set. Unable to complete request '
|
||||
'correctly. Check log for NVP communication errors.')
|
||||
raise NvpApiClient.ServiceUnavailable(message=msg)
|
||||
|
922
neutron/tests/unit/nicira/nsxlib/test_router.py
Normal file
922
neutron/tests/unit/nicira/nsxlib/test_router.py
Normal file
@ -0,0 +1,922 @@
|
||||
# Copyright (c) 2014 VMware, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import mock
|
||||
|
||||
from neutron.common import exceptions
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
from neutron.tests.unit.nicira.test_nvplib import NsxlibNegativeBaseTestCase
|
||||
from neutron.tests.unit.nicira.test_nvplib import NvplibTestCase
|
||||
from neutron.tests.unit import test_api_v2
|
||||
|
||||
_uuid = test_api_v2._uuid
|
||||
|
||||
|
||||
class TestNatRules(NvplibTestCase):
|
||||
|
||||
def _test_create_lrouter_dnat_rule(self, version):
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
tenant_id = 'pippo'
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
'fake_router',
|
||||
'192.168.0.1')
|
||||
nat_rule = routerlib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '10.0.0.99',
|
||||
match_criteria={'destination_ip_addresses':
|
||||
'192.168.0.5'})
|
||||
uri = nvplib._build_uri_path(routerlib.LROUTERNAT_RESOURCE,
|
||||
nat_rule['uuid'],
|
||||
lrouter['uuid'])
|
||||
resp_obj = nvplib.do_request("GET", uri, cluster=self.fake_cluster)
|
||||
self.assertEqual('DestinationNatRule', resp_obj['type'])
|
||||
self.assertEqual('192.168.0.5',
|
||||
resp_obj['match']['destination_ip_addresses'])
|
||||
|
||||
def test_create_lrouter_dnat_rule_v2(self):
|
||||
self._test_create_lrouter_dnat_rule('2.9')
|
||||
|
||||
def test_create_lrouter_dnat_rule_v31(self):
|
||||
self._test_create_lrouter_dnat_rule('3.1')
|
||||
|
||||
|
||||
class TestExplicitLRouters(NvplibTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.fake_version = '3.2'
|
||||
super(TestExplicitLRouters, self).setUp()
|
||||
|
||||
def _get_lrouter(self, tenant_id, router_name, router_id, relations=None):
|
||||
schema = '/ws.v1/schema/RoutingTableRoutingConfig'
|
||||
|
||||
router = {'display_name': router_name,
|
||||
'uuid': router_id,
|
||||
'tags': [{'scope': 'quantum', 'tag': nvplib.NEUTRON_VERSION},
|
||||
{'scope': 'os_tid', 'tag': '%s' % tenant_id}],
|
||||
'distributed': False,
|
||||
'routing_config': {'type': 'RoutingTableRoutingConfig',
|
||||
'_schema': schema},
|
||||
'_schema': schema,
|
||||
'nat_synchronization_enabled': True,
|
||||
'replication_mode': 'service',
|
||||
'type': 'LogicalRouterConfig',
|
||||
'_href': '/ws.v1/lrouter/%s' % router_id, }
|
||||
if relations:
|
||||
router['_relations'] = relations
|
||||
return router
|
||||
|
||||
def _get_single_route(self, router_id, route_id='fake_route_id_0',
|
||||
prefix='0.0.0.0/0', next_hop_ip='1.1.1.1'):
|
||||
return {'protocol': 'static',
|
||||
'_href': '/ws.v1/lrouter/%s/rib/%s' % (router_id, route_id),
|
||||
'prefix': prefix,
|
||||
'_schema': '/ws.v1/schema/RoutingTableEntry',
|
||||
'next_hop_ip': next_hop_ip,
|
||||
'action': 'accept',
|
||||
'uuid': route_id}
|
||||
|
||||
def test_prepare_body_with_implicit_routing_config(self):
|
||||
router_name = 'fake_router_name'
|
||||
tenant_id = 'fake_tenant_id'
|
||||
neutron_router_id = 'pipita_higuain'
|
||||
router_type = 'SingleDefaultRouteImplicitRoutingConfig'
|
||||
route_config = {
|
||||
'default_route_next_hop': {'gateway_ip_address': 'fake_address',
|
||||
'type': 'RouterNextHop'}, }
|
||||
body = routerlib._prepare_lrouter_body(router_name, neutron_router_id,
|
||||
tenant_id, router_type,
|
||||
**route_config)
|
||||
expected = {'display_name': 'fake_router_name',
|
||||
'routing_config': {
|
||||
'default_route_next_hop':
|
||||
{'gateway_ip_address': 'fake_address',
|
||||
'type': 'RouterNextHop'},
|
||||
'type': 'SingleDefaultRouteImplicitRoutingConfig'},
|
||||
'tags': [{'scope': 'os_tid', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'q_router_id', 'tag': 'pipita_higuain'},
|
||||
{'scope': 'quantum',
|
||||
'tag': nvplib.NEUTRON_VERSION}],
|
||||
'type': 'LogicalRouterConfig'}
|
||||
self.assertEqual(expected, body)
|
||||
|
||||
def test_prepare_body_without_routing_config(self):
|
||||
router_name = 'fake_router_name'
|
||||
tenant_id = 'fake_tenant_id'
|
||||
neutron_router_id = 'marekiaro_hamsik'
|
||||
router_type = 'RoutingTableRoutingConfig'
|
||||
body = routerlib._prepare_lrouter_body(router_name, neutron_router_id,
|
||||
tenant_id, router_type)
|
||||
expected = {'display_name': 'fake_router_name',
|
||||
'routing_config': {'type': 'RoutingTableRoutingConfig'},
|
||||
'tags': [{'scope': 'os_tid', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'q_router_id',
|
||||
'tag': 'marekiaro_hamsik'},
|
||||
{'scope': 'quantum',
|
||||
'tag': nvplib.NEUTRON_VERSION}],
|
||||
'type': 'LogicalRouterConfig'}
|
||||
self.assertEqual(expected, body)
|
||||
|
||||
def test_get_lrouter(self):
|
||||
tenant_id = 'fake_tenant_id'
|
||||
router_name = 'fake_router_name'
|
||||
router_id = 'fake_router_id'
|
||||
relations = {
|
||||
'LogicalRouterStatus':
|
||||
{'_href': '/ws.v1/lrouter/%s/status' % router_id,
|
||||
'lport_admin_up_count': 1,
|
||||
'_schema': '/ws.v1/schema/LogicalRouterStatus',
|
||||
'lport_count': 1,
|
||||
'fabric_status': True,
|
||||
'type': 'LogicalRouterStatus',
|
||||
'lport_link_up_count': 0, }, }
|
||||
|
||||
with mock.patch.object(routerlib, 'do_request',
|
||||
return_value=self._get_lrouter(tenant_id,
|
||||
router_name,
|
||||
router_id,
|
||||
relations)):
|
||||
lrouter = routerlib.get_lrouter(self.fake_cluster, router_id)
|
||||
self.assertTrue(
|
||||
lrouter['_relations']['LogicalRouterStatus']['fabric_status'])
|
||||
|
||||
def test_create_lrouter(self):
|
||||
tenant_id = 'fake_tenant_id'
|
||||
router_name = 'fake_router_name'
|
||||
router_id = 'fake_router_id'
|
||||
nexthop_ip = '10.0.0.1'
|
||||
with mock.patch.object(
|
||||
routerlib, 'do_request',
|
||||
return_value=self._get_lrouter(tenant_id,
|
||||
router_name,
|
||||
router_id)):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
router_name, nexthop_ip)
|
||||
self.assertEqual(lrouter['routing_config']['type'],
|
||||
'RoutingTableRoutingConfig')
|
||||
self.assertNotIn('default_route_next_hop',
|
||||
lrouter['routing_config'])
|
||||
|
||||
def test_update_lrouter_with_no_routes(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nvp_routes = [self._get_single_route(router_id)]
|
||||
with mock.patch.object(routerlib, 'get_explicit_routes_lrouter',
|
||||
return_value=nvp_routes):
|
||||
with mock.patch.object(routerlib, 'create_explicit_route_lrouter',
|
||||
return_value='fake_uuid'):
|
||||
old_routes = routerlib.update_explicit_routes_lrouter(
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
self.assertEqual(old_routes, nvp_routes)
|
||||
|
||||
def test_update_lrouter_with_no_routes_raise_nsx_exception(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nsx_routes = [self._get_single_route(router_id)]
|
||||
with mock.patch.object(routerlib, 'get_explicit_routes_lrouter',
|
||||
return_value=nsx_routes):
|
||||
with mock.patch.object(routerlib, 'create_explicit_route_lrouter',
|
||||
side_effect=NvpApiClient.NvpApiException):
|
||||
self.assertRaises(NvpApiClient.NvpApiException,
|
||||
routerlib.update_explicit_routes_lrouter,
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
|
||||
def test_update_lrouter_with_routes(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"next_hop_ip": "10.0.0.2",
|
||||
"prefix": "169.254.169.0/30"}, ]
|
||||
|
||||
nsx_routes = [self._get_single_route(router_id),
|
||||
self._get_single_route(router_id, 'fake_route_id_1',
|
||||
'0.0.0.1/24', '10.0.0.3'),
|
||||
self._get_single_route(router_id, 'fake_route_id_2',
|
||||
'0.0.0.2/24', '10.0.0.4'), ]
|
||||
|
||||
with mock.patch.object(routerlib, 'get_explicit_routes_lrouter',
|
||||
return_value=nsx_routes):
|
||||
with mock.patch.object(routerlib, 'delete_explicit_route_lrouter',
|
||||
return_value=None):
|
||||
with mock.patch.object(routerlib,
|
||||
'create_explicit_route_lrouter',
|
||||
return_value='fake_uuid'):
|
||||
old_routes = routerlib.update_explicit_routes_lrouter(
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
self.assertEqual(old_routes, nsx_routes)
|
||||
|
||||
def test_update_lrouter_with_routes_raises_nsx_expception(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nsx_routes = [self._get_single_route(router_id),
|
||||
self._get_single_route(router_id, 'fake_route_id_1',
|
||||
'0.0.0.1/24', '10.0.0.3'),
|
||||
self._get_single_route(router_id, 'fake_route_id_2',
|
||||
'0.0.0.2/24', '10.0.0.4'), ]
|
||||
|
||||
with mock.patch.object(routerlib, 'get_explicit_routes_lrouter',
|
||||
return_value=nsx_routes):
|
||||
with mock.patch.object(routerlib, 'delete_explicit_route_lrouter',
|
||||
side_effect=NvpApiClient.NvpApiException):
|
||||
with mock.patch.object(
|
||||
routerlib, 'create_explicit_route_lrouter',
|
||||
return_value='fake_uuid'):
|
||||
self.assertRaises(
|
||||
NvpApiClient.NvpApiException,
|
||||
routerlib.update_explicit_routes_lrouter,
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
|
||||
|
||||
class RouterNegativeTestCase(NsxlibNegativeBaseTestCase):
|
||||
|
||||
def test_create_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
routerlib.create_lrouter,
|
||||
self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pluto',
|
||||
'fake_router',
|
||||
'my_hop')
|
||||
|
||||
def test_delete_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
routerlib.delete_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router')
|
||||
|
||||
def test_get_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
routerlib.get_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router')
|
||||
|
||||
def test_update_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
routerlib.update_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router',
|
||||
'pluto',
|
||||
'new_hop')
|
||||
|
||||
|
||||
class TestLogicalRouters(NvplibTestCase):
|
||||
|
||||
def _verify_lrouter(self, res_lrouter,
|
||||
expected_uuid,
|
||||
expected_display_name,
|
||||
expected_nexthop,
|
||||
expected_tenant_id,
|
||||
expected_neutron_id=None,
|
||||
expected_distributed=None):
|
||||
self.assertEqual(res_lrouter['uuid'], expected_uuid)
|
||||
nexthop = (res_lrouter['routing_config']
|
||||
['default_route_next_hop']['gateway_ip_address'])
|
||||
self.assertEqual(nexthop, expected_nexthop)
|
||||
router_tags = self._build_tag_dict(res_lrouter['tags'])
|
||||
self.assertIn('os_tid', router_tags)
|
||||
self.assertEqual(res_lrouter['display_name'], expected_display_name)
|
||||
self.assertEqual(expected_tenant_id, router_tags['os_tid'])
|
||||
if expected_distributed is not None:
|
||||
self.assertEqual(expected_distributed,
|
||||
res_lrouter['distributed'])
|
||||
if expected_neutron_id:
|
||||
self.assertIn('q_router_id', router_tags)
|
||||
self.assertEqual(expected_neutron_id, router_tags['q_router_id'])
|
||||
|
||||
def test_get_lrouters(self):
|
||||
lrouter_uuids = [routerlib.create_lrouter(
|
||||
self.fake_cluster, 'whatever', 'pippo', 'fake-lrouter-%s' % k,
|
||||
'10.0.0.1')['uuid'] for k in range(3)]
|
||||
routers = routerlib.get_lrouters(self.fake_cluster, 'pippo')
|
||||
for router in routers:
|
||||
self.assertIn(router['uuid'], lrouter_uuids)
|
||||
|
||||
def _create_lrouter(self, version, neutron_id=None, distributed=None):
|
||||
with mock.patch.object(
|
||||
self.fake_cluster.api_client, 'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
if not neutron_id:
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = routerlib.create_lrouter(
|
||||
self.fake_cluster, neutron_id, 'pippo',
|
||||
'fake-lrouter', '10.0.0.1', distributed=distributed)
|
||||
return routerlib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
|
||||
def test_create_and_get_lrouter_v30(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.0', neutron_id=neutron_id)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def test_create_and_get_lrouter_v31_centralized(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id,
|
||||
distributed=False)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id,
|
||||
expected_distributed=False)
|
||||
|
||||
def test_create_and_get_lrouter_v31_distributed(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id,
|
||||
distributed=True)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id,
|
||||
expected_distributed=True)
|
||||
|
||||
def test_create_and_get_lrouter_name_exceeds_40chars(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
display_name = '*' * 50
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
display_name,
|
||||
'10.0.0.1')
|
||||
res_lrouter = routerlib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'*' * 40, '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def _test_version_dependent_update_lrouter(self, version):
|
||||
def foo(*args, **kwargs):
|
||||
return version
|
||||
|
||||
foo_func_dict = {
|
||||
'update_lrouter': {
|
||||
2: {-1: foo},
|
||||
3: {-1: foo, 2: foo}
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
with mock.patch.dict(routerlib.ROUTER_FUNC_DICT,
|
||||
foo_func_dict, clear=True):
|
||||
return routerlib.update_lrouter(
|
||||
self.fake_cluster, 'foo_router_id', 'foo_router_name',
|
||||
'foo_nexthop', routes={'foo_destination': 'foo_address'})
|
||||
|
||||
def test_version_dependent_update_lrouter_old_versions(self):
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"2.9")
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"3.0")
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"3.1")
|
||||
|
||||
def test_version_dependent_update_lrouter_new_versions(self):
|
||||
self.assertEqual("3.2",
|
||||
self._test_version_dependent_update_lrouter("3.2"))
|
||||
self.assertEqual("4.0",
|
||||
self._test_version_dependent_update_lrouter("4.0"))
|
||||
self.assertEqual("4.1",
|
||||
self._test_version_dependent_update_lrouter("4.1"))
|
||||
|
||||
def test_update_lrouter_no_nexthop(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter = routerlib.update_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'],
|
||||
'new_name',
|
||||
None)
|
||||
res_lrouter = routerlib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'new_name', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def test_update_lrouter(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter = routerlib.update_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'],
|
||||
'new_name',
|
||||
'192.168.0.1')
|
||||
res_lrouter = routerlib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'new_name', '192.168.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def test_update_nonexistent_lrouter_raises(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
routerlib.update_lrouter,
|
||||
self.fake_cluster,
|
||||
'whatever',
|
||||
'foo', '9.9.9.9')
|
||||
|
||||
def test_delete_lrouter(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
routerlib.delete_lrouter(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
routerlib.get_lrouter,
|
||||
self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
|
||||
def test_query_lrouter_ports(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
router_port_uuids = [routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo',
|
||||
'qp_id_%s' % k, 'port-%s' % k, True,
|
||||
['192.168.0.%s' % k], '00:11:22:33:44:55')['uuid']
|
||||
for k in range(3)]
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 3)
|
||||
for res_port in ports:
|
||||
self.assertIn(res_port['uuid'], router_port_uuids)
|
||||
|
||||
def test_query_lrouter_lports_nonexistent_lrouter_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, routerlib.create_router_lport,
|
||||
self.fake_cluster, 'booo', 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def test_create_and_get_lrouter_port(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
port_tags = self._build_tag_dict(res_port['tags'])
|
||||
self.assertEqual(['192.168.0.1'], res_port['ip_addresses'])
|
||||
self.assertIn('os_tid', port_tags)
|
||||
self.assertIn('q_port_id', port_tags)
|
||||
self.assertEqual('pippo', port_tags['os_tid'])
|
||||
self.assertEqual('neutron_port_id', port_tags['q_port_id'])
|
||||
|
||||
def test_create_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, routerlib.create_router_lport,
|
||||
self.fake_cluster, 'booo', 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def test_update_lrouter_port(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
routerlib.update_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
'pippo', 'another_port_id', 'name', False,
|
||||
['192.168.0.1', '10.10.10.254'])
|
||||
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
port_tags = self._build_tag_dict(res_port['tags'])
|
||||
self.assertEqual(['192.168.0.1', '10.10.10.254'],
|
||||
res_port['ip_addresses'])
|
||||
self.assertEqual('False', res_port['admin_status_enabled'])
|
||||
self.assertIn('os_tid', port_tags)
|
||||
self.assertIn('q_port_id', port_tags)
|
||||
self.assertEqual('pippo', port_tags['os_tid'])
|
||||
self.assertEqual('another_port_id', port_tags['q_port_id'])
|
||||
|
||||
def test_update_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, routerlib.update_router_lport,
|
||||
self.fake_cluster, 'boo-router', 'boo-port', 'pippo',
|
||||
'neutron_port_id', 'name', True, ['192.168.0.1'])
|
||||
|
||||
def test_update_lrouter_port_nonexistent_port_raises(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, routerlib.update_router_lport,
|
||||
self.fake_cluster, lrouter['uuid'], 'boo-port', 'pippo',
|
||||
'neutron_port_id', 'name', True, ['192.168.0.1'])
|
||||
|
||||
def test_delete_lrouter_port(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [],
|
||||
'00:11:22:33:44:55')
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
routerlib.delete_router_lport(self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'])
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertFalse(len(ports))
|
||||
|
||||
def test_delete_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
routerlib.delete_router_lport,
|
||||
self.fake_cluster, 'xyz', 'abc')
|
||||
|
||||
def test_delete_lrouter_port_nonexistent_port_raises(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
routerlib.delete_router_lport,
|
||||
self.fake_cluster, lrouter['uuid'], 'abc')
|
||||
|
||||
def test_delete_peer_lrouter_port(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [],
|
||||
'00:11:22:33:44:55')
|
||||
|
||||
def fakegetport(*args, **kwargs):
|
||||
return {'_relations': {'LogicalPortAttachment':
|
||||
{'peer_port_uuid': lrouter_port['uuid']}}}
|
||||
# mock get_port
|
||||
with mock.patch.object(routerlib, 'get_port', new=fakegetport):
|
||||
routerlib.delete_peer_router_lport(self.fake_cluster,
|
||||
lrouter_port['uuid'],
|
||||
'whatwever', 'whatever')
|
||||
|
||||
def test_update_lrouter_port_ips_add_only(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
routerlib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
['10.10.10.254'], [])
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['10.10.10.254', '192.168.0.1'],
|
||||
res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_remove_only(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1', '10.10.10.254'],
|
||||
'00:11:22:33:44:55')
|
||||
routerlib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
[], ['10.10.10.254'])
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['192.168.0.1'], res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_add_and_remove(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
routerlib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
['10.10.10.254'], ['192.168.0.1'])
|
||||
ports = routerlib.query_lrouter_lports(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['10.10.10.254'], res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpPluginException, routerlib.update_lrouter_port_ips,
|
||||
self.fake_cluster, 'boo-router', 'boo-port', [], [])
|
||||
|
||||
def test_update_lrouter_port_ips_nsx_exception_raises(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def raise_nsx_exc(*args, **kwargs):
|
||||
raise NvpApiClient.NvpApiException()
|
||||
|
||||
with mock.patch.object(routerlib, 'do_request', new=raise_nsx_exc):
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpPluginException, routerlib.update_lrouter_port_ips,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'], [], [])
|
||||
|
||||
def test_plug_lrouter_port_patch_attachment(self):
|
||||
tenant_id = 'pippo'
|
||||
transport_zones_config = [{'zone_uuid': _uuid(),
|
||||
'transport_type': 'stt'}]
|
||||
lswitch = nvplib.create_lswitch(self.fake_cluster,
|
||||
_uuid(),
|
||||
tenant_id, 'fake-switch',
|
||||
transport_zones_config)
|
||||
lport = nvplib.create_lport(self.fake_cluster, lswitch['uuid'],
|
||||
tenant_id, 'xyz',
|
||||
'name', 'device_id', True)
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66')
|
||||
result = routerlib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
lport['uuid'], 'PatchAttachment')
|
||||
self.assertEqual(lport['uuid'],
|
||||
result['LogicalPortAttachment']['peer_port_uuid'])
|
||||
|
||||
def test_plug_lrouter_port_l3_gw_attachment(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66')
|
||||
result = routerlib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
'gw_att', 'L3GatewayAttachment')
|
||||
self.assertEqual(
|
||||
'gw_att',
|
||||
result['LogicalPortAttachment']['l3_gateway_service_uuid'])
|
||||
|
||||
def test_plug_lrouter_port_l3_gw_attachment_with_vlan(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
result = routerlib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
'gw_att', 'L3GatewayAttachment', 123)
|
||||
self.assertEqual(
|
||||
'gw_att',
|
||||
result['LogicalPortAttachment']['l3_gateway_service_uuid'])
|
||||
self.assertEqual(
|
||||
'123',
|
||||
result['LogicalPortAttachment']['vlan_id'])
|
||||
|
||||
def test_plug_lrouter_port_invalid_attachment_type_raises(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = routerlib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
self.assertRaises(nvp_exc.NvpInvalidAttachmentType,
|
||||
routerlib.plug_router_port_attachment,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'], 'gw_att', 'BadType')
|
||||
|
||||
def _test_create_router_snat_rule(self, version):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=200,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.24'})
|
||||
rules = routerlib.query_nat_rules(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 1)
|
||||
|
||||
def test_create_router_snat_rule_v3(self):
|
||||
self._test_create_router_snat_rule('3.0')
|
||||
|
||||
def test_create_router_snat_rule_v2(self):
|
||||
self._test_create_router_snat_rule('2.0')
|
||||
|
||||
def _test_create_router_dnat_rule(self, version, dest_port=None):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
routerlib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200,
|
||||
dest_port=dest_port,
|
||||
match_criteria={'destination_ip_addresses': '10.0.0.3'})
|
||||
rules = routerlib.query_nat_rules(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 1)
|
||||
|
||||
def test_create_router_dnat_rule_v3(self):
|
||||
self._test_create_router_dnat_rule('3.0')
|
||||
|
||||
def test_create_router_dnat_rule_v2(self):
|
||||
self._test_create_router_dnat_rule('2.0')
|
||||
|
||||
def test_create_router_dnat_rule_v2_with_destination_port(self):
|
||||
self._test_create_router_dnat_rule('2.0', 8080)
|
||||
|
||||
def test_create_router_dnat_rule_v3_with_destination_port(self):
|
||||
self._test_create_router_dnat_rule('3.0', 8080)
|
||||
|
||||
def test_create_router_snat_rule_invalid_match_keys_raises(self):
|
||||
# In this case the version does not make a difference
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: '2.0'):
|
||||
self.assertRaises(AttributeError,
|
||||
routerlib.create_lrouter_snat_rule,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=200,
|
||||
match_criteria={'foo': 'bar'})
|
||||
|
||||
def _test_create_router_nosnat_rule(self, version, expected=1):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
routerlib.create_lrouter_nosnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
order=100,
|
||||
match_criteria={'destination_ip_addresses': '192.168.0.0/24'})
|
||||
rules = routerlib.query_nat_rules(
|
||||
self.fake_cluster, lrouter['uuid'])
|
||||
# NoSNAT rules do not exist in V2
|
||||
self.assertEqual(len(rules), expected)
|
||||
|
||||
def test_create_router_nosnat_rule_v2(self):
|
||||
self._test_create_router_nosnat_rule('2.0', expected=0)
|
||||
|
||||
def test_create_router_nosnat_rule_v3(self):
|
||||
self._test_create_router_nosnat_rule('3.0')
|
||||
|
||||
def _prepare_nat_rules_for_delete_tests(self):
|
||||
lrouter = routerlib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
# v2 or v3 makes no difference for this test
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion('2.0')):
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=220,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.0/24'})
|
||||
routerlib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.3', '10.0.0.3', order=200,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.2/32'})
|
||||
routerlib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200,
|
||||
match_criteria={'destination_ip_addresses': '10.0.0.3'})
|
||||
return lrouter
|
||||
|
||||
def test_delete_router_nat_rules_by_match_on_destination_ip(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 1, 1,
|
||||
destination_ip_addresses='10.0.0.3')
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 2)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_on_source_ip(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'SourceNatRule', 1, 1,
|
||||
source_ip_addresses='192.168.0.2/32')
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 2)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_no_match_expected(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'SomeWeirdType', 0)
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
routerlib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 0,
|
||||
destination_ip_addresses='99.99.99.99')
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_no_match_raises(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = routerlib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpNatRuleMismatch,
|
||||
routerlib.delete_nat_rules_by_match,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'SomeWeirdType', 1, 1)
|
57
neutron/tests/unit/nicira/nsxlib/test_versioning.py
Normal file
57
neutron/tests/unit/nicira/nsxlib/test_versioning.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2014 VMware, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||
from neutron.plugins.nicira.nsxlib import versioning
|
||||
from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
class TestVersioning(base.BaseTestCase):
|
||||
|
||||
def test_function_handling_missing_minor(self):
|
||||
version = NvpApiClient.NVPVersion('2.0')
|
||||
function = versioning.get_function_by_version(
|
||||
routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version)
|
||||
self.assertEqual(routerlib.create_implicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_both_major_and_minor(self):
|
||||
version = NvpApiClient.NVPVersion('3.2')
|
||||
function = versioning.get_function_by_version(
|
||||
routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version)
|
||||
self.assertEqual(routerlib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_newer_major(self):
|
||||
version = NvpApiClient.NVPVersion('5.2')
|
||||
function = versioning.get_function_by_version(
|
||||
routerlib.ROUTER_FUNC_DICT, 'create_lrouter', version)
|
||||
self.assertEqual(routerlib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_obsolete_major(self):
|
||||
version = NvpApiClient.NVPVersion('1.2')
|
||||
self.assertRaises(NotImplementedError,
|
||||
versioning.get_function_by_version,
|
||||
routerlib.ROUTER_FUNC_DICT,
|
||||
'create_lrouter', version)
|
||||
|
||||
def test_function_handling_with_unknown_version(self):
|
||||
self.assertRaises(NvpApiClient.ServiceUnavailable,
|
||||
versioning.get_function_by_version,
|
||||
routerlib.ROUTER_FUNC_DICT,
|
||||
'create_lrouter', None)
|
@ -638,7 +638,7 @@ class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
||||
self._test_router_create_with_distributed(True, True)
|
||||
|
||||
def test_router_create_distributed_with_new_nvp_versions(self):
|
||||
with mock.patch.object(nvplib, 'create_explicit_route_lrouter'):
|
||||
with mock.patch.object(nsxlib.router, 'create_explicit_route_lrouter'):
|
||||
self._test_router_create_with_distributed(True, True, '3.2')
|
||||
self._test_router_create_with_distributed(True, True, '4.0')
|
||||
self._test_router_create_with_distributed(True, True, '4.1')
|
||||
@ -655,12 +655,13 @@ class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
||||
def test_router_create_on_obsolete_platform(self):
|
||||
|
||||
def obsolete_response(*args, **kwargs):
|
||||
response = nvplib._create_implicit_routing_lrouter(*args, **kwargs)
|
||||
response = (nsxlib.router.
|
||||
_create_implicit_routing_lrouter(*args, **kwargs))
|
||||
response.pop('distributed')
|
||||
return response
|
||||
|
||||
with mock.patch.object(
|
||||
nvplib, 'create_lrouter', new=obsolete_response):
|
||||
nsxlib.router, 'create_lrouter', new=obsolete_response):
|
||||
self._test_router_create_with_distributed(None, False, '2.2')
|
||||
|
||||
def _create_router_with_gw_info_for_test(self, subnet):
|
||||
@ -673,7 +674,7 @@ class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
||||
return router_req.get_response(self.ext_api)
|
||||
|
||||
def test_router_create_nvp_error_returns_500(self, vlan_id=None):
|
||||
with mock.patch.object(nvplib,
|
||||
with mock.patch.object(nsxlib.router,
|
||||
'create_router_lport',
|
||||
side_effect=NvpApiClient.NvpApiException):
|
||||
with self._create_l3_ext_network(vlan_id) as net:
|
||||
@ -1019,7 +1020,7 @@ class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
||||
with self._create_l3_ext_network() as net:
|
||||
with self.subnet(network=net) as s:
|
||||
with mock.patch.object(
|
||||
nvplib,
|
||||
nsxlib.router,
|
||||
'do_request',
|
||||
side_effect=nvp_exc.MaintenanceInProgress):
|
||||
data = {'router': {'tenant_id': 'whatever'}}
|
||||
|
@ -171,7 +171,8 @@ class NsxUtilsTestCase(base.BaseTestCase):
|
||||
# found for a given port identifier
|
||||
exp_lr_uuid = uuidutils.generate_uuid()
|
||||
self._mock_router_mapping_db_calls(None)
|
||||
with mock.patch(nicira_method('query_lrouters'),
|
||||
with mock.patch(nicira_method('query_lrouters',
|
||||
module_name='nsxlib.router'),
|
||||
return_value=[{'uuid': exp_lr_uuid}]):
|
||||
self._verify_get_nsx_router_id(exp_lr_uuid)
|
||||
|
||||
@ -179,6 +180,7 @@ class NsxUtilsTestCase(base.BaseTestCase):
|
||||
# This test verifies that the function returns None if the mapping
|
||||
# are not found both in the db and in the backend
|
||||
self._mock_router_mapping_db_calls(None)
|
||||
with mock.patch(nicira_method('query_lrouters'),
|
||||
with mock.patch(nicira_method('query_lrouters',
|
||||
module_name='nsxlib.router'),
|
||||
return_value=[]):
|
||||
self._verify_get_nsx_router_id(None)
|
||||
|
@ -22,7 +22,6 @@ import mock
|
||||
|
||||
from neutron.common import constants
|
||||
from neutron.common import exceptions
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.nicira.common import config # noqa
|
||||
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||
from neutron.plugins.nicira.common import utils
|
||||
@ -31,7 +30,6 @@ from neutron.plugins.nicira import NvpApiClient
|
||||
from neutron.plugins.nicira import nvplib
|
||||
from neutron.tests import base
|
||||
from neutron.tests.unit.nicira import fake_nvpapiclient
|
||||
from neutron.tests.unit.nicira import nicira_method
|
||||
from neutron.tests.unit.nicira import NVPAPI_NAME
|
||||
from neutron.tests.unit.nicira import STUBS_PATH
|
||||
from neutron.tests.unit import test_api_v2
|
||||
@ -74,38 +72,7 @@ class NvplibTestCase(base.BaseTestCase):
|
||||
return dict((t['scope'], t['tag']) for t in tags)
|
||||
|
||||
|
||||
class TestNvplibNatRules(NvplibTestCase):
|
||||
|
||||
def _test_create_lrouter_dnat_rule(self, version):
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
tenant_id = 'pippo'
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
'fake_router',
|
||||
'192.168.0.1')
|
||||
nat_rule = nvplib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '10.0.0.99',
|
||||
match_criteria={'destination_ip_addresses':
|
||||
'192.168.0.5'})
|
||||
uri = nvplib._build_uri_path(nvplib.LROUTERNAT_RESOURCE,
|
||||
nat_rule['uuid'],
|
||||
lrouter['uuid'])
|
||||
resp_obj = nvplib.do_request("GET", uri, cluster=self.fake_cluster)
|
||||
self.assertEqual('DestinationNatRule', resp_obj['type'])
|
||||
self.assertEqual('192.168.0.5',
|
||||
resp_obj['match']['destination_ip_addresses'])
|
||||
|
||||
def test_create_lrouter_dnat_rule_v2(self):
|
||||
self._test_create_lrouter_dnat_rule('2.9')
|
||||
|
||||
def test_create_lrouter_dnat_rule_v31(self):
|
||||
self._test_create_lrouter_dnat_rule('3.1')
|
||||
|
||||
|
||||
class NvplibNegativeTests(base.BaseTestCase):
|
||||
class NsxlibNegativeBaseTestCase(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
# mock nvp api client
|
||||
@ -132,10 +99,13 @@ class NvplibNegativeTests(base.BaseTestCase):
|
||||
self.fake_cluster.req_timeout, self.fake_cluster.http_timeout,
|
||||
self.fake_cluster.retries, self.fake_cluster.redirects)
|
||||
|
||||
super(NvplibNegativeTests, self).setUp()
|
||||
super(NsxlibNegativeBaseTestCase, self).setUp()
|
||||
self.addCleanup(self.fc.reset_all)
|
||||
self.addCleanup(self.mock_nvpapi.stop)
|
||||
|
||||
|
||||
class L2GatewayNegativeTestCase(NsxlibNegativeBaseTestCase):
|
||||
|
||||
def test_create_l2_gw_service_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
nvplib.create_l2_gw_service,
|
||||
@ -164,35 +134,6 @@ class NvplibNegativeTests(base.BaseTestCase):
|
||||
'fake-gateway',
|
||||
'pluto')
|
||||
|
||||
def test_create_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
nvplib.create_lrouter,
|
||||
self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pluto',
|
||||
'fake_router',
|
||||
'my_hop')
|
||||
|
||||
def test_delete_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
nvplib.delete_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router')
|
||||
|
||||
def test_get_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
nvplib.get_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router')
|
||||
|
||||
def test_update_lrouter_on_failure(self):
|
||||
self.assertRaises(nvplib.NvpApiClient.NvpApiException,
|
||||
nvplib.update_lrouter,
|
||||
self.fake_cluster,
|
||||
'fake_router',
|
||||
'pluto',
|
||||
'new_hop')
|
||||
|
||||
|
||||
class TestNvplibL2Gateway(NvplibTestCase):
|
||||
|
||||
@ -404,824 +345,6 @@ class TestNvplibLogicalSwitches(NvplibTestCase):
|
||||
self.fake_cluster, 'whatever', ['whatever'])
|
||||
|
||||
|
||||
class TestNvplibExplicitLRouters(NvplibTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.fake_version = '3.2'
|
||||
super(TestNvplibExplicitLRouters, self).setUp()
|
||||
|
||||
def _get_lrouter(self, tenant_id, router_name, router_id, relations=None):
|
||||
schema = '/ws.v1/schema/RoutingTableRoutingConfig'
|
||||
|
||||
router = {'display_name': router_name,
|
||||
'uuid': router_id,
|
||||
'tags': [{'scope': 'quantum', 'tag': nvplib.NEUTRON_VERSION},
|
||||
{'scope': 'os_tid', 'tag': '%s' % tenant_id}],
|
||||
'distributed': False,
|
||||
'routing_config': {'type': 'RoutingTableRoutingConfig',
|
||||
'_schema': schema},
|
||||
'_schema': schema,
|
||||
'nat_synchronization_enabled': True,
|
||||
'replication_mode': 'service',
|
||||
'type': 'LogicalRouterConfig',
|
||||
'_href': '/ws.v1/lrouter/%s' % router_id, }
|
||||
if relations:
|
||||
router['_relations'] = relations
|
||||
return router
|
||||
|
||||
def _get_single_route(self, router_id, route_id='fake_route_id_0',
|
||||
prefix='0.0.0.0/0', next_hop_ip='1.1.1.1'):
|
||||
return {'protocol': 'static',
|
||||
'_href': '/ws.v1/lrouter/%s/rib/%s' % (router_id, route_id),
|
||||
'prefix': prefix,
|
||||
'_schema': '/ws.v1/schema/RoutingTableEntry',
|
||||
'next_hop_ip': next_hop_ip,
|
||||
'action': 'accept',
|
||||
'uuid': route_id}
|
||||
|
||||
def test_prepare_body_with_implicit_routing_config(self):
|
||||
router_name = 'fake_router_name'
|
||||
tenant_id = 'fake_tenant_id'
|
||||
neutron_router_id = 'pipita_higuain'
|
||||
router_type = 'SingleDefaultRouteImplicitRoutingConfig'
|
||||
route_config = {
|
||||
'default_route_next_hop': {'gateway_ip_address': 'fake_address',
|
||||
'type': 'RouterNextHop'}, }
|
||||
body = nvplib._prepare_lrouter_body(router_name, neutron_router_id,
|
||||
tenant_id, router_type,
|
||||
**route_config)
|
||||
expected = {'display_name': 'fake_router_name',
|
||||
'routing_config': {
|
||||
'default_route_next_hop':
|
||||
{'gateway_ip_address': 'fake_address',
|
||||
'type': 'RouterNextHop'},
|
||||
'type': 'SingleDefaultRouteImplicitRoutingConfig'},
|
||||
'tags': [{'scope': 'os_tid', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'q_router_id', 'tag': 'pipita_higuain'},
|
||||
{'scope': 'quantum',
|
||||
'tag': nvplib.NEUTRON_VERSION}],
|
||||
'type': 'LogicalRouterConfig'}
|
||||
self.assertEqual(expected, body)
|
||||
|
||||
def test_prepare_body_without_routing_config(self):
|
||||
router_name = 'fake_router_name'
|
||||
tenant_id = 'fake_tenant_id'
|
||||
router_type = 'RoutingTableRoutingConfig'
|
||||
neutron_router_id = 'marekiaro_hamsik'
|
||||
body = nvplib._prepare_lrouter_body(router_name, neutron_router_id,
|
||||
tenant_id, router_type)
|
||||
expected = {'display_name': 'fake_router_name',
|
||||
'routing_config': {'type': 'RoutingTableRoutingConfig'},
|
||||
'tags': [{'scope': 'os_tid', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'q_router_id',
|
||||
'tag': 'marekiaro_hamsik'},
|
||||
{'scope': 'quantum',
|
||||
'tag': nvplib.NEUTRON_VERSION}],
|
||||
'type': 'LogicalRouterConfig'}
|
||||
self.assertEqual(expected, body)
|
||||
|
||||
def test_get_lrouter(self):
|
||||
tenant_id = 'fake_tenant_id'
|
||||
router_name = 'fake_router_name'
|
||||
router_id = 'fake_router_id'
|
||||
relations = {
|
||||
'LogicalRouterStatus':
|
||||
{'_href': '/ws.v1/lrouter/%s/status' % router_id,
|
||||
'lport_admin_up_count': 1,
|
||||
'_schema': '/ws.v1/schema/LogicalRouterStatus',
|
||||
'lport_count': 1,
|
||||
'fabric_status': True,
|
||||
'type': 'LogicalRouterStatus',
|
||||
'lport_link_up_count': 0, }, }
|
||||
|
||||
with mock.patch(nicira_method('do_request'),
|
||||
return_value=self._get_lrouter(tenant_id,
|
||||
router_name,
|
||||
router_id,
|
||||
relations)):
|
||||
lrouter = nvplib.get_lrouter(self.fake_cluster, router_id)
|
||||
self.assertTrue(
|
||||
lrouter['_relations']['LogicalRouterStatus']['fabric_status'])
|
||||
|
||||
def test_create_lrouter(self):
|
||||
tenant_id = 'fake_tenant_id'
|
||||
router_name = 'fake_router_name'
|
||||
router_id = 'fake_router_id'
|
||||
nexthop_ip = '10.0.0.1'
|
||||
with mock.patch(nicira_method('do_request'),
|
||||
return_value=self._get_lrouter(tenant_id,
|
||||
router_name,
|
||||
router_id)):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
router_name, nexthop_ip)
|
||||
self.assertEqual(lrouter['routing_config']['type'],
|
||||
'RoutingTableRoutingConfig')
|
||||
self.assertNotIn('default_route_next_hop',
|
||||
lrouter['routing_config'])
|
||||
|
||||
def test_update_lrouter_nvp_with_no_routes(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nvp_routes = [self._get_single_route(router_id)]
|
||||
with mock.patch(nicira_method('get_explicit_routes_lrouter'),
|
||||
return_value=nvp_routes):
|
||||
with mock.patch(nicira_method('create_explicit_route_lrouter'),
|
||||
return_value='fake_uuid'):
|
||||
old_routes = nvplib.update_explicit_routes_lrouter(
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
self.assertEqual(old_routes, nvp_routes)
|
||||
|
||||
def test_update_lrouter_nvp_with_no_routes_raise_nvp_exception(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nvp_routes = [self._get_single_route(router_id)]
|
||||
with mock.patch(nicira_method('get_explicit_routes_lrouter'),
|
||||
return_value=nvp_routes):
|
||||
with mock.patch(nicira_method('create_explicit_route_lrouter'),
|
||||
side_effect=NvpApiClient.NvpApiException):
|
||||
self.assertRaises(NvpApiClient.NvpApiException,
|
||||
nvplib.update_explicit_routes_lrouter,
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
|
||||
def test_update_lrouter_with_routes(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"next_hop_ip": "10.0.0.2",
|
||||
"prefix": "169.254.169.0/30"}, ]
|
||||
|
||||
nvp_routes = [self._get_single_route(router_id),
|
||||
self._get_single_route(router_id, 'fake_route_id_1',
|
||||
'0.0.0.1/24', '10.0.0.3'),
|
||||
self._get_single_route(router_id, 'fake_route_id_2',
|
||||
'0.0.0.2/24', '10.0.0.4'), ]
|
||||
|
||||
with mock.patch(nicira_method('get_explicit_routes_lrouter'),
|
||||
return_value=nvp_routes):
|
||||
with mock.patch(nicira_method('delete_explicit_route_lrouter'),
|
||||
return_value=None):
|
||||
with mock.patch(nicira_method(
|
||||
'create_explicit_route_lrouter'),
|
||||
return_value='fake_uuid'):
|
||||
old_routes = nvplib.update_explicit_routes_lrouter(
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
self.assertEqual(old_routes, nvp_routes)
|
||||
|
||||
def test_update_lrouter_with_routes_raises_nvp_expception(self):
|
||||
router_id = 'fake_router_id'
|
||||
new_routes = [{"nexthop": "10.0.0.2",
|
||||
"destination": "169.254.169.0/30"}, ]
|
||||
|
||||
nvp_routes = [self._get_single_route(router_id),
|
||||
self._get_single_route(router_id, 'fake_route_id_1',
|
||||
'0.0.0.1/24', '10.0.0.3'),
|
||||
self._get_single_route(router_id, 'fake_route_id_2',
|
||||
'0.0.0.2/24', '10.0.0.4'), ]
|
||||
|
||||
with mock.patch(nicira_method('get_explicit_routes_lrouter'),
|
||||
return_value=nvp_routes):
|
||||
with mock.patch(nicira_method('delete_explicit_route_lrouter'),
|
||||
side_effect=NvpApiClient.NvpApiException):
|
||||
with mock.patch(
|
||||
nicira_method('create_explicit_route_lrouter'),
|
||||
return_value='fake_uuid'):
|
||||
self.assertRaises(
|
||||
NvpApiClient.NvpApiException,
|
||||
nvplib.update_explicit_routes_lrouter,
|
||||
self.fake_cluster, router_id, new_routes)
|
||||
|
||||
|
||||
class TestNvplibLogicalRouters(NvplibTestCase):
|
||||
|
||||
def _verify_lrouter(self, res_lrouter,
|
||||
expected_uuid,
|
||||
expected_display_name,
|
||||
expected_nexthop,
|
||||
expected_tenant_id,
|
||||
expected_neutron_id=None,
|
||||
expected_distributed=None):
|
||||
self.assertEqual(res_lrouter['uuid'], expected_uuid)
|
||||
nexthop = (res_lrouter['routing_config']
|
||||
['default_route_next_hop']['gateway_ip_address'])
|
||||
self.assertEqual(nexthop, expected_nexthop)
|
||||
router_tags = self._build_tag_dict(res_lrouter['tags'])
|
||||
self.assertIn('os_tid', router_tags)
|
||||
self.assertEqual(res_lrouter['display_name'], expected_display_name)
|
||||
self.assertEqual(expected_tenant_id, router_tags['os_tid'])
|
||||
if expected_distributed is not None:
|
||||
self.assertEqual(expected_distributed,
|
||||
res_lrouter['distributed'])
|
||||
if expected_neutron_id:
|
||||
self.assertIn('q_router_id', router_tags)
|
||||
self.assertEqual(expected_neutron_id, router_tags['q_router_id'])
|
||||
|
||||
def test_get_lrouters(self):
|
||||
lrouter_uuids = [nvplib.create_lrouter(
|
||||
self.fake_cluster, 'whatever', 'pippo', 'fake-lrouter-%s' % k,
|
||||
'10.0.0.1')['uuid'] for k in range(3)]
|
||||
routers = nvplib.get_lrouters(self.fake_cluster, 'pippo')
|
||||
for router in routers:
|
||||
self.assertIn(router['uuid'], lrouter_uuids)
|
||||
|
||||
def _create_lrouter(self, version, neutron_id=None, distributed=None):
|
||||
with mock.patch.object(
|
||||
self.fake_cluster.api_client, 'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
if not neutron_id:
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = nvplib.create_lrouter(
|
||||
self.fake_cluster, neutron_id, 'pippo',
|
||||
'fake-lrouter', '10.0.0.1', distributed=distributed)
|
||||
return nvplib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
|
||||
def test_create_and_get_lrouter_v30(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.0', neutron_id=neutron_id)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
neutron_id)
|
||||
|
||||
def test_create_and_get_lrouter_v31_centralized(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id,
|
||||
distributed=False)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id,
|
||||
expected_distributed=False)
|
||||
|
||||
def test_create_and_get_lrouter_v31_distributed(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
res_lrouter = self._create_lrouter('3.1', neutron_id=neutron_id,
|
||||
distributed=True)
|
||||
self._verify_lrouter(res_lrouter, res_lrouter['uuid'],
|
||||
'fake-lrouter', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id,
|
||||
expected_distributed=True)
|
||||
|
||||
def test_create_and_get_lrouter_name_exceeds_40chars(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
display_name = '*' * 50
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
display_name,
|
||||
'10.0.0.1')
|
||||
res_lrouter = nvplib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'*' * 40, '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def _test_version_dependent_update_lrouter(self, version):
|
||||
def foo(*args, **kwargs):
|
||||
return version
|
||||
|
||||
foo_func_dict = {
|
||||
'update_lrouter': {
|
||||
2: {-1: foo},
|
||||
3: {-1: foo, 2: foo}
|
||||
}
|
||||
}
|
||||
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
with mock.patch.dict(nvplib.NVPLIB_FUNC_DICT,
|
||||
foo_func_dict, clear=True):
|
||||
return nvplib.update_lrouter(
|
||||
self.fake_cluster, 'foo_router_id', 'foo_router_name',
|
||||
'foo_nexthop', routes={'foo_destination': 'foo_address'})
|
||||
|
||||
def test_version_dependent_update_lrouter_old_versions(self):
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"2.9")
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"3.0")
|
||||
self.assertRaises(nvp_exc.NvpInvalidVersion,
|
||||
self._test_version_dependent_update_lrouter,
|
||||
"3.1")
|
||||
|
||||
def test_version_dependent_update_lrouter_new_versions(self):
|
||||
self.assertEqual("3.2",
|
||||
self._test_version_dependent_update_lrouter("3.2"))
|
||||
self.assertEqual("4.0",
|
||||
self._test_version_dependent_update_lrouter("4.0"))
|
||||
self.assertEqual("4.1",
|
||||
self._test_version_dependent_update_lrouter("4.1"))
|
||||
|
||||
def test_update_lrouter_no_nexthop(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter = nvplib.update_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'],
|
||||
'new_name',
|
||||
None)
|
||||
res_lrouter = nvplib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'new_name', '10.0.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def test_update_lrouter(self):
|
||||
neutron_id = uuidutils.generate_uuid()
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
neutron_id,
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter = nvplib.update_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'],
|
||||
'new_name',
|
||||
'192.168.0.1')
|
||||
res_lrouter = nvplib.get_lrouter(self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
self._verify_lrouter(res_lrouter, lrouter['uuid'],
|
||||
'new_name', '192.168.0.1', 'pippo',
|
||||
expected_neutron_id=neutron_id)
|
||||
|
||||
def test_update_nonexistent_lrouter_raises(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
nvplib.update_lrouter,
|
||||
self.fake_cluster,
|
||||
'whatever',
|
||||
'foo', '9.9.9.9')
|
||||
|
||||
def test_delete_lrouter(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
nvplib.delete_lrouter(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
nvplib.get_lrouter,
|
||||
self.fake_cluster,
|
||||
lrouter['uuid'])
|
||||
|
||||
def test_query_lrouter_ports(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
router_port_uuids = [nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo',
|
||||
'qp_id_%s' % k, 'port-%s' % k, True,
|
||||
['192.168.0.%s' % k], '00:11:22:33:44:55')['uuid']
|
||||
for k in range(3)]
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 3)
|
||||
for res_port in ports:
|
||||
self.assertIn(res_port['uuid'], router_port_uuids)
|
||||
|
||||
def test_query_lrouter_lports_nonexistent_lrouter_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, nvplib.create_router_lport,
|
||||
self.fake_cluster, 'booo', 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def test_create_and_get_lrouter_port(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
port_tags = self._build_tag_dict(res_port['tags'])
|
||||
self.assertEqual(['192.168.0.1'], res_port['ip_addresses'])
|
||||
self.assertIn('os_tid', port_tags)
|
||||
self.assertIn('q_port_id', port_tags)
|
||||
self.assertEqual('pippo', port_tags['os_tid'])
|
||||
self.assertEqual('neutron_port_id', port_tags['q_port_id'])
|
||||
|
||||
def test_create_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, nvplib.create_router_lport,
|
||||
self.fake_cluster, 'booo', 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def test_update_lrouter_port(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
nvplib.update_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
'pippo', 'another_port_id', 'name', False,
|
||||
['192.168.0.1', '10.10.10.254'])
|
||||
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
port_tags = self._build_tag_dict(res_port['tags'])
|
||||
self.assertEqual(['192.168.0.1', '10.10.10.254'],
|
||||
res_port['ip_addresses'])
|
||||
self.assertEqual('False', res_port['admin_status_enabled'])
|
||||
self.assertIn('os_tid', port_tags)
|
||||
self.assertIn('q_port_id', port_tags)
|
||||
self.assertEqual('pippo', port_tags['os_tid'])
|
||||
self.assertEqual('another_port_id', port_tags['q_port_id'])
|
||||
|
||||
def test_update_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, nvplib.update_router_lport,
|
||||
self.fake_cluster, 'boo-router', 'boo-port', 'pippo',
|
||||
'neutron_port_id', 'name', True, ['192.168.0.1'])
|
||||
|
||||
def test_update_lrouter_port_nonexistent_port_raises(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
self.assertRaises(
|
||||
exceptions.NotFound, nvplib.update_router_lport,
|
||||
self.fake_cluster, lrouter['uuid'], 'boo-port', 'pippo',
|
||||
'neutron_port_id', 'name', True, ['192.168.0.1'])
|
||||
|
||||
def test_delete_lrouter_port(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [],
|
||||
'00:11:22:33:44:55')
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
nvplib.delete_router_lport(self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'])
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertFalse(len(ports))
|
||||
|
||||
def test_delete_lrouter_port_nonexistent_router_raises(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
nvplib.delete_router_lport,
|
||||
self.fake_cluster, 'xyz', 'abc')
|
||||
|
||||
def test_delete_lrouter_port_nonexistent_port_raises(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
nvplib.delete_router_lport,
|
||||
self.fake_cluster, lrouter['uuid'], 'abc')
|
||||
|
||||
def test_delete_peer_lrouter_port(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'x', 'y', True, [],
|
||||
'00:11:22:33:44:55')
|
||||
|
||||
def fakegetport(*args, **kwargs):
|
||||
return {'_relations': {'LogicalPortAttachment':
|
||||
{'peer_port_uuid': lrouter_port['uuid']}}}
|
||||
# mock get_port
|
||||
with mock.patch.object(nvplib, 'get_port', new=fakegetport):
|
||||
nvplib.delete_peer_router_lport(self.fake_cluster,
|
||||
lrouter_port['uuid'],
|
||||
'whatwever', 'whatever')
|
||||
|
||||
def test_update_lrouter_port_ips_add_only(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
nvplib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
['10.10.10.254'], [])
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['10.10.10.254', '192.168.0.1'],
|
||||
res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_remove_only(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1', '10.10.10.254'],
|
||||
'00:11:22:33:44:55')
|
||||
nvplib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
[], ['10.10.10.254'])
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['192.168.0.1'], res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_add_and_remove(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
nvplib.update_lrouter_port_ips(
|
||||
self.fake_cluster, lrouter['uuid'], lrouter_port['uuid'],
|
||||
['10.10.10.254'], ['192.168.0.1'])
|
||||
ports = nvplib.query_lrouter_lports(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(ports), 1)
|
||||
res_port = ports[0]
|
||||
self.assertEqual(['10.10.10.254'], res_port['ip_addresses'])
|
||||
|
||||
def test_update_lrouter_port_ips_nonexistent_router_raises(self):
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpPluginException, nvplib.update_lrouter_port_ips,
|
||||
self.fake_cluster, 'boo-router', 'boo-port', [], [])
|
||||
|
||||
def test_update_lrouter_port_ips_nvp_exception_raises(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
|
||||
def raise_nvp_exc(*args, **kwargs):
|
||||
raise NvpApiClient.NvpApiException()
|
||||
|
||||
with mock.patch.object(nvplib, 'do_request', new=raise_nvp_exc):
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpPluginException, nvplib.update_lrouter_port_ips,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'], [], [])
|
||||
|
||||
def test_plug_lrouter_port_patch_attachment(self):
|
||||
tenant_id = 'pippo'
|
||||
transport_zones_config = [{'zone_uuid': _uuid(),
|
||||
'transport_type': 'stt'}]
|
||||
lswitch = nvplib.create_lswitch(self.fake_cluster,
|
||||
_uuid(),
|
||||
tenant_id, 'fake-switch',
|
||||
transport_zones_config)
|
||||
lport = nvplib.create_lport(self.fake_cluster, lswitch['uuid'],
|
||||
tenant_id, 'xyz',
|
||||
'name', 'device_id', True)
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
tenant_id,
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66')
|
||||
result = nvplib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
lport['uuid'], 'PatchAttachment')
|
||||
self.assertEqual(lport['uuid'],
|
||||
result['LogicalPortAttachment']['peer_port_uuid'])
|
||||
|
||||
def test_plug_lrouter_port_l3_gw_attachment(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55:66')
|
||||
result = nvplib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
'gw_att', 'L3GatewayAttachment')
|
||||
self.assertEqual(
|
||||
'gw_att',
|
||||
result['LogicalPortAttachment']['l3_gateway_service_uuid'])
|
||||
|
||||
def test_plug_lrouter_port_l3_gw_attachment_with_vlan(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
result = nvplib.plug_router_port_attachment(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'],
|
||||
'gw_att', 'L3GatewayAttachment', 123)
|
||||
self.assertEqual(
|
||||
'gw_att',
|
||||
result['LogicalPortAttachment']['l3_gateway_service_uuid'])
|
||||
self.assertEqual(
|
||||
'123',
|
||||
result['LogicalPortAttachment']['vlan_id'])
|
||||
|
||||
def test_plug_lrouter_port_invalid_attachment_type_raises(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
lrouter_port = nvplib.create_router_lport(
|
||||
self.fake_cluster, lrouter['uuid'], 'pippo', 'neutron_port_id',
|
||||
'name', True, ['192.168.0.1'], '00:11:22:33:44:55')
|
||||
self.assertRaises(nvp_exc.NvpInvalidAttachmentType,
|
||||
nvplib.plug_router_port_attachment,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
lrouter_port['uuid'], 'gw_att', 'BadType')
|
||||
|
||||
def _test_create_router_snat_rule(self, version):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=200,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.24'})
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 1)
|
||||
|
||||
def test_create_router_snat_rule_v3(self):
|
||||
self._test_create_router_snat_rule('3.0')
|
||||
|
||||
def test_create_router_snat_rule_v2(self):
|
||||
self._test_create_router_snat_rule('2.0')
|
||||
|
||||
def _test_create_router_dnat_rule(self, version, dest_port=None):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
return_value=NvpApiClient.NVPVersion(version)):
|
||||
nvplib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200,
|
||||
dest_port=dest_port,
|
||||
match_criteria={'destination_ip_addresses': '10.0.0.3'})
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 1)
|
||||
|
||||
def test_create_router_dnat_rule_v3(self):
|
||||
self._test_create_router_dnat_rule('3.0')
|
||||
|
||||
def test_create_router_dnat_rule_v2(self):
|
||||
self._test_create_router_dnat_rule('2.0')
|
||||
|
||||
def test_create_router_dnat_rule_v2_with_destination_port(self):
|
||||
self._test_create_router_dnat_rule('2.0', 8080)
|
||||
|
||||
def test_create_router_dnat_rule_v3_with_destination_port(self):
|
||||
self._test_create_router_dnat_rule('3.0', 8080)
|
||||
|
||||
def test_create_router_snat_rule_invalid_match_keys_raises(self):
|
||||
# In this case the version does not make a difference
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: '2.0'):
|
||||
self.assertRaises(AttributeError,
|
||||
nvplib.create_lrouter_snat_rule,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=200,
|
||||
match_criteria={'foo': 'bar'})
|
||||
|
||||
def _test_create_router_nosnat_rule(self, version, expected=1):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion(version)):
|
||||
nvplib.create_lrouter_nosnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
order=100,
|
||||
match_criteria={'destination_ip_addresses': '192.168.0.0/24'})
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
# NoSNAT rules do not exist in V2
|
||||
self.assertEqual(len(rules), expected)
|
||||
|
||||
def test_create_router_nosnat_rule_v2(self):
|
||||
self._test_create_router_nosnat_rule('2.0', expected=0)
|
||||
|
||||
def test_create_router_nosnat_rule_v3(self):
|
||||
self._test_create_router_nosnat_rule('3.0')
|
||||
|
||||
def _prepare_nat_rules_for_delete_tests(self):
|
||||
lrouter = nvplib.create_lrouter(self.fake_cluster,
|
||||
uuidutils.generate_uuid(),
|
||||
'pippo',
|
||||
'fake-lrouter',
|
||||
'10.0.0.1')
|
||||
# v2 or v3 makes no difference for this test
|
||||
with mock.patch.object(self.fake_cluster.api_client,
|
||||
'get_nvp_version',
|
||||
new=lambda: NvpApiClient.NVPVersion('2.0')):
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.2', '10.0.0.2', order=220,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.0/24'})
|
||||
nvplib.create_lrouter_snat_rule(
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'10.0.0.3', '10.0.0.3', order=200,
|
||||
match_criteria={'source_ip_addresses': '192.168.0.2/32'})
|
||||
nvplib.create_lrouter_dnat_rule(
|
||||
self.fake_cluster, lrouter['uuid'], '192.168.0.2', order=200,
|
||||
match_criteria={'destination_ip_addresses': '10.0.0.3'})
|
||||
return lrouter
|
||||
|
||||
def test_delete_router_nat_rules_by_match_on_destination_ip(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 1, 1,
|
||||
destination_ip_addresses='10.0.0.3')
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 2)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_on_source_ip(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'SourceNatRule', 1, 1,
|
||||
source_ip_addresses='192.168.0.2/32')
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 2)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_no_match_expected(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'SomeWeirdType', 0)
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
nvplib.delete_nat_rules_by_match(
|
||||
self.fake_cluster, lrouter['uuid'], 'DestinationNatRule', 0,
|
||||
destination_ip_addresses='99.99.99.99')
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
|
||||
def test_delete_router_nat_rules_by_match_no_match_raises(self):
|
||||
lrouter = self._prepare_nat_rules_for_delete_tests()
|
||||
rules = nvplib.query_nat_rules(self.fake_cluster, lrouter['uuid'])
|
||||
self.assertEqual(len(rules), 3)
|
||||
self.assertRaises(
|
||||
nvp_exc.NvpNatRuleMismatch,
|
||||
nvplib.delete_nat_rules_by_match,
|
||||
self.fake_cluster, lrouter['uuid'],
|
||||
'SomeWeirdType', 1, 1)
|
||||
|
||||
|
||||
class TestNvplibSecurityProfile(NvplibTestCase):
|
||||
|
||||
def test_create_and_get_security_profile(self):
|
||||
@ -1515,38 +638,6 @@ class TestNvplibClusterManagement(NvplibTestCase):
|
||||
cluster=self.fake_cluster)
|
||||
|
||||
|
||||
class TestNvplibVersioning(base.BaseTestCase):
|
||||
|
||||
def test_function_handling_missing_minor(self):
|
||||
version = NvpApiClient.NVPVersion('2.0')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_implicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_both_major_and_minor(self):
|
||||
version = NvpApiClient.NVPVersion('3.2')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_newer_major(self):
|
||||
version = NvpApiClient.NVPVersion('5.2')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_obsolete_major(self):
|
||||
version = NvpApiClient.NVPVersion('1.2')
|
||||
self.assertRaises(NotImplementedError,
|
||||
nvplib.get_function_by_version,
|
||||
'create_lrouter', version)
|
||||
|
||||
def test_function_handling_with_unknown_version(self):
|
||||
self.assertRaises(NvpApiClient.ServiceUnavailable,
|
||||
nvplib.get_function_by_version,
|
||||
'create_lrouter', None)
|
||||
|
||||
|
||||
class NvplibMiscTestCase(base.BaseTestCase):
|
||||
|
||||
def test_check_and_truncate_name_with_none(self):
|
||||
@ -1625,7 +716,3 @@ class NvplibMiscTestCase(base.BaseTestCase):
|
||||
(nvplib.URI_PREFIX, parent_res,
|
||||
par_id, child_res, res_id, 'doh'))
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
|
||||
def _nicira_method(method_name, module_name='nvplib'):
|
||||
return '%s.%s.%s' % ('neutron.plugins.nicira', module_name, method_name)
|
||||
|
Loading…
x
Reference in New Issue
Block a user