[wolsen,r=] Add support for overriding public endpoint addresses.
Adds in the config option for overriding public endpoint addresses and introduces a unit tests to ensure that the override for the public address is functioning correctly. Closes-Bug: #1398182
This commit is contained in:
12
config.yaml
12
config.yaml
@@ -100,6 +100,18 @@ options:
|
||||
192.168.0.0/24)
|
||||
.
|
||||
This network will be used for public endpoints.
|
||||
endpoint-public-name:
|
||||
type: string
|
||||
default:
|
||||
description: |
|
||||
The hostname or address of the public endpoints created for ceilometer
|
||||
in the keystone identity provider.
|
||||
.
|
||||
This value will be used for public endpoints. For example, an
|
||||
endpoint-public-name set to 'ceilometer.example.com' with ssl enabled will
|
||||
create the following public endpoints for ceilometer.
|
||||
.
|
||||
https://ceilometer.example.com:8777/
|
||||
# HA configuration settings
|
||||
vip:
|
||||
type: string
|
||||
|
||||
@@ -26,8 +26,6 @@ from charmhelpers.contrib.network.ip import (
|
||||
)
|
||||
from charmhelpers.contrib.hahelpers.cluster import is_clustered
|
||||
|
||||
from functools import partial
|
||||
|
||||
PUBLIC = 'public'
|
||||
INTERNAL = 'int'
|
||||
ADMIN = 'admin'
|
||||
@@ -35,15 +33,18 @@ ADMIN = 'admin'
|
||||
ADDRESS_MAP = {
|
||||
PUBLIC: {
|
||||
'config': 'os-public-network',
|
||||
'fallback': 'public-address'
|
||||
'fallback': 'public-address',
|
||||
'override': 'endpoint-public-name',
|
||||
},
|
||||
INTERNAL: {
|
||||
'config': 'os-internal-network',
|
||||
'fallback': 'private-address'
|
||||
'fallback': 'private-address',
|
||||
'override': 'endpoint-internal-name',
|
||||
},
|
||||
ADMIN: {
|
||||
'config': 'os-admin-network',
|
||||
'fallback': 'private-address'
|
||||
'fallback': 'private-address',
|
||||
'override': 'endpoint-admin-name',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,13 +58,35 @@ def canonical_url(configs, endpoint_type=PUBLIC):
|
||||
:param endpoint_type: str endpoint type to resolve.
|
||||
:param returns: str base URL for services on the current service unit.
|
||||
"""
|
||||
scheme = _get_scheme(configs)
|
||||
|
||||
# Allow the user to override the address which is used. This is
|
||||
# useful for proxy services or exposing a public endpoint url, etc.
|
||||
override_key = ADDRESS_MAP[endpoint_type]['override']
|
||||
addr_override = config(override_key)
|
||||
if addr_override:
|
||||
address = addr_override
|
||||
else:
|
||||
address = resolve_address(endpoint_type)
|
||||
if is_ipv6(address):
|
||||
address = "[{}]".format(address)
|
||||
|
||||
return '%s://%s' % (scheme, address)
|
||||
|
||||
|
||||
def _get_scheme(configs):
|
||||
"""Returns the scheme to use for the url (either http or https)
|
||||
depending upon whether https is in the configs value.
|
||||
|
||||
:param configs: OSTemplateRenderer config templating object to inspect
|
||||
for a complete https context.
|
||||
:returns: either 'http' or 'https' depending on whether https is
|
||||
configured within the configs context.
|
||||
"""
|
||||
scheme = 'http'
|
||||
if 'https' in configs.complete_contexts():
|
||||
scheme = 'https'
|
||||
address = resolve_address(endpoint_type)
|
||||
if is_ipv6(address):
|
||||
address = "[{}]".format(address)
|
||||
return '%s://%s' % (scheme, address)
|
||||
return scheme
|
||||
|
||||
|
||||
def resolve_address(endpoint_type=PUBLIC):
|
||||
@@ -109,38 +132,3 @@ def resolve_address(endpoint_type=PUBLIC):
|
||||
"clustered=%s)" % (net_type, clustered))
|
||||
|
||||
return resolved_address
|
||||
|
||||
|
||||
def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC,
|
||||
override=None):
|
||||
"""Returns the correct endpoint URL to advertise to Keystone.
|
||||
|
||||
This method provides the correct endpoint URL which should be advertised to
|
||||
the keystone charm for endpoint creation. This method allows for the url to
|
||||
be overridden to force a keystone endpoint to have specific URL for any of
|
||||
the defined scopes (admin, internal, public).
|
||||
|
||||
:param configs: OSTemplateRenderer config templating object to inspect
|
||||
for a complete https context.
|
||||
:param url_template: str format string for creating the url template. Only
|
||||
two values will be passed - the scheme+hostname
|
||||
returned by the canonical_url and the port.
|
||||
:param endpoint_type: str endpoint type to resolve.
|
||||
:param override: str the name of the config option which overrides the
|
||||
endpoint URL defined by the charm itself. None will
|
||||
disable any overrides (default).
|
||||
"""
|
||||
if override:
|
||||
# Return any user-defined overrides for the keystone endpoint URL.
|
||||
user_value = config(override)
|
||||
if user_value:
|
||||
return user_value.strip()
|
||||
|
||||
return url_template % (canonical_url(configs, endpoint_type), port)
|
||||
|
||||
|
||||
public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC)
|
||||
|
||||
internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL)
|
||||
|
||||
admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN)
|
||||
|
||||
@@ -31,7 +31,6 @@ TO_PATCH = [
|
||||
'get_ceilometer_context',
|
||||
'lsb_release',
|
||||
'get_packages',
|
||||
'canonical_url',
|
||||
'service_restart',
|
||||
'update_nrpe_config',
|
||||
'configure_https',
|
||||
@@ -136,9 +135,10 @@ class CeilometerHooksTest(CharmTestCase):
|
||||
self.assertTrue(self.CONFIGS.write_all.called)
|
||||
self.assertTrue(joined.called)
|
||||
|
||||
@patch.object(hooks, 'canonical_url')
|
||||
@patch('charmhelpers.core.hookenv.config')
|
||||
def test_keystone_joined(self, mock_config):
|
||||
self.canonical_url.return_value = "http://thishost"
|
||||
def test_keystone_joined(self, mock_config, _canonical_url):
|
||||
_canonical_url.return_value = "http://thishost"
|
||||
self.test_config.set('region', 'myregion')
|
||||
hooks.hooks.execute(['hooks/identity-service-relation-joined'])
|
||||
url = "http://{}:{}".format('thishost', hooks.CEILOMETER_PORT)
|
||||
@@ -148,6 +148,28 @@ class CeilometerHooksTest(CharmTestCase):
|
||||
requested_roles=hooks.CEILOMETER_ROLE,
|
||||
region='myregion', relation_id=None)
|
||||
|
||||
@patch('charmhelpers.contrib.openstack.ip.is_ipv6')
|
||||
@patch('charmhelpers.contrib.openstack.ip.resolve_address')
|
||||
@patch('charmhelpers.core.hookenv.config')
|
||||
@patch('charmhelpers.contrib.openstack.ip.config')
|
||||
def test_keystone_joined_url_override(self, _config, mock_config,
|
||||
_resolve_address, _is_ipv6):
|
||||
_is_ipv6.return_value = False
|
||||
_resolve_address.return_value = "thishost"
|
||||
_config.side_effect = self.test_config.get
|
||||
mock_config.side_effect = self.test_config.get
|
||||
self.test_config.set('region', 'myregion')
|
||||
self.test_config.set('endpoint-public-name', 'ceilometer.example.com')
|
||||
hooks.keystone_joined(None)
|
||||
url = "http://{}:{}".format('thishost', hooks.CEILOMETER_PORT)
|
||||
public_url = "http://{}:{}".format('ceilometer.example.com',
|
||||
hooks.CEILOMETER_PORT)
|
||||
self.relation_set.assert_called_with(
|
||||
service=hooks.CEILOMETER_SERVICE,
|
||||
public_url=public_url, admin_url=url, internal_url=url,
|
||||
requested_roles=hooks.CEILOMETER_ROLE,
|
||||
region='myregion', relation_id=None)
|
||||
|
||||
@patch('charmhelpers.core.hookenv.config')
|
||||
def test_ceilometer_joined(self, mock_config):
|
||||
self.relation_ids.return_value = ['ceilometer:0']
|
||||
|
||||
Reference in New Issue
Block a user