Update charmhelpers for stable/yoga
Change-Id: Iad3d5bd2dc7d4976a8cb4dd429af45a03330566c
This commit is contained in:
@@ -16,6 +16,7 @@ import glob
|
||||
import re
|
||||
import subprocess
|
||||
import socket
|
||||
import ssl
|
||||
|
||||
from functools import partial
|
||||
|
||||
@@ -527,19 +528,56 @@ def get_hostname(address, fqdn=True):
|
||||
return result.split('.')[0]
|
||||
|
||||
|
||||
def port_has_listener(address, port):
|
||||
class SSLPortCheckInfo(object):
|
||||
|
||||
def __init__(self, key, cert, ca_cert, check_hostname=False):
|
||||
self.key = key
|
||||
self.cert = cert
|
||||
self.ca_cert = ca_cert
|
||||
# NOTE: by default we do not check hostname since the port check is
|
||||
# typically performed using 0.0.0.0 which will not match the
|
||||
# certificate. Hence the default for this is False.
|
||||
self.check_hostname = check_hostname
|
||||
|
||||
@property
|
||||
def ssl_context(self):
|
||||
context = ssl.create_default_context()
|
||||
context.check_hostname = self.check_hostname
|
||||
context.load_cert_chain(self.cert, self.key)
|
||||
context.load_verify_locations(self.ca_cert)
|
||||
return context
|
||||
|
||||
|
||||
def port_has_listener(address, port, sslinfo=None):
|
||||
"""
|
||||
Returns True if the address:port is open and being listened to,
|
||||
else False.
|
||||
else False. By default uses netcat to check ports but if sslinfo is
|
||||
provided will use an SSL connection instead.
|
||||
|
||||
@param address: an IP address or hostname
|
||||
@param port: integer port
|
||||
@param sslinfo: optional SSLPortCheckInfo object.
|
||||
If provided, the check is performed using an ssl
|
||||
connection.
|
||||
|
||||
Note calls 'zc' via a subprocess shell
|
||||
"""
|
||||
cmd = ['nc', '-z', address, str(port)]
|
||||
result = subprocess.call(cmd)
|
||||
return not (bool(result))
|
||||
if not sslinfo:
|
||||
cmd = ['nc', '-z', address, str(port)]
|
||||
result = subprocess.call(cmd)
|
||||
return not (bool(result))
|
||||
|
||||
try:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
|
||||
ssock = sslinfo.ssl_context.wrap_socket(sock,
|
||||
server_hostname=address)
|
||||
ssock.connect((address, port))
|
||||
# this bit is crucial to ensure tls close_notify is sent
|
||||
ssock.unwrap()
|
||||
|
||||
return True
|
||||
except ConnectionRefusedError:
|
||||
return False
|
||||
|
||||
|
||||
def assert_charm_supports_ipv6():
|
||||
|
||||
@@ -198,6 +198,21 @@ class OSContextGenerator(object):
|
||||
return self.related
|
||||
|
||||
|
||||
class KeystoneAuditMiddleware(OSContextGenerator):
|
||||
def __init__(self, service: str) -> None:
|
||||
self.service_name = service
|
||||
|
||||
def __call__(self):
|
||||
"""Return context dictionary containing configuration status of
|
||||
audit-middleware and the charm service name.
|
||||
"""
|
||||
ctxt = {
|
||||
'audit_middleware': config('audit-middleware') or False,
|
||||
'service_name': self.service_name
|
||||
}
|
||||
return ctxt
|
||||
|
||||
|
||||
class SharedDBContext(OSContextGenerator):
|
||||
interfaces = ['shared-db']
|
||||
|
||||
@@ -477,7 +492,7 @@ class IdentityServiceContext(OSContextGenerator):
|
||||
'service_project_id': rdata.get('service_tenant_id'),
|
||||
'service_domain_id': rdata.get('service_domain_id')})
|
||||
|
||||
# we keep all veriables in ctxt for compatibility and
|
||||
# we keep all variables in ctxt for compatibility and
|
||||
# add nested dictionary for keystone_authtoken generic
|
||||
# templating
|
||||
if keystonemiddleware_os_release:
|
||||
@@ -489,6 +504,7 @@ class IdentityServiceContext(OSContextGenerator):
|
||||
# NOTE(jamespage) this is required for >= icehouse
|
||||
# so a missing value just indicates keystone needs
|
||||
# upgrading
|
||||
ctxt['admin_user_id'] = rdata.get('service_user_id')
|
||||
ctxt['admin_tenant_id'] = rdata.get('service_tenant_id')
|
||||
ctxt['admin_domain_id'] = rdata.get('service_domain_id')
|
||||
return ctxt
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{% if audit_middleware -%}
|
||||
[audit_middleware_notifications]
|
||||
driver = log
|
||||
{% endif -%}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% if audit_middleware and service_name -%}
|
||||
[filter:audit]
|
||||
paste.filter_factory = keystonemiddleware.audit:filter_factory
|
||||
audit_map_file = /etc/{{ service_name }}/api_audit_map.conf
|
||||
service_name = {{ service_name }}
|
||||
{% endif -%}
|
||||
@@ -410,17 +410,6 @@ def get_os_version_codename(codename, version_map=OPENSTACK_CODENAMES):
|
||||
error_out(e)
|
||||
|
||||
|
||||
def get_os_version_codename_swift(codename):
|
||||
'''Determine OpenStack version number of swift from codename.'''
|
||||
# for k, v in six.iteritems(SWIFT_CODENAMES):
|
||||
for k, v in SWIFT_CODENAMES.items():
|
||||
if k == codename:
|
||||
return v[-1]
|
||||
e = 'Could not derive swift version for '\
|
||||
'codename: %s' % codename
|
||||
error_out(e)
|
||||
|
||||
|
||||
def get_swift_codename(version):
|
||||
'''Determine OpenStack codename that corresponds to swift version.'''
|
||||
codenames = [k for k, v in SWIFT_CODENAMES.items() if version in v]
|
||||
@@ -579,7 +568,6 @@ def get_installed_os_version():
|
||||
return openstack_release().get('OPENSTACK_CODENAME')
|
||||
|
||||
|
||||
@cached
|
||||
def openstack_release():
|
||||
"""Return /etc/os-release in a dict."""
|
||||
d = {}
|
||||
@@ -841,14 +829,10 @@ def openstack_upgrade_available(package):
|
||||
if not cur_vers:
|
||||
# The package has not been installed yet do not attempt upgrade
|
||||
return False
|
||||
if "swift" in package:
|
||||
codename = get_os_codename_install_source(src)
|
||||
avail_vers = get_os_version_codename_swift(codename)
|
||||
else:
|
||||
try:
|
||||
avail_vers = get_os_version_install_source(src)
|
||||
except Exception:
|
||||
avail_vers = cur_vers
|
||||
try:
|
||||
avail_vers = get_os_version_install_source(src)
|
||||
except Exception:
|
||||
avail_vers = cur_vers
|
||||
apt.init()
|
||||
return apt.version_compare(avail_vers, cur_vers) >= 1
|
||||
|
||||
@@ -1216,12 +1200,14 @@ def _ows_check_services_running(services, ports):
|
||||
return ows_check_services_running(services, ports)
|
||||
|
||||
|
||||
def ows_check_services_running(services, ports):
|
||||
def ows_check_services_running(services, ports, ssl_check_info=None):
|
||||
"""Check that the services that should be running are actually running
|
||||
and that any ports specified are being listened to.
|
||||
|
||||
@param services: list of strings OR dictionary specifying services/ports
|
||||
@param ports: list of ports
|
||||
@param ssl_check_info: SSLPortCheckInfo object. If provided, port checks
|
||||
will be done using an SSL connection.
|
||||
@returns state, message: strings or None, None
|
||||
"""
|
||||
messages = []
|
||||
@@ -1237,7 +1223,7 @@ def ows_check_services_running(services, ports):
|
||||
# also verify that the ports that should be open are open
|
||||
# NB, that ServiceManager objects only OPTIONALLY have ports
|
||||
map_not_open, ports_open = (
|
||||
_check_listening_on_services_ports(services))
|
||||
_check_listening_on_services_ports(services, ssl_check_info))
|
||||
if not all(ports_open):
|
||||
# find which service has missing ports. They are in service
|
||||
# order which makes it a bit easier.
|
||||
@@ -1252,7 +1238,8 @@ def ows_check_services_running(services, ports):
|
||||
|
||||
if ports is not None:
|
||||
# and we can also check ports which we don't know the service for
|
||||
ports_open, ports_open_bools = _check_listening_on_ports_list(ports)
|
||||
ports_open, ports_open_bools = \
|
||||
_check_listening_on_ports_list(ports, ssl_check_info)
|
||||
if not all(ports_open_bools):
|
||||
messages.append(
|
||||
"Ports which should be open, but are not: {}"
|
||||
@@ -1311,7 +1298,8 @@ def _check_running_services(services):
|
||||
return list(zip(services, services_running)), services_running
|
||||
|
||||
|
||||
def _check_listening_on_services_ports(services, test=False):
|
||||
def _check_listening_on_services_ports(services, test=False,
|
||||
ssl_check_info=None):
|
||||
"""Check that the unit is actually listening (has the port open) on the
|
||||
ports that the service specifies are open. If test is True then the
|
||||
function returns the services with ports that are open rather than
|
||||
@@ -1321,11 +1309,14 @@ def _check_listening_on_services_ports(services, test=False):
|
||||
|
||||
@param services: OrderedDict(service: [port, ...], ...)
|
||||
@param test: default=False, if False, test for closed, otherwise open.
|
||||
@param ssl_check_info: SSLPortCheckInfo object. If provided, port checks
|
||||
will be done using an SSL connection.
|
||||
@returns OrderedDict(service: [port-not-open, ...]...), [boolean]
|
||||
"""
|
||||
test = not (not (test)) # ensure test is True or False
|
||||
all_ports = list(itertools.chain(*services.values()))
|
||||
ports_states = [port_has_listener('0.0.0.0', p) for p in all_ports]
|
||||
ports_states = [port_has_listener('0.0.0.0', p, ssl_check_info)
|
||||
for p in all_ports]
|
||||
map_ports = OrderedDict()
|
||||
matched_ports = [p for p, opened in zip(all_ports, ports_states)
|
||||
if opened == test] # essentially opened xor test
|
||||
@@ -1336,16 +1327,19 @@ def _check_listening_on_services_ports(services, test=False):
|
||||
return map_ports, ports_states
|
||||
|
||||
|
||||
def _check_listening_on_ports_list(ports):
|
||||
def _check_listening_on_ports_list(ports, ssl_check_info=None):
|
||||
"""Check that the ports list given are being listened to
|
||||
|
||||
Returns a list of ports being listened to and a list of the
|
||||
booleans.
|
||||
|
||||
@param ssl_check_info: SSLPortCheckInfo object. If provided, port checks
|
||||
will be done using an SSL connection.
|
||||
@param ports: LIST of port numbers.
|
||||
@returns [(port_num, boolean), ...], [boolean]
|
||||
"""
|
||||
ports_open = [port_has_listener('0.0.0.0', p) for p in ports]
|
||||
ports_open = [port_has_listener('0.0.0.0', p, ssl_check_info)
|
||||
for p in ports]
|
||||
return zip(ports, ports_open), ports_open
|
||||
|
||||
|
||||
|
||||
@@ -159,15 +159,19 @@ def get_osd_settings(relation_name):
|
||||
return _order_dict_by_key(osd_settings)
|
||||
|
||||
|
||||
def send_application_name(relid=None):
|
||||
def send_application_name(relid=None, app_name=None):
|
||||
"""Send the application name down the relation.
|
||||
|
||||
:param relid: Relation id to set application name in.
|
||||
:type relid: str
|
||||
:param app_name: Application name to send in the relation.
|
||||
:type app_name: str
|
||||
"""
|
||||
if app_name is None:
|
||||
app_name = application_name()
|
||||
relation_set(
|
||||
relation_id=relid,
|
||||
relation_settings={'application-name': application_name()})
|
||||
relation_settings={'application-name': app_name})
|
||||
|
||||
|
||||
def send_osd_settings():
|
||||
|
||||
@@ -256,8 +256,11 @@ def service_resume(service_name, init_dir="/etc/init",
|
||||
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
||||
sysv_file = os.path.join(initd_dir, service_name)
|
||||
if init_is_systemd(service_name=service_name):
|
||||
service('unmask', service_name)
|
||||
service('enable', service_name)
|
||||
if service('is-enabled', service_name):
|
||||
log('service {} already enabled'.format(service_name), level=DEBUG)
|
||||
else:
|
||||
service('unmask', service_name)
|
||||
service('enable', service_name)
|
||||
elif os.path.exists(upstart_file):
|
||||
override_path = os.path.join(
|
||||
init_dir, '{}.override'.format(service_name))
|
||||
|
||||
Reference in New Issue
Block a user