Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion neutron/agent/ovn/agent/ovn_neutron_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ def __init__(self, conf):
self.ovn_bridge = None
self.ext_manager_api = ext_mgr.OVNAgentExtensionAPI()
self.ext_manager = ext_mgr.OVNAgentExtensionManager(self._conf)
self.ext_manager.initialize(None, 'ovn', self.ext_manager_api)
self.ext_manager.initialize(None, 'ovn', self)

def __getitem__(self, name):
"""Return the named extension objet from ``self.ext_manager``"""
return self.ext_manager[name].obj

@property
def ovs_idl(self):
Expand Down
7 changes: 6 additions & 1 deletion neutron/agent/ovn/extensions/extension_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,14 @@ def __init__(self):
super().__init__()
self.agent_api = None

@property
@abc.abstractmethod
def name(self):
pass

def initialize(self, *args):
"""Initialize agent extension."""
self.agent_api = None
pass

def consume_api(self, agent_api):
"""Configure the Agent API.
Expand Down
4 changes: 4 additions & 0 deletions neutron/agent/ovn/extensions/noop.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

class NoopOVNAgentExtension(extension_manager.OVNAgentExtension):

@property
def name(self):
return 'Noop OVN agent extension'

@property
def ovs_idl_events(self):
return []
Expand Down
21 changes: 13 additions & 8 deletions neutron/agent/ovn/extensions/qos_hwol.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@


LOG = logging.getLogger(__name__)
EXT_NAME = 'qos_hwol'
# NOTE(ralonsoh): move these constants from ``eswitch_manager`` to ``pci_lib``.
MAX_TX_RATE = eswitch_manager.IP_LINK_CAPABILITY_RATE
MIN_TX_RATE = eswitch_manager.IP_LINK_CAPABILITY_MIN_TX_RATE
Expand Down Expand Up @@ -59,10 +60,10 @@ def match_fn(self, event, row, old):

def run(self, event, row, old):
if event in (self.ROW_CREATE, self.ROW_UPDATE):
self.ovn_agent.qos_hwol_ext.add_port(
self.ovn_agent[EXT_NAME].add_port(
row.external_ids['iface-id'], row.name)
elif event == self.ROW_DELETE:
self.ovn_agent.qos_hwol_ext.remove_egress(
self.ovn_agent[EXT_NAME].remove_egress(
row.external_ids['iface-id'])
LOG.debug(self.LOG_MSG, row.external_ids['iface-id'], row.name, event)

Expand All @@ -82,7 +83,7 @@ def match_fn(self, event, row, old):

# Check if the port has a Port ID and if this ID is bound to this host.
port_id = row.external_ids.get(ovn_const.OVN_PORT_EXT_ID_KEY)
if not port_id or not self.ovn_agent.qos_hwol_ext.get_port(port_id):
if not port_id or not self.ovn_agent[EXT_NAME].get_port(port_id):
return False

if event in (self.ROW_CREATE, self.ROW_DELETE):
Expand All @@ -104,7 +105,7 @@ def run(self, event, row, old):
max_kbps, min_kbps = agent_ovsdb.get_port_qos(self.ovn_agent.nb_idl,
port_id)
LOG.debug(self.LOG_MSG, str(row.uuid), port_id, max_kbps, event)
self.ovn_agent.qos_hwol_ext.update_egress(port_id, max_kbps, min_kbps)
self.ovn_agent[EXT_NAME].update_egress(port_id, max_kbps, min_kbps)


class QoSMinimumBandwidthEvent(row_event.RowEvent):
Expand All @@ -129,7 +130,7 @@ def match_fn(self, event, row, old):
except (KeyError, AttributeError):
return False

if not self.ovn_agent.qos_hwol_ext.get_port(row.name):
if not self.ovn_agent[EXT_NAME].get_port(row.name):
return False

return True
Expand All @@ -138,7 +139,7 @@ def run(self, event, row, old):
max_kbps, min_kbps = agent_ovsdb.get_port_qos(self.ovn_agent.nb_idl,
row.name)
LOG.debug(self.LOG_MSG, row.name, min_kbps, event)
self.ovn_agent.qos_hwol_ext.update_egress(row.name, max_kbps, min_kbps)
self.ovn_agent[EXT_NAME].update_egress(row.name, max_kbps, min_kbps)


class _PortBindingChassisEvent(row_event.RowEvent):
Expand Down Expand Up @@ -176,8 +177,8 @@ def run(self, event, row, old):
event)
max_kbps, min_kbps = agent_ovsdb.get_port_qos(self.ovn_agent.nb_idl,
row.logical_port)
self.ovn_agent.qos_hwol_ext.update_egress(row.logical_port, max_kbps,
min_kbps)
self.ovn_agent[EXT_NAME].update_egress(row.logical_port, max_kbps,
min_kbps)


class QoSHardwareOffloadExtension(extension_manager.OVNAgentExtension):
Expand All @@ -187,6 +188,10 @@ def __init__(self):
# _ovs_ports = {Neutron port ID: OVS port name}
self._ovs_ports = {}

@property
def name(self):
return 'QoS hardware offloaded extension'

@property
def ovs_idl_events(self):
return [OVSInterfaceEvent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def run(self, event, row, old):

class FakeOVNAgentExtension(ext_mgr.OVNAgentExtension):

@property
def name(self):
return 'Fake OVN agent extension'

@property
def ovs_idl_events(self):
return [OVSInterfaceEvent]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
from neutron.tests.functional import base


TEST_EXTENSION = 'testing'


class TestOVNNeutronAgent(base.TestOVNFunctionalBase):

OVN_BRIDGE = 'br-int'
Expand All @@ -36,9 +39,13 @@ def setUp(self, **kwargs):
agent_ovsdb, 'get_own_chassis_name').start()
self.ovn_agent = self._start_ovn_neutron_agent()

def _check_loaded_extensions(self, ovn_agent):
loaded_ext = ovn_agent[TEST_EXTENSION]
self.assertEqual('Fake OVN agent extension', loaded_ext.name)

def _start_ovn_neutron_agent(self):
conf = self.useFixture(fixture_config.Config()).conf
conf.set_override('extensions', 'testing', group='agent')
conf.set_override('extensions', TEST_EXTENSION, group='agent')
ovn_nb_db = self.ovsdb_server_mgr.get_ovsdb_connection_path('nb')
conf.set_override('ovn_nb_connection', ovn_nb_db, group='ovn')
ovn_sb_db = self.ovsdb_server_mgr.get_ovsdb_connection_path('sb')
Expand All @@ -52,6 +59,7 @@ def _start_ovn_neutron_agent(self):
agt.test_ovn_sb_idl = []
agt.test_ovn_nb_idl = []
agt.start()
self._check_loaded_extensions(agt)

self.add_fake_chassis(self.FAKE_CHASSIS_HOST, name=self.chassis_name)

Expand Down
16 changes: 8 additions & 8 deletions neutron/tests/functional/agent/ovn/extensions/test_qos_hwol.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _cleanup(self):
def test_port_creation_and_deletion(self):
def check_add_port_called():
try:
mock_agent.qos_hwol_ext.add_port.assert_has_calls(
mock_agent[qos_hwol.EXT_NAME].add_port.assert_has_calls(
[mock.call(port_iface_id, self.port_name)])
return True
except AssertionError:
Expand All @@ -52,7 +52,7 @@ def check_remove_egress_called():
return False

port_iface_id = 'port_iface-id'
mock_agent = mock.Mock()
mock_agent = mock.MagicMock()
events = [qos_hwol.OVSInterfaceEvent(mock_agent)]
self.ovs_idl = agent_ovsdb.MonitorAgentOvsIdl(events=events).start()
self.br_name = ('brtest-' + uuidutils.generate_uuid())[:13]
Expand Down Expand Up @@ -91,13 +91,13 @@ def setUp(self, **kwargs):
def test_qos_bw_limit_created_and_updated(self):
def check_update_egress_called(rate):
try:
mock_agent.qos_hwol_ext.update_egress.assert_has_calls(
mock_agent[qos_hwol.EXT_NAME].update_egress.assert_has_calls(
[mock.call(port_id, rate, 0)])
return True
except AssertionError:
return False

mock_agent = mock.Mock(nb_idl=self.nb_api)
mock_agent = mock.MagicMock(nb_idl=self.nb_api)
events = [qos_hwol.QoSBandwidthLimitEvent(mock_agent)]
agent_ovsdb.MonitorAgentOvnNbIdl(qos_hwol.NB_IDL_TABLES,
events).start()
Expand Down Expand Up @@ -133,13 +133,13 @@ def setUp(self, **kwargs):
def test_qos_min_bw_created_and_updated(self):
def check_update_egress_called(max_kbps, min_kbps):
try:
mock_agent.qos_hwol_ext.update_egress.assert_has_calls(
mock_agent[qos_hwol.EXT_NAME].update_egress.assert_has_calls(
[mock.call(port_id, max_kbps, min_kbps)])
return True
except AssertionError:
return False

mock_agent = mock.Mock(nb_idl=self.nb_api)
mock_agent = mock.MagicMock(nb_idl=self.nb_api)
events = [qos_hwol.QoSMinimumBandwidthEvent(mock_agent)]
agent_ovsdb.MonitorAgentOvnNbIdl(qos_hwol.NB_IDL_TABLES,
events).start()
Expand Down Expand Up @@ -169,15 +169,15 @@ def test_port_binding_chassis_create_event(self, mock_get_port_qos,
*args):
def check_update_egress_called(max_kbps, min_kbps):
try:
mock_agent.qos_hwol_ext.update_egress.assert_has_calls(
mock_agent[qos_hwol.EXT_NAME].update_egress.assert_has_calls(
[mock.call(self.port['id'], max_kbps, min_kbps)])
return True
except AssertionError:
return False

max_kbps, min_kbps = 1000, 800
mock_get_port_qos.return_value = max_kbps, min_kbps
mock_agent = mock.Mock(nb_idl=self.nb_api)
mock_agent = mock.MagicMock(nb_idl=self.nb_api)
events = [qos_hwol.PortBindingChassisCreatedEvent(mock_agent)]
chassis_name = self.add_fake_chassis('ovn-host-fake')
mock_agent.chassis = chassis_name
Expand Down