Merge "Add config use-internal-endpoints option."
This commit is contained in:
commit
71916888e5
|
@ -415,3 +415,10 @@ options:
|
|||
description: |
|
||||
If True, displays an ‘Admin Password’ field on the Change Password form
|
||||
to verify that it is indeed the admin logged-in who wants to change the password.
|
||||
use-internal-endpoints:
|
||||
type: boolean
|
||||
default: False
|
||||
description: |
|
||||
Openstack mostly defaults to using public endpoints for internal
|
||||
communication between services. If set to True this option will
|
||||
configure services to use internal endpoints where possible.
|
||||
|
|
|
@ -23,8 +23,8 @@ from charmhelpers.core.hookenv import (
|
|||
relation_get,
|
||||
local_unit,
|
||||
log,
|
||||
WARNING,
|
||||
ERROR,
|
||||
WARNING,
|
||||
)
|
||||
from charmhelpers.core.strutils import bool_from_string
|
||||
from charmhelpers.contrib.openstack import context
|
||||
|
@ -90,8 +90,6 @@ class HorizonHAProxyContext(OSContextGenerator):
|
|||
return ctxt
|
||||
|
||||
|
||||
# NOTE: this is a stripped-down version of
|
||||
# contrib.openstack.IdentityServiceContext
|
||||
class IdentityServiceContext(OSContextGenerator):
|
||||
interfaces = ['identity-service']
|
||||
|
||||
|
@ -126,6 +124,9 @@ class IdentityServiceContext(OSContextGenerator):
|
|||
default_role = role
|
||||
serv_host = rdata.get('service_host')
|
||||
serv_host = format_ipv6_addr(serv_host) or serv_host
|
||||
internal_host = rdata.get('internal_host')
|
||||
internal_host = (format_ipv6_addr(internal_host)
|
||||
or internal_host)
|
||||
region = rdata.get('region')
|
||||
|
||||
local_ctxt = {
|
||||
|
@ -136,6 +137,7 @@ class IdentityServiceContext(OSContextGenerator):
|
|||
'api_version': rdata.get('api_version', '2'),
|
||||
'default_role': default_role
|
||||
}
|
||||
|
||||
# If using keystone v3 the context is incomplete without the
|
||||
# admin domain id
|
||||
if local_ctxt['api_version'] == '3':
|
||||
|
@ -145,11 +147,41 @@ class IdentityServiceContext(OSContextGenerator):
|
|||
if not context_complete(local_ctxt):
|
||||
continue
|
||||
|
||||
# internal_* keys will be treated as optional, since the user
|
||||
# could be upgrading the openstack-dashboard charm before
|
||||
# keystone, so we add them to `local_ctxt` after calling
|
||||
# `context_complete()`.
|
||||
local_ctxt.update({
|
||||
'internal_port': rdata.get('internal_port'),
|
||||
'internal_host': internal_host,
|
||||
'internal_protocol':
|
||||
rdata.get('internal_protocol') or 'http',
|
||||
})
|
||||
|
||||
# if the use configured the charm to use internal endpoints,
|
||||
# but the keystone charm didn't provide the internal_host key
|
||||
# in the relation we fallback to use the service_host.
|
||||
if config("use-internal-endpoints") and internal_host:
|
||||
log("Using internal endpoints to configure horizon")
|
||||
local_ctxt["ks_protocol"] = local_ctxt["internal_protocol"]
|
||||
local_ctxt["ks_host"] = local_ctxt["internal_host"]
|
||||
local_ctxt["ks_port"] = local_ctxt["internal_port"]
|
||||
else:
|
||||
log("Using service host to configure horizon")
|
||||
local_ctxt["ks_protocol"] = local_ctxt["service_protocol"]
|
||||
local_ctxt["ks_host"] = local_ctxt["service_host"]
|
||||
local_ctxt["ks_port"] = local_ctxt["service_port"]
|
||||
|
||||
# Update the service endpoint and title for each available
|
||||
# region in order to support multi-region deployments
|
||||
if region is not None:
|
||||
endpoint = ("%(service_protocol)s://%(service_host)s"
|
||||
":%(service_port)s/v2.0") % local_ctxt
|
||||
if config("use-internal-endpoints") and internal_host:
|
||||
endpoint = ("%(internal_protocol)s://%(internal_host)s"
|
||||
":%(internal_port)s/v2.0") % local_ctxt
|
||||
else:
|
||||
endpoint = ("%(service_protocol)s://%(service_host)s"
|
||||
":%(service_port)s/v2.0") % local_ctxt
|
||||
|
||||
for reg in region.split():
|
||||
regions.add((endpoint, reg))
|
||||
|
||||
|
|
|
@ -139,8 +139,8 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
|
||||
# Disable SSL certificate checks (useful for self-signed certificates):
|
||||
|
|
|
@ -161,8 +161,8 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
# Enables keystone web single-sign-on if set to True.
|
||||
#WEBSSO_ENABLED = False
|
||||
|
|
|
@ -202,15 +202,15 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
{% if api_version == "3" -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_API_VERSIONS = { "identity": 3, }
|
||||
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = {{ multi_domain }}
|
||||
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "{{ default_domain or admin_domain_id }}"
|
||||
{% else -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
{% endif -%}
|
||||
|
||||
|
||||
|
|
|
@ -202,15 +202,15 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
{% if api_version == "3" -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_API_VERSIONS = { "identity": 3, }
|
||||
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = {{ multi_domain }}
|
||||
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "{{ default_domain or admin_domain_id }}"
|
||||
{% else -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
{% endif -%}
|
||||
|
||||
|
||||
|
|
|
@ -203,15 +203,15 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
{% if api_version == "3" -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_API_VERSIONS = { "identity": 3, }
|
||||
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = {{ multi_domain }}
|
||||
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "{{ default_domain or admin_domain_id }}"
|
||||
{% else -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
{% endif -%}
|
||||
|
||||
|
||||
|
|
|
@ -203,15 +203,15 @@ AVAILABLE_REGIONS = [
|
|||
]
|
||||
{% endif -%}
|
||||
|
||||
OPENSTACK_HOST = "{{ service_host }}"
|
||||
OPENSTACK_HOST = "{{ ks_host }}"
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ default_role }}"
|
||||
{% if api_version == "3" -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v3" % OPENSTACK_HOST
|
||||
OPENSTACK_API_VERSIONS = { "identity": 3, }
|
||||
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = {{ multi_domain }}
|
||||
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "{{ default_domain or admin_domain_id }}"
|
||||
{% else -%}
|
||||
OPENSTACK_KEYSTONE_URL = "{{ service_protocol }}://%s:{{ service_port }}/v2.0" % OPENSTACK_HOST
|
||||
OPENSTACK_KEYSTONE_URL = "{{ ks_protocol }}://%s:{{ ks_port }}/v2.0" % OPENSTACK_HOST
|
||||
{% endif -%}
|
||||
|
||||
|
||||
|
|
|
@ -684,43 +684,59 @@ class TestHorizonContexts(CharmTestCase):
|
|||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_data(self, mock_format_ipv6_addr):
|
||||
mock_format_ipv6_addr.return_value = "foo"
|
||||
mock_format_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000})
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001})
|
||||
self.test_config.set('use-internal-endpoints', False)
|
||||
self.context_complete.return_value = True
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(),
|
||||
{'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo', 'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'default_role': 'member',
|
||||
'api_version': '2', 'service_protocol': 'http'})
|
||||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_single_region(self, mock_format_ipv6_addr):
|
||||
mock_format_ipv6_addr.return_value = "foo"
|
||||
mock_format_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'region': 'regionOne'})
|
||||
self.context_complete.return_value = True
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(),
|
||||
{'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo', 'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'default_role': 'member',
|
||||
'api_version': '2', 'service_protocol': 'http'})
|
||||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_multi_region(self, mock_format_ipv6_addr):
|
||||
mock_format_ipv6_addr.return_value = "foo"
|
||||
mock_format_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'region': 'regionOne regionTwo'})
|
||||
self.context_complete.return_value = True
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(),
|
||||
{'service_host': 'foo', 'service_port': 5000,
|
||||
'service_protocol': 'http', 'api_version': '2',
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo', 'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'default_role': 'member',
|
||||
'regions': [{'endpoint': 'http://foo:5000/v2.0',
|
||||
'title': 'regionOne'},
|
||||
|
@ -729,13 +745,15 @@ class TestHorizonContexts(CharmTestCase):
|
|||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_api3(self, mock_format_ipv6_addr):
|
||||
mock_format_ipv6_addr.return_value = "foo"
|
||||
mock_format_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'internal_host': 'bar',
|
||||
'internal_port': 5001,
|
||||
'region': 'regionOne',
|
||||
'api_version': '3',
|
||||
'admin_domain_id': 'admindomainid'})
|
||||
|
@ -743,6 +761,12 @@ class TestHorizonContexts(CharmTestCase):
|
|||
self.assertEqual(horizon_contexts.IdentityServiceContext()(), {
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'internal_host': 'bar',
|
||||
'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo',
|
||||
'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'api_version': '3',
|
||||
'default_role': 'member',
|
||||
'admin_domain_id': 'admindomainid',
|
||||
|
@ -781,13 +805,16 @@ class TestHorizonContexts(CharmTestCase):
|
|||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_default_role(self, mock_format_ipv6_addr):
|
||||
self.test_config.set('default-role', 'member')
|
||||
mock_format_ipv6_addr.return_value = "foo"
|
||||
mock_format_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'internal_host': 'bar',
|
||||
'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'region': 'regionOne',
|
||||
'api_version': '3',
|
||||
'created_roles': 'Member',
|
||||
|
@ -796,6 +823,12 @@ class TestHorizonContexts(CharmTestCase):
|
|||
self.assertEqual(horizon_contexts.IdentityServiceContext()(), {
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'internal_host': 'bar',
|
||||
'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo',
|
||||
'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'api_version': '3',
|
||||
'default_role': 'Member',
|
||||
'admin_domain_id': 'admindomainid',
|
||||
|
@ -805,25 +838,77 @@ class TestHorizonContexts(CharmTestCase):
|
|||
def test_IdentityServiceContext_default_role_fallback(self,
|
||||
mock_ipv6_addr):
|
||||
self.test_config.set('default-role', 'member')
|
||||
mock_ipv6_addr.return_value = "foo"
|
||||
mock_ipv6_addr.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'region': 'regionOne',
|
||||
'api_version': '3',
|
||||
'admin_domain_id': 'admindomainid'})
|
||||
self.context_complete.return_value = True
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(), {
|
||||
'service_host': 'foo',
|
||||
'service_port': 5000,
|
||||
'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo', 'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'api_version': '3',
|
||||
'default_role': 'member',
|
||||
'admin_domain_id': 'admindomainid',
|
||||
'service_protocol': 'http'})
|
||||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_use_internal_endpoints(self,
|
||||
mock_format_ipv6):
|
||||
mock_format_ipv6.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000,
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'region': 'regionOne'})
|
||||
self.test_config.set('use-internal-endpoints', True)
|
||||
self.context_complete.return_value = True
|
||||
self.maxDiff = None
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(),
|
||||
{'service_host': 'foo', 'service_port': 5000,
|
||||
'service_protocol': 'http',
|
||||
'internal_host': 'bar', 'internal_port': 5001,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'bar', 'ks_port': 5001,
|
||||
'ks_protocol': 'http',
|
||||
'api_version': '2',
|
||||
'default_role': 'member'})
|
||||
|
||||
@patch("hooks.horizon_contexts.format_ipv6_addr")
|
||||
def test_IdentityServiceContext_use_internal_endpoints_no_internal_host(
|
||||
self, mock_format_ipv6):
|
||||
mock_format_ipv6.side_effect = lambda x: x
|
||||
self.relation_ids.return_value = ['foo']
|
||||
self.related_units.return_value = ['bar', 'baz']
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.test_relation.set({'service_host': 'foo', 'service_port': 5000,
|
||||
'region': 'regionOne regionTwo'})
|
||||
self.test_config.set('use-internal-endpoints', True)
|
||||
self.context_complete.return_value = True
|
||||
self.maxDiff = None
|
||||
self.assertEqual(horizon_contexts.IdentityServiceContext()(),
|
||||
{'service_host': 'foo', 'service_port': 5000,
|
||||
'service_protocol': 'http',
|
||||
'internal_host': None, 'internal_port': None,
|
||||
'internal_protocol': 'http',
|
||||
'ks_host': 'foo', 'ks_port': 5000,
|
||||
'ks_protocol': 'http',
|
||||
'api_version': '2',
|
||||
'default_role': 'member',
|
||||
'regions': [{'endpoint': 'http://foo:5000/v2.0',
|
||||
'title': 'regionOne'},
|
||||
{'endpoint': 'http://foo:5000/v2.0',
|
||||
'title': 'regionTwo'}]})
|
||||
|
||||
def test_HorizonHAProxyContext_no_cluster(self):
|
||||
self.relation_ids.return_value = []
|
||||
self.local_unit.return_value = 'openstack-dashboard/0'
|
||||
|
|
Loading…
Reference in New Issue