Browse Source

Merge "[OVN] Only account for bound ports in metadata agent" into stable/train

changes/82/789582/1
Zuul 1 week ago
committed by Gerrit Code Review
parent
commit
40afd45f01
4 changed files with 29 additions and 16 deletions
  1. +2
    -1
      networking_ovn/agent/metadata/agent.py
  2. +7
    -4
      networking_ovn/agent/metadata/server.py
  3. +10
    -3
      networking_ovn/ovsdb/impl_idl_ovn.py
  4. +10
    -8
      networking_ovn/tests/unit/agent/metadata/test_server.py

+ 2
- 1
networking_ovn/agent/metadata/agent.py View File

@ -225,7 +225,8 @@ class MetadataAgent(object):
self._load_config()
# Launch the server that will act as a proxy between the VM's and Nova.
proxy = metadata_server.UnixDomainMetadataProxy(self.conf)
proxy = metadata_server.UnixDomainMetadataProxy(self.conf,
self.chassis)
proxy.run()
tables = ('Encap', 'Port_Binding', 'Datapath_Binding', 'SB_Global',


+ 7
- 4
networking_ovn/agent/metadata/server.py View File

@ -45,8 +45,9 @@ MODE_MAP = {
class MetadataProxyHandler(object):
def __init__(self, conf):
def __init__(self, conf, chassis):
self.conf = conf
self.chassis = chassis
self.subscribe()
def subscribe(self):
@ -58,7 +59,8 @@ class MetadataProxyHandler(object):
# We need to open a connection to OVN SouthBound database for
# each worker so that we can process the metadata requests.
self.sb_idl = ovsdb.MetadataAgentOvnSbIdl(
tables=('Port_Binding', 'Datapath_Binding')).start()
tables=('Port_Binding', 'Datapath_Binding', 'Chassis'),
chassis=self.chassis).start()
@webob.dec.wsgify(RequestClass=webob.Request)
def __call__(self, req):
@ -175,8 +177,9 @@ class MetadataProxyHandler(object):
class UnixDomainMetadataProxy(object):
def __init__(self, conf):
def __init__(self, conf, chassis):
self.conf = conf
self.chassis = chassis
agent_utils.ensure_directory_exists_without_file(
cfg.CONF.metadata_proxy_socket)
@ -201,7 +204,7 @@ class UnixDomainMetadataProxy(object):
def run(self):
self.server = agent_utils.UnixDomainWSGIServer(
'networking-ovn-metadata-agent')
self.server.start(MetadataProxyHandler(self.conf),
self.server.start(MetadataProxyHandler(self.conf, self.chassis),
self.conf.metadata_proxy_socket,
workers=self.conf.metadata_workers,
backlog=self.conf.metadata_backlog,


+ 10
- 3
networking_ovn/ovsdb/impl_idl_ovn.py View File

@ -803,9 +803,16 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
rows = self.db_list_rows('Port_Binding').execute(check_error=True)
# TODO(twilson) It would be useful to have a db_find that takes a
# comparison function
return [r for r in rows
if (r.mac and str(r.datapath.uuid) == network) and
ip_address in r.mac[0].split(' ')]
def check_net_and_ip(port):
# If the port is not bound to any chassis it is not relevant
if not port.chassis:
return False
return port.mac and str(port.datapath.uuid) == network and (
ip_address in port.mac[0].split(' '))
return [r for r in rows if check_net_and_ip(r)]
def set_port_cidrs(self, name, cidrs):
# TODO(twilson) add if_exists to db commands


+ 10
- 8
networking_ovn/tests/unit/agent/metadata/test_server.py View File

@ -26,7 +26,8 @@ import webob
from networking_ovn.agent.metadata import server as agent
from networking_ovn.conf.agent.metadata import config as meta_conf
OvnPortInfo = collections.namedtuple('OvnPortInfo', 'external_ids')
OvnPortInfo = collections.namedtuple(
'OvnPortInfo', ['external_ids', 'chassis'])
class ConfFixture(config_fixture.Config):
@ -53,7 +54,7 @@ class TestMetadataProxyHandler(base.BaseTestCase):
self.useFixture(self.fake_conf_fixture)
self.log_p = mock.patch.object(agent, 'LOG')
self.log = self.log_p.start()
self.handler = agent.MetadataProxyHandler(self.fake_conf)
self.handler = agent.MetadataProxyHandler(self.fake_conf, 'chassis1')
self.handler.sb_idl = mock.Mock()
def test_call(self):
@ -112,7 +113,8 @@ class TestMetadataProxyHandler(base.BaseTestCase):
ovn_port = OvnPortInfo(
external_ids={'neutron:device_id': 'device_id',
'neutron:project_id': 'project_id'})
'neutron:project_id': 'project_id'},
chassis=['chassis1'])
ports = [[ovn_port]]
self.assertEqual(
@ -219,14 +221,14 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
@mock.patch.object(fileutils, 'ensure_tree')
def test_init_doesnot_exists(self, ensure_dir):
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
ensure_dir.assert_called_once_with('/the', mode=0o755)
def test_init_exists(self):
with mock.patch('os.path.isdir') as isdir:
with mock.patch('os.unlink') as unlink:
isdir.return_value = True
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
def test_init_exists_unlink_no_file(self):
@ -237,7 +239,7 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
exists.return_value = False
unlink.side_effect = OSError
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
def test_init_exists_unlink_fails_file_still_exists(self):
@ -249,14 +251,14 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
unlink.side_effect = OSError
with testtools.ExpectedException(OSError):
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
@mock.patch.object(agent, 'MetadataProxyHandler')
@mock.patch.object(agent_utils, 'UnixDomainWSGIServer')
@mock.patch.object(fileutils, 'ensure_tree')
def test_run(self, ensure_dir, server, handler):
p = agent.UnixDomainMetadataProxy(self.cfg.CONF)
p = agent.UnixDomainMetadataProxy(self.cfg.CONF, 'chassis1')
p.run()
ensure_dir.assert_called_once_with('/the', mode=0o755)


Loading…
Cancel
Save