Add Groovy to the test gate

Also sync libraries

Change-Id: I4e9d276edde7fb46ebf6b641edb3ad5df86cd040
This commit is contained in:
Aurelien Lourot 2020-11-05 12:43:42 +01:00
parent a165b2a3bb
commit e87ef6ec00
7 changed files with 146 additions and 39 deletions

View File

@ -34,12 +34,14 @@ from charmhelpers.core.hookenv import (
WARNING,
)
from charmhelpers.contrib.openstack.ip import (
ADMIN,
resolve_address,
get_vip_in_network,
INTERNAL,
PUBLIC,
ADDRESS_MAP)
ADDRESS_MAP,
get_default_api_bindings,
)
from charmhelpers.contrib.network.ip import (
get_relation_ip,
)
from charmhelpers.core.host import (
mkdir,
@ -113,44 +115,118 @@ class CertRequest(object):
return req
def get_certificate_request(json_encode=True):
"""Generate a certificatee requests based on the network confioguration
def get_certificate_request(json_encode=True, bindings=None):
"""Generate a certificate requests based on the network configuration
:param json_encode: Encode request in JSON or not. Used for setting
directly on a relation.
:type json_encode: boolean
:param bindings: List of bindings to check in addition to default api
bindings.
:type bindings: list of strings
:returns: CertRequest request as dictionary or JSON string.
:rtype: Union[dict, json]
"""
if bindings:
# Add default API bindings to bindings list
bindings = set(bindings + get_default_api_bindings())
else:
# Use default API bindings
bindings = get_default_api_bindings()
req = CertRequest(json_encode=json_encode)
req.add_hostname_cn()
# Add os-hostname entries
for net_type in [INTERNAL, ADMIN, PUBLIC]:
net_config = config(ADDRESS_MAP[net_type]['override'])
_sans = get_certificate_sans()
# Handle specific hostnames per binding
for binding in bindings:
hostname_override = config(ADDRESS_MAP[binding]['override'])
try:
net_addr = resolve_address(endpoint_type=net_type)
net_addr = resolve_address(endpoint_type=binding)
ip = network_get_primary_address(
ADDRESS_MAP[net_type]['binding'])
ADDRESS_MAP[binding]['binding'])
addresses = [net_addr, ip]
vip = get_vip_in_network(resolve_network_cidr(ip))
if vip:
addresses.append(vip)
if net_config:
# Add hostname certificate request
if hostname_override:
req.add_entry(
net_type,
net_config,
binding,
hostname_override,
addresses)
else:
# There is network address with no corresponding hostname.
# Add the ip to the hostname cert to allow for this.
req.add_hostname_cn_ip(addresses)
# Remove hostname specific addresses from _sans
for addr in addresses:
try:
_sans.remove(addr)
except (ValueError, KeyError):
pass
except NoNetworkBinding:
log("Skipping request for certificate for ip in {} space, no "
"local address found".format(net_type), WARNING)
"local address found".format(binding), WARNING)
# Gurantee all SANs are covered
# These are network addresses with no corresponding hostname.
# Add the ips to the hostname cert to allow for this.
req.add_hostname_cn_ip(_sans)
return req.get_request()
def get_certificate_sans(bindings=None):
"""Get all possible IP addresses for certificate SANs.
"""
_sans = [unit_get('private-address')]
if bindings:
# Add default API bindings to bindings list
bindings = set(bindings + get_default_api_bindings())
else:
# Use default API bindings
bindings = get_default_api_bindings()
for binding in bindings:
# Check for config override
try:
net_config = config(ADDRESS_MAP[binding]['config'])
except KeyError:
# There is no configuration network for this binding name
net_config = None
# Using resolve_address is likely redundant. Keeping it here in
# case there is an edge case it handles.
net_addr = resolve_address(endpoint_type=binding)
ip = get_relation_ip(binding, cidr_network=net_config)
_sans = _sans + [net_addr, ip]
vip = get_vip_in_network(resolve_network_cidr(ip))
if vip:
_sans.append(vip)
return set(_sans)
def create_ip_cert_links(ssl_dir, custom_hostname_link=None):
"""Create symlinks for SAN records
:param ssl_dir: str Directory to create symlinks in
:param custom_hostname_link: str Additional link to be created
"""
# This includes the hostname cert and any specific bindng certs:
# admin, internal, public
req = get_certificate_request(json_encode=False)["cert_requests"]
# Specific certs
for cert_req in req.keys():
requested_cert = os.path.join(
ssl_dir,
'cert_{}'.format(cert_req))
requested_key = os.path.join(
ssl_dir,
'key_{}'.format(cert_req))
for addr in req[cert_req]['sans']:
cert = os.path.join(ssl_dir, 'cert_{}'.format(addr))
key = os.path.join(ssl_dir, 'key_{}'.format(addr))
if os.path.isfile(requested_cert) and not os.path.isfile(cert):
os.symlink(requested_cert, cert)
os.symlink(requested_key, key)
# Handle custom hostnames
hostname = get_hostname(unit_get('private-address'))
hostname_cert = os.path.join(
ssl_dir,
@ -158,18 +234,6 @@ def create_ip_cert_links(ssl_dir, custom_hostname_link=None):
hostname_key = os.path.join(
ssl_dir,
'key_{}'.format(hostname))
# Add links to hostname cert, used if os-hostname vars not set
for net_type in [INTERNAL, ADMIN, PUBLIC]:
try:
addr = resolve_address(endpoint_type=net_type)
cert = os.path.join(ssl_dir, 'cert_{}'.format(addr))
key = os.path.join(ssl_dir, 'key_{}'.format(addr))
if os.path.isfile(hostname_cert) and not os.path.isfile(cert):
os.symlink(hostname_cert, cert)
os.symlink(hostname_key, key)
except NoNetworkBinding:
log("Skipping creating cert symlink for ip in {} space, no "
"local address found".format(net_type), WARNING)
if custom_hostname_link:
custom_cert = os.path.join(
ssl_dir,

View File

@ -33,6 +33,7 @@ INTERNAL = 'int'
ADMIN = 'admin'
ACCESS = 'access'
# TODO: reconcile 'int' vs 'internal' binding names
ADDRESS_MAP = {
PUBLIC: {
'binding': 'public',
@ -58,6 +59,14 @@ ADDRESS_MAP = {
'fallback': 'private-address',
'override': 'os-access-hostname',
},
# Note (thedac) bridge to begin the reconciliation between 'int' vs
# 'internal' binding names
'internal': {
'binding': 'internal',
'config': 'os-internal-network',
'fallback': 'private-address',
'override': 'os-internal-hostname',
},
}
@ -195,3 +204,10 @@ def get_vip_in_network(network):
if is_address_in_network(network, vip):
matching_vip = vip
return matching_vip
def get_default_api_bindings():
_default_bindings = []
for binding in [INTERNAL, ADMIN, PUBLIC]:
_default_bindings.append(ADDRESS_MAP[binding]['binding'])
return _default_bindings

View File

@ -230,7 +230,7 @@ SWIFT_CODENAMES = OrderedDict([
('ussuri',
['2.24.0', '2.25.0']),
('victoria',
['2.25.0']),
['2.25.0', '2.26.0']),
])
# >= Liberty version->codename mapping

View File

@ -41,6 +41,7 @@ from subprocess import (
)
from charmhelpers import deprecate
from charmhelpers.core.hookenv import (
application_name,
config,
service_name,
local_unit,
@ -162,6 +163,17 @@ def get_osd_settings(relation_name):
return _order_dict_by_key(osd_settings)
def send_application_name(relid=None):
"""Send the application name down the relation.
:param relid: Relation id to set application name in.
:type relid: str
"""
relation_set(
relation_id=relid,
relation_settings={'application-name': application_name()})
def send_osd_settings():
"""Pass on requested OSD settings to osd units."""
try:
@ -2203,6 +2215,7 @@ def send_request_if_needed(request, relation='ceph'):
for rid in relation_ids(relation):
log('Sending request {}'.format(request.request_id), level=DEBUG)
relation_set(relation_id=rid, broker_req=request.request)
relation_set(relation_id=rid, relation_settings={'unit-name': local_unit()})
def has_broker_rsp(rid=None, unit=None):

View File

@ -750,7 +750,7 @@ def handle_create_cephfs(request, service):
"""
cephfs_name = request.get('mds_name')
data_pool = request.get('data_pool')
extra_pools = request.get('extra_pools', [])
extra_pools = request.get('extra_pools', None) or []
metadata_pool = request.get('metadata_pool')
# Check if the user params were provided
if not cephfs_name or not data_pool or not metadata_pool:

View File

@ -2141,6 +2141,8 @@ def roll_monitor_cluster(new_version, upgrade_key):
# A sorted list of osd unit names
mon_sorted_list = sorted(monitor_list)
# Install packages immediately but defer restarts to when it's our time.
upgrade_monitor(new_version, restart_daemons=False)
try:
position = mon_sorted_list.index(my_name)
log("upgrade position: {}".format(position))
@ -2182,7 +2184,7 @@ def noop():
pass
def upgrade_monitor(new_version, kick_function=None):
def upgrade_monitor(new_version, kick_function=None, restart_daemons=True):
"""Upgrade the current ceph monitor to the new version
:param new_version: String version to upgrade to.
@ -2207,6 +2209,22 @@ def upgrade_monitor(new_version, kick_function=None):
status_set("blocked", "Upgrade to {} failed".format(new_version))
sys.exit(1)
kick_function()
try:
apt_install(packages=determine_packages(), fatal=True)
rm_packages = determine_packages_to_remove()
if rm_packages:
apt_purge(packages=rm_packages, fatal=True)
except subprocess.CalledProcessError as err:
log("Upgrading packages failed "
"with message: {}".format(err))
status_set("blocked", "Upgrade to {} failed".format(new_version))
sys.exit(1)
if not restart_daemons:
log("Packages upgraded but not restarting daemons yet.")
return
try:
if systemd():
service_stop('ceph-mon')
@ -2216,10 +2234,7 @@ def upgrade_monitor(new_version, kick_function=None):
service_stop('ceph-mgr.target')
else:
service_stop('ceph-mon-all')
apt_install(packages=determine_packages(), fatal=True)
rm_packages = determine_packages_to_remove()
if rm_packages:
apt_purge(packages=rm_packages, fatal=True)
kick_function()
owner = ceph_user()

View File

@ -1,5 +1,6 @@
charm_name: ceph-mon
gate_bundles:
- groovy-victoria
- focal-victoria
- focal-ussuri-ec
- focal-ussuri
@ -16,8 +17,6 @@ gate_bundles:
- trusty-mitaka
smoke_bundles:
- bionic-train
dev_bundles:
- groovy-victoria
configure:
- zaza.openstack.charm_tests.glance.setup.add_lts_image
tests: