Browse Source

Fix handling of ERROR ports and '' device_id

This change contains two fixes:
1. When a port goes to ERROR state, treat it as a delete
2. When a device_id is '', don't query for all instances

Change-Id: I587fef123e0552cc3bd2fe3fb74cfcb2dbb23c8b
(cherry picked from commit 7ac2b9585e)
tags/2019.1.5^0
Mitchell Jameson 1 month ago
parent
commit
a3016cde0f
5 changed files with 116 additions and 16 deletions
  1. +14
    -10
      networking_arista/common/db_lib.py
  2. +7
    -6
      networking_arista/ml2/mechanism_arista.py
  3. +56
    -0
      networking_arista/tests/unit/common/test_db_lib.py
  4. +5
    -0
      networking_arista/tests/unit/ml2/ml2_test_base.py
  5. +34
    -0
      networking_arista/tests/unit/ml2/test_mechanism_arista.py

+ 14
- 10
networking_arista/common/db_lib.py View File

@@ -159,7 +159,8 @@ def filter_inactive_ports(query):
"""Filter ports that aren't in active status """
port_model = models_v2.Port
query = (query
.filter(port_model.status == n_const.PORT_STATUS_ACTIVE))
.filter(port_model.status.in_([n_const.PORT_STATUS_ACTIVE,
n_const.PORT_STATUS_BUILD])))
return query


@@ -197,7 +198,7 @@ def get_tenants(tenant_id=None):
with session.begin():
for m in [models_v2.Network, models_v2.Port, l3_models.Router]:
q = session.query(m.project_id).filter(m.project_id != '')
if tenant_id:
if tenant_id is not None:
q = q.filter(m.project_id == tenant_id)
project_ids.update(pid[0] for pid in q.distinct())
return [{'project_id': project_id} for project_id in project_ids]
@@ -212,7 +213,7 @@ def get_networks(network_id=None):
networks = (session.query(model, l3ha_network)
.outerjoin(l3ha_network,
l3ha_network.network_id == model.id))
if network_id:
if network_id is not None:
networks = networks.filter(model.id == network_id)
return networks.all()

@@ -223,7 +224,7 @@ def get_segments(segment_id=None):
with session.begin():
model = segment_models.NetworkSegment
segments = session.query(model).filter_network_type()
if segment_id:
if segment_id is not None:
segments = segments.filter(model.id == segment_id)
return segments.all()

@@ -248,7 +249,7 @@ def get_instances(device_owners=None, vnic_type=None, instance_id=None):
.distinct(port_model.device_id)
.group_by(port_model.device_id)
.filter_unnecessary_ports(device_owners, vnic_type))
if instance_id:
if instance_id is not None:
instances = instances.filter(port_model.device_id == instance_id)
return instances.all()

@@ -291,7 +292,7 @@ def get_ports(device_owners=None, vnic_type=None, port_id=None, active=True):
.outerjoin(router_model,
router_model.id == port_model.device_id)
.filter_unnecessary_ports(device_owners, vnic_type, active))
if port_id:
if port_id is not None:
ports = ports.filter(port_model.id == port_id)
return ports.all()

@@ -363,8 +364,9 @@ def get_port_bindings(binding_key=None):
dist_binding_model.host ==
binding_level_model.host))
.filter_unnecessary_ports()
.filter(dist_binding_model.status ==
n_const.PORT_STATUS_ACTIVE)
.filter(dist_binding_model.status.in_([
n_const.PORT_STATUS_BUILD,
n_const.PORT_STATUS_ACTIVE]))
.join(aliased_blm,
and_(dist_binding_model.port_id ==
aliased_blm.port_id,
@@ -454,7 +456,8 @@ def instance_provisioned(device_id):
with session.begin():
port_model = models_v2.Port
res = bool(session.query(port_model)
.filter(port_model.device_id == device_id).count())
.filter(port_model.device_id == device_id)
.filter_inactive_ports().count())
return res


@@ -464,7 +467,8 @@ def port_provisioned(port_id):
with session.begin():
port_model = models_v2.Port
res = bool(session.query(port_model)
.filter(port_model.id == port_id).count())
.filter(port_model.id == port_id)
.filter_inactive_ports().count())
return res




+ 7
- 6
networking_arista/ml2/mechanism_arista.py View File

@@ -241,17 +241,18 @@ class AristaDriver(driver_api.MechanismDriver):
if orig_port and port['device_id'] != orig_port['device_id']:
self.delete_port_binding(orig_port, context.original_host)

if context.status == n_const.PORT_STATUS_DOWN:
if (context.original_host and
context.status != context.original_status):
self.delete_port_binding(orig_port, context.original_host)
self._try_to_release_dynamic_segment(context, migration=True)
else:
if context.status in [n_const.PORT_STATUS_ACTIVE,
n_const.PORT_STATUS_BUILD]:
if context.binding_levels:
segments = [
level['bound_segment'] for level in context.binding_levels]
self.create_network(network, segments)
self.create_port_binding(port, context.host)
else:
if (context.original_host and
context.status != context.original_status):
self.delete_port_binding(orig_port, context.original_host)
self._try_to_release_dynamic_segment(context, migration=True)

