Support for shared services in multi region mode

The services are declared in a list in config.
shared_services_types=image, volume, volumev2

Change-Id: I64c00756cc28db616e9e49e6eb1613b76a19068e
Story: 2003772
Task: 26464
This commit is contained in:
Nakul Dahiwade 2018-09-13 21:47:49 +00:00 committed by David Peacock
parent 28ce9f3ad4
commit fd41115805
8 changed files with 37 additions and 13 deletions

View File

@ -60,6 +60,13 @@ service_opts = [
'SSL is used.')),
cfg.StrOpt('region_name_for_services',
help=_('Default region name used to get services endpoints.')),
cfg.StrOpt('region_name_for_shared_services',
help=_('Region name for shared services endpoints.')),
cfg.ListOpt('shared_services_types',
default=['image', 'volume', 'volumev2'],
help=_('The shared services located in the other region.'
'Needs region_name_for_shared_services option to '
'be set for this to take effect.')),
cfg.StrOpt('heat_stack_user_role',
default="heat_stack_user",
help=_('Keystone role for heat template-defined users.')),

View File

@ -88,7 +88,14 @@ class ClientPlugin(object):
pass
def _get_region_name(self):
return self.context.region_name or cfg.CONF.region_name_for_services
reg = self.context.region_name or cfg.CONF.region_name_for_services
# If Shared Services configured, override region for image/volumes
shared_services_region_name = cfg.CONF.region_name_for_shared_services
shared_services_types = cfg.CONF.shared_services_types
if shared_services_region_name:
if set(self.service_types) & set(shared_services_types):
reg = shared_services_region_name
return reg
def url_for(self, **kwargs):
keystone_session = self.context.keystone_session

View File

@ -27,7 +27,8 @@ class KeystoneClientPlugin(client_plugin.ClientPlugin):
service_types = [IDENTITY] = ['identity']
def _create(self):
return hkc.KeystoneClient(self.context)
region_name = self._get_region_name()
return hkc.KeystoneClient(self.context, region_name)
def is_not_found(self, ex):
return isinstance(ex, (ks_exceptions.NotFound,

View File

@ -58,7 +58,7 @@ class KsClientWrapper(object):
directly instantiate instances of this class inside resources themselves.
"""
def __init__(self, context):
def __init__(self, context, region_name):
# If a trust_id is specified in the context, we immediately
# authenticate so we can populate the context with a trust token
# otherwise, we delay client authentication until needed to avoid
@ -75,6 +75,7 @@ class KsClientWrapper(object):
self._admin_auth = None
self._domain_admin_auth = None
self._domain_admin_client = None
self._region_name = region_name
self.session = self.context.keystone_session
self.v3_endpoint = self.context.keystone_v3_endpoint
@ -123,8 +124,7 @@ class KsClientWrapper(object):
importutils.import_module('keystonemiddleware.auth_token')
auth_region = cfg.CONF.keystone_authtoken.region_name
if not auth_region:
auth_region = (self.context.region_name or
cfg.CONF.region_name_for_services)
auth_region = self._region_name
return auth_region
@property
@ -596,9 +596,9 @@ class KeystoneClient(object):
needs to be initialized.
"""
def __new__(cls, context):
def __new__(cls, context, region_name=None):
if cfg.CONF.keystone_backend == _default_keystone_backend:
return KsClientWrapper(context)
return KsClientWrapper(context, region_name)
else:
return importutils.import_object(
cfg.CONF.keystone_backend,

View File

@ -150,6 +150,8 @@ class DeployedServer(server_base.BaseServer):
),
}
default_client_name = 'heat'
def __init__(self, name, json_snippet, stack):
super(DeployedServer, self).__init__(name, json_snippet, stack)
self._register_access_key()

View File

@ -61,14 +61,15 @@ class BaseServer(stack_user.StackUser):
return container_name, object_name
def _get_region_name(self):
return self.client_plugin()._get_region_name()
def _populate_deployments_metadata(self, meta, props):
meta['deployments'] = meta.get('deployments', [])
meta['os-collect-config'] = meta.get('os-collect-config', {})
occ = meta['os-collect-config']
collectors = list(self.default_collectors)
occ['collectors'] = collectors
region_name = (self.context.region_name or
cfg.CONF.region_name_for_services)
# set existing values to None to override any boot-time config
occ_keys = ('heat', 'zaqar', 'cfn', 'request')
@ -89,7 +90,7 @@ class BaseServer(stack_user.StackUser):
'project_id': self.stack.stack_user_project_id,
'stack_id': self.stack.identifier().stack_path(),
'resource_name': self.name,
'region_name': region_name}})
'region_name': self._get_region_name()}})
collectors.append('heat')
elif self.transport_zaqar_message(props):
@ -101,7 +102,7 @@ class BaseServer(stack_user.StackUser):
fallback_endpoint=self.context.auth_url),
'project_id': self.stack.stack_user_project_id,
'queue_id': queue_id,
'region_name': region_name}})
'region_name': self._get_region_name()}})
collectors.append('zaqar')
elif self.transport_poll_server_cfn(props):

View File

@ -93,6 +93,9 @@ class SignalResponder(stack_user.StackUser):
return self.properties.get(
self.SIGNAL_TRANSPORT) == self.ZAQAR_SIGNAL
def _get_region_name(self):
return self.client_plugin('heat')._get_region_name()
def _get_heat_signal_credentials(self):
"""Return OpenStack credentials that can be used to send a signal.
@ -110,8 +113,7 @@ class SignalResponder(stack_user.StackUser):
'password': self.password,
'project_id': self.stack.stack_user_project_id,
'domain_id': self.keystone().stack_domain_id,
'region_name': (self.context.region_name or
cfg.CONF.region_name_for_services)}
'region_name': self._get_region_name()}
def _get_ec2_signed_url(self, signal_type=SIGNAL):
"""Create properly formatted and pre-signed URL.

View File

@ -0,0 +1,4 @@
---
features:
- Support shared services in multi region mode. The services are declared
in a list in config. shared_services_types=image, volume, volumev2.