From c84fe147a3e4345cf18d1c80d1ded2889c13c3e4 Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Fri, 31 Mar 2023 20:49:28 -0700 Subject: [PATCH] Utilize the JSON-RPC port Adds storage of the json-rpc port number to the conductor hostname to enable rpc clients to understand which rpc servies they need to connect to. Depends-On: https://review.opendev.org/c/openstack/ironic-lib/+/879211 Change-Id: I6021152c83ab5025a9a9e6d8d24c64278c4c1053 --- ironic/common/release_mappings.py | 2 +- ironic/conductor/base_manager.py | 17 ++++++++++++ ironic/conductor/manager.py | 2 +- ironic/conductor/rpcapi.py | 3 ++- .../tests/unit/conductor/test_base_manager.py | 27 +++++++++++++++++++ ...hostname-for-jsonrpc-cdcd2c20a68a22c1.yaml | 16 +++++++++++ requirements.txt | 2 +- 7 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/use-port-in-hostname-for-jsonrpc-cdcd2c20a68a22c1.yaml diff --git a/ironic/common/release_mappings.py b/ironic/common/release_mappings.py index 4fdc705385..33c5586af0 100644 --- a/ironic/common/release_mappings.py +++ b/ironic/common/release_mappings.py @@ -575,7 +575,7 @@ RELEASE_MAPPING = { }, 'master': { 'api': '1.87', - 'rpc': '1.57', + 'rpc': '1.58', 'objects': { 'Allocation': ['1.1'], 'BIOSSetting': ['1.1'], diff --git a/ironic/conductor/base_manager.py b/ironic/conductor/base_manager.py index c5c677ab38..538418f649 100644 --- a/ironic/conductor/base_manager.py +++ b/ironic/conductor/base_manager.py @@ -24,6 +24,7 @@ from ironic_lib import mdns from oslo_db import exception as db_exception from oslo_log import log from oslo_utils import excutils +from oslo_utils import netutils from oslo_utils import versionutils from ironic.common import context as ironic_context @@ -73,6 +74,15 @@ class BaseConductorManager(object): Under normal operation, this is also when the initial database connectivity is established for the conductor's normal operation. """ + # Determine the hostname to utilize/register + if (CONF.rpc_transport == 'json-rpc' + and CONF.json_rpc.port != 8089 + and self._use_jsonrpc_port()): + # in the event someone configures self.host + # as an ipv6 address... + host = netutils.escape_ipv6(self.host) + self.host = f'{host}:{CONF.json_rpc.port}' + # NOTE(TheJulia) We need to clear locks early on in the process # of starting where the database shows we still hold them. # This must be done before we re-register our existence in the @@ -224,6 +234,13 @@ class BaseConductorManager(object): self._started = True + def _use_jsonrpc_port(self): + """Determines if the JSON-RPC port can be used.""" + release_ver = versions.RELEASE_MAPPING.get(CONF.pin_release_version) + version_cap = (release_ver['rpc'] if release_ver + else self.RPC_API_VERSION) + return versionutils.is_compatible('1.58', version_cap) + def _use_groups(self): release_ver = versions.RELEASE_MAPPING.get(CONF.pin_release_version) # NOTE(jroll) self.RPC_API_VERSION is actually defined in a subclass, diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py index 5a98138b80..10deaf5d90 100644 --- a/ironic/conductor/manager.py +++ b/ironic/conductor/manager.py @@ -94,7 +94,7 @@ class ConductorManager(base_manager.BaseConductorManager): # NOTE(rloo): This must be in sync with rpcapi.ConductorAPI's. # NOTE(pas-ha): This also must be in sync with # ironic.common.release_mappings.RELEASE_MAPPING['master'] - RPC_API_VERSION = '1.57' + RPC_API_VERSION = '1.58' target = messaging.Target(version=RPC_API_VERSION) diff --git a/ironic/conductor/rpcapi.py b/ironic/conductor/rpcapi.py index f268a17aee..502e21947a 100644 --- a/ironic/conductor/rpcapi.py +++ b/ironic/conductor/rpcapi.py @@ -154,12 +154,13 @@ class ConductorAPI(object): | 1.55 - Added change_node_boot_mode | 1.56 - Added continue_inspection | 1.57 - Added do_node_service + | 1.58 - Added support for json-rpc port usage """ # NOTE(rloo): This must be in sync with manager.ConductorManager's. # NOTE(pas-ha): This also must be in sync with # ironic.common.release_mappings.RELEASE_MAPPING['master'] - RPC_API_VERSION = '1.57' + RPC_API_VERSION = '1.58' def __init__(self, topic=None): super(ConductorAPI, self).__init__() diff --git a/ironic/tests/unit/conductor/test_base_manager.py b/ironic/tests/unit/conductor/test_base_manager.py index 7de7be3724..8838cff076 100644 --- a/ironic/tests/unit/conductor/test_base_manager.py +++ b/ironic/tests/unit/conductor/test_base_manager.py @@ -311,6 +311,33 @@ class StartStopTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): # 3 without reuse of the database connection. self.assertEqual(2, mock_dbapi.call_count) + def test_start_with_json_rpc(self): + CONF.set_override('rpc_transport', 'json-rpc') + CONF.set_override('host', 'foo.bar.baz') + self._start_service() + res = objects.Conductor.get_by_hostname(self.context, self.hostname) + self.assertEqual(self.hostname, res['hostname']) + + def test_start_with_json_rpc_port(self): + CONF.set_override('rpc_transport', 'json-rpc') + CONF.set_override('host', 'foo.bar.baz') + CONF.set_override('port', 8192, group='json_rpc') + + self._start_service() + res = objects.Conductor.get_by_hostname(self.context, + self.service.host) + self.assertEqual(f'{self.hostname}:8192', res['hostname']) + + def test_start_without_jsonrpc_port_pined_version(self): + CONF.set_override('rpc_transport', 'json-rpc') + CONF.set_override('host', 'foo.bar.baz') + CONF.set_override('port', 8192, group='json_rpc') + CONF.set_override('pin_release_version', '21.4') + self._start_service() + res = objects.Conductor.get_by_hostname(self.context, + self.service.host) + self.assertEqual(self.hostname, res['hostname']) + class KeepAliveTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): def test__conductor_service_record_keepalive(self): diff --git a/releasenotes/notes/use-port-in-hostname-for-jsonrpc-cdcd2c20a68a22c1.yaml b/releasenotes/notes/use-port-in-hostname-for-jsonrpc-cdcd2c20a68a22c1.yaml new file mode 100644 index 0000000000..1226d59074 --- /dev/null +++ b/releasenotes/notes/use-port-in-hostname-for-jsonrpc-cdcd2c20a68a22c1.yaml @@ -0,0 +1,16 @@ +features: + - | + Adds the storage of the ``[json_rpc]port`` configuration value to the + internal conductor hostname field when the ``[DEFAULT]rpc_transport`` + setting is set to "json-rpc". This allows deployments to utilize varying + port configurations for JSON-RPC. As a result of this change, the RPC + API version has been incremented to ``1.57`` and the feature is not + available until any ``[DEFAULT]pin_release_version`` setting is removed. +upgrade: + - | + Operators utilizing JSON-RPC transport to conductors with a non-default + port configuration should expect to see the hash ring layout change as + the port number is now included in the hash ring calculation. This will + only occur once the hash ring pin has been removed. + - Requires ``ironic-lib`` version *5.5.0* for the json-rpc port to be + properly set and utilized. diff --git a/requirements.txt b/requirements.txt index d6918b9fec..a112cbd40d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ WebOb>=1.7.1 # MIT python-cinderclient!=4.0.0,>=3.3.0 # Apache-2.0 python-glanceclient>=2.8.0 # Apache-2.0 keystoneauth1>=4.2.0 # Apache-2.0 -ironic-lib>=5.4.0 # Apache-2.0 +ironic-lib>=5.5.0 # Apache-2.0 python-swiftclient>=3.2.0 # Apache-2.0 pytz>=2013.6 # MIT stevedore>=1.29.0 # Apache-2.0