def delete_port_postcommit(self, context):
"""Delete the port from CVX"""


+ 56
- 0
networking_arista/tests/unit/common/test_db_lib.py View File

@@ -250,3 +250,59 @@ class DbLibTest(testlib_api.SqlTestCase):
'driver': 'arista'}]}])
self.assertTrue(db_lib.segment_bound(bound_segment_id))
self.assertFalse(db_lib.segment_bound(unbound_segment_id))

def test_empty_device_id(self):
utils.create_networks([{'id': 'n1',
'project_id': 't1'}])
utils.create_segments([{'id': 's1',
'network_id': 'n1',
'network_type': 'vlan',
'segmentation_id': 100,
'is_dynamic': True}])
utils.create_ports([{'admin_state_up': True,
'status': 'ERROR',
'device_id': '',
'device_owner': 'compute:None',
'binding': {'host': 'host',
'vif_type': 'other',
'vnic_type': 'baremetal'},
'tenant_id': 't1',
'id': 'p1',
'network_id': 'n1',
'mac_address': '01:02:03:04:05:06',
'binding_levels': []},
{'admin_state_up': True,
'status': 'ACTIVE',
'device_id': 'bm1',
'device_owner': 'compute:None',
'binding': {'host': 'host',
'vif_type': 'other',
'vnic_type': 'baremetal'},
'tenant_id': 't1',
'id': 'p2',
'network_id': 'n1',
'mac_address': '01:02:03:04:05:07',
'binding_levels': [
{'host': 'host',
'segment_id': 's1',
'level': 0,
'driver': 'arista'}]},
{'admin_state_up': True,
'status': 'ACTIVE',
'device_id': 'bm2',
'device_owner': 'compute:None',
'binding': {'host': 'host',
'vif_type': 'other',
'vnic_type': 'baremetal'},
'tenant_id': 't1',
'id': 'p3',
'network_id': 'n1',
'mac_address': '01:02:03:04:05:08',
'binding_levels': [
{'host': 'host',
'segment_id': 's1',
'level': 0,
'driver': 'arista'}]}])
expected_instances = []
instances = db_lib.get_baremetal_instances(instance_id='')
self.assertItemsEqual(instances, expected_instances)

+ 5
- 0
networking_arista/tests/unit/ml2/ml2_test_base.py View File

@@ -61,6 +61,7 @@ class MechTestBase(test_plugin.Ml2PluginV2TestCase):

def setUp(self):
if ENABLE_LOGGING:
log_fixture.setlevel.logging.root.setLevel(logging.DEBUG)
self.useFixture(log_fixture.SetLogLevel(['neutron'],
logging.DEBUG))
if ENABLE_PROFILER:
@@ -292,6 +293,10 @@ class MechTestBase(test_plugin.Ml2PluginV2TestCase):
self.plugin.update_port_status(
self.context, port['id'], n_const.PORT_STATUS_DOWN, host)

def set_port_to_error_state(self, port):
self.plugin.update_port_status(
self.context, port['id'], n_const.PORT_STATUS_ERROR)

def delete_port(self, port_id):
self.plugin.delete_port(self.context, port_id)



+ 34
- 0
networking_arista/tests/unit/ml2/test_mechanism_arista.py View File

@@ -786,6 +786,40 @@ class BasicMechDriverTestCase(ml2_test_base.MechTestBase):
self.assertPortBindingDeleted(
(subport['id'], (switch_id, switch_port)))

def test_error_port(self):
network_tenant = 'net-ten'
net_dict = {'network': {'name': 'net',
'tenant_id': network_tenant,
'admin_state_up': True,
'shared': False,
'provider:physical_network': self.physnet,
'provider:network_type': 'vlan'}}
network, _ = self.create_network(net_dict)

# Create port
device_id = 'vm-1'
port_tenant = 'port-ten'
port_host = self.host1
port_dict = {'name': 'port1',
'tenant_id': port_tenant,
'network_id': network['id'],
'admin_state_up': True,
'fixed_ips': [],
'device_id': device_id,
'device_owner': 'compute:',
'binding:host_id': port_host}
port, _ = self.create_port(port_dict)
self.assertTenantCreated(port_tenant)
self.assertVmCreated(device_id)
self.assertVmPortCreated(port['id'])
self.assertPortBindingCreated((port['id'], port_host))

# Set port to ERROR state
self.set_port_to_error_state(port)
self.assertVmDeleted(device_id)
self.assertVmPortDeleted(port['id'])
self.assertPortBindingDeleted((port['id'], port_host))


class BasicHpbMechDriverTestCase(ml2_test_base.MechTestBase):



Loading…
Cancel
Save