Merge "Charm-helpers sync"

This commit is contained in:
Zuul 2023-03-28 20:54:24 +00:00 committed by Gerrit Code Review
commit 2e0440f07c
7 changed files with 79 additions and 41 deletions

View File

@ -469,66 +469,80 @@ class IdentityServiceContext(OSContextGenerator):
# forwards compat with application data # forwards compat with application data
# bag driven approach to relation. # bag driven approach to relation.
_adata = relation_get(rid=rid, app=remote_service_name(rid)) _adata = relation_get(rid=rid, app=remote_service_name(rid))
adata = {}
# if no app data bag presented - fallback
# to legacy unit based relation data
rdata = relation_get(rid=rid, unit=unit)
if _adata: if _adata:
# New app data bag uses - instead of _ # New app data bag uses - instead of _
# in key names - remap for compat with # in key names - remap for compat with
# existing relation data keys # existing relation data keys
for key, value in _adata.items(): for key, value in _adata.items():
if key == 'api-version': if key == 'api-version':
rdata[key.replace('-', '_')] = value.strip('v') adata[key.replace('-', '_')] = value.strip('v')
else: else:
rdata[key.replace('-', '_')] = value adata[key.replace('-', '_')] = value
# Re-map some keys for backwards compatibility # Re-map some keys for backwards compatibility
for target, source in self._forward_compat_remaps.items(): for target, source in self._forward_compat_remaps.items():
rdata[target] = _adata.get(source) adata[target] = _adata.get(source)
else: # Now preferentially get data from the app data bag, but if
# No app data bag presented - fallback # it's not available, get it from the legacy based relation
# to legacy unit based relation data # data.
rdata = relation_get(rid=rid, unit=unit)
serv_host = rdata.get('service_host') def _resolve(key):
return adata.get(key) or rdata.get(key)
serv_host = _resolve('service_host')
serv_host = format_ipv6_addr(serv_host) or serv_host serv_host = format_ipv6_addr(serv_host) or serv_host
auth_host = rdata.get('auth_host') auth_host = _resolve('auth_host')
auth_host = format_ipv6_addr(auth_host) or auth_host auth_host = format_ipv6_addr(auth_host) or auth_host
int_host = rdata.get('internal_host') int_host = _resolve('internal_host',)
int_host = format_ipv6_addr(int_host) or int_host int_host = format_ipv6_addr(int_host) or int_host
svc_protocol = rdata.get('service_protocol') or 'http' svc_protocol = _resolve('service_protocol') or 'http'
auth_protocol = rdata.get('auth_protocol') or 'http' auth_protocol = _resolve('auth_protocol') or 'http'
int_protocol = rdata.get('internal_protocol') or 'http' admin_role = _resolve('admin_role') or 'Admin'
api_version = rdata.get('api_version') or '2.0' int_protocol = _resolve('internal_protocol') or 'http'
ctxt.update({'service_port': rdata.get('service_port'), api_version = _resolve('api_version') or '2.0'
ctxt.update({'service_port': _resolve('service_port'),
'service_host': serv_host, 'service_host': serv_host,
'auth_host': auth_host, 'auth_host': auth_host,
'auth_port': rdata.get('auth_port'), 'auth_port': _resolve('auth_port'),
'internal_host': int_host, 'internal_host': int_host,
'internal_port': rdata.get('internal_port'), 'internal_port': _resolve('internal_port'),
'admin_tenant_name': rdata.get('service_tenant'), 'admin_tenant_name': _resolve('service_tenant'),
'admin_user': rdata.get('service_username'), 'admin_user': _resolve('service_username'),
'admin_password': rdata.get('service_password'), 'admin_password': _resolve('service_password'),
'admin_role': admin_role,
'service_protocol': svc_protocol, 'service_protocol': svc_protocol,
'auth_protocol': auth_protocol, 'auth_protocol': auth_protocol,
'internal_protocol': int_protocol, 'internal_protocol': int_protocol,
'api_version': api_version}) 'api_version': api_version})
if rdata.get('service_type'): service_type = _resolve('service_type')
ctxt['service_type'] = rdata.get('service_type') if service_type:
ctxt['service_type'] = service_type
if float(api_version) > 2: if float(api_version) > 2:
ctxt.update({ ctxt.update({
'admin_domain_name': rdata.get('service_domain'), 'admin_domain_name': _resolve('service_domain'),
'service_project_id': rdata.get('service_tenant_id'), 'service_project_id': _resolve('service_tenant_id'),
'service_domain_id': rdata.get('service_domain_id')}) 'service_domain_id': _resolve('service_domain_id')})
# NOTE: # NOTE:
# keystone-k8s operator presents full URLS # keystone-k8s operator presents full URLS
# for all three endpoints - public and internal are # for all three endpoints - public and internal are
# externally addressable for machine based charm # externally addressable for machine based charm
if 'public_auth_url' in rdata: public_auth_url = _resolve('public_auth_url')
# if 'public_auth_url' in rdata:
if public_auth_url:
ctxt.update({ ctxt.update({
'public_auth_url': rdata.get('public_auth_url'), 'public_auth_url': public_auth_url,
}) })
if 'internal_auth_url' in rdata: internal_auth_url = _resolve('internal_auth_url')
# if 'internal_auth_url' in rdata:
if internal_auth_url:
ctxt.update({ ctxt.update({
'internal_auth_url': rdata.get('internal_auth_url'), 'internal_auth_url': internal_auth_url,
}) })
# we keep all veriables in ctxt for compatibility and # we keep all veriables in ctxt for compatibility and
@ -543,8 +557,8 @@ class IdentityServiceContext(OSContextGenerator):
# NOTE(jamespage) this is required for >= icehouse # NOTE(jamespage) this is required for >= icehouse
# so a missing value just indicates keystone needs # so a missing value just indicates keystone needs
# upgrading # upgrading
ctxt['admin_tenant_id'] = rdata.get('service_tenant_id') ctxt['admin_tenant_id'] = _resolve('service_tenant_id')
ctxt['admin_domain_id'] = rdata.get('service_domain_id') ctxt['admin_domain_id'] = _resolve('service_domain_id')
return ctxt return ctxt
return {} return {}

