diff options
Diffstat (limited to 'neutron/plugins')
4 files changed, 29 insertions, 41 deletions
diff --git a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py index 27595ee07f..0e5d57d9eb 100644 --- a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py +++ b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py @@ -243,3 +243,12 @@ class AgentCache: for cls in NeutronAgent.types.values()} # Return the cached agents of agent_ids whose keys are in the cache return (agent for agent in self if agent.agent_id in agent_ids) + + def get_agents(self, filters=None): + filters = filters or {} + agent_list = [] + for agent in self: + agent_dict = agent.as_dict() + if all(agent_dict[k] in v for k, v in filters.items()): + agent_list.append(agent) + return agent_list diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py index 42d7f5311b..f2373a38d3 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py @@ -953,8 +953,7 @@ class OVNMechanismDriver(api.MechanismDriver): # OVN chassis information is needed to ensure a valid port bind. # Collect port binding data and refuse binding if the OVN chassis - # cannot be found. - chassis_physnets = [] + # cannot be found or is dead. try: # The PortContext host property contains special handling that # we need to take into account, thus passing both the port Dict @@ -963,14 +962,6 @@ class OVNMechanismDriver(api.MechanismDriver): bind_host = self._ovn_client.determine_bind_host( port, port_context=context) - datapath_type, iface_types, chassis_physnets = ( - self.sb_ovn.get_chassis_data_for_ml2_bind_port(bind_host)) - iface_types = iface_types.split(',') if iface_types else [] - except RuntimeError: - LOG.debug('Refusing to bind port %(port_id)s due to ' - 'no OVN chassis for host: %(host)s', - {'port_id': port['id'], 'host': bind_host}) - return except n_exc.InvalidInput as e: # The port binding profile is validated both on port creation and # update. The new rules apply to a VNIC type previously not @@ -979,7 +970,23 @@ class OVNMechanismDriver(api.MechanismDriver): LOG.error('Validation of binding profile unexpectedly failed ' 'while attempting to bind port %s', port['id']) raise e - + agents = n_agent.AgentCache().get_agents({'host': bind_host}) + if not agents: + LOG.warning('Refusing to bind port %(port_id)s due to ' + 'no OVN chassis for host: %(host)s', + {'port_id': port['id'], 'host': bind_host}) + return + agent = agents[0] + if not agent.alive: + LOG.warning("Refusing to bind port %(pid)s to dead agent: " + "%(agent)s", {'pid': context.current['id'], + 'agent': agent}) + return + chassis = agent.chassis + datapath_type = chassis.external_ids.get('datapath-type', '') + iface_types = chassis.external_ids.get('iface-types', '') + iface_types = iface_types.split(',') if iface_types else [] + chassis_physnets = self.sb_ovn._get_chassis_physnets(chassis) for segment_to_bind in context.segments_to_bind: network_type = segment_to_bind['network_type'] segmentation_id = segment_to_bind['segmentation_id'] @@ -1290,12 +1297,8 @@ class OVNMechanismDriver(api.MechanismDriver): def get_agents(self, context, filters=None, fields=None, _driver=None): _driver.ping_all_chassis() filters = filters or {} - agent_list = [] - for agent in n_agent.AgentCache(): - agent_dict = agent.as_dict() - if all(agent_dict[k] in v for k, v in filters.items()): - agent_list.append(agent_dict) - return agent_list + agent_list = n_agent.AgentCache().get_agents(filters) + return [agent.as_dict() for agent in agent_list] def get_agent(self, context, id, fields=None, _driver=None): diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py index 0d16d3f100..e6266c53f0 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py @@ -657,16 +657,3 @@ class SbAPI(api.API, metaclass=abc.ABCMeta): :param chassis_type: The type of chassis :type chassis_type: string """ - - @abc.abstractmethod - def get_chassis_data_for_ml2_bind_port(self, hostname): - """Return chassis data for ML2 port binding. - - @param hostname: The hostname of the chassis - @type hostname: string - :returns: Tuple containing the chassis datapath type, - iface types and physical networks for the - OVN bridge mappings. - :raises: RuntimeError exception if an OVN chassis - does not exist. - """ diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py index 1ee32650a8..eaabe8a181 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py @@ -876,17 +876,6 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend): card_serial_number) raise RuntimeError(msg) - def get_chassis_data_for_ml2_bind_port(self, hostname): - try: - cmd = self.db_find_rows('Chassis', ('hostname', '=', hostname)) - chassis = next(c for c in cmd.execute(check_error=True)) - except StopIteration: - msg = _('Chassis with hostname %s does not exist') % hostname - raise RuntimeError(msg) - return (chassis.external_ids.get('datapath-type', ''), - chassis.external_ids.get('iface-types', ''), - self._get_chassis_physnets(chassis)) - def get_metadata_port_network(self, network): # TODO(twilson) This function should really just take a Row/RowView try: |