summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Riteau <pierre@stackhpc.com>2023-02-24 05:34:07 +0100
committerPierre Riteau <pierre@stackhpc.com>2023-02-24 05:34:07 +0100
commit827fbd01c306ce292e46b0d881bc3cc804202285 (patch)
treee3be1040417172c1985031356b8ad37e00478935
parentaa40aef70fac609c086c4c6511c6b17e597da044 (diff)
downloadneutron-827fbd01c306ce292e46b0d881bc3cc804202285.tar.gz
Normalise format of OVN agent heartbeat timestamp
A recent change [1] to show the real heartbeat timestamp from OVN agents had a side effect of changing the timestamp format, which now includes a timezone: +-------------------+----------------------------------+ | Field | Value | +-------------------+----------------------------------+ | last_heartbeat_at | 2023-02-23 14:12:07.471000+00:00 | +-------------------+----------------------------------+ This unexpected format change causes some clients to fail to parse the response to GET /v2.0/agents. Normalise the format of the timestamp to remove timezone information. Also remove the microsecond part, which was not done for OVN, but is absent from other network agents. [1] https://review.opendev.org/c/openstack/neutron/+/844179 Closes-Bug: #2008257 Change-Id: I75a37fb9b49a421e4524da6b56ef8362ceb6107b
-rw-r--r--neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py3
-rw-r--r--neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py2
-rw-r--r--neutron/tests/unit/plugins/ml2/drivers/ovn/agent/test_neutron_agent.py17
-rw-r--r--releasenotes/notes/fix-ovn-agent-heartbeat-timestamp-format-dcf80badbe267c68.yaml6
4 files changed, 26 insertions, 2 deletions
diff --git a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
index 61f8ded970..222c9e9cce 100644
--- a/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
+++ b/neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py
@@ -81,7 +81,8 @@ class NeutronAgent(abc.ABC):
return {
'binary': self.binary,
'host': self.chassis.hostname,
- 'heartbeat_timestamp': self.updated_at,
+ 'heartbeat_timestamp': timeutils.normalize_time(
+ self.updated_at.replace(microsecond=0)),
'availability_zone': ', '.join(
ovn_utils.get_chassis_availability_zones(self.chassis)),
'topic': 'n/a',
diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
index b7cb07735c..18f3f0d554 100644
--- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
+++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py
@@ -1148,7 +1148,7 @@ class TestAgentApi(base.TestOVNFunctionalBase):
'Chassis_Private', self.chassis, 'nb_cfg_timestamp'
).execute(check_error=True)
updated_at = datetime.datetime.fromtimestamp(
- int(chassis_ts / 1000), datetime.timezone.utc)
+ int(chassis_ts / 1000))
# if table Chassis_Private present, agent.updated_at is
# Chassis_Private.nb_cfg_timestamp
self.assertEqual(updated_at, heartbeat_timestamp)
diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/agent/test_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/agent/test_neutron_agent.py
index cd92c93753..9f92a65ff0 100644
--- a/neutron/tests/unit/plugins/ml2/drivers/ovn/agent/test_neutron_agent.py
+++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/agent/test_neutron_agent.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import datetime
from unittest import mock
import eventlet
@@ -67,3 +68,19 @@ class AgentCacheTestCase(base.BaseTestCase):
agents = list(agents)
self.assertEqual(1, len(agents))
self.assertEqual('chassis5', agents[0].agent_id)
+
+ @mock.patch.object(neutron_agent.ControllerAgent, 'alive')
+ def test_heartbeat_timestamp_format(self, agent_alive):
+ chassis_private = fakes.FakeOvsdbRow.create_one_ovsdb_row(
+ attrs={'name': 'chassis5'})
+ agents = self.agent_cache.agents_by_chassis_private(chassis_private)
+ agent = list(agents)[0]
+ agent.chassis.hostname = 'fake-hostname'
+ agent.updated_at = datetime.datetime(
+ year=2023, month=2, day=23, hour=1, minute=2, second=3,
+ microsecond=456789).replace(tzinfo=datetime.timezone.utc)
+ agent_alive.return_value = True
+
+ # Verify that both microseconds and timezone are dropped
+ self.assertEqual(str(agent.as_dict()['heartbeat_timestamp']),
+ '2023-02-23 01:02:03')
diff --git a/releasenotes/notes/fix-ovn-agent-heartbeat-timestamp-format-dcf80badbe267c68.yaml b/releasenotes/notes/fix-ovn-agent-heartbeat-timestamp-format-dcf80badbe267c68.yaml
new file mode 100644
index 0000000000..0f806e7b8a
--- /dev/null
+++ b/releasenotes/notes/fix-ovn-agent-heartbeat-timestamp-format-dcf80badbe267c68.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Normalise OVN agent heartbeat timestamp format to match other agent types.
+ This fixes parsing of ``GET /v2.0/agents`` for some clients, such as
+ gophercloud.