Sync charm-helpers
Change-Id: I296f081e9de99da2fefe5a581dfc2ffe5fba4429
This commit is contained in:
parent
cd8b510f95
commit
4c5204ee19
|
@ -110,7 +110,12 @@ def get_address_in_network(network, fallback=None, fatal=False):
|
|||
_validate_cidr(network)
|
||||
network = netaddr.IPNetwork(network)
|
||||
for iface in netifaces.interfaces():
|
||||
addresses = netifaces.ifaddresses(iface)
|
||||
try:
|
||||
addresses = netifaces.ifaddresses(iface)
|
||||
except ValueError:
|
||||
# If an instance was deleted between
|
||||
# netifaces.interfaces() run and now, its interfaces are gone
|
||||
continue
|
||||
if network.version == 4 and netifaces.AF_INET in addresses:
|
||||
for addr in addresses[netifaces.AF_INET]:
|
||||
cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'],
|
||||
|
|
|
@ -92,7 +92,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||
return 'endpoint not found'
|
||||
|
||||
def validate_v3_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
public_port, expected, expected_num_eps=3):
|
||||
"""Validate keystone v3 endpoint data.
|
||||
|
||||
Validate the v3 endpoint data which has changed from v2. The
|
||||
|
@ -138,7 +138,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||
if ret:
|
||||
return 'unexpected endpoint data - {}'.format(ret)
|
||||
|
||||
if len(found) != 3:
|
||||
if len(found) != expected_num_eps:
|
||||
return 'Unexpected number of endpoints found'
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual):
|
||||
|
|
|
@ -1637,18 +1637,84 @@ class InternalEndpointContext(OSContextGenerator):
|
|||
endpoints by default so this allows admins to optionally use internal
|
||||
endpoints.
|
||||
"""
|
||||
def __init__(self, ost_rel_check_pkg_name):
|
||||
self.ost_rel_check_pkg_name = ost_rel_check_pkg_name
|
||||
def __call__(self):
|
||||
return {'use_internal_endpoints': config('use-internal-endpoints')}
|
||||
|
||||
|
||||
class VolumeAPIContext(InternalEndpointContext):
|
||||
"""Volume API context.
|
||||
|
||||
This context provides information regarding the volume endpoint to use
|
||||
when communicating between services. It determines which version of the
|
||||
API is appropriate for use.
|
||||
|
||||
This value will be determined in the resulting context dictionary
|
||||
returned from calling the VolumeAPIContext object. Information provided
|
||||
by this context is as follows:
|
||||
|
||||
volume_api_version: the volume api version to use, currently
|
||||
'v2' or 'v3'
|
||||
volume_catalog_info: the information to use for a cinder client
|
||||
configuration that consumes API endpoints from the keystone
|
||||
catalog. This is defined as the type:name:endpoint_type string.
|
||||
"""
|
||||
# FIXME(wolsen) This implementation is based on the provider being able
|
||||
# to specify the package version to check but does not guarantee that the
|
||||
# volume service api version selected is available. In practice, it is
|
||||
# quite likely the volume service *is* providing the v3 volume service.
|
||||
# This should be resolved when the service-discovery spec is implemented.
|
||||
def __init__(self, pkg):
|
||||
"""
|
||||
Creates a new VolumeAPIContext for use in determining which version
|
||||
of the Volume API should be used for communication. A package codename
|
||||
should be supplied for determining the currently installed OpenStack
|
||||
version.
|
||||
|
||||
:param pkg: the package codename to use in order to determine the
|
||||
component version (e.g. nova-common). See
|
||||
charmhelpers.contrib.openstack.utils.PACKAGE_CODENAMES for more.
|
||||
"""
|
||||
super(VolumeAPIContext, self).__init__()
|
||||
self._ctxt = None
|
||||
if not pkg:
|
||||
raise ValueError('package name must be provided in order to '
|
||||
'determine current OpenStack version.')
|
||||
self.pkg = pkg
|
||||
|
||||
@property
|
||||
def ctxt(self):
|
||||
if self._ctxt is not None:
|
||||
return self._ctxt
|
||||
self._ctxt = self._determine_ctxt()
|
||||
return self._ctxt
|
||||
|
||||
def _determine_ctxt(self):
|
||||
"""Determines the Volume API endpoint information.
|
||||
|
||||
Determines the appropriate version of the API that should be used
|
||||
as well as the catalog_info string that would be supplied. Returns
|
||||
a dict containing the volume_api_version and the volume_catalog_info.
|
||||
"""
|
||||
rel = os_release(self.pkg, base='icehouse')
|
||||
version = '2'
|
||||
if CompareOpenStackReleases(rel) >= 'pike':
|
||||
version = '3'
|
||||
|
||||
service_type = 'volumev{version}'.format(version=version)
|
||||
service_name = 'cinderv{version}'.format(version=version)
|
||||
endpoint_type = 'publicURL'
|
||||
if config('use-internal-endpoints'):
|
||||
endpoint_type = 'internalURL'
|
||||
catalog_info = '{type}:{name}:{endpoint}'.format(
|
||||
type=service_type, name=service_name, endpoint=endpoint_type)
|
||||
|
||||
return {
|
||||
'volume_api_version': version,
|
||||
'volume_catalog_info': catalog_info,
|
||||
}
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {'use_internal_endpoints': config('use-internal-endpoints')}
|
||||
rel = os_release(self.ost_rel_check_pkg_name, base='icehouse')
|
||||
if CompareOpenStackReleases(rel) >= 'pike':
|
||||
ctxt['volume_api_version'] = '3'
|
||||
else:
|
||||
ctxt['volume_api_version'] = '2'
|
||||
|
||||
return ctxt
|
||||
return self.ctxt
|
||||
|
||||
|
||||
class AppArmorContext(OSContextGenerator):
|
||||
|
|
|
@ -20,7 +20,8 @@ from charmhelpers.core import hookenv
|
|||
|
||||
|
||||
def render(source, target, context, owner='root', group='root',
|
||||
perms=0o444, templates_dir=None, encoding='UTF-8', template_loader=None):
|
||||
perms=0o444, templates_dir=None, encoding='UTF-8',
|
||||
template_loader=None, config_template=None):
|
||||
"""
|
||||
Render a template.
|
||||
|
||||
|
@ -32,6 +33,9 @@ def render(source, target, context, owner='root', group='root',
|
|||
The context should be a dict containing the values to be replaced in the
|
||||
template.
|
||||
|
||||
config_template may be provided to render from a provided template instead
|
||||
of loading from a file.
|
||||
|
||||
The `owner`, `group`, and `perms` options will be passed to `write_file`.
|
||||
|
||||
If omitted, `templates_dir` defaults to the `templates` folder in the charm.
|
||||
|
@ -65,14 +69,19 @@ def render(source, target, context, owner='root', group='root',
|
|||
if templates_dir is None:
|
||||
templates_dir = os.path.join(hookenv.charm_dir(), 'templates')
|
||||
template_env = Environment(loader=FileSystemLoader(templates_dir))
|
||||
try:
|
||||
source = source
|
||||
template = template_env.get_template(source)
|
||||
except exceptions.TemplateNotFound as e:
|
||||
hookenv.log('Could not load template %s from %s.' %
|
||||
(source, templates_dir),
|
||||
level=hookenv.ERROR)
|
||||
raise e
|
||||
|
||||
# load from a string if provided explicitly
|
||||
if config_template is not None:
|
||||
template = template_env.from_string(config_template)
|
||||
else:
|
||||
try:
|
||||
source = source
|
||||
template = template_env.get_template(source)
|
||||
except exceptions.TemplateNotFound as e:
|
||||
hookenv.log('Could not load template %s from %s.' %
|
||||
(source, templates_dir),
|
||||
level=hookenv.ERROR)
|
||||
raise e
|
||||
content = template.render(context)
|
||||
if target is not None:
|
||||
target_dir = os.path.dirname(target)
|
||||
|
|
|
@ -92,7 +92,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||
return 'endpoint not found'
|
||||
|
||||
def validate_v3_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
public_port, expected, expected_num_eps=3):
|
||||
"""Validate keystone v3 endpoint data.
|
||||
|
||||
Validate the v3 endpoint data which has changed from v2. The
|
||||
|
@ -138,7 +138,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||
if ret:
|
||||
return 'unexpected endpoint data - {}'.format(ret)
|
||||
|
||||
if len(found) != 3:
|
||||
if len(found) != expected_num_eps:
|
||||
return 'Unexpected number of endpoints found'
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual):
|
||||
|
|
|
@ -20,7 +20,8 @@ from charmhelpers.core import hookenv
|
|||
|
||||
|
||||
def render(source, target, context, owner='root', group='root',
|
||||
perms=0o444, templates_dir=None, encoding='UTF-8', template_loader=None):
|
||||
perms=0o444, templates_dir=None, encoding='UTF-8',
|
||||
template_loader=None, config_template=None):
|
||||
"""
|
||||
Render a template.
|
||||
|
||||
|
@ -32,6 +33,9 @@ def render(source, target, context, owner='root', group='root',
|
|||
The context should be a dict containing the values to be replaced in the
|
||||
template.
|
||||
|
||||
config_template may be provided to render from a provided template instead
|
||||
of loading from a file.
|
||||
|
||||
The `owner`, `group`, and `perms` options will be passed to `write_file`.
|
||||
|
||||
If omitted, `templates_dir` defaults to the `templates` folder in the charm.
|
||||
|
@ -65,14 +69,19 @@ def render(source, target, context, owner='root', group='root',
|
|||
if templates_dir is None:
|
||||
templates_dir = os.path.join(hookenv.charm_dir(), 'templates')
|
||||
template_env = Environment(loader=FileSystemLoader(templates_dir))
|
||||
try:
|
||||
source = source
|
||||
template = template_env.get_template(source)
|
||||
except exceptions.TemplateNotFound as e:
|
||||
hookenv.log('Could not load template %s from %s.' %
|
||||
(source, templates_dir),
|
||||
level=hookenv.ERROR)
|
||||
raise e
|
||||
|
||||
# load from a string if provided explicitly
|
||||
if config_template is not None:
|
||||
template = template_env.from_string(config_template)
|
||||
else:
|
||||
try:
|
||||
source = source
|
||||
template = template_env.get_template(source)
|
||||
except exceptions.TemplateNotFound as e:
|
||||
hookenv.log('Could not load template %s from %s.' %
|
||||
(source, templates_dir),
|
||||
level=hookenv.ERROR)
|
||||
raise e
|
||||
content = template.render(context)
|
||||
if target is not None:
|
||||
target_dir = os.path.dirname(target)
|
||||
|
|
Loading…
Reference in New Issue