Merge keystone/next into change to get ready for final merge
This commit is contained in:
1
Makefile
1
Makefile
@@ -13,6 +13,7 @@ test:
|
|||||||
|
|
||||||
functional_test:
|
functional_test:
|
||||||
@echo Starting Amulet tests...
|
@echo Starting Amulet tests...
|
||||||
|
@tests/setup/00-setup
|
||||||
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
|
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
|
||||||
|
|
||||||
bin/charm_helpers_sync.py:
|
bin/charm_helpers_sync.py:
|
||||||
|
@@ -11,7 +11,7 @@ include:
|
|||||||
- cluster
|
- cluster
|
||||||
- contrib.python
|
- contrib.python
|
||||||
- contrib.unison
|
- contrib.unison
|
||||||
- payload.execd
|
- payload
|
||||||
- contrib.peerstorage
|
- contrib.peerstorage
|
||||||
- contrib.network.ip
|
- contrib.network.ip
|
||||||
- contrib.python.packages
|
- contrib.python.packages
|
||||||
|
@@ -237,12 +237,14 @@ def neutron_plugins():
|
|||||||
plugins['midonet']['driver'] = (
|
plugins['midonet']['driver'] = (
|
||||||
'neutron.plugins.midonet.plugin.MidonetPluginV2')
|
'neutron.plugins.midonet.plugin.MidonetPluginV2')
|
||||||
if release >= 'liberty':
|
if release >= 'liberty':
|
||||||
plugins['midonet']['driver'] = (
|
midonet_origin = config('midonet-origin')
|
||||||
'midonet.neutron.plugin_v1.MidonetPluginV2')
|
if midonet_origin is not None and midonet_origin[4:5] == '1':
|
||||||
plugins['midonet']['server_packages'].remove(
|
plugins['midonet']['driver'] = (
|
||||||
'python-neutron-plugin-midonet')
|
'midonet.neutron.plugin_v1.MidonetPluginV2')
|
||||||
plugins['midonet']['server_packages'].append(
|
plugins['midonet']['server_packages'].remove(
|
||||||
'python-networking-midonet')
|
'python-neutron-plugin-midonet')
|
||||||
|
plugins['midonet']['server_packages'].append(
|
||||||
|
'python-networking-midonet')
|
||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
|
73
charmhelpers/payload/archive.py
Normal file
73
charmhelpers/payload/archive.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tarfile
|
||||||
|
import zipfile
|
||||||
|
from charmhelpers.core import (
|
||||||
|
host,
|
||||||
|
hookenv,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ArchiveError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_archive_handler(archive_name):
|
||||||
|
if os.path.isfile(archive_name):
|
||||||
|
if tarfile.is_tarfile(archive_name):
|
||||||
|
return extract_tarfile
|
||||||
|
elif zipfile.is_zipfile(archive_name):
|
||||||
|
return extract_zipfile
|
||||||
|
else:
|
||||||
|
# look at the file name
|
||||||
|
for ext in ('.tar', '.tar.gz', '.tgz', 'tar.bz2', '.tbz2', '.tbz'):
|
||||||
|
if archive_name.endswith(ext):
|
||||||
|
return extract_tarfile
|
||||||
|
for ext in ('.zip', '.jar'):
|
||||||
|
if archive_name.endswith(ext):
|
||||||
|
return extract_zipfile
|
||||||
|
|
||||||
|
|
||||||
|
def archive_dest_default(archive_name):
|
||||||
|
archive_file = os.path.basename(archive_name)
|
||||||
|
return os.path.join(hookenv.charm_dir(), "archives", archive_file)
|
||||||
|
|
||||||
|
|
||||||
|
def extract(archive_name, destpath=None):
|
||||||
|
handler = get_archive_handler(archive_name)
|
||||||
|
if handler:
|
||||||
|
if not destpath:
|
||||||
|
destpath = archive_dest_default(archive_name)
|
||||||
|
if not os.path.isdir(destpath):
|
||||||
|
host.mkdir(destpath)
|
||||||
|
handler(archive_name, destpath)
|
||||||
|
return destpath
|
||||||
|
else:
|
||||||
|
raise ArchiveError("No handler for archive")
|
||||||
|
|
||||||
|
|
||||||
|
def extract_tarfile(archive_name, destpath):
|
||||||
|
"Unpack a tar archive, optionally compressed"
|
||||||
|
archive = tarfile.open(archive_name)
|
||||||
|
archive.extractall(destpath)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_zipfile(archive_name, destpath):
|
||||||
|
"Unpack a zip file"
|
||||||
|
archive = zipfile.ZipFile(archive_name)
|
||||||
|
archive.extractall(destpath)
|
@@ -1,11 +1,11 @@
|
|||||||
options:
|
options:
|
||||||
debug:
|
debug:
|
||||||
default: "false"
|
type: boolean
|
||||||
type: string
|
default: False
|
||||||
description: Enable verbose logging.
|
description: Enable verbose logging.
|
||||||
verbose:
|
verbose:
|
||||||
default: "false"
|
type: boolean
|
||||||
type: string
|
default: False
|
||||||
description: Enable debug logging.
|
description: Enable debug logging.
|
||||||
use-syslog:
|
use-syslog:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@@ -189,7 +189,7 @@ class KeystoneContext(context.OSContextGenerator):
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
from keystone_utils import (
|
from keystone_utils import (
|
||||||
api_port, set_admin_token, endpoint_url, resolve_address,
|
api_port, set_admin_token, endpoint_url, resolve_address,
|
||||||
PUBLIC, ADMIN, PKI_CERTS_DIR, SSH_USER, ensure_permissions,
|
PUBLIC, ADMIN, PKI_CERTS_DIR, ensure_pki_cert_paths,
|
||||||
)
|
)
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
ctxt['token'] = set_admin_token(config('admin-token'))
|
ctxt['token'] = set_admin_token(config('admin-token'))
|
||||||
@@ -198,10 +198,8 @@ class KeystoneContext(context.OSContextGenerator):
|
|||||||
ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
|
ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
|
||||||
singlenode_mode=True)
|
singlenode_mode=True)
|
||||||
|
|
||||||
debug = config('debug')
|
ctxt['debug'] = config('debug')
|
||||||
ctxt['debug'] = debug and bool_from_string(debug)
|
ctxt['verbose'] = config('verbose')
|
||||||
verbose = config('verbose')
|
|
||||||
ctxt['verbose'] = verbose and bool_from_string(verbose)
|
|
||||||
ctxt['token_expiration'] = config('token-expiration')
|
ctxt['token_expiration'] = config('token-expiration')
|
||||||
|
|
||||||
ctxt['identity_backend'] = config('identity-backend')
|
ctxt['identity_backend'] = config('identity-backend')
|
||||||
@@ -219,32 +217,16 @@ class KeystoneContext(context.OSContextGenerator):
|
|||||||
|
|
||||||
enable_pki = config('enable-pki')
|
enable_pki = config('enable-pki')
|
||||||
if enable_pki and bool_from_string(enable_pki):
|
if enable_pki and bool_from_string(enable_pki):
|
||||||
ctxt['signing'] = True
|
log("Enabling PKI", level=DEBUG)
|
||||||
ctxt['token_provider'] = 'pki'
|
ctxt['token_provider'] = 'pki'
|
||||||
|
|
||||||
if 'token_provider' in ctxt:
|
ensure_pki_cert_paths()
|
||||||
log("Configuring PKI token cert paths", level=DEBUG)
|
certs = os.path.join(PKI_CERTS_DIR, 'certs')
|
||||||
certs = os.path.join(PKI_CERTS_DIR, 'certs')
|
privates = os.path.join(PKI_CERTS_DIR, 'privates')
|
||||||
privates = os.path.join(PKI_CERTS_DIR, 'privates')
|
ctxt.update({'certfile': os.path.join(certs, 'signing_cert.pem'),
|
||||||
for path in [PKI_CERTS_DIR, certs, privates]:
|
'keyfile': os.path.join(privates, 'signing_key.pem'),
|
||||||
perms = 0o755
|
'ca_certs': os.path.join(certs, 'ca.pem'),
|
||||||
if not os.path.isdir(path):
|
'ca_key': os.path.join(certs, 'ca_key.pem')})
|
||||||
mkdir(path=path, owner=SSH_USER, group='keystone',
|
|
||||||
perms=perms)
|
|
||||||
else:
|
|
||||||
# Ensure accessible by ssh user and group (for sync).
|
|
||||||
ensure_permissions(path, user=SSH_USER,
|
|
||||||
group='keystone', perms=perms)
|
|
||||||
|
|
||||||
signing_paths = {'certfile': os.path.join(certs,
|
|
||||||
'signing_cert.pem'),
|
|
||||||
'keyfile': os.path.join(privates,
|
|
||||||
'signing_key.pem'),
|
|
||||||
'ca_certs': os.path.join(certs, 'ca.pem'),
|
|
||||||
'ca_key': os.path.join(certs, 'ca_key.pem')}
|
|
||||||
|
|
||||||
for key, val in signing_paths.iteritems():
|
|
||||||
ctxt[key] = val
|
|
||||||
|
|
||||||
# Base endpoint URL's which are used in keystone responses
|
# Base endpoint URL's which are used in keystone responses
|
||||||
# to unauthenticated requests to redirect clients to the
|
# to unauthenticated requests to redirect clients to the
|
||||||
@@ -255,6 +237,7 @@ class KeystoneContext(context.OSContextGenerator):
|
|||||||
ctxt['admin_endpoint'] = endpoint_url(
|
ctxt['admin_endpoint'] = endpoint_url(
|
||||||
resolve_address(ADMIN),
|
resolve_address(ADMIN),
|
||||||
api_port('keystone-admin')).rstrip('v2.0')
|
api_port('keystone-admin')).rstrip('v2.0')
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
@@ -263,7 +246,7 @@ class KeystoneLoggingContext(context.OSContextGenerator):
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
debug = config('debug')
|
debug = config('debug')
|
||||||
if debug and bool_from_string(debug):
|
if debug:
|
||||||
ctxt['root_level'] = 'DEBUG'
|
ctxt['root_level'] = 'DEBUG'
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
@@ -74,13 +74,15 @@ from keystone_utils import (
|
|||||||
clear_ssl_synced_units,
|
clear_ssl_synced_units,
|
||||||
is_db_initialised,
|
is_db_initialised,
|
||||||
update_certs_if_available,
|
update_certs_if_available,
|
||||||
is_pki_enabled,
|
|
||||||
ensure_ssl_dir,
|
ensure_ssl_dir,
|
||||||
ensure_pki_dir_permissions,
|
ensure_pki_dir_permissions,
|
||||||
ensure_permissions,
|
ensure_permissions,
|
||||||
force_ssl_sync,
|
force_ssl_sync,
|
||||||
filter_null,
|
filter_null,
|
||||||
ensure_ssl_dirs,
|
ensure_ssl_dirs,
|
||||||
|
ensure_pki_cert_paths,
|
||||||
|
is_service_present,
|
||||||
|
delete_service_entry,
|
||||||
assess_status,
|
assess_status,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -175,8 +177,7 @@ def config_changed_postupgrade():
|
|||||||
update_nrpe_config()
|
update_nrpe_config()
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
|
|
||||||
if is_pki_enabled():
|
initialise_pki()
|
||||||
initialise_pki()
|
|
||||||
|
|
||||||
update_all_identity_relation_units()
|
update_all_identity_relation_units()
|
||||||
|
|
||||||
@@ -192,11 +193,14 @@ def config_changed_postupgrade():
|
|||||||
|
|
||||||
@synchronize_ca_if_changed(fatal=True)
|
@synchronize_ca_if_changed(fatal=True)
|
||||||
def initialise_pki():
|
def initialise_pki():
|
||||||
"""Create certs and keys required for PKI token signing.
|
"""Create certs and keys required for token signing.
|
||||||
|
|
||||||
|
Used for PKI and signing token revocation list.
|
||||||
|
|
||||||
NOTE: keystone.conf [signing] section must be up-to-date prior to
|
NOTE: keystone.conf [signing] section must be up-to-date prior to
|
||||||
executing this.
|
executing this.
|
||||||
"""
|
"""
|
||||||
|
ensure_pki_cert_paths()
|
||||||
if not peer_units() or is_ssl_cert_master():
|
if not peer_units() or is_ssl_cert_master():
|
||||||
log("Ensuring PKI token certs created", level=DEBUG)
|
log("Ensuring PKI token certs created", level=DEBUG)
|
||||||
cmd = ['keystone-manage', 'pki_setup', '--keystone-user', 'keystone',
|
cmd = ['keystone-manage', 'pki_setup', '--keystone-user', 'keystone',
|
||||||
@@ -337,6 +341,8 @@ def identity_changed(relation_id=None, remote_unit=None):
|
|||||||
return
|
return
|
||||||
|
|
||||||
add_service_to_keystone(relation_id, remote_unit)
|
add_service_to_keystone(relation_id, remote_unit)
|
||||||
|
if is_service_present('neutron', 'network'):
|
||||||
|
delete_service_entry('quantum', 'network')
|
||||||
settings = relation_get(rid=relation_id, unit=remote_unit)
|
settings = relation_get(rid=relation_id, unit=remote_unit)
|
||||||
service = settings.get('service', None)
|
service = settings.get('service', None)
|
||||||
if service:
|
if service:
|
||||||
@@ -377,44 +383,36 @@ def send_ssl_sync_request():
|
|||||||
Note the we do nothing if the setting is already applied.
|
Note the we do nothing if the setting is already applied.
|
||||||
"""
|
"""
|
||||||
unit = local_unit().replace('/', '-')
|
unit = local_unit().replace('/', '-')
|
||||||
count = 0
|
# Start with core config (e.g. used for signing revoked token list)
|
||||||
|
ssl_config = 0b1
|
||||||
|
|
||||||
use_https = config('use-https')
|
use_https = config('use-https')
|
||||||
if use_https and bool_from_string(use_https):
|
if use_https and bool_from_string(use_https):
|
||||||
count += 1
|
ssl_config ^= 0b10
|
||||||
|
|
||||||
https_service_endpoints = config('https-service-endpoints')
|
https_service_endpoints = config('https-service-endpoints')
|
||||||
if (https_service_endpoints and
|
if (https_service_endpoints and
|
||||||
bool_from_string(https_service_endpoints)):
|
bool_from_string(https_service_endpoints)):
|
||||||
count += 2
|
ssl_config ^= 0b100
|
||||||
|
|
||||||
enable_pki = config('enable-pki')
|
enable_pki = config('enable-pki')
|
||||||
if enable_pki and bool_from_string(enable_pki):
|
if enable_pki and bool_from_string(enable_pki):
|
||||||
count += 3
|
ssl_config ^= 0b1000
|
||||||
|
|
||||||
key = 'ssl-sync-required-%s' % (unit)
|
key = 'ssl-sync-required-%s' % (unit)
|
||||||
settings = {key: count}
|
settings = {key: ssl_config}
|
||||||
|
|
||||||
# If all ssl is disabled ensure this is set to 0 so that cluster hook runs
|
prev = 0b0
|
||||||
# and endpoints are updated.
|
|
||||||
if not count:
|
|
||||||
log("Setting %s=%s" % (key, count), level=DEBUG)
|
|
||||||
for rid in relation_ids('cluster'):
|
|
||||||
relation_set(relation_id=rid, relation_settings=settings)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
prev = 0
|
|
||||||
rid = None
|
rid = None
|
||||||
for rid in relation_ids('cluster'):
|
for rid in relation_ids('cluster'):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
_prev = relation_get(rid=rid, unit=unit, attribute=key) or 0
|
_prev = relation_get(rid=rid, unit=unit, attribute=key) or 0b0
|
||||||
if _prev and _prev > prev:
|
if _prev and _prev > prev:
|
||||||
prev = _prev
|
prev = bin(_prev)
|
||||||
|
|
||||||
if rid and prev < count:
|
if rid and prev ^ ssl_config:
|
||||||
clear_ssl_synced_units()
|
clear_ssl_synced_units()
|
||||||
log("Setting %s=%s" % (key, count), level=DEBUG)
|
log("Setting %s=%s" % (key, bin(ssl_config)), level=DEBUG)
|
||||||
relation_set(relation_id=rid, relation_settings=settings)
|
relation_set(relation_id=rid, relation_settings=settings)
|
||||||
|
|
||||||
|
|
||||||
@@ -459,8 +457,7 @@ def cluster_changed():
|
|||||||
|
|
||||||
check_peer_actions()
|
check_peer_actions()
|
||||||
|
|
||||||
if is_pki_enabled():
|
initialise_pki()
|
||||||
initialise_pki()
|
|
||||||
|
|
||||||
# Figure out if we need to mandate a sync
|
# Figure out if we need to mandate a sync
|
||||||
units = get_ssl_sync_request_units()
|
units = get_ssl_sync_request_units()
|
||||||
|
@@ -251,6 +251,10 @@ valid_services = {
|
|||||||
"type": "network",
|
"type": "network",
|
||||||
"desc": "Quantum Networking Service"
|
"desc": "Quantum Networking Service"
|
||||||
},
|
},
|
||||||
|
"neutron": {
|
||||||
|
"type": "network",
|
||||||
|
"desc": "Neutron Networking Service"
|
||||||
|
},
|
||||||
"oxygen": {
|
"oxygen": {
|
||||||
"type": "oxygen",
|
"type": "oxygen",
|
||||||
"desc": "Oxygen Cloud Image Service"
|
"desc": "Oxygen Cloud Image Service"
|
||||||
@@ -282,7 +286,15 @@ valid_services = {
|
|||||||
"ironic": {
|
"ironic": {
|
||||||
"type": "baremetal",
|
"type": "baremetal",
|
||||||
"desc": "Ironic bare metal provisioning service"
|
"desc": "Ironic bare metal provisioning service"
|
||||||
}
|
},
|
||||||
|
"designate": {
|
||||||
|
"type": "dns",
|
||||||
|
"desc": "Designate DNS service"
|
||||||
|
},
|
||||||
|
"astara": {
|
||||||
|
"type": "astara",
|
||||||
|
"desc": "Astara Network Orchestration Service",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# The interface is said to be satisfied if anyone of the interfaces in the
|
# The interface is said to be satisfied if anyone of the interfaces in the
|
||||||
@@ -493,6 +505,25 @@ def get_admin_token():
|
|||||||
error_out('Could not find admin_token line in %s' % KEYSTONE_CONF)
|
error_out('Could not find admin_token line in %s' % KEYSTONE_CONF)
|
||||||
|
|
||||||
|
|
||||||
|
def is_service_present(service_name, service_type):
|
||||||
|
import manager
|
||||||
|
manager = manager.KeystoneManager(endpoint=get_local_endpoint(),
|
||||||
|
token=get_admin_token())
|
||||||
|
service_id = manager.resolve_service_id(service_name, service_type)
|
||||||
|
return service_id is not None
|
||||||
|
|
||||||
|
|
||||||
|
def delete_service_entry(service_name, service_type):
|
||||||
|
""" Delete a service from keystone"""
|
||||||
|
import manager
|
||||||
|
manager = manager.KeystoneManager(endpoint=get_local_endpoint(),
|
||||||
|
token=get_admin_token())
|
||||||
|
service_id = manager.resolve_service_id(service_name, service_type)
|
||||||
|
if service_id:
|
||||||
|
manager.api.services.delete(service_id)
|
||||||
|
log("Deleted service entry '%s'" % service_name, level=DEBUG)
|
||||||
|
|
||||||
|
|
||||||
def create_service_entry(service_name, service_type, service_desc, owner=None):
|
def create_service_entry(service_name, service_type, service_desc, owner=None):
|
||||||
""" Add a new service entry to keystone if one does not already exist """
|
""" Add a new service entry to keystone if one does not already exist """
|
||||||
import manager
|
import manager
|
||||||
@@ -970,20 +1001,6 @@ def is_ssl_cert_master(votes=None):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_ssl_enabled():
|
|
||||||
use_https = config('use-https')
|
|
||||||
https_service_endpoints = config('https-service-endpoints')
|
|
||||||
if ((use_https and bool_from_string(use_https)) or
|
|
||||||
(https_service_endpoints and
|
|
||||||
bool_from_string(https_service_endpoints)) or
|
|
||||||
is_pki_enabled()):
|
|
||||||
log("SSL/HTTPS is enabled", level=DEBUG)
|
|
||||||
return True
|
|
||||||
|
|
||||||
log("SSL/HTTPS is NOT enabled", level=DEBUG)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def get_ssl_cert_master_votes():
|
def get_ssl_cert_master_votes():
|
||||||
"""Returns a list of unique votes."""
|
"""Returns a list of unique votes."""
|
||||||
votes = []
|
votes = []
|
||||||
@@ -1004,10 +1021,6 @@ def ensure_ssl_cert_master():
|
|||||||
Normally the cluster leader will take control but we allow for this to be
|
Normally the cluster leader will take control but we allow for this to be
|
||||||
ignored since this could be called before the cluster is ready.
|
ignored since this could be called before the cluster is ready.
|
||||||
"""
|
"""
|
||||||
# Don't do anything if we are not in ssl/https mode
|
|
||||||
if not is_ssl_enabled():
|
|
||||||
return False
|
|
||||||
|
|
||||||
master_override = False
|
master_override = False
|
||||||
elect = is_elected_leader(CLUSTER_RES)
|
elect = is_elected_leader(CLUSTER_RES)
|
||||||
|
|
||||||
@@ -1067,6 +1080,23 @@ def is_pki_enabled():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_pki_cert_paths():
|
||||||
|
certs = os.path.join(PKI_CERTS_DIR, 'certs')
|
||||||
|
privates = os.path.join(PKI_CERTS_DIR, 'privates')
|
||||||
|
not_exists = [p for p in [PKI_CERTS_DIR, certs, privates]
|
||||||
|
if not os.path.exists(p)]
|
||||||
|
if not_exists:
|
||||||
|
log("Configuring token signing cert paths", level=DEBUG)
|
||||||
|
perms = 0o755
|
||||||
|
for path in not_exists:
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
mkdir(path=path, owner=SSH_USER, group='keystone', perms=perms)
|
||||||
|
else:
|
||||||
|
# Ensure accessible by ssh user and group (for sync).
|
||||||
|
ensure_permissions(path, user=SSH_USER, group='keystone',
|
||||||
|
perms=perms)
|
||||||
|
|
||||||
|
|
||||||
def ensure_pki_dir_permissions():
|
def ensure_pki_dir_permissions():
|
||||||
# Ensure accessible by unison user and group (for sync).
|
# Ensure accessible by unison user and group (for sync).
|
||||||
ensure_permissions(PKI_CERTS_DIR, user=SSH_USER, group='keystone',
|
ensure_permissions(PKI_CERTS_DIR, user=SSH_USER, group='keystone',
|
||||||
@@ -1138,10 +1168,10 @@ def synchronize_ca(fatal=False):
|
|||||||
peer_service_actions['restart'].append('apache2')
|
peer_service_actions['restart'].append('apache2')
|
||||||
peer_actions.append('update-ca-certificates')
|
peer_actions.append('update-ca-certificates')
|
||||||
|
|
||||||
if is_pki_enabled():
|
# NOTE: certs needed for token signing e.g. pki and revocation list query.
|
||||||
log("Syncing token certs", level=DEBUG)
|
log("Syncing token certs", level=DEBUG)
|
||||||
paths_to_sync.append(PKI_CERTS_DIR)
|
paths_to_sync.append(PKI_CERTS_DIR)
|
||||||
peer_actions.append('ensure-pki-permissions')
|
peer_actions.append('ensure-pki-permissions')
|
||||||
|
|
||||||
if not paths_to_sync:
|
if not paths_to_sync:
|
||||||
log("Nothing to sync - skipping", level=DEBUG)
|
log("Nothing to sync - skipping", level=DEBUG)
|
||||||
|
@@ -28,12 +28,16 @@ class KeystoneManager(object):
|
|||||||
if name == u['name']:
|
if name == u['name']:
|
||||||
return u['id']
|
return u['id']
|
||||||
|
|
||||||
def resolve_service_id(self, name):
|
def resolve_service_id(self, name, service_type=None):
|
||||||
"""Find the service_id of a given service"""
|
"""Find the service_id of a given service"""
|
||||||
services = [s._info for s in self.api.services.list()]
|
services = [s._info for s in self.api.services.list()]
|
||||||
for s in services:
|
for s in services:
|
||||||
if name == s['name']:
|
if service_type:
|
||||||
return s['id']
|
if name == s['name'] and service_type == s['type']:
|
||||||
|
return s['id']
|
||||||
|
else:
|
||||||
|
if name == s['name']:
|
||||||
|
return s['id']
|
||||||
|
|
||||||
def resolve_service_id_by_type(self, type):
|
def resolve_service_id_by_type(self, type):
|
||||||
"""Find the service_id of a given service"""
|
"""Find the service_id of a given service"""
|
||||||
|
@@ -70,8 +70,6 @@ driver = keystone.assignment.backends.{{ assignment_backend }}.Assignment
|
|||||||
|
|
||||||
[oauth1]
|
[oauth1]
|
||||||
|
|
||||||
[signing]
|
|
||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
methods = external,password,token,oauth1
|
methods = external,password,token,oauth1
|
||||||
password = keystone.auth.plugins.password.Password
|
password = keystone.auth.plugins.password.Password
|
||||||
|
0
tests/020-basic-trusty-liberty → tests/018-basic-trusty-liberty
Normal file → Executable file
0
tests/020-basic-trusty-liberty → tests/018-basic-trusty-liberty
Normal file → Executable file
11
tests/019-basic-trusty-mitaka
Executable file
11
tests/019-basic-trusty-mitaka
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic keystone deployment on trusty-mitaka."""
|
||||||
|
|
||||||
|
from basic_deployment import KeystoneBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = KeystoneBasicDeployment(series='trusty',
|
||||||
|
openstack='cloud:trusty-mitaka',
|
||||||
|
source='cloud:trusty-updates/mitaka')
|
||||||
|
deployment.run_tests()
|
0
tests/021-basic-wily-liberty → tests/020-basic-wily-liberty
Normal file → Executable file
0
tests/021-basic-wily-liberty → tests/020-basic-wily-liberty
Normal file → Executable file
4
tests/019-basic-vivid-kilo → tests/021-basic-xenial-mitaka
Executable file → Normal file
4
tests/019-basic-vivid-kilo → tests/021-basic-xenial-mitaka
Executable file → Normal file
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
"""Amulet tests on a basic keystone deployment on vivid-kilo."""
|
"""Amulet tests on a basic keystone deployment on xenial-mitaka."""
|
||||||
|
|
||||||
from basic_deployment import KeystoneBasicDeployment
|
from basic_deployment import KeystoneBasicDeployment
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
deployment = KeystoneBasicDeployment(series='vivid')
|
deployment = KeystoneBasicDeployment(series='xenial')
|
||||||
deployment.run_tests()
|
deployment.run_tests()
|
117
tests/README
117
tests/README
@@ -1,62 +1,113 @@
|
|||||||
This directory provides Amulet tests that focus on verification of Keystone
|
This directory provides Amulet tests to verify basic deployment functionality
|
||||||
deployments.
|
from the perspective of this charm, its requirements and its features, as
|
||||||
|
exercised in a subset of the full OpenStack deployment test bundle topology.
|
||||||
|
|
||||||
test_* methods are called in lexical sort order.
|
Reference: lp:openstack-charm-testing for full test bundles.
|
||||||
|
|
||||||
Test name convention to ensure desired test order:
|
A single topology and configuration is defined and deployed, once for each of
|
||||||
|
the defined Ubuntu:OpenStack release combos. The ongoing goal is for this
|
||||||
|
charm to always possess tests and combo definitions for all currently-supported
|
||||||
|
release combinations of U:OS.
|
||||||
|
|
||||||
|
test_* methods are called in lexical sort order, as with most runners. However,
|
||||||
|
each individual test method should be idempotent and expected to pass regardless
|
||||||
|
of run order or Ubuntu:OpenStack combo. When writing or modifying tests,
|
||||||
|
ensure that every individual test is not dependent on another test_ method.
|
||||||
|
|
||||||
|
Test naming convention, purely for code organization purposes:
|
||||||
1xx service and endpoint checks
|
1xx service and endpoint checks
|
||||||
2xx relation checks
|
2xx relation checks
|
||||||
3xx config checks
|
3xx config checks
|
||||||
4xx functional checks
|
4xx functional checks
|
||||||
9xx restarts and other final checks
|
9xx restarts, config changes, actions and other final checks
|
||||||
|
|
||||||
In order to run tests, you'll need charm-tools installed (in addition to
|
In order to run tests, charm-tools and juju must be installed:
|
||||||
juju, of course):
|
|
||||||
sudo add-apt-repository ppa:juju/stable
|
sudo add-apt-repository ppa:juju/stable
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install charm-tools
|
sudo apt-get install charm-tools juju juju-deployer amulet
|
||||||
|
|
||||||
If you use a web proxy server to access the web, you'll need to set the
|
Alternatively, tests may be exercised with proposed or development versions
|
||||||
AMULET_HTTP_PROXY environment variable to the http URL of the proxy server.
|
of juju and related tools:
|
||||||
|
|
||||||
|
# juju proposed version
|
||||||
|
sudo add-apt-repository ppa:juju/proposed
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install charm-tools juju juju-deployer
|
||||||
|
|
||||||
|
# juju development version
|
||||||
|
sudo add-apt-repository ppa:juju/devel
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install charm-tools juju juju-deployer
|
||||||
|
|
||||||
|
Some tests may need to download files. If a web proxy server is required in
|
||||||
|
the environment, the AMULET_HTTP_PROXY environment variable must be set and
|
||||||
|
passed into the juju test command. This is unrelated to juju's http proxy
|
||||||
|
settings or behavior.
|
||||||
|
|
||||||
The following examples demonstrate different ways that tests can be executed.
|
The following examples demonstrate different ways that tests can be executed.
|
||||||
All examples are run from the charm's root directory.
|
All examples are run from the charm's root directory.
|
||||||
|
|
||||||
* To run all tests (starting with 00-setup):
|
* To run all +x tests in the tests directory:
|
||||||
|
|
||||||
make test
|
bzr branch lp:charms/trusty/foo
|
||||||
|
cd foo
|
||||||
|
make functional_test
|
||||||
|
|
||||||
* To run a specific test module (or modules):
|
* To run the tests against a specific release combo as defined in tests/:
|
||||||
|
|
||||||
juju test -v -p AMULET_HTTP_PROXY 15-basic-trusty-icehouse
|
bzr branch lp:charms/trusty/foo
|
||||||
|
cd foo
|
||||||
|
juju test -v -p AMULET_HTTP_PROXY 015-basic-trusty-icehouse
|
||||||
|
|
||||||
* To run a specific test module (or modules), and keep the environment
|
* To run tests and keep the juju environment deployed after a failure:
|
||||||
deployed after a failure:
|
|
||||||
|
|
||||||
juju test --set-e -v -p AMULET_HTTP_PROXY 15-basic-trusty-icehouse
|
bzr branch lp:charms/trusty/foo
|
||||||
|
cd foo
|
||||||
|
juju test --set-e -v -p AMULET_HTTP_PROXY 015-basic-trusty-icehouse
|
||||||
|
|
||||||
* To re-run a test module against an already deployed environment (one
|
* To re-run a test module against an already deployed environment (one
|
||||||
that was deployed by a previous call to 'juju test --set-e'):
|
that was deployed by a previous call to 'juju test --set-e'):
|
||||||
|
|
||||||
./tests/15-basic-trusty-icehouse
|
./tests/015-basic-trusty-icehouse
|
||||||
|
|
||||||
For debugging and test development purposes, all code should be idempotent.
|
* Even with --set-e, `juju test` will tear down the deployment when all
|
||||||
In other words, the code should have the ability to be re-run without changing
|
tests pass. The following work flow may be more effective when
|
||||||
the results beyond the initial run. This enables editing and re-running of a
|
iterating on test writing.
|
||||||
test module against an already deployed environment, as described above.
|
|
||||||
|
|
||||||
Manual debugging tips:
|
bzr branch lp:charms/trusty/foo
|
||||||
|
cd foo
|
||||||
|
./tests/setup/00-setup
|
||||||
|
juju bootstrap
|
||||||
|
./tests/015-basic-trusty-icehouse
|
||||||
|
# make some changes, run tests again
|
||||||
|
./tests/015-basic-trusty-icehouse
|
||||||
|
# make some changes, run tests again
|
||||||
|
./tests/015-basic-trusty-icehouse
|
||||||
|
|
||||||
* Set the following env vars before using the OpenStack CLI as admin:
|
* There may be test definitions in the tests/ dir which are not set +x
|
||||||
export OS_AUTH_URL=http://`juju-deployer -f keystone 2>&1 | tail -n 1`:5000/v2.0
|
executable. This is generally true for deprecated releases, or for
|
||||||
export OS_TENANT_NAME=admin
|
upcoming releases which are not yet validated and enabled. To enable
|
||||||
|
and run these tests:
|
||||||
|
bzr branch lp:charms/trusty/foo
|
||||||
|
cd foo
|
||||||
|
ls tests
|
||||||
|
chmod +x tests/017-basic-trusty-kilo
|
||||||
|
./tests/setup/00-setup
|
||||||
|
juju bootstrap
|
||||||
|
./tests/017-basic-trusty-kilo
|
||||||
|
|
||||||
|
|
||||||
|
Additional notes:
|
||||||
|
|
||||||
|
* Use DEBUG to turn on debug logging, use ERROR otherwise.
|
||||||
|
u = OpenStackAmuletUtils(ERROR)
|
||||||
|
u = OpenStackAmuletUtils(DEBUG)
|
||||||
|
|
||||||
|
* To interact with the deployed environment:
|
||||||
export OS_USERNAME=admin
|
export OS_USERNAME=admin
|
||||||
export OS_PASSWORD=openstack
|
export OS_PASSWORD=openstack
|
||||||
|
export OS_TENANT_NAME=admin
|
||||||
export OS_REGION_NAME=RegionOne
|
export OS_REGION_NAME=RegionOne
|
||||||
|
export OS_AUTH_URL=${OS_AUTH_PROTOCOL:-http}://`juju-deployer -e trusty -f keystone`:5000/v2.0
|
||||||
* Set the following env vars before using the OpenStack CLI as demoUser:
|
keystone user-list
|
||||||
export OS_AUTH_URL=http://`juju-deployer -f keystone 2>&1 | tail -n 1`:5000/v2.0
|
glance image-list
|
||||||
export OS_TENANT_NAME=demoTenant
|
|
||||||
export OS_USERNAME=demoUser
|
|
||||||
export OS_PASSWORD=password
|
|
||||||
export OS_REGION_NAME=RegionOne
|
|
||||||
|
@@ -6,7 +6,6 @@ Basic keystone amulet functional tests.
|
|||||||
|
|
||||||
import amulet
|
import amulet
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from charmhelpers.contrib.openstack.amulet.deployment import (
|
from charmhelpers.contrib.openstack.amulet.deployment import (
|
||||||
@@ -36,6 +35,11 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
self._add_relations()
|
self._add_relations()
|
||||||
self._configure_services()
|
self._configure_services()
|
||||||
self._deploy()
|
self._deploy()
|
||||||
|
|
||||||
|
u.log.info('Waiting on extended status checks...')
|
||||||
|
exclude_services = ['mysql']
|
||||||
|
self._auto_wait_for_status(exclude_services=exclude_services)
|
||||||
|
|
||||||
self._initialize_tests()
|
self._initialize_tests()
|
||||||
|
|
||||||
def _assert_services(self, should_run):
|
def _assert_services(self, should_run):
|
||||||
@@ -52,6 +56,7 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
"""
|
"""
|
||||||
this_service = {'name': 'keystone'}
|
this_service = {'name': 'keystone'}
|
||||||
other_services = [{'name': 'mysql'},
|
other_services = [{'name': 'mysql'},
|
||||||
|
{'name': 'rabbitmq-server'}, # satisfy wrkload stat
|
||||||
{'name': 'cinder'}]
|
{'name': 'cinder'}]
|
||||||
super(KeystoneBasicDeployment, self)._add_services(this_service,
|
super(KeystoneBasicDeployment, self)._add_services(this_service,
|
||||||
other_services)
|
other_services)
|
||||||
@@ -59,6 +64,8 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
def _add_relations(self):
|
def _add_relations(self):
|
||||||
"""Add all of the relations for the services."""
|
"""Add all of the relations for the services."""
|
||||||
relations = {'keystone:shared-db': 'mysql:shared-db',
|
relations = {'keystone:shared-db': 'mysql:shared-db',
|
||||||
|
'cinder:shared-db': 'mysql:shared-db',
|
||||||
|
'cinder:amqp': 'rabbitmq-server:amqp',
|
||||||
'cinder:identity-service': 'keystone:identity-service'}
|
'cinder:identity-service': 'keystone:identity-service'}
|
||||||
super(KeystoneBasicDeployment, self)._add_relations(relations)
|
super(KeystoneBasicDeployment, self)._add_relations(relations)
|
||||||
|
|
||||||
@@ -113,9 +120,6 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
u.log.debug('openstack release str: {}'.format(
|
u.log.debug('openstack release str: {}'.format(
|
||||||
self._get_openstack_release_string()))
|
self._get_openstack_release_string()))
|
||||||
|
|
||||||
# Let things settle a bit before moving forward
|
|
||||||
time.sleep(30)
|
|
||||||
|
|
||||||
# Authenticate keystone admin
|
# Authenticate keystone admin
|
||||||
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
|
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
|
||||||
user='admin',
|
user='admin',
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
bootstrap: true
|
bootstrap: true
|
||||||
reset: true
|
reset: false
|
||||||
virtualenv: true
|
virtualenv: true
|
||||||
makefile:
|
makefile:
|
||||||
- lint
|
- lint
|
||||||
@@ -9,6 +9,7 @@ sources:
|
|||||||
packages:
|
packages:
|
||||||
- amulet
|
- amulet
|
||||||
- distro-info-data
|
- distro-info-data
|
||||||
|
- python-ceilometerclient
|
||||||
- python-cinderclient
|
- python-cinderclient
|
||||||
- python-distro-info
|
- python-distro-info
|
||||||
- python-glanceclient
|
- python-glanceclient
|
||||||
|
4
tox.ini
4
tox.ini
@@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = lint,py27
|
envlist = pep8,py27
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
@@ -14,7 +14,7 @@ basepython = python2.7
|
|||||||
deps = -r{toxinidir}/requirements.txt
|
deps = -r{toxinidir}/requirements.txt
|
||||||
-r{toxinidir}/test-requirements.txt
|
-r{toxinidir}/test-requirements.txt
|
||||||
|
|
||||||
[testenv:lint]
|
[testenv:pep8]
|
||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
deps = -r{toxinidir}/requirements.txt
|
deps = -r{toxinidir}/requirements.txt
|
||||||
-r{toxinidir}/test-requirements.txt
|
-r{toxinidir}/test-requirements.txt
|
||||||
|
@@ -26,11 +26,9 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
@patch('keystone_utils.ensure_permissions')
|
@patch('keystone_utils.ensure_permissions')
|
||||||
@patch('keystone_utils.determine_ports')
|
@patch('keystone_utils.determine_ports')
|
||||||
@patch('keystone_utils.is_ssl_cert_master')
|
@patch('keystone_utils.is_ssl_cert_master')
|
||||||
@patch('keystone_utils.is_ssl_enabled')
|
|
||||||
@patch.object(context, 'log')
|
@patch.object(context, 'log')
|
||||||
def test_apache_ssl_context_ssl_not_master(self,
|
def test_apache_ssl_context_ssl_not_master(self,
|
||||||
mock_log,
|
mock_log,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_determine_ports,
|
mock_determine_ports,
|
||||||
mock_ensure_permissions,
|
mock_ensure_permissions,
|
||||||
@@ -38,7 +36,6 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
mock_mkdir,
|
mock_mkdir,
|
||||||
mock_cert_provided_in_config):
|
mock_cert_provided_in_config):
|
||||||
mock_cert_provided_in_config.return_value = False
|
mock_cert_provided_in_config.return_value = False
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
mock_is_ssl_cert_master.return_value = False
|
mock_is_ssl_cert_master.return_value = False
|
||||||
|
|
||||||
context.ApacheSSLContext().configure_cert('foo')
|
context.ApacheSSLContext().configure_cert('foo')
|
||||||
@@ -49,7 +46,6 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
|
|
||||||
@patch('keystone_utils.determine_ports')
|
@patch('keystone_utils.determine_ports')
|
||||||
@patch('keystone_utils.is_ssl_cert_master')
|
@patch('keystone_utils.is_ssl_cert_master')
|
||||||
@patch('keystone_utils.is_ssl_enabled')
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.config')
|
@patch('charmhelpers.contrib.openstack.context.config')
|
||||||
@patch('charmhelpers.contrib.openstack.context.is_clustered')
|
@patch('charmhelpers.contrib.openstack.context.is_clustered')
|
||||||
@patch('charmhelpers.contrib.openstack.context.determine_apache_port')
|
@patch('charmhelpers.contrib.openstack.context.determine_apache_port')
|
||||||
@@ -62,10 +58,8 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
mock_determine_apache_port,
|
mock_determine_apache_port,
|
||||||
mock_is_clustered,
|
mock_is_clustered,
|
||||||
mock_config,
|
mock_config,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_determine_ports):
|
mock_determine_ports):
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
mock_https.return_value = True
|
mock_https.return_value = True
|
||||||
mock_unit_get.return_value = '1.2.3.4'
|
mock_unit_get.return_value = '1.2.3.4'
|
||||||
@@ -97,10 +91,11 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
@patch('charmhelpers.contrib.openstack.context.related_units')
|
@patch('charmhelpers.contrib.openstack.context.related_units')
|
||||||
@patch('charmhelpers.contrib.openstack.context.relation_get')
|
@patch('charmhelpers.contrib.openstack.context.relation_get')
|
||||||
@patch('charmhelpers.contrib.openstack.context.log')
|
@patch('charmhelpers.contrib.openstack.context.log')
|
||||||
|
@patch('charmhelpers.contrib.openstack.context.kv')
|
||||||
@patch('__builtin__.open')
|
@patch('__builtin__.open')
|
||||||
def test_haproxy_context_service_enabled(
|
def test_haproxy_context_service_enabled(
|
||||||
self, mock_open, mock_log, mock_relation_get, mock_related_units,
|
self, mock_open, mock_kv, mock_log, mock_relation_get,
|
||||||
mock_unit_get, mock_relation_ids, mock_config,
|
mock_related_units, mock_unit_get, mock_relation_ids, mock_config,
|
||||||
mock_get_address_in_network, mock_get_netmask_for_address,
|
mock_get_address_in_network, mock_get_netmask_for_address,
|
||||||
mock_api_port):
|
mock_api_port):
|
||||||
os.environ['JUJU_UNIT_NAME'] = 'keystone'
|
os.environ['JUJU_UNIT_NAME'] = 'keystone'
|
||||||
@@ -114,13 +109,11 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
mock_get_netmask_for_address.return_value = '255.255.255.0'
|
mock_get_netmask_for_address.return_value = '255.255.255.0'
|
||||||
self.determine_apache_port.return_value = '34'
|
self.determine_apache_port.return_value = '34'
|
||||||
mock_api_port.return_value = '12'
|
mock_api_port.return_value = '12'
|
||||||
|
mock_kv().get.return_value = 'abcdefghijklmnopqrstuvwxyz123456'
|
||||||
|
|
||||||
ctxt = context.HAProxyContext()
|
ctxt = context.HAProxyContext()
|
||||||
|
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
# [ajkavangh] due to rev:514 the stat_port has changed format
|
|
||||||
# and stat_password (new) is dynamically generated.
|
|
||||||
_ctxt = ctxt()
|
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
ctxt(),
|
ctxt(),
|
||||||
{'listen_ports': {'admin_port': '12',
|
{'listen_ports': {'admin_port': '12',
|
||||||
@@ -128,7 +121,7 @@ class TestKeystoneContexts(CharmTestCase):
|
|||||||
'local_host': '127.0.0.1',
|
'local_host': '127.0.0.1',
|
||||||
'haproxy_host': '0.0.0.0',
|
'haproxy_host': '0.0.0.0',
|
||||||
'stat_port': '8888',
|
'stat_port': '8888',
|
||||||
'stat_password': _ctxt['stat_password'],
|
'stat_password': 'abcdefghijklmnopqrstuvwxyz123456',
|
||||||
'service_ports': {'admin-port': ['12', '34'],
|
'service_ports': {'admin-port': ['12', '34'],
|
||||||
'public-port': ['12', '34']},
|
'public-port': ['12', '34']},
|
||||||
'default_backend': '1.2.3.4',
|
'default_backend': '1.2.3.4',
|
||||||
|
@@ -71,6 +71,8 @@ TO_PATCH = [
|
|||||||
'get_netmask_for_address',
|
'get_netmask_for_address',
|
||||||
'get_address_in_network',
|
'get_address_in_network',
|
||||||
'git_install',
|
'git_install',
|
||||||
|
'is_service_present',
|
||||||
|
'delete_service_entry',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -349,9 +351,9 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch('keystone_utils.ensure_ssl_dirs')
|
@patch('keystone_utils.ensure_ssl_dirs')
|
||||||
@patch.object(hooks, 'ensure_permissions')
|
@patch.object(hooks, 'ensure_permissions')
|
||||||
|
@patch.object(hooks, 'ensure_pki_cert_paths')
|
||||||
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
||||||
@patch.object(hooks, 'ensure_ssl_dir')
|
@patch.object(hooks, 'ensure_ssl_dir')
|
||||||
@patch.object(hooks, 'is_pki_enabled')
|
|
||||||
@patch.object(hooks, 'is_ssl_cert_master')
|
@patch.object(hooks, 'is_ssl_cert_master')
|
||||||
@patch.object(hooks, 'send_ssl_sync_request')
|
@patch.object(hooks, 'send_ssl_sync_request')
|
||||||
@patch.object(hooks, 'peer_units')
|
@patch.object(hooks, 'peer_units')
|
||||||
@@ -371,8 +373,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_peer_units,
|
mock_peer_units,
|
||||||
mock_send_ssl_sync_request,
|
mock_send_ssl_sync_request,
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_is_pki_enabled,
|
|
||||||
mock_ensure_ssl_dir,
|
mock_ensure_ssl_dir,
|
||||||
|
mock_ensure_pki_cert_paths,
|
||||||
mock_ensure_permissions,
|
mock_ensure_permissions,
|
||||||
mock_ensure_pki_dir_permissions,
|
mock_ensure_pki_dir_permissions,
|
||||||
mock_ensure_ssl_dirs,
|
mock_ensure_ssl_dirs,
|
||||||
@@ -380,7 +382,6 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
mock_is_db_initialised):
|
mock_is_db_initialised):
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_pki_enabled.return_value = True
|
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
self.is_db_ready.return_value = True
|
self.is_db_ready.return_value = True
|
||||||
@@ -414,9 +415,9 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
@patch('keystone_utils.ensure_ssl_dirs')
|
@patch('keystone_utils.ensure_ssl_dirs')
|
||||||
@patch.object(hooks, 'update_all_identity_relation_units')
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'ensure_permissions')
|
@patch.object(hooks, 'ensure_permissions')
|
||||||
|
@patch.object(hooks, 'ensure_pki_cert_paths')
|
||||||
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
||||||
@patch.object(hooks, 'ensure_ssl_dir')
|
@patch.object(hooks, 'ensure_ssl_dir')
|
||||||
@patch.object(hooks, 'is_pki_enabled')
|
|
||||||
@patch.object(hooks, 'peer_units')
|
@patch.object(hooks, 'peer_units')
|
||||||
@patch.object(hooks, 'is_ssl_cert_master')
|
@patch.object(hooks, 'is_ssl_cert_master')
|
||||||
@patch.object(hooks, 'cluster_joined')
|
@patch.object(hooks, 'cluster_joined')
|
||||||
@@ -431,16 +432,15 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
ensure_user, cluster_joined,
|
ensure_user, cluster_joined,
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_peer_units,
|
mock_peer_units,
|
||||||
mock_is_pki_enabled,
|
|
||||||
mock_ensure_ssl_dir,
|
mock_ensure_ssl_dir,
|
||||||
mock_ensure_permissions,
|
mock_ensure_permissions,
|
||||||
|
mock_ensure_pki_cert_paths,
|
||||||
mock_ensure_pki_permissions,
|
mock_ensure_pki_permissions,
|
||||||
mock_update_all_id_rel_units,
|
mock_update_all_id_rel_units,
|
||||||
ensure_ssl_dirs,
|
ensure_ssl_dirs,
|
||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, git_requested):
|
mock_log, git_requested):
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_pki_enabled.return_value = True
|
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
mock_peer_units.return_value = []
|
mock_peer_units.return_value = []
|
||||||
self.openstack_upgrade_available.return_value = False
|
self.openstack_upgrade_available.return_value = False
|
||||||
@@ -465,9 +465,9 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch('keystone_utils.ensure_ssl_dirs')
|
@patch('keystone_utils.ensure_ssl_dirs')
|
||||||
@patch.object(hooks, 'ensure_permissions')
|
@patch.object(hooks, 'ensure_permissions')
|
||||||
|
@patch.object(hooks, 'ensure_pki_cert_paths')
|
||||||
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
||||||
@patch.object(hooks, 'ensure_ssl_dir')
|
@patch.object(hooks, 'ensure_ssl_dir')
|
||||||
@patch.object(hooks, 'is_pki_enabled')
|
|
||||||
@patch.object(hooks, 'is_ssl_cert_master')
|
@patch.object(hooks, 'is_ssl_cert_master')
|
||||||
@patch.object(hooks, 'send_ssl_sync_request')
|
@patch.object(hooks, 'send_ssl_sync_request')
|
||||||
@patch.object(hooks, 'peer_units')
|
@patch.object(hooks, 'peer_units')
|
||||||
@@ -486,16 +486,15 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_peer_units,
|
mock_peer_units,
|
||||||
mock_send_ssl_sync_request,
|
mock_send_ssl_sync_request,
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_is_pki_enabled,
|
|
||||||
mock_ensure_ssl_dir,
|
mock_ensure_ssl_dir,
|
||||||
mock_ensure_permissions,
|
mock_ensure_permissions,
|
||||||
|
mock_ensure_pki_cert_paths,
|
||||||
mock_ensure_pki_permissions,
|
mock_ensure_pki_permissions,
|
||||||
mock_ensure_ssl_dirs,
|
mock_ensure_ssl_dirs,
|
||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
mock_is_db_initialised):
|
mock_is_db_initialised):
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_pki_enabled.return_value = True
|
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
self.is_db_ready.return_value = True
|
self.is_db_ready.return_value = True
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
@@ -525,12 +524,12 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
remote_unit='unit/0')
|
remote_unit='unit/0')
|
||||||
admin_relation_changed.assert_called_with('identity-service:0')
|
admin_relation_changed.assert_called_with('identity-service:0')
|
||||||
|
|
||||||
|
@patch.object(hooks, 'initialise_pki')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@patch.object(hooks, 'config_value_changed')
|
@patch.object(hooks, 'config_value_changed')
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch.object(hooks, 'ensure_ssl_dir')
|
@patch.object(hooks, 'ensure_ssl_dir')
|
||||||
@patch.object(hooks, 'is_pki_enabled')
|
|
||||||
@patch.object(hooks, 'send_ssl_sync_request')
|
@patch.object(hooks, 'send_ssl_sync_request')
|
||||||
@patch.object(hooks, 'is_db_initialised')
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
@patch.object(hooks, 'is_db_ready')
|
@patch.object(hooks, 'is_db_ready')
|
||||||
@@ -550,14 +549,13 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_is_db_ready,
|
mock_is_db_ready,
|
||||||
mock_is_db_initialised,
|
mock_is_db_initialised,
|
||||||
mock_send_ssl_sync_request,
|
mock_send_ssl_sync_request,
|
||||||
mock_is_pki_enabled,
|
|
||||||
mock_ensure_ssl_dir,
|
mock_ensure_ssl_dir,
|
||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, config_val_changed,
|
mock_log, config_val_changed,
|
||||||
git_requested):
|
git_requested,
|
||||||
|
mock_initialise_pki):
|
||||||
git_requested.return_value = True
|
git_requested.return_value = True
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
mock_is_pki_enabled.return_value = False
|
|
||||||
self.openstack_upgrade_available.return_value = False
|
self.openstack_upgrade_available.return_value = False
|
||||||
self.is_elected_leader.return_value = True
|
self.is_elected_leader.return_value = True
|
||||||
mock_peer_units.return_value = []
|
mock_peer_units.return_value = []
|
||||||
@@ -584,12 +582,12 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
self.assertFalse(self.openstack_upgrade_available.called)
|
self.assertFalse(self.openstack_upgrade_available.called)
|
||||||
self.assertFalse(self.do_openstack_upgrade_reexec.called)
|
self.assertFalse(self.do_openstack_upgrade_reexec.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'initialise_pki')
|
||||||
@patch.object(hooks, 'is_db_initialised')
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@patch.object(hooks, 'config_value_changed')
|
@patch.object(hooks, 'config_value_changed')
|
||||||
@patch.object(hooks, 'ensure_ssl_dir')
|
@patch.object(hooks, 'ensure_ssl_dir')
|
||||||
@patch.object(hooks, 'configure_https')
|
@patch.object(hooks, 'configure_https')
|
||||||
@patch.object(hooks, 'is_pki_enabled')
|
|
||||||
@patch.object(hooks, 'is_ssl_cert_master')
|
@patch.object(hooks, 'is_ssl_cert_master')
|
||||||
@patch.object(hooks, 'peer_units')
|
@patch.object(hooks, 'peer_units')
|
||||||
@patch.object(unison, 'get_homedir')
|
@patch.object(unison, 'get_homedir')
|
||||||
@@ -600,13 +598,13 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
ensure_user,
|
ensure_user,
|
||||||
get_home,
|
get_home,
|
||||||
peer_units, is_ssl,
|
peer_units, is_ssl,
|
||||||
is_pki, config_https,
|
config_https,
|
||||||
ensure_ssl_dir,
|
ensure_ssl_dir,
|
||||||
config_value_changed,
|
config_value_changed,
|
||||||
git_requested,
|
git_requested,
|
||||||
mock_db_init):
|
mock_db_init,
|
||||||
|
mock_initialise_pki):
|
||||||
ensure_ssl_cert.return_value = False
|
ensure_ssl_cert.return_value = False
|
||||||
is_pki.return_value = False
|
|
||||||
peer_units.return_value = []
|
peer_units.return_value = []
|
||||||
|
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
@@ -627,6 +625,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_log, mock_is_db_initialised):
|
mock_log, mock_is_db_initialised):
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
self.is_db_ready.return_value = True
|
self.is_db_ready.return_value = True
|
||||||
|
self.is_service_present.return_value = True
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
hooks.identity_changed(
|
hooks.identity_changed(
|
||||||
relation_id='identity-service:0',
|
relation_id='identity-service:0',
|
||||||
@@ -634,6 +633,28 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
self.add_service_to_keystone.assert_called_with(
|
self.add_service_to_keystone.assert_called_with(
|
||||||
'identity-service:0',
|
'identity-service:0',
|
||||||
'unit/0')
|
'unit/0')
|
||||||
|
self.delete_service_entry.assert_called_with(
|
||||||
|
'quantum',
|
||||||
|
'network')
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
@patch('keystone_utils.log')
|
||||||
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
|
@patch.object(hooks, 'hashlib')
|
||||||
|
@patch.object(hooks, 'send_notifications')
|
||||||
|
def test_identity_changed_leader_no_neutron(self, mock_send_notifications,
|
||||||
|
mock_hashlib,
|
||||||
|
mock_ensure_ssl_cert_master,
|
||||||
|
mock_log,
|
||||||
|
mock_is_db_initialised):
|
||||||
|
mock_is_db_initialised.return_value = True
|
||||||
|
self.is_db_ready.return_value = True
|
||||||
|
self.is_service_present.return_value = False
|
||||||
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
|
hooks.identity_changed(
|
||||||
|
relation_id='identity-service:0',
|
||||||
|
remote_unit='unit/0')
|
||||||
|
self.assertFalse(self.delete_service_entry.called)
|
||||||
|
|
||||||
@patch.object(hooks, 'local_unit')
|
@patch.object(hooks, 'local_unit')
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@@ -662,6 +683,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
user=self.ssh_user, group='juju_keystone',
|
user=self.ssh_user, group='juju_keystone',
|
||||||
peer_interface='cluster', ensure_local_user=True)
|
peer_interface='cluster', ensure_local_user=True)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'initialise_pki')
|
||||||
@patch.object(hooks, 'update_all_identity_relation_units')
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'get_ssl_sync_request_units')
|
@patch.object(hooks, 'get_ssl_sync_request_units')
|
||||||
@patch.object(hooks, 'is_ssl_cert_master')
|
@patch.object(hooks, 'is_ssl_cert_master')
|
||||||
@@ -681,7 +703,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_peer_units,
|
mock_peer_units,
|
||||||
mock_is_ssl_cert_master,
|
mock_is_ssl_cert_master,
|
||||||
mock_get_ssl_sync_request_units,
|
mock_get_ssl_sync_request_units,
|
||||||
mock_update_all_identity_relation_units):
|
mock_update_all_identity_relation_units,
|
||||||
|
mock_initialise_pki):
|
||||||
|
|
||||||
relation_settings = {'foo_passwd': '123',
|
relation_settings = {'foo_passwd': '123',
|
||||||
'identity-service:16_foo': 'bar'}
|
'identity-service:16_foo': 'bar'}
|
||||||
|
@@ -479,22 +479,11 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
self.assertTrue(utils.is_db_ready())
|
self.assertTrue(utils.is_db_ready())
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
def test_ensure_ssl_cert_master_ssl_no_peers(self, mock_peer_units):
|
||||||
def test_ensure_ssl_cert_master_no_ssl(self, mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
|
||||||
mock_is_ssl_enabled.return_value = False
|
|
||||||
self.assertFalse(utils.ensure_ssl_cert_master())
|
|
||||||
self.assertFalse(self.relation_set.called)
|
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
|
||||||
def test_ensure_ssl_cert_master_ssl_no_peers(self, mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
|
||||||
def mock_rel_get(unit=None, **kwargs):
|
def mock_rel_get(unit=None, **kwargs):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self.relation_get.side_effect = mock_rel_get
|
self.relation_get.side_effect = mock_rel_get
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
self.related_units.return_value = []
|
self.related_units.return_value = []
|
||||||
@@ -508,9 +497,7 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
relation_settings=settings)
|
relation_settings=settings)
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
|
||||||
def test_ensure_ssl_cert_master_ssl_master_no_peers(self,
|
def test_ensure_ssl_cert_master_ssl_master_no_peers(self,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
mock_peer_units):
|
||||||
def mock_rel_get(unit=None, **kwargs):
|
def mock_rel_get(unit=None, **kwargs):
|
||||||
if unit == 'unit/0':
|
if unit == 'unit/0':
|
||||||
@@ -519,7 +506,6 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
self.relation_get.side_effect = mock_rel_get
|
self.relation_get.side_effect = mock_rel_get
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
self.related_units.return_value = []
|
self.related_units.return_value = []
|
||||||
@@ -533,10 +519,7 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
relation_settings=settings)
|
relation_settings=settings)
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
def test_ensure_ssl_cert_master_ssl_not_leader(self, mock_peer_units):
|
||||||
def test_ensure_ssl_cert_master_ssl_not_leader(self, mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
mock_peer_units.return_value = ['unit/1']
|
mock_peer_units.return_value = ['unit/1']
|
||||||
@@ -546,9 +529,7 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
self.assertFalse(self.relation_set.called)
|
self.assertFalse(self.relation_set.called)
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
|
||||||
def test_ensure_ssl_cert_master_is_leader_new_peer(self,
|
def test_ensure_ssl_cert_master_is_leader_new_peer(self,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
mock_peer_units):
|
||||||
def mock_rel_get(unit=None, **kwargs):
|
def mock_rel_get(unit=None, **kwargs):
|
||||||
if unit == 'unit/0':
|
if unit == 'unit/0':
|
||||||
@@ -557,7 +538,6 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
return 'unknown'
|
return 'unknown'
|
||||||
|
|
||||||
self.relation_get.side_effect = mock_rel_get
|
self.relation_get.side_effect = mock_rel_get
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
mock_peer_units.return_value = ['unit/1']
|
mock_peer_units.return_value = ['unit/1']
|
||||||
@@ -570,9 +550,7 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
relation_settings=settings)
|
relation_settings=settings)
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
|
||||||
def test_ensure_ssl_cert_master_is_leader_no_new_peer(self,
|
def test_ensure_ssl_cert_master_is_leader_no_new_peer(self,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
mock_peer_units):
|
||||||
def mock_rel_get(unit=None, **kwargs):
|
def mock_rel_get(unit=None, **kwargs):
|
||||||
if unit == 'unit/0':
|
if unit == 'unit/0':
|
||||||
@@ -581,7 +559,6 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
return 'unit/0'
|
return 'unit/0'
|
||||||
|
|
||||||
self.relation_get.side_effect = mock_rel_get
|
self.relation_get.side_effect = mock_rel_get
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
mock_peer_units.return_value = ['unit/1']
|
mock_peer_units.return_value = ['unit/1']
|
||||||
@@ -621,9 +598,7 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@patch.object(utils, 'peer_units')
|
@patch.object(utils, 'peer_units')
|
||||||
@patch.object(utils, 'is_ssl_enabled')
|
|
||||||
def test_ensure_ssl_cert_master_is_leader_bad_votes(self,
|
def test_ensure_ssl_cert_master_is_leader_bad_votes(self,
|
||||||
mock_is_ssl_enabled,
|
|
||||||
mock_peer_units):
|
mock_peer_units):
|
||||||
counter = {0: 0}
|
counter = {0: 0}
|
||||||
|
|
||||||
@@ -637,7 +612,6 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
self.relation_get.side_effect = mock_rel_get
|
self.relation_get.side_effect = mock_rel_get
|
||||||
mock_is_ssl_enabled.return_value = True
|
|
||||||
self.relation_ids.return_value = ['cluster:0']
|
self.relation_ids.return_value = ['cluster:0']
|
||||||
self.local_unit.return_value = 'unit/0'
|
self.local_unit.return_value = 'unit/0'
|
||||||
mock_peer_units.return_value = ['unit/1']
|
mock_peer_units.return_value = ['unit/1']
|
||||||
@@ -730,6 +704,28 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
self.assertEquals(render.call_args_list, expected)
|
self.assertEquals(render.call_args_list, expected)
|
||||||
service_restart.assert_called_with('keystone')
|
service_restart.assert_called_with('keystone')
|
||||||
|
|
||||||
|
@patch.object(manager, 'KeystoneManager')
|
||||||
|
def test_is_service_present(self, KeystoneManager):
|
||||||
|
mock_keystone = MagicMock()
|
||||||
|
mock_keystone.resolve_service_id.return_value = 'sid1'
|
||||||
|
KeystoneManager.return_value = mock_keystone
|
||||||
|
self.assertTrue(utils.is_service_present('bob', 'bill'))
|
||||||
|
|
||||||
|
@patch.object(manager, 'KeystoneManager')
|
||||||
|
def test_is_service_present_false(self, KeystoneManager):
|
||||||
|
mock_keystone = MagicMock()
|
||||||
|
mock_keystone.resolve_service_id.return_value = None
|
||||||
|
KeystoneManager.return_value = mock_keystone
|
||||||
|
self.assertFalse(utils.is_service_present('bob', 'bill'))
|
||||||
|
|
||||||
|
@patch.object(manager, 'KeystoneManager')
|
||||||
|
def test_delete_service_entry(self, KeystoneManager):
|
||||||
|
mock_keystone = MagicMock()
|
||||||
|
mock_keystone.resolve_service_id.return_value = 'sid1'
|
||||||
|
KeystoneManager.return_value = mock_keystone
|
||||||
|
utils.delete_service_entry('bob', 'bill')
|
||||||
|
mock_keystone.api.services.delete.assert_called_with('sid1')
|
||||||
|
|
||||||
@patch.object(utils, 'HookData')
|
@patch.object(utils, 'HookData')
|
||||||
@patch.object(utils, 'kv')
|
@patch.object(utils, 'kv')
|
||||||
def test_is_paused(self, kv, HookData):
|
def test_is_paused(self, kv, HookData):
|
||||||
|
Reference in New Issue
Block a user