View File

@ -127,7 +127,9 @@ def deferred_events():
""" """
events = [] events = []
for defer_file in deferred_events_files(): for defer_file in deferred_events_files():
events.append((defer_file, read_event_file(defer_file))) event = read_event_file(defer_file)
if event.policy_requestor_name == hookenv.service_name():
events.append((defer_file, event))
return events return events

View File

@ -159,6 +159,7 @@ OPENSTACK_CODENAMES = OrderedDict([
('2021.2', 'xena'), ('2021.2', 'xena'),
('2022.1', 'yoga'), ('2022.1', 'yoga'),
('2022.2', 'zed'), ('2022.2', 'zed'),
('2023.1', 'antelope'),
]) ])
# The ugly duckling - must list releases oldest to newest # The ugly duckling - must list releases oldest to newest

View File

@ -173,6 +173,11 @@ def retrieve_secret_id(url, token):
# hvac < 0.9.2 assumes adapter is an instance, so doesn't instantiate # hvac < 0.9.2 assumes adapter is an instance, so doesn't instantiate
if not isinstance(client.adapter, hvac.adapters.Request): if not isinstance(client.adapter, hvac.adapters.Request):
client.adapter = hvac.adapters.Request(base_uri=url, token=token) client.adapter = hvac.adapters.Request(base_uri=url, token=token)
try:
# hvac == 1.0.0 has an API to unwrap with the user token
response = client.sys.unwrap()
except AttributeError:
# fallback to hvac < 1.0.0
response = client._post('/v1/sys/wrapping/unwrap') response = client._post('/v1/sys/wrapping/unwrap')
if response.status_code == 200: if response.status_code == 200:
data = response.json() data = response.json()

View File

@ -31,6 +31,7 @@ UBUNTU_RELEASES = (
'impish', 'impish',
'jammy', 'jammy',
'kinetic', 'kinetic',
'lunar',
) )

View File

