Merge pull request #284 from Cerberus98/rm10638
Adds connection switching to the Nvp driver
This commit is contained in:
commit
32790d450c
@ -17,6 +17,8 @@
|
||||
NVP client driver for Quark
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
|
||||
import aiclib
|
||||
from neutron.extensions import securitygroup as sg_ext
|
||||
from neutron.openstack.common import log as logging
|
||||
@ -89,6 +91,7 @@ class NVPDriver(base.BaseDriver):
|
||||
# NOTE(mdietz): What does default_tz actually mean?
|
||||
# We don't have one default.
|
||||
# NOTE(jkoelker): Transport Zone
|
||||
# NOTE(mdietz): :-/ tz isn't the issue. default is
|
||||
default_tz = CONF.NVP.default_tz
|
||||
LOG.info("Loading NVP settings " + str(default_tz))
|
||||
connections = CONF.NVP.controller_connection
|
||||
@ -99,6 +102,7 @@ class NVPDriver(base.BaseDriver):
|
||||
'max_rules_per_group': CONF.NVP.max_rules_per_group,
|
||||
'max_rules_per_port': CONF.NVP.max_rules_per_port})
|
||||
LOG.info("Loading NVP settings " + str(connections))
|
||||
|
||||
for conn in connections:
|
||||
(ip, port, user, pw, req_timeout,
|
||||
http_timeout, retries, redirects) = conn.split(":")
|
||||
@ -114,7 +118,11 @@ class NVPDriver(base.BaseDriver):
|
||||
default_tz=default_tz,
|
||||
backoff=backoff))
|
||||
|
||||
def get_connection(self):
|
||||
def _connection(self):
|
||||
if len(self.nvp_connections) == 0:
|
||||
raise exceptions.NoBackendConnectionsDefined(
|
||||
msg="No NVP connections defined cannot continue")
|
||||
|
||||
conn = self.nvp_connections[self.conn_index]
|
||||
if "connection" not in conn:
|
||||
scheme = conn["port"] == "443" and "https" or "http"
|
||||
@ -132,6 +140,22 @@ class NVPDriver(base.BaseDriver):
|
||||
backoff=backoff)
|
||||
return conn["connection"]
|
||||
|
||||
def _next_connection(self):
|
||||
# TODO(anyone): Do we want to drop and create new connections at some
|
||||
# point? What about recycling them after a certain
|
||||
# number of usages or time, proactively?
|
||||
conn_len = len(self.nvp_connections)
|
||||
if conn_len:
|
||||
self.conn_index = (self.conn_index + 1) % conn_len
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_connection(self):
|
||||
try:
|
||||
yield self._connection()
|
||||
except Exception:
|
||||
self._next_connection()
|
||||
raise
|
||||
|
||||
def create_network(self, context, network_name, tags=None,
|
||||
network_id=None, **kwargs):
|
||||
return self._lswitch_create(context, network_name, tags,
|
||||
@ -187,67 +211,67 @@ class NVPDriver(base.BaseDriver):
|
||||
security_groups = security_groups or []
|
||||
tenant_id = context.tenant_id
|
||||
lswitch = self._create_or_choose_lswitch(context, network_id)
|
||||
connection = self.get_connection()
|
||||
port = connection.lswitch_port(lswitch)
|
||||
port.admin_status_enabled(status)
|
||||
nvp_group_ids = self._get_security_groups_for_port(context,
|
||||
security_groups)
|
||||
port.security_profiles(nvp_group_ids)
|
||||
tags = [dict(tag=network_id, scope="neutron_net_id"),
|
||||
dict(tag=port_id, scope="neutron_port_id"),
|
||||
dict(tag=tenant_id, scope="os_tid"),
|
||||
dict(tag=device_id, scope="vm_id")]
|
||||
LOG.debug("Creating port on switch %s" % lswitch)
|
||||
port.tags(tags)
|
||||
res = port.create()
|
||||
try:
|
||||
"""Catching odd NVP returns here will make it safe to assume that
|
||||
NVP returned something correct."""
|
||||
res["lswitch"] = lswitch
|
||||
except TypeError:
|
||||
LOG.exception("Unexpected return from NVP: %s" % res)
|
||||
raise
|
||||
port = connection.lswitch_port(lswitch)
|
||||
port.uuid = res["uuid"]
|
||||
port.attachment_vif(port_id)
|
||||
return res
|
||||
with self.get_connection() as connection:
|
||||
port = connection.lswitch_port(lswitch)
|
||||
port.admin_status_enabled(status)
|
||||
nvp_group_ids = self._get_security_groups_for_port(context,
|
||||
security_groups)
|
||||
port.security_profiles(nvp_group_ids)
|
||||
tags = [dict(tag=network_id, scope="neutron_net_id"),
|
||||
dict(tag=port_id, scope="neutron_port_id"),
|
||||
dict(tag=tenant_id, scope="os_tid"),
|
||||
dict(tag=device_id, scope="vm_id")]
|
||||
LOG.debug("Creating port on switch %s" % lswitch)
|
||||
port.tags(tags)
|
||||
res = port.create()
|
||||
try:
|
||||
"""Catching odd NVP returns here will make it safe to assume that
|
||||
NVP returned something correct."""
|
||||
res["lswitch"] = lswitch
|
||||
except TypeError:
|
||||
LOG.exception("Unexpected return from NVP: %s" % res)
|
||||
raise
|
||||
port = connection.lswitch_port(lswitch)
|
||||
port.uuid = res["uuid"]
|
||||
port.attachment_vif(port_id)
|
||||
return res
|
||||
|
||||
def update_port(self, context, port_id, status=True,
|
||||
security_groups=None, **kwargs):
|
||||
security_groups = security_groups or []
|
||||
connection = self.get_connection()
|
||||
lswitch_id = self._lswitch_from_port(context, port_id)
|
||||
port = connection.lswitch_port(lswitch_id, port_id)
|
||||
nvp_group_ids = self._get_security_groups_for_port(context,
|
||||
security_groups)
|
||||
if nvp_group_ids:
|
||||
port.security_profiles(nvp_group_ids)
|
||||
port.admin_status_enabled(status)
|
||||
return port.update()
|
||||
with self.get_connection() as connection:
|
||||
lswitch_id = self._lswitch_from_port(context, port_id)
|
||||
port = connection.lswitch_port(lswitch_id, port_id)
|
||||
nvp_group_ids = self._get_security_groups_for_port(context,
|
||||
security_groups)
|
||||
if nvp_group_ids:
|
||||
port.security_profiles(nvp_group_ids)
|
||||
port.admin_status_enabled(status)
|
||||
return port.update()
|
||||
|
||||
def delete_port(self, context, port_id, **kwargs):
|
||||
connection = self.get_connection()
|
||||
lswitch_uuid = kwargs.get('lswitch_uuid', None)
|
||||
try:
|
||||
if not lswitch_uuid:
|
||||
lswitch_uuid = self._lswitch_from_port(context, port_id)
|
||||
LOG.debug("Deleting port %s from lswitch %s"
|
||||
% (port_id, lswitch_uuid))
|
||||
connection.lswitch_port(lswitch_uuid, port_id).delete()
|
||||
except aiclib.core.AICException as ae:
|
||||
if ae.code == 404:
|
||||
LOG.info("LSwitchPort/Port %s not found in NVP."
|
||||
" Ignoring explicitly. Code: %s, Message: %s"
|
||||
% (port_id, ae.code, ae.message))
|
||||
else:
|
||||
LOG.info("AICException deleting LSwitchPort/Port %s in NVP."
|
||||
" Ignoring explicitly. Code: %s, Message: %s"
|
||||
% (port_id, ae.code, ae.message))
|
||||
with self.get_connection() as connection:
|
||||
lswitch_uuid = kwargs.get('lswitch_uuid', None)
|
||||
try:
|
||||
if not lswitch_uuid:
|
||||
lswitch_uuid = self._lswitch_from_port(context, port_id)
|
||||
LOG.debug("Deleting port %s from lswitch %s"
|
||||
% (port_id, lswitch_uuid))
|
||||
connection.lswitch_port(lswitch_uuid, port_id).delete()
|
||||
except aiclib.core.AICException as ae:
|
||||
if ae.code == 404:
|
||||
LOG.info("LSwitchPort/Port %s not found in NVP."
|
||||
" Ignoring explicitly. Code: %s, Message: %s"
|
||||
% (port_id, ae.code, ae.message))
|
||||
else:
|
||||
LOG.info("AICException deleting LSwitchPort/Port %s in "
|
||||
"NVP. Ignoring explicitly. Code: %s, Message: %s"
|
||||
% (port_id, ae.code, ae.message))
|
||||
|
||||
except Exception as e:
|
||||
LOG.info("Failed to delete LSwitchPort/Port %s in NVP."
|
||||
" Ignoring explicitly. Message: %s"
|
||||
% (port_id, e.args[0]))
|
||||
except Exception as e:
|
||||
LOG.info("Failed to delete LSwitchPort/Port %s in NVP."
|
||||
" Ignoring explicitly. Message: %s"
|
||||
% (port_id, e.args[0]))
|
||||
|
||||
def _collect_lport_info(self, lport, get_status):
|
||||
info = {
|
||||
@ -291,23 +315,23 @@ class NVPDriver(base.BaseDriver):
|
||||
return info
|
||||
|
||||
def diag_port(self, context, port_id, get_status=False, **kwargs):
|
||||
connection = self.get_connection()
|
||||
lswitch_uuid = self._lswitch_from_port(context, port_id)
|
||||
lswitch_port = connection.lswitch_port(lswitch_uuid, port_id)
|
||||
with self.get_connection() as connection:
|
||||
lswitch_uuid = self._lswitch_from_port(context, port_id)
|
||||
lswitch_port = connection.lswitch_port(lswitch_uuid, port_id)
|
||||
|
||||
query = lswitch_port.query()
|
||||
query.relations("LogicalPortAttachment")
|
||||
results = query.results()
|
||||
if results['result_count'] == 0:
|
||||
return {'lport': "Logical port not found."}
|
||||
query = lswitch_port.query()
|
||||
query.relations("LogicalPortAttachment")
|
||||
results = query.results()
|
||||
if results['result_count'] == 0:
|
||||
return {'lport': "Logical port not found."}
|
||||
|
||||
config = results['results'][0]
|
||||
relations = config.pop('_relations')
|
||||
config['attachment'] = relations['LogicalPortAttachment']['type']
|
||||
if get_status:
|
||||
config['status'] = lswitch_port.status()
|
||||
config['statistics'] = lswitch_port.statistics()
|
||||
return {'lport': self._collect_lport_info(config, get_status)}
|
||||
config = results['results'][0]
|
||||
relations = config.pop('_relations')
|
||||
config['attachment'] = relations['LogicalPortAttachment']['type']
|
||||
if get_status:
|
||||
config['status'] = lswitch_port.status()
|
||||
config['statistics'] = lswitch_port.statistics()
|
||||
return {'lport': self._collect_lport_info(config, get_status)}
|
||||
|
||||
def _get_network_details(self, context, network_id, switches):
|
||||
name, phys_net, phys_type, segment_id = None, None, None, None
|
||||
@ -326,55 +350,55 @@ class NVPDriver(base.BaseDriver):
|
||||
|
||||
def create_security_group(self, context, group_name, **group):
|
||||
tenant_id = context.tenant_id
|
||||
connection = self.get_connection()
|
||||
group_id = group.get('group_id')
|
||||
profile = connection.securityprofile()
|
||||
if group_name:
|
||||
profile.display_name(group_name)
|
||||
ingress_rules = group.get('port_ingress_rules', [])
|
||||
egress_rules = group.get('port_egress_rules', [])
|
||||
with self.get_connection() as connection:
|
||||
group_id = group.get('group_id')
|
||||
profile = connection.securityprofile()
|
||||
if group_name:
|
||||
profile.display_name(group_name)
|
||||
ingress_rules = group.get('port_ingress_rules', [])
|
||||
egress_rules = group.get('port_egress_rules', [])
|
||||
|
||||
if (len(ingress_rules) + len(egress_rules) >
|
||||
self.limits['max_rules_per_group']):
|
||||
raise exceptions.DriverLimitReached(limit="rules per group")
|
||||
if (len(ingress_rules) + len(egress_rules) >
|
||||
self.limits['max_rules_per_group']):
|
||||
raise exceptions.DriverLimitReached(limit="rules per group")
|
||||
|
||||
if egress_rules:
|
||||
profile.port_egress_rules(egress_rules)
|
||||
if ingress_rules:
|
||||
profile.port_ingress_rules(ingress_rules)
|
||||
tags = [dict(tag=group_id, scope="neutron_group_id"),
|
||||
dict(tag=tenant_id, scope="os_tid")]
|
||||
LOG.debug("Creating security profile %s" % group_name)
|
||||
profile.tags(tags)
|
||||
return profile.create()
|
||||
if egress_rules:
|
||||
profile.port_egress_rules(egress_rules)
|
||||
if ingress_rules:
|
||||
profile.port_ingress_rules(ingress_rules)
|
||||
tags = [dict(tag=group_id, scope="neutron_group_id"),
|
||||
dict(tag=tenant_id, scope="os_tid")]
|
||||
LOG.debug("Creating security profile %s" % group_name)
|
||||
profile.tags(tags)
|
||||
return profile.create()
|
||||
|
||||
def delete_security_group(self, context, group_id, **kwargs):
|
||||
guuid = self._get_security_group_id(context, group_id)
|
||||
connection = self.get_connection()
|
||||
LOG.debug("Deleting security profile %s" % group_id)
|
||||
connection.securityprofile(guuid).delete()
|
||||
with self.get_connection() as connection:
|
||||
LOG.debug("Deleting security profile %s" % group_id)
|
||||
connection.securityprofile(guuid).delete()
|
||||
|
||||
def update_security_group(self, context, group_id, **group):
|
||||
query = self._get_security_group(context, group_id)
|
||||
connection = self.get_connection()
|
||||
profile = connection.securityprofile(query.get('uuid'))
|
||||
with self.get_connection() as connection:
|
||||
profile = connection.securityprofile(query.get('uuid'))
|
||||
|
||||
ingress_rules = group.get('port_ingress_rules',
|
||||
query.get('logical_port_ingress_rules'))
|
||||
egress_rules = group.get('port_egress_rules',
|
||||
query.get('logical_port_egress_rules'))
|
||||
ingress_rules = group.get('port_ingress_rules',
|
||||
query.get('logical_port_ingress_rules'))
|
||||
egress_rules = group.get('port_egress_rules',
|
||||
query.get('logical_port_egress_rules'))
|
||||
|
||||
if (len(ingress_rules) + len(egress_rules) >
|
||||
self.limits['max_rules_per_group']):
|
||||
raise exceptions.DriverLimitReached(limit="rules per group")
|
||||
if (len(ingress_rules) + len(egress_rules) >
|
||||
self.limits['max_rules_per_group']):
|
||||
raise exceptions.DriverLimitReached(limit="rules per group")
|
||||
|
||||
if group.get('name', None):
|
||||
profile.display_name(group['name'])
|
||||
if group.get('port_ingress_rules', None) is not None:
|
||||
profile.port_ingress_rules(ingress_rules)
|
||||
if group.get('port_egress_rules', None) is not None:
|
||||
profile.port_egress_rules(egress_rules)
|
||||
return profile.update()
|
||||
if group.get('name', None):
|
||||
profile.display_name(group['name'])
|
||||
if group.get('port_ingress_rules', None) is not None:
|
||||
profile.port_ingress_rules(ingress_rules)
|
||||
if group.get('port_egress_rules', None) is not None:
|
||||
profile.port_egress_rules(egress_rules)
|
||||
return profile.update()
|
||||
|
||||
def _update_security_group_rules(self, context, group_id, rule, operation,
|
||||
checks):
|
||||
@ -447,9 +471,9 @@ class NVPDriver(base.BaseDriver):
|
||||
return None
|
||||
|
||||
def _lswitch_delete(self, context, lswitch_uuid):
|
||||
connection = self.get_connection()
|
||||
LOG.debug("Deleting lswitch %s" % lswitch_uuid)
|
||||
connection.lswitch(lswitch_uuid).delete()
|
||||
with self.get_connection() as connection:
|
||||
LOG.debug("Deleting lswitch %s" % lswitch_uuid)
|
||||
connection.lswitch(lswitch_uuid).delete()
|
||||
|
||||
def _config_provider_attrs(self, connection, switch, phys_net,
|
||||
net_type, segment_id):
|
||||
@ -491,64 +515,65 @@ class NVPDriver(base.BaseDriver):
|
||||
(context.tenant_id, network_name))
|
||||
|
||||
tenant_id = context.tenant_id
|
||||
connection = self.get_connection()
|
||||
with self.get_connection() as connection:
|
||||
switch = connection.lswitch()
|
||||
if network_name is None:
|
||||
network_name = network_id
|
||||
switch.display_name(network_name[:40])
|
||||
tags = tags or []
|
||||
tags.append({"tag": tenant_id, "scope": "os_tid"})
|
||||
if network_id:
|
||||
tags.append({"tag": network_id, "scope": "neutron_net_id"})
|
||||
switch.tags(tags)
|
||||
pnet = phys_net or CONF.NVP.default_tz
|
||||
ptype = phys_type or CONF.NVP.default_tz_type
|
||||
switch.transport_zone(pnet, ptype)
|
||||
LOG.debug("Creating lswitch for network %s" % network_id)
|
||||
|
||||
switch = connection.lswitch()
|
||||
if network_name is None:
|
||||
network_name = network_id
|
||||
switch.display_name(network_name[:40])
|
||||
tags = tags or []
|
||||
tags.append({"tag": tenant_id, "scope": "os_tid"})
|
||||
if network_id:
|
||||
tags.append({"tag": network_id, "scope": "neutron_net_id"})
|
||||
switch.tags(tags)
|
||||
pnet = phys_net or CONF.NVP.default_tz
|
||||
ptype = phys_type or CONF.NVP.default_tz_type
|
||||
switch.transport_zone(pnet, ptype)
|
||||
LOG.debug("Creating lswitch for network %s" % network_id)
|
||||
|
||||
# When connecting to public or snet, we need switches that are
|
||||
# connected to their respective public/private transport zones
|
||||
# using a "bridge" connector. Public uses no VLAN, whereas private
|
||||
# uses VLAN 122 in netdev. Probably need this to be configurable
|
||||
self._config_provider_attrs(connection, switch, phys_net, phys_type,
|
||||
segment_id)
|
||||
res = switch.create()
|
||||
try:
|
||||
uuid = res["uuid"]
|
||||
return uuid
|
||||
except TypeError:
|
||||
LOG.exception("Unexpected return from NVP: %s" % res)
|
||||
raise
|
||||
# When connecting to public or snet, we need switches that are
|
||||
# connected to their respective public/private transport zones
|
||||
# using a "bridge" connector. Public uses no VLAN, whereas private
|
||||
# uses VLAN 122 in netdev. Probably need this to be configurable
|
||||
self._config_provider_attrs(connection, switch, phys_net,
|
||||
phys_type, segment_id)
|
||||
res = switch.create()
|
||||
try:
|
||||
uuid = res["uuid"]
|
||||
return uuid
|
||||
except TypeError:
|
||||
LOG.exception("Unexpected return from NVP: %s" % res)
|
||||
raise
|
||||
|
||||
def _lswitches_for_network(self, context, network_id):
|
||||
connection = self.get_connection()
|
||||
query = connection.lswitch().query()
|
||||
query.tagscopes(['os_tid', 'neutron_net_id'])
|
||||
query.tags([context.tenant_id, network_id])
|
||||
return query
|
||||
with self.get_connection() as connection:
|
||||
query = connection.lswitch().query()
|
||||
query.tagscopes(['os_tid', 'neutron_net_id'])
|
||||
query.tags([context.tenant_id, network_id])
|
||||
return query
|
||||
|
||||
def _lswitch_from_port(self, context, port_id):
|
||||
connection = self.get_connection()
|
||||
query = connection.lswitch_port("*").query()
|
||||
query.relations("LogicalSwitchConfig")
|
||||
query.uuid(port_id)
|
||||
port = query.results()
|
||||
if port['result_count'] > 1:
|
||||
raise Exception("Could not identify lswitch for port %s" % port_id)
|
||||
if port['result_count'] < 1:
|
||||
raise Exception("No lswitch found for port %s" % port_id)
|
||||
return port['results'][0]["_relations"]["LogicalSwitchConfig"]["uuid"]
|
||||
with self.get_connection() as connection:
|
||||
query = connection.lswitch_port("*").query()
|
||||
query.relations("LogicalSwitchConfig")
|
||||
query.uuid(port_id)
|
||||
port = query.results()
|
||||
if port['result_count'] > 1:
|
||||
raise Exception("Could not identify lswitch for port %s" %
|
||||
port_id)
|
||||
if port['result_count'] < 1:
|
||||
raise Exception("No lswitch found for port %s" % port_id)
|
||||
cfg = port['results'][0]["_relations"]["LogicalSwitchConfig"]
|
||||
return cfg["uuid"]
|
||||
|
||||
def _get_security_group(self, context, group_id):
|
||||
connection = self.get_connection()
|
||||
query = connection.securityprofile().query()
|
||||
query.tagscopes(['os_tid', 'neutron_group_id'])
|
||||
query.tags([context.tenant_id, group_id])
|
||||
query = query.results()
|
||||
if query['result_count'] != 1:
|
||||
raise sg_ext.SecurityGroupNotFound(id=group_id)
|
||||
return query['results'][0]
|
||||
with self.get_connection() as connection:
|
||||
query = connection.securityprofile().query()
|
||||
query.tagscopes(['os_tid', 'neutron_group_id'])
|
||||
query.tags([context.tenant_id, group_id])
|
||||
query = query.results()
|
||||
if query['result_count'] != 1:
|
||||
raise sg_ext.SecurityGroupNotFound(id=group_id)
|
||||
return query['results'][0]
|
||||
|
||||
def _get_security_group_id(self, context, group_id):
|
||||
return self._get_security_group(context, group_id)['uuid']
|
||||
@ -567,24 +592,25 @@ class NVPDriver(base.BaseDriver):
|
||||
if rule.get(key):
|
||||
rule_clone[key] = rule[key]
|
||||
|
||||
connection = self.get_connection()
|
||||
secrule = connection.securityrule(ethertype, **rule_clone)
|
||||
with self.get_connection() as connection:
|
||||
secrule = connection.securityrule(ethertype, **rule_clone)
|
||||
|
||||
direction = rule.get('direction', '')
|
||||
if direction not in ['ingress', 'egress']:
|
||||
raise AttributeError(
|
||||
"Direction not specified as 'ingress' or 'egress'.")
|
||||
return (direction, secrule)
|
||||
direction = rule.get('direction', '')
|
||||
if direction not in ['ingress', 'egress']:
|
||||
raise AttributeError(
|
||||
"Direction not specified as 'ingress' or 'egress'.")
|
||||
return (direction, secrule)
|
||||
|
||||
def _check_rule_count_per_port(self, context, group_id):
|
||||
connection = self.get_connection()
|
||||
ports = connection.lswitch_port("*").query().security_profile_uuid(
|
||||
'=', self._get_security_group_id(
|
||||
context, group_id)).results().get('results', [])
|
||||
groups = (port.get('security_profiles', []) for port in ports)
|
||||
return max([self._check_rule_count_for_groups(
|
||||
context, (connection.securityprofile(gp).read() for gp in group))
|
||||
for group in groups] or [0])
|
||||
with self.get_connection() as connection:
|
||||
ports = connection.lswitch_port("*").query().security_profile_uuid(
|
||||
'=', self._get_security_group_id(
|
||||
context, group_id)).results().get('results', [])
|
||||
groups = (port.get('security_profiles', []) for port in ports)
|
||||
return max([self._check_rule_count_for_groups(
|
||||
context, (connection.securityprofile(gp).read()
|
||||
for gp in group))
|
||||
for group in groups] or [0])
|
||||
|
||||
def _check_rule_count_for_groups(self, context, groups):
|
||||
return sum(len(group['logical_port_ingress_rules']) +
|
||||
|
@ -123,3 +123,8 @@ class RedisConnectionFailure(exceptions.NeutronException):
|
||||
|
||||
class RedisSlaveWritesForbidden(exceptions.NeutronException):
|
||||
message = _("No write actions can be applied to Slave redis nodes.")
|
||||
|
||||
|
||||
class NoBackendConnectionsDefined(exceptions.NeutronException):
|
||||
message = _("This driver cannot be used without a backend connection "
|
||||
"definition. %(msg)")
|
||||
|
@ -124,10 +124,10 @@ class TestNVPDriverCreateNetwork(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
) as (conn,):
|
||||
connection = self._create_connection()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_create_network(self):
|
||||
@ -151,8 +151,8 @@ class TestNVPDriverProviderNetwork(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, tz):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
) as (conn,):
|
||||
connection = self._create_connection()
|
||||
switch = self._create_lswitch(1, False)
|
||||
switch.transport_zone = mock.Mock()
|
||||
@ -161,7 +161,7 @@ class TestNVPDriverProviderNetwork(TestNVPDriver):
|
||||
tz_query = mock.Mock()
|
||||
tz_query.query = mock.Mock(return_value=tz_results)
|
||||
connection.transportzone = mock.Mock(return_value=tz_query)
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection, switch
|
||||
|
||||
def test_config_provider_attrs_flat_net(self):
|
||||
@ -286,11 +286,11 @@ class TestNVPDriverDeleteNetwork(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, network_exists=True):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
) as (get_connection, switch_list):
|
||||
) as (conn, switch_list):
|
||||
connection = self._create_connection()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
if network_exists:
|
||||
ret = {"results": [{"uuid": self.lswitch_uuid}]}
|
||||
else:
|
||||
@ -318,12 +318,12 @@ class TestNVPDriverDeleteNetworkWithExceptions(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, network_exists=True, exception=None):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_delete" % self.d_pkg),
|
||||
) as (get_connection, switch_list, switch_delete):
|
||||
) as (conn, switch_list, switch_delete):
|
||||
connection = self._create_connection()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
if network_exists:
|
||||
ret = {"results": [{"uuid": self.lswitch_uuid}]}
|
||||
else:
|
||||
@ -372,13 +372,14 @@ class TestNVPDriverCreatePort(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, has_lswitch=True, maxed_ports=False, net_details=None):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
mock.patch("%s._get_network_details" % self.d_pkg),
|
||||
) as (get_connection, get_switches, get_net_dets):
|
||||
) as (conn, next_conn, get_switches, get_net_dets):
|
||||
connection = self._create_connection(has_switches=has_lswitch,
|
||||
maxed_ports=maxed_ports)
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
get_switches.return_value = connection.lswitch().query()
|
||||
get_net_dets.return_value = net_details
|
||||
yield connection
|
||||
@ -517,11 +518,12 @@ class TestNVPDriverUpdatePort(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_update_port(self):
|
||||
@ -550,10 +552,10 @@ class TestNVPDriverLswitchesForNetwork(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, single_switch=True):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
) as (conn,):
|
||||
connection = self._create_connection(switch_count=1)
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_get_lswitches(self):
|
||||
@ -606,10 +608,11 @@ class TestNVPDriverDeletePort(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, switch_count=1):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection(switch_count=switch_count)
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_delete_port(self):
|
||||
@ -645,11 +648,11 @@ class TestNVPDriverDeletePortWithExceptions(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, switch_exception=None, delete_exception=None):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_from_port" % self.d_pkg),
|
||||
) as (get_connection, switch):
|
||||
) as (conn, switch):
|
||||
connection = self._create_connection()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
if switch_exception:
|
||||
switch.side_effect = switch_exception
|
||||
else:
|
||||
@ -729,11 +732,12 @@ class TestNVPDriverCreateSecurityGroup(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_security_group_create(self):
|
||||
@ -783,11 +787,12 @@ class TestNVPDriverDeleteSecurityGroup(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_security_group_delete(self):
|
||||
@ -812,11 +817,12 @@ class TestNVPDriverUpdateSecurityGroup(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_security_group_update(self):
|
||||
@ -872,14 +878,15 @@ class TestNVPDriverCreateSecurityGroupRule(TestNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._next_connection" % self.d_pkg),
|
||||
) as (conn, next_conn):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
connection.securityrule = self._create_security_rule()
|
||||
connection.lswitch_port().query.return_value = (
|
||||
self._create_lport_query(1, [self.profile_id]))
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_security_rule_create(self):
|
||||
@ -955,13 +962,13 @@ class TestNVPDriverDeleteSecurityGroupRule(TestNVPDriver):
|
||||
rulelist['logical_port_%s_rules' % rule.pop('direction')].append(
|
||||
rule)
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
) as (get_connection,):
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
) as (conn,):
|
||||
connection = self._create_connection()
|
||||
connection.securityprofile = self._create_security_profile()
|
||||
connection.securityrule = self._create_security_rule()
|
||||
connection.securityprofile().read().update(rulelist)
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
yield connection
|
||||
|
||||
def test_delete_security_group(self):
|
||||
@ -1023,16 +1030,40 @@ class TestNVPGetConnection(TestNVPDriver):
|
||||
http_timeout=10,
|
||||
retries=1,
|
||||
backoff=0))
|
||||
with mock.patch("aiclib.nvp.Connection") as (aiclib_conn):
|
||||
yield aiclib_conn
|
||||
with contextlib.nested(
|
||||
mock.patch("aiclib.nvp.Connection"),
|
||||
mock.patch("%s._next_connection" % self.d_pkg)
|
||||
) as (aiclib_conn, next_conn):
|
||||
yield aiclib_conn, next_conn
|
||||
cfg.CONF.clear_override("controller_connection", "NVP")
|
||||
|
||||
def test_get_connection(self):
|
||||
with self._stubs(has_conn=False) as aiclib_conn:
|
||||
self.driver.get_connection()
|
||||
with self._stubs(has_conn=False) as (aiclib_conn, next_conn):
|
||||
with self.driver.get_connection():
|
||||
pass
|
||||
self.assertTrue(aiclib_conn.called)
|
||||
self.assertFalse(next_conn.called)
|
||||
|
||||
def test_get_connection_connection_defined(self):
|
||||
with self._stubs(has_conn=True) as aiclib_conn:
|
||||
self.driver.get_connection()
|
||||
with self._stubs(has_conn=True) as (aiclib_conn, next_conn):
|
||||
with self.driver.get_connection():
|
||||
pass
|
||||
self.assertFalse(aiclib_conn.called)
|
||||
self.assertFalse(next_conn.called)
|
||||
|
||||
def test_get_connection_iterates(self):
|
||||
with self._stubs(has_conn=True) as (aiclib_conn, next_conn):
|
||||
try:
|
||||
with self.driver.get_connection():
|
||||
raise Exception("Failure")
|
||||
except Exception:
|
||||
pass
|
||||
self.assertFalse(aiclib_conn.called)
|
||||
self.assertTrue(next_conn.called)
|
||||
|
||||
|
||||
class TestNVPGetConnectionNoneDefined(TestNVPDriver):
|
||||
def test_get_connection(self):
|
||||
with self.assertRaises(q_exc.NoBackendConnectionsDefined):
|
||||
with self.driver.get_connection():
|
||||
pass
|
||||
|
@ -52,13 +52,13 @@ class TestOptimizedNVPDriverDeleteNetwork(TestOptimizedNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, switch_count=1):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_by_nvp_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
) as (get_connection, select_switch, get_switches):
|
||||
) as (conn, select_switch, get_switches):
|
||||
connection = self._create_connection()
|
||||
switch = self._create_lswitch_mock()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
select_switch.return_value = switch
|
||||
get_switches.return_value = [switch] * switch_count
|
||||
self.context.session.delete = mock.Mock(return_value=None)
|
||||
@ -105,14 +105,14 @@ class TestOptimizedNVPDriverDeleteNetworkWithExceptions(
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, switch_count=1, error_code=500):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_by_nvp_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_delete" % self.d_pkg)
|
||||
) as (get_connection, select_switch, get_switches, delete_switch):
|
||||
) as (conn, select_switch, get_switches, delete_switch):
|
||||
connection = self._create_connection()
|
||||
switch = self._create_lswitch_mock()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
select_switch.return_value = switch
|
||||
get_switches.return_value = [switch] * switch_count
|
||||
delete_switch.side_effect = aiclib.core.AICException(
|
||||
@ -151,17 +151,17 @@ class TestOptimizedNVPDriverDeletePortMultiSwitch(TestOptimizedNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, port_count=2, exception=None):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lport_select_by_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_by_nvp_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
mock.patch("%s._lport_delete" % self.d_pkg),
|
||||
) as (get_connection, select_port, select_switch,
|
||||
) as (conn, select_port, select_switch,
|
||||
two_switch, port_delete):
|
||||
connection = self._create_connection()
|
||||
port = self._create_lport_mock(port_count)
|
||||
switch = self._create_lswitch_mock()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
select_port.return_value = port
|
||||
select_switch.return_value = switch
|
||||
two_switch.return_value = [switch, switch]
|
||||
@ -244,15 +244,15 @@ class TestOptimizedNVPDriverDeletePortSingleSwitch(TestOptimizedNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, port_count=2):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lport_select_by_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_by_nvp_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitches_for_network" % self.d_pkg),
|
||||
) as (get_connection, select_port, select_switch, one_switch):
|
||||
) as (conn, select_port, select_switch, one_switch):
|
||||
connection = self._create_connection()
|
||||
port = self._create_lport_mock(port_count)
|
||||
switch = self._create_lswitch_mock()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
select_port.return_value = port
|
||||
select_switch.return_value = switch
|
||||
one_switch.return_value = [switch]
|
||||
@ -274,16 +274,16 @@ class TestOptimizedNVPDriverCreatePort(TestOptimizedNVPDriver):
|
||||
@contextlib.contextmanager
|
||||
def _stubs(self, has_lswitch=True, maxed_ports=False):
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_free" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_first" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_select_by_nvp_id" % self.d_pkg),
|
||||
mock.patch("%s._lswitch_create_optimized" % self.d_pkg),
|
||||
mock.patch("%s._get_network_details" % self.d_pkg)
|
||||
) as (get_connection, select_free, select_first,
|
||||
) as (conn, select_free, select_first,
|
||||
select_by_id, create_opt, get_net_dets):
|
||||
connection = self._create_connection()
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
if has_lswitch:
|
||||
select_first.return_value = mock.Mock(nvp_id=self.lswitch_uuid)
|
||||
if not has_lswitch:
|
||||
@ -427,7 +427,7 @@ class TestOptimizedNVPDriverUpdatePort(TestOptimizedNVPDriver):
|
||||
|
||||
class TestCreateSecurityGroups(TestOptimizedNVPDriver):
|
||||
def test_create_security_group(self):
|
||||
with mock.patch("%s.get_connection" % self.d_pkg):
|
||||
with mock.patch("%s._connection" % self.d_pkg):
|
||||
self.driver.create_security_group(self.context, "newgroup")
|
||||
self.assertTrue(self.context.session.add.called)
|
||||
|
||||
@ -436,7 +436,7 @@ class TestDeleteSecurityGroups(TestOptimizedNVPDriver):
|
||||
def test_delete_security_group(self):
|
||||
mod_path = "quark.drivers.nvp_driver.NVPDriver"
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._query_security_group" % self.d_pkg),
|
||||
mock.patch("%s.delete_security_group" % mod_path)):
|
||||
|
||||
@ -452,10 +452,10 @@ class TestSecurityGroupRules(TestOptimizedNVPDriver):
|
||||
def _stubs(self, rules=None):
|
||||
rules = rules or []
|
||||
with contextlib.nested(
|
||||
mock.patch("%s.get_connection" % self.d_pkg),
|
||||
mock.patch("%s._connection" % self.d_pkg),
|
||||
mock.patch("%s._query_security_group" % self.d_pkg),
|
||||
mock.patch("%s._check_rule_count_per_port" % self.d_pkg),
|
||||
) as (get_connection, query_sec_group, rule_count):
|
||||
) as (conn, query_sec_group, rule_count):
|
||||
query_sec_group.return_value = (quark.drivers.optimized_nvp_driver.
|
||||
SecurityProfile())
|
||||
connection = self._create_connection()
|
||||
@ -464,7 +464,7 @@ class TestSecurityGroupRules(TestOptimizedNVPDriver):
|
||||
connection.securityrule = self._create_security_rule()
|
||||
connection.lswitch_port().query.return_value = (
|
||||
self._create_lport_query(1, [self.profile_id]))
|
||||
get_connection.return_value = connection
|
||||
conn.return_value = connection
|
||||
|
||||
old_query = self.context.session.query
|
||||
sec_group = quark.db.models.SecurityGroup()
|
||||
|
Loading…
x
Reference in New Issue
Block a user