summaryrefslogtreecommitdiff
path: root/neutron
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-07-04 08:52:24 +0000
committerGerrit Code Review <review@openstack.org>2022-07-04 08:52:24 +0000
commit96acf7283c2053e0dcc7052bb90977ddf7548c1f (patch)
tree191f53bf677f59fb3c10f073d1d42c16ebecae8c /neutron
parent5709c984bca1c9fc628929bfecdc595aea36d4fb (diff)
parentcfc0678caf39a5ec002fc56a878275a94dc11b94 (diff)
downloadneutron-96acf7283c2053e0dcc7052bb90977ddf7548c1f.tar.gz
Merge "[ovn]support read chassis update time from nb_cfg_timestamp" into stable/yoga
Diffstat (limited to 'neutron')
-rw-r--r--neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py17
-rw-r--r--neutron/tests/functional/base.py5
-rw-r--r--neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py18
-rw-r--r--neutron/tests/unit/agent/l2/extensions/dhcp/test_ipv6.py15
-rw-r--r--neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py27
5 files changed, 76 insertions, 6 deletions
diff --git a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
index 0e5d57d9eb..6f0d69eec7 100644
--- a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
+++ b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
@@ -14,6 +14,7 @@
import abc
import copy
+import datetime
from oslo_config import cfg
from oslo_utils import timeutils
@@ -44,7 +45,21 @@ class NeutronAgent(abc.ABC):
def update(self, chassis_private, updated_at=None, clear_down=False):
self.chassis_private = chassis_private
- self.updated_at = updated_at or timeutils.utcnow(with_timezone=True)
+ if not updated_at:
+ # When use the Chassis_Private table for agents health check,
+ # chassis_private has attribute nb_cfg_timestamp.
+ # nb_cfg_timestamp: the timestamp when ovn-controller finishes
+ # processing the change corresponding to nb_cfg(
+ # https://www.ovn.org/support/dist-docs/ovn-sb.5.html).
+ # it can better reflect the status of chassis.
+ # nb_cfg_timestamp is milliseconds, need to convert to datetime.
+ if hasattr(chassis_private, 'nb_cfg_timestamp'):
+ updated_at = datetime.datetime.fromtimestamp(
+ chassis_private.nb_cfg_timestamp / 1000,
+ datetime.timezone.utc)
+ else:
+ updated_at = timeutils.utcnow(with_timezone=True)
+ self.updated_at = updated_at
if clear_down:
self.set_down = False
diff --git a/neutron/tests/functional/base.py b/neutron/tests/functional/base.py
index f50ef4cfe7..dc1c70af7b 100644
--- a/neutron/tests/functional/base.py
+++ b/neutron/tests/functional/base.py
@@ -29,6 +29,7 @@ from oslo_config import cfg
from oslo_db import exception as os_db_exc
from oslo_db.sqlalchemy import provision
from oslo_log import log
+from oslo_utils import timeutils
from oslo_utils import uuidutils
from neutron.agent.linux import utils
@@ -450,9 +451,11 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase,
name, ['geneve'], '172.24.4.%d' % self._counter,
external_ids=external_ids, hostname=host).execute(check_error=True)
if self.sb_api.is_table_present('Chassis_Private'):
+ nb_cfg_timestamp = timeutils.utcnow_ts() * 1000
self.sb_api.db_create(
'Chassis_Private', name=name, external_ids=external_ids,
- chassis=chassis.uuid).execute(check_error=True)
+ chassis=chassis.uuid, nb_cfg_timestamp=nb_cfg_timestamp
+ ).execute(check_error=True)
return name
def del_fake_chassis(self, chassis, if_exists=True):
diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py
index 08d955c8c6..3e184fdf89 100644
--- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py
+++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py
@@ -11,7 +11,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-
+import datetime
import functools
from unittest import mock
@@ -22,6 +22,7 @@ from neutron_lib.api.definitions import portbindings
from neutron_lib.plugins import constants as plugin_constants
from neutron_lib.plugins import directory
from oslo_concurrency import processutils
+from oslo_utils import timeutils
from oslo_utils import uuidutils
from ovsdbapp.backend.ovs_idl import event
from ovsdbapp.backend.ovs_idl import idlutils
@@ -454,6 +455,21 @@ class TestAgentMonitor(base.TestOVNFunctionalBase):
self.assertEqual(neutron_agent.ControllerAgent,
type(neutron_agent.AgentCache()[self.chassis_name]))
+ def test_agent_updated_at_use_nb_cfg_timestamp(self):
+ if not self.sb_api.is_table_present('Chassis_Private'):
+ self.skipTest('Ovn sb not support Chassis_Private')
+ timestamp = timeutils.utcnow_ts()
+ nb_cfg_timestamp = timestamp * 1000
+ updated_at = datetime.datetime.fromtimestamp(
+ timestamp, datetime.timezone.utc)
+ self.sb_api.db_set('Chassis_Private', self.chassis_name, (
+ 'nb_cfg_timestamp', nb_cfg_timestamp)).execute(check_error=True)
+ n_utils.wait_until_true(lambda:
+ neutron_agent.AgentCache()[self.chassis_name].
+ chassis_private.nb_cfg_timestamp == nb_cfg_timestamp)
+ agent = neutron_agent.AgentCache()[self.chassis_name]
+ self.assertEqual(updated_at, agent.updated_at)
+
class TestOvnIdlProbeInterval(base.TestOVNFunctionalBase):
def setUp(self):
diff --git a/neutron/tests/unit/agent/l2/extensions/dhcp/test_ipv6.py b/neutron/tests/unit/agent/l2/extensions/dhcp/test_ipv6.py
index 5ec0ca8343..6181d053ed 100644
--- a/neutron/tests/unit/agent/l2/extensions/dhcp/test_ipv6.py
+++ b/neutron/tests/unit/agent/l2/extensions/dhcp/test_ipv6.py
@@ -95,7 +95,10 @@ class DHCPIPv6ResponderTestCase(dhcp_test_base.DHCPResponderBaseTestCase):
expect_ident = (
b'\x00\x01\x00\x01\x00\x00\x00\x01\x00\x01\x02\x03\x04\x05')
- time.time = mock.Mock(return_value=ONE_SEC_AFTER_2000)
+ time_p = mock.patch.object(time, 'time',
+ return_value=ONE_SEC_AFTER_2000)
+ time_p.start()
+ self.addCleanup(time_p.stop)
client_ident = client_ident = (
self.dhcp6_responer.get_dhcpv6_client_ident(
self.port_info['mac_address'], []))
@@ -164,7 +167,10 @@ class DHCPIPv6ResponderTestCase(dhcp_test_base.DHCPResponderBaseTestCase):
option_list=option_list,
options_len=0)
- time.time = mock.Mock(return_value=ONE_SEC_AFTER_2000)
+ time_p = mock.patch.object(time, 'time',
+ return_value=ONE_SEC_AFTER_2000)
+ time_p.start()
+ self.addCleanup(time_p.stop)
packet_in = self._create_test_dhcp6_packet(zero_time=zero_time)
pkt_dhcp = packet_in.get_protocol(dhcp6.dhcp6)
dhcp_req_state = dhcp_ipv6.DHCPV6_TYPE_MAP.get(pkt_dhcp.msg_type)
@@ -192,7 +198,10 @@ class DHCPIPv6ResponderTestCase(dhcp_test_base.DHCPResponderBaseTestCase):
mac = '00:01:02:03:04:05'
packet_in = self._create_test_dhcp6_packet()
header_dhcp = packet_in.get_protocol(dhcp6.dhcp6)
- time.time = mock.Mock(return_value=ONE_SEC_AFTER_2000)
+ time_p = mock.patch.object(time, 'time',
+ return_value=ONE_SEC_AFTER_2000)
+ time_p.start()
+ self.addCleanup(time_p.stop)
dhcp_options = self.dhcp6_responer.get_reply_dhcp_options(
mac, message="all addresses still on link",
req_options=header_dhcp.options.option_list)
diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
index 04808f8d53..9b3fcac8f0 100644
--- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
+++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
@@ -2217,6 +2217,33 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
self.assertFalse(agent.alive, "Agent of type %s alive=%s" %
(agent.agent_type, agent.alive))
+ def test_agent_with_nb_cfg_timestamp_timeout(self):
+ nb_cfg = 3
+ chassis_private = self._add_chassis(nb_cfg)
+
+ self.mech_driver.nb_ovn.nb_global.nb_cfg = nb_cfg + 2
+ updated_at = (timeutils.utcnow_ts() - cfg.CONF.agent_down_time - 1
+ ) * 1000
+ chassis_private.nb_cfg_timestamp = updated_at
+ agent_type = ovn_const.OVN_CONTROLLER_AGENT
+ agent = self._add_chassis_agent(nb_cfg, agent_type,
+ chassis_private)
+ self.assertFalse(agent.alive, "Agent of type %s alive=%s" %
+ (agent.agent_type, agent.alive))
+
+ def test_agent_with_nb_cfg_timestamp_not_timeout(self):
+ nb_cfg = 3
+ chassis_private = self._add_chassis(nb_cfg)
+
+ self.mech_driver.nb_ovn.nb_global.nb_cfg = nb_cfg + 2
+ updated_at = timeutils.utcnow_ts() * 1000
+ chassis_private.nb_cfg_timestamp = updated_at
+ agent_type = ovn_const.OVN_CONTROLLER_AGENT
+ agent = self._add_chassis_agent(nb_cfg, agent_type,
+ chassis_private)
+ self.assertTrue(agent.alive, "Agent of type %s alive=%s" % (
+ agent.agent_type, agent.alive))
+
def _test__update_dnat_entry_if_needed(self, up=True):
ovn_conf.cfg.CONF.set_override(
'enable_distributed_floating_ip', True, group='ovn')