@ -171,8 +171,9 @@ class Storage(object):
path parameter which causes sqlite3 to only build the db in memory. path parameter which causes sqlite3 to only build the db in memory.
This should only be used for testing purposes. This should only be used for testing purposes.
""" """
def __init__(self, path=None): def __init__(self, path=None, keep_revisions=False):
self.db_path = path self.db_path = path
self.keep_revisions = keep_revisions
if path is None: if path is None:
if 'UNIT_STATE_DB' in os.environ: if 'UNIT_STATE_DB' in os.environ:
self.db_path = os.environ['UNIT_STATE_DB'] self.db_path = os.environ['UNIT_STATE_DB']
@ -242,7 +243,7 @@ class Storage(object):
Remove a key from the database entirely. Remove a key from the database entirely.
""" """
self.cursor.execute('delete from kv where key=?', [key]) self.cursor.execute('delete from kv where key=?', [key])
if self.revision and self.cursor.rowcount: if self.keep_revisions and self.revision and self.cursor.rowcount:
self.cursor.execute( self.cursor.execute(
'insert into kv_revisions values (?, ?, ?)', 'insert into kv_revisions values (?, ?, ?)',
[key, self.revision, json.dumps('DELETED')]) [key, self.revision, json.dumps('DELETED')])
@ -259,14 +260,14 @@ class Storage(object):
if keys is not None: if keys is not None:
keys = ['%s%s' % (prefix, key) for key in keys] keys = ['%s%s' % (prefix, key) for key in keys]
self.cursor.execute('delete from kv where key in (%s)' % ','.join(['?'] * len(keys)), keys) self.cursor.execute('delete from kv where key in (%s)' % ','.join(['?'] * len(keys)), keys)
if self.revision and self.cursor.rowcount: if self.keep_revisions and self.revision and self.cursor.rowcount:
self.cursor.execute( self.cursor.execute(
'insert into kv_revisions values %s' % ','.join(['(?, ?, ?)'] * len(keys)), 'insert into kv_revisions values %s' % ','.join(['(?, ?, ?)'] * len(keys)),
list(itertools.chain.from_iterable((key, self.revision, json.dumps('DELETED')) for key in keys))) list(itertools.chain.from_iterable((key, self.revision, json.dumps('DELETED')) for key in keys)))
else: else:
self.cursor.execute('delete from kv where key like ?', self.cursor.execute('delete from kv where key like ?',
['%s%%' % prefix]) ['%s%%' % prefix])
if self.revision and self.cursor.rowcount: if self.keep_revisions and self.revision and self.cursor.rowcount:
self.cursor.execute( self.cursor.execute(
'insert into kv_revisions values (?, ?, ?)', 'insert into kv_revisions values (?, ?, ?)',
['%s%%' % prefix, self.revision, json.dumps('DELETED')]) ['%s%%' % prefix, self.revision, json.dumps('DELETED')])
@ -299,7 +300,7 @@ class Storage(object):
where key = ?''', [serialized, key]) where key = ?''', [serialized, key])
# Save # Save
if not self.revision: if (not self.keep_revisions) or (not self.revision):
return value return value
self.cursor.execute( self.cursor.execute(

View File

@ -230,6 +230,14 @@ CLOUD_ARCHIVE_POCKETS = {
'zed/proposed': 'jammy-proposed/zed', 'zed/proposed': 'jammy-proposed/zed',
'jammy-zed/proposed': 'jammy-proposed/zed', 'jammy-zed/proposed': 'jammy-proposed/zed',
'jammy-proposed/zed': 'jammy-proposed/zed', 'jammy-proposed/zed': 'jammy-proposed/zed',
# antelope
'antelope': 'jammy-updates/antelope',
'jammy-antelope': 'jammy-updates/antelope',
'jammy-antelope/updates': 'jammy-updates/antelope',
'jammy-updates/antelope': 'jammy-updates/antelope',
'antelope/proposed': 'jammy-proposed/antelope',
'jammy-antelope/proposed': 'jammy-proposed/antelope',
'jammy-proposed/antelope': 'jammy-proposed/antelope',
# OVN # OVN
'focal-ovn-22.03': 'focal-updates/ovn-22.03', 'focal-ovn-22.03': 'focal-updates/ovn-22.03',
@ -261,6 +269,7 @@ OPENSTACK_RELEASES = (
'xena', 'xena',
'yoga', 'yoga',
'zed', 'zed',
'antelope',
) )
@ -288,6 +297,7 @@ UBUNTU_OPENSTACK_RELEASE = OrderedDict([
('impish', 'xena'), ('impish', 'xena'),
('jammy', 'yoga'), ('jammy', 'yoga'),
('kinetic', 'zed'), ('kinetic', 'zed'),
('lunar', 'antelope'),
]) ])
@ -945,10 +955,14 @@ def _run_with_retries(cmd, max_retries=CMD_RETRY_COUNT, retry_exitcodes=(1,),
try: try:
result = subprocess.check_call(cmd, env=env, **kwargs) result = subprocess.check_call(cmd, env=env, **kwargs)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
retry_count = retry_count + 1
if retry_count > max_retries:
raise
result = e.returncode result = e.returncode
if result not in retry_results:
# a non-retriable exitcode was produced
raise
retry_count += 1
if retry_count > max_retries:
# a retriable exitcode was produced more than {max_retries} times
raise
log(retry_message) log(retry_message)
time.sleep(CMD_RETRY_DELAY) time.sleep(CMD_RETRY_DELAY)