Optionally change service port for ssl

If a charm class sets ssl_port_bump to True then when configuring
the service for TLS also change the port it is listening on.

The need for this comes from the nova-scheduler and nova-compute
services which cache the url for the placement service, when the
placement service switches protocol the nova services fail which
does not trigger them to reexamine the catalogue.

Closes-Bug: #1862974

Change-Id: I790c55e78439b9a5ea2c3f12edbe5928a4f08e05
This commit is contained in:
Liam Young 2020-09-24 17:08:27 +00:00
parent 69eb753b02
commit c1db249cfb
3 changed files with 31 additions and 14 deletions

View File

@ -727,7 +727,7 @@ class APIConfigurationAdapter(ConfigurationAdapter):
"APIConfigurationAdapter.__init__()", level=hookenv.WARNING)
self.port_map = port_map
elif self.charm_instance is not None:
self.port_map = self.charm_instance.api_ports
self.port_map = self.charm_instance.active_api_ports
else:
self.port_map = None
if service_name is not None:

View File

@ -413,15 +413,32 @@ class BaseOpenStackCharm(object, metaclass=BaseOpenStackCharmMeta):
charm_instance=self)
return self.__options
@property
def active_api_ports(self):
"""Return the api port map adjusting ports as required.
"""
# If charm class sets ssl_port_bump to True then
# prepend a 1 to the port number eg 8779 -> 18779
ssl_port_bump = getattr(self, 'ssl_port_bump', False)
if ssl_port_bump and self.get_state('ssl.enabled'):
_api_ports = {}
for svc in self.api_ports:
_api_ports[svc] = {}
for ep_type, port in self.api_ports[svc].items():
_api_ports[svc][ep_type] = int("1{}".format(port))
return _api_ports
else:
return self.api_ports
def api_port(self, service, endpoint_type=os_ip.PUBLIC):
"""Return the API port for a particular endpoint type from the
self.api_ports{}.
self.active_api_ports{}.
:param service: string for service name
:param endpoing_type: one of charm.openstack.ip.PUBLIC| INTERNAL| ADMIN
:returns: port (int)
"""
return self.api_ports[service][endpoint_type]
return self.active_api_ports[service][endpoint_type]
def set_state(self, state, value=None):
"""proxy for charms.reactive.bus.set_state()"""
@ -929,7 +946,7 @@ class BaseOpenStackCharmActions(object):
:param ports: List of api port numbers or None.
"""
ports = list(map(int, (
ports or self._default_port_list(self.api_ports or {}))))
ports or self._default_port_list(self.active_api_ports or {}))))
current_ports = list(map(int, self.opened_ports()))
ports_to_open = set(ports).difference(current_ports)
ports_to_close = set(current_ports).difference(ports)
@ -1261,7 +1278,7 @@ class BaseOpenStackCharmAssessStatus(object):
"""
return os_utils._ows_check_if_paused(
services=self.services,
ports=self.ports_to_check(self.api_ports))
ports=self.ports_to_check(self.active_api_ports))
def ports_to_check(self, ports):
"""Return a flattened, sorted, unique list of ports from self.api_ports
@ -1382,8 +1399,8 @@ class BaseOpenStackCharmAssessStatus(object):
def check_services_running(self):
"""Check that the services that should be running are actually running.
This uses the self.services and self.api_ports to determine what should
be checked.
This uses the self.services and self.active_api_ports to determine what
should be checked.
:returns: (status, message) or (None, None).
"""
@ -1391,7 +1408,7 @@ class BaseOpenStackCharmAssessStatus(object):
# is not running or the ports are not open.
_services, _ports = ch_cluster.get_managed_services_and_ports(
self.services,
self.ports_to_check(self.api_ports))
self.ports_to_check(self.active_api_ports))
return os_utils._ows_check_services_running(
services=_services,
ports=_ports)

View File

@ -582,14 +582,14 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
class TestCharm(object):
api_ports = TestAPIConfigurationAdapter.api_ports
active_api_ports = TestAPIConfigurationAdapter.api_ports
name = 'test-charm'
with mock.patch.object(adapters.hookenv, 'config', new=lambda: {}), \
mock.patch.object(adapters.APIConfigurationAdapter,
'get_network_addresses'):
c = adapters.APIConfigurationAdapter(charm_instance=TestCharm())
self.assertEqual(c.port_map, TestCharm.api_ports)
self.assertEqual(c.port_map, TestCharm.active_api_ports)
self.assertEqual(c.service_name, 'test-charm')
def test_ipv4_mode(self):
@ -853,7 +853,7 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
def test_memcache_ctx(self):
class MockCharmInstance(object):
api_ports = {}
active_api_ports = {}
name = 'hello'
def __init__(self, release):
@ -974,7 +974,7 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
class ChInstance1(object):
name = 'test-name'
wsgi_script = 'test-script'
api_ports = {}
api_ports = active_api_ports = {}
class ChInstance2(object):
name = 'test-name'
@ -984,7 +984,7 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
wsgi_process_weight = 0.5
wsgi_admin_process_weight = 0.1
wsgi_public_process_weight = 0.4
api_ports = {}
api_ports = active_api_ports = {}
class ChInstance3(object):
name = 'test-name'
@ -994,7 +994,7 @@ class TestAPIConfigurationAdapter(unittest.TestCase):
wsgi_process_weight = None
wsgi_admin_process_weight = 0.1
wsgi_public_process_weight = 0.4
api_ports = {}
api_ports = active_api_ports = {}
class FakeWSGIWorkerConfigContext():
copy_kwargs = None