Rebase on trunk
This commit is contained in:
commit
044a71b596
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>openstack-dashboard</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/openstack-dashboard/hooks</path>
|
||||
<path>/openstack-dashboard/unit_tests</path>
|
||||
</pydev_pathproperty>
|
||||
</pydev_project>
|
|
@ -6,4 +6,5 @@ include:
|
|||
- contrib.openstack
|
||||
- contrib.storage.linux
|
||||
- contrib.hahelpers
|
||||
- contrib.storage
|
||||
- payload.execd
|
||||
|
|
|
@ -26,6 +26,12 @@ options:
|
|||
description: |
|
||||
Default role for Horizon operations that will be created in
|
||||
Keystone upon introduction of an identity-service relation.
|
||||
use-syslog:
|
||||
type: boolean
|
||||
default: False
|
||||
description: |
|
||||
By default, all services will log into their corresponding log files.
|
||||
Setting this to True will force all services to log to the syslog.
|
||||
vip:
|
||||
type: string
|
||||
description: "Virtual IP to use to front openstack dashboard ha configuration"
|
||||
|
@ -80,4 +86,4 @@ options:
|
|||
description: Use Ubuntu theme for the dashboard.
|
||||
secret:
|
||||
type: string
|
||||
descriptions: Secret for Horizon to use when securing internal data; set this when using multiple dashboard units.
|
||||
description: Secret for Horizon to use when securing internal data; set this when using multiple dashboard units.
|
||||
|
|
|
@ -126,17 +126,17 @@ def determine_api_port(public_port):
|
|||
return public_port - (i * 10)
|
||||
|
||||
|
||||
def determine_haproxy_port(public_port):
|
||||
def determine_apache_port(public_port):
|
||||
'''
|
||||
Description: Determine correct proxy listening port based on public IP +
|
||||
existence of HTTPS reverse proxy.
|
||||
Description: Determine correct apache listening port based on public IP +
|
||||
state of the cluster.
|
||||
|
||||
public_port: int: standard public port for given service
|
||||
|
||||
returns: int: the correct listening port for the HAProxy service
|
||||
'''
|
||||
i = 0
|
||||
if https():
|
||||
if len(peer_units()) > 0 or is_clustered():
|
||||
i += 1
|
||||
return public_port - (i * 10)
|
||||
|
||||
|
|
|
@ -23,15 +23,12 @@ from charmhelpers.core.hookenv import (
|
|||
unit_get,
|
||||
unit_private_ip,
|
||||
ERROR,
|
||||
WARNING,
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.hahelpers.cluster import (
|
||||
determine_apache_port,
|
||||
determine_api_port,
|
||||
determine_haproxy_port,
|
||||
https,
|
||||
is_clustered,
|
||||
peer_units,
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.hahelpers.apache import (
|
||||
|
@ -68,6 +65,43 @@ def context_complete(ctxt):
|
|||
return True
|
||||
|
||||
|
||||
def config_flags_parser(config_flags):
|
||||
if config_flags.find('==') >= 0:
|
||||
log("config_flags is not in expected format (key=value)",
|
||||
level=ERROR)
|
||||
raise OSContextError
|
||||
# strip the following from each value.
|
||||
post_strippers = ' ,'
|
||||
# we strip any leading/trailing '=' or ' ' from the string then
|
||||
# split on '='.
|
||||
split = config_flags.strip(' =').split('=')
|
||||
limit = len(split)
|
||||
flags = {}
|
||||
for i in xrange(0, limit - 1):
|
||||
current = split[i]
|
||||
next = split[i + 1]
|
||||
vindex = next.rfind(',')
|
||||
if (i == limit - 2) or (vindex < 0):
|
||||
value = next
|
||||
else:
|
||||
value = next[:vindex]
|
||||
|
||||
if i == 0:
|
||||
key = current
|
||||
else:
|
||||
# if this not the first entry, expect an embedded key.
|
||||
index = current.rfind(',')
|
||||
if index < 0:
|
||||
log("invalid config value(s) at index %s" % (i),
|
||||
level=ERROR)
|
||||
raise OSContextError
|
||||
key = current[index + 1:]
|
||||
|
||||
# Add to collection.
|
||||
flags[key.strip(post_strippers)] = value.rstrip(post_strippers)
|
||||
return flags
|
||||
|
||||
|
||||
class OSContextGenerator(object):
|
||||
interfaces = []
|
||||
|
||||
|
@ -182,10 +216,17 @@ class AMQPContext(OSContextGenerator):
|
|||
# Sufficient information found = break out!
|
||||
break
|
||||
# Used for active/active rabbitmq >= grizzly
|
||||
ctxt['rabbitmq_hosts'] = []
|
||||
if ('clustered' not in ctxt or relation_get('ha-vip-only') == 'True') and \
|
||||
len(related_units(rid)) > 1:
|
||||
if relation_get('ha_queues'):
|
||||
ctxt['rabbitmq_ha_queues'] = relation_get('ha_queues')
|
||||
else:
|
||||
ctxt['rabbitmq_ha_queues'] = False
|
||||
rabbitmq_hosts = []
|
||||
for unit in related_units(rid):
|
||||
ctxt['rabbitmq_hosts'].append(relation_get('private-address',
|
||||
rabbitmq_hosts.append(relation_get('private-address',
|
||||
rid=rid, unit=unit))
|
||||
ctxt['rabbitmq_hosts'] = ','.join(rabbitmq_hosts)
|
||||
if not context_complete(ctxt):
|
||||
return {}
|
||||
else:
|
||||
|
@ -209,11 +250,13 @@ class CephContext(OSContextGenerator):
|
|||
unit=unit))
|
||||
auth = relation_get('auth', rid=rid, unit=unit)
|
||||
key = relation_get('key', rid=rid, unit=unit)
|
||||
use_syslog = str(config('use-syslog')).lower()
|
||||
|
||||
ctxt = {
|
||||
'mon_hosts': ' '.join(mon_hosts),
|
||||
'auth': auth,
|
||||
'key': key,
|
||||
'use_syslog': use_syslog
|
||||
}
|
||||
|
||||
if not os.path.isdir('/etc/ceph'):
|
||||
|
@ -286,6 +329,7 @@ class ImageServiceContext(OSContextGenerator):
|
|||
|
||||
|
||||
class ApacheSSLContext(OSContextGenerator):
|
||||
|
||||
"""
|
||||
Generates a context for an apache vhost configuration that configures
|
||||
HTTPS reverse proxying for one or many endpoints. Generated context
|
||||
|
@ -341,11 +385,9 @@ class ApacheSSLContext(OSContextGenerator):
|
|||
'private_address': unit_get('private-address'),
|
||||
'endpoints': []
|
||||
}
|
||||
for ext_port in self.external_ports:
|
||||
if peer_units() or is_clustered():
|
||||
int_port = determine_haproxy_port(ext_port)
|
||||
else:
|
||||
int_port = determine_api_port(ext_port)
|
||||
for api_port in self.external_ports:
|
||||
ext_port = determine_apache_port(api_port)
|
||||
int_port = determine_api_port(api_port)
|
||||
portmap = (int(ext_port), int(int_port))
|
||||
ctxt['endpoints'].append(portmap)
|
||||
return ctxt
|
||||
|
@ -428,33 +470,37 @@ class NeutronContext(object):
|
|||
elif self.plugin == 'nvp':
|
||||
ctxt.update(self.nvp_ctxt())
|
||||
|
||||
alchemy_flags = config('neutron-alchemy-flags')
|
||||
if alchemy_flags:
|
||||
flags = config_flags_parser(alchemy_flags)
|
||||
ctxt['neutron_alchemy_flags'] = flags
|
||||
|
||||
self._save_flag_file()
|
||||
return ctxt
|
||||
|
||||
|
||||
class OSConfigFlagContext(OSContextGenerator):
|
||||
'''
|
||||
Responsible adding user-defined config-flags in charm config to a
|
||||
to a template context.
|
||||
'''
|
||||
|
||||
"""
|
||||
Responsible for adding user-defined config-flags in charm config to a
|
||||
template context.
|
||||
|
||||
NOTE: the value of config-flags may be a comma-separated list of
|
||||
key=value pairs and some Openstack config files support
|
||||
comma-separated lists as values.
|
||||
"""
|
||||
|
||||
def __call__(self):
|
||||
config_flags = config('config-flags')
|
||||
if not config_flags or config_flags in ['None', '']:
|
||||
if not config_flags:
|
||||
return {}
|
||||
config_flags = config_flags.split(',')
|
||||
flags = {}
|
||||
for flag in config_flags:
|
||||
if '=' not in flag:
|
||||
log('Improperly formatted config-flag, expected k=v '
|
||||
'got %s' % flag, level=WARNING)
|
||||
continue
|
||||
k, v = flag.split('=')
|
||||
flags[k.strip()] = v
|
||||
ctxt = {'user_config_flags': flags}
|
||||
return ctxt
|
||||
|
||||
flags = config_flags_parser(config_flags)
|
||||
return {'user_config_flags': flags}
|
||||
|
||||
|
||||
class SubordinateConfigContext(OSContextGenerator):
|
||||
|
||||
"""
|
||||
Responsible for inspecting relations to subordinates that
|
||||
may be exporting required config via a json blob.
|
||||
|
@ -495,6 +541,7 @@ class SubordinateConfigContext(OSContextGenerator):
|
|||
}
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, service, config_file, interface):
|
||||
"""
|
||||
:param service : Service name key to query in any subordinate
|
||||
|
@ -539,3 +586,12 @@ class SubordinateConfigContext(OSContextGenerator):
|
|||
ctxt['sections'] = {}
|
||||
|
||||
return ctxt
|
||||
|
||||
|
||||
class SyslogContext(OSContextGenerator):
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {
|
||||
'use_syslog': config('use-syslog')
|
||||
}
|
||||
return ctxt
|
||||
|
|
|
@ -202,7 +202,7 @@ def os_release(package, base='essex'):
|
|||
|
||||
|
||||
def import_key(keyid):
|
||||
cmd = "apt-key adv --keyserver keyserver.ubuntu.com " \
|
||||
cmd = "apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 " \
|
||||
"--recv-keys %s" % keyid
|
||||
try:
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
|
@ -415,7 +415,7 @@ def get_host_ip(hostname):
|
|||
return ns_query(hostname)
|
||||
|
||||
|
||||
def get_hostname(address):
|
||||
def get_hostname(address, fqdn=True):
|
||||
"""
|
||||
Resolves hostname for given IP, or returns the input
|
||||
if it is already a hostname.
|
||||
|
@ -434,7 +434,11 @@ def get_hostname(address):
|
|||
if not result:
|
||||
return None
|
||||
|
||||
if fqdn:
|
||||
# strip trailing .
|
||||
if result.endswith('.'):
|
||||
return result[:-1]
|
||||
else:
|
||||
return result
|
||||
else:
|
||||
return result.split('.')[0]
|
||||
|
|
|
@ -49,6 +49,9 @@ CEPH_CONF = """[global]
|
|||
auth supported = {auth}
|
||||
keyring = {keyring}
|
||||
mon host = {mon_hosts}
|
||||
log to syslog = {use_syslog}
|
||||
err to syslog = {use_syslog}
|
||||
clog to syslog = {use_syslog}
|
||||
"""
|
||||
|
||||
|
||||
|
@ -194,7 +197,7 @@ def get_ceph_nodes():
|
|||
return hosts
|
||||
|
||||
|
||||
def configure(service, key, auth):
|
||||
def configure(service, key, auth, use_syslog):
|
||||
''' Perform basic configuration of Ceph '''
|
||||
create_keyring(service, key)
|
||||
create_key_file(service, key)
|
||||
|
@ -202,7 +205,8 @@ def configure(service, key, auth):
|
|||
with open('/etc/ceph/ceph.conf', 'w') as ceph_conf:
|
||||
ceph_conf.write(CEPH_CONF.format(auth=auth,
|
||||
keyring=_keyring_path(service),
|
||||
mon_hosts=",".join(map(str, hosts))))
|
||||
mon_hosts=",".join(map(str, hosts)),
|
||||
use_syslog=use_syslog))
|
||||
modprobe('rbd')
|
||||
|
||||
|
||||
|
|
|
@ -22,4 +22,4 @@ def zap_disk(block_device):
|
|||
|
||||
:param block_device: str: Full path of block device to clean.
|
||||
'''
|
||||
check_call(['sgdisk', '--zap-all', block_device])
|
||||
check_call(['sgdisk', '--zap-all', '--mbrtogpt', block_device])
|
||||
|
|
|
@ -8,6 +8,7 @@ import os
|
|||
import json
|
||||
import yaml
|
||||
import subprocess
|
||||
import sys
|
||||
import UserDict
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
|
@ -149,6 +150,11 @@ def service_name():
|
|||
return local_unit().split('/')[0]
|
||||
|
||||
|
||||
def hook_name():
|
||||
"""The name of the currently executing hook"""
|
||||
return os.path.basename(sys.argv[0])
|
||||
|
||||
|
||||
@cached
|
||||
def config(scope=None):
|
||||
"""Juju charm configuration"""
|
||||
|
|
|
@ -194,7 +194,7 @@ def file_hash(path):
|
|||
return None
|
||||
|
||||
|
||||
def restart_on_change(restart_map):
|
||||
def restart_on_change(restart_map, stopstart=False):
|
||||
"""Restart services based on configuration files changing
|
||||
|
||||
This function is used a decorator, for example
|
||||
|
@ -219,8 +219,14 @@ def restart_on_change(restart_map):
|
|||
for path in restart_map:
|
||||
if checksums[path] != file_hash(path):
|
||||
restarts += restart_map[path]
|
||||
for service_name in list(OrderedDict.fromkeys(restarts)):
|
||||
services_list = list(OrderedDict.fromkeys(restarts))
|
||||
if not stopstart:
|
||||
for service_name in services_list:
|
||||
service('restart', service_name)
|
||||
else:
|
||||
for action in ['stop', 'start']:
|
||||
for service_name in services_list:
|
||||
service(action, service_name)
|
||||
return wrapped_f
|
||||
return wrap
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ def apt_hold(packages, fatal=False):
|
|||
|
||||
def add_source(source, key=None):
|
||||
if (source.startswith('ppa:') or
|
||||
source.startswith('http:') or
|
||||
source.startswith('http') or
|
||||
source.startswith('deb ') or
|
||||
source.startswith('cloud-archive:')):
|
||||
subprocess.check_call(['add-apt-repository', '--yes', source])
|
||||
|
@ -156,7 +156,9 @@ def add_source(source, key=None):
|
|||
with open('/etc/apt/sources.list.d/proposed.list', 'w') as apt:
|
||||
apt.write(PROPOSED_POCKET.format(release))
|
||||
if key:
|
||||
subprocess.check_call(['apt-key', 'import', key])
|
||||
subprocess.check_call(['apt-key', 'adv', '--keyserver',
|
||||
'keyserver.ubuntu.com', '--recv',
|
||||
key])
|
||||
|
||||
|
||||
class SourceConfigError(Exception):
|
||||
|
|
|
@ -34,6 +34,7 @@ from horizon_utils import (
|
|||
from charmhelpers.contrib.hahelpers.apache import install_ca_cert
|
||||
from charmhelpers.contrib.hahelpers.cluster import get_hacluster_config
|
||||
from charmhelpers.payload.execd import execd_preinstall
|
||||
from base64 import b64decode
|
||||
|
||||
hooks = Hooks()
|
||||
CONFIGS = register_configs()
|
||||
|
@ -95,7 +96,7 @@ def keystone_joined(rel_id=None):
|
|||
def keystone_changed():
|
||||
CONFIGS.write(LOCAL_SETTINGS)
|
||||
if relation_get('ca_cert'):
|
||||
install_ca_cert(relation_get('ca_cert'))
|
||||
install_ca_cert(b64decode(relation_get('ca_cert')))
|
||||
|
||||
|
||||
@hooks.hook('cluster-relation-departed',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# vim: set ts=4:et
|
||||
import horizon_contexts
|
||||
import charmhelpers.contrib.openstack.templating as templating
|
||||
import charmhelpers.contrib.openstack.context as context
|
||||
import subprocess
|
||||
import os
|
||||
from collections import OrderedDict
|
||||
|
@ -38,15 +39,18 @@ TEMPLATES = 'templates'
|
|||
CONFIG_FILES = OrderedDict([
|
||||
(LOCAL_SETTINGS, {
|
||||
'hook_contexts': [horizon_contexts.HorizonContext(),
|
||||
horizon_contexts.IdentityServiceContext()],
|
||||
horizon_contexts.IdentityServiceContext(),
|
||||
context.SyslogContext()],
|
||||
'services': ['apache2']
|
||||
}),
|
||||
(APACHE_CONF, {
|
||||
'hook_contexts': [horizon_contexts.HorizonContext()],
|
||||
'hook_contexts': [horizon_contexts.HorizonContext(),
|
||||
context.SyslogContext()],
|
||||
'services': ['apache2'],
|
||||
}),
|
||||
(APACHE_24_CONF, {
|
||||
'hook_contexts': [horizon_contexts.HorizonContext()],
|
||||
'hook_contexts': [horizon_contexts.HorizonContext(),
|
||||
context.SyslogContext()],
|
||||
'services': ['apache2'],
|
||||
}),
|
||||
(APACHE_SSL, {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from openstack_dashboard import exceptions
|
||||
{% if use_syslog %}
|
||||
from logging.handlers import SysLogHandler
|
||||
{% endif %}
|
||||
|
||||
DEBUG = {{ debug }}
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
@ -176,6 +178,12 @@ LOGGING = {
|
|||
'level': 'DEBUG',
|
||||
'class': 'django.utils.log.NullHandler',
|
||||
},
|
||||
{% if use_syslog %}
|
||||
'syslog': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
},
|
||||
{% endif %}
|
||||
'console': {
|
||||
# Set the level to "DEBUG" for verbose output logging.
|
||||
'level': 'INFO',
|
||||
|
@ -194,27 +202,59 @@ LOGGING = {
|
|||
'propagate': False,
|
||||
},
|
||||
'horizon': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_dashboard': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_auth': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'novaclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'keystoneclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'glanceclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'nose.plugins.manager': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
{% if use_syslog %}
|
||||
from logging.handlers import SysLogHandler
|
||||
{% endif %}
|
||||
|
||||
from openstack_dashboard import exceptions
|
||||
|
||||
|
@ -248,6 +251,12 @@ LOGGING = {
|
|||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
},
|
||||
{% if use_syslog %}
|
||||
'syslog': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.handlers.SysLogHandler',
|
||||
}
|
||||
{% endif %}
|
||||
},
|
||||
'loggers': {
|
||||
# Logging from django.db.backends is VERY verbose, send to null
|
||||
|
@ -261,35 +270,75 @@ LOGGING = {
|
|||
'propagate': False,
|
||||
},
|
||||
'horizon': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_dashboard': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'openstack_auth': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'novaclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'cinderclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'keystoneclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'glanceclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'heatclient': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
},
|
||||
'nose.plugins.manager': {
|
||||
{% if use_syslog %}
|
||||
'handlers': ['syslog'],
|
||||
{% else %}
|
||||
'handlers': ['console'],
|
||||
{% endif %}
|
||||
'propagate': False,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ def patch_open():
|
|||
|
||||
|
||||
class TestHorizonContexts(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestHorizonContexts, self).setUp(horizon_contexts, TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
|
@ -67,7 +68,7 @@ class TestHorizonContexts(CharmTestCase):
|
|||
call('key')
|
||||
])
|
||||
# Security check on key permissions
|
||||
_chmod.assert_called_with('/etc/ssl/private/dashboard.key', 0600)
|
||||
_chmod.assert_called_with('/etc/ssl/private/dashboard.key', 0o600)
|
||||
|
||||
def test_ApacheSSLContext_disabled(self):
|
||||
self.get_cert.return_value = (None, None)
|
||||
|
@ -78,42 +79,48 @@ class TestHorizonContexts(CharmTestCase):
|
|||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': True, 'debug': False,
|
||||
'default_role': 'Member', 'webroot': '/horizon',
|
||||
'ubuntu_theme': True, 'secret': 'secret'})
|
||||
'ubuntu_theme': True,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_HorizonContext_debug(self):
|
||||
self.test_config.set('debug', 'yes')
|
||||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': True, 'debug': True,
|
||||
'default_role': 'Member', 'webroot': '/horizon',
|
||||
'ubuntu_theme': True, 'secret': 'secret'})
|
||||
'ubuntu_theme': True,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_HorizonContext_theme(self):
|
||||
self.test_config.set('ubuntu-theme', False)
|
||||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': True, 'debug': False,
|
||||
'default_role': 'Member', 'webroot': '/horizon',
|
||||
'ubuntu_theme': False, 'secret': 'secret'})
|
||||
'ubuntu_theme': False,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_HorizonContext_compression(self):
|
||||
self.test_config.set('offline-compression', 'no')
|
||||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': False, 'debug': False,
|
||||
'default_role': 'Member', 'webroot': '/horizon',
|
||||
'ubuntu_theme': True, 'secret': 'secret'})
|
||||
'ubuntu_theme': True,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_HorizonContext_role(self):
|
||||
self.test_config.set('default-role', 'foo')
|
||||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': True, 'debug': False,
|
||||
'default_role': 'foo', 'webroot': '/horizon',
|
||||
'ubuntu_theme': True, 'secret': 'secret'})
|
||||
'ubuntu_theme': True,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_HorizonContext_webroot(self):
|
||||
self.test_config.set('webroot', '/')
|
||||
self.assertEquals(horizon_contexts.HorizonContext()(),
|
||||
{'compress_offline': True, 'debug': False,
|
||||
'default_role': 'Member', 'webroot': '/',
|
||||
'ubuntu_theme': True, 'secret': 'secret'})
|
||||
'ubuntu_theme': True,
|
||||
'secret': 'secret'})
|
||||
|
||||
def test_IdentityServiceContext_not_related(self):
|
||||
self.relation_ids.return_value = []
|
||||
|
|
|
@ -27,7 +27,12 @@ TO_PATCH = [
|
|||
'install_ca_cert',
|
||||
'unit_get',
|
||||
'log',
|
||||
'execd_preinstall']
|
||||
'execd_preinstall',
|
||||
'b64decode']
|
||||
|
||||
|
||||
def passthrough(value):
|
||||
return value
|
||||
|
||||
|
||||
class TestHorizonHooks(CharmTestCase):
|
||||
|
@ -35,6 +40,7 @@ class TestHorizonHooks(CharmTestCase):
|
|||
def setUp(self):
|
||||
super(TestHorizonHooks, self).setUp(hooks, TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
self.b64decode.side_effect = passthrough
|
||||
|
||||
def _call_hook(self, hookname):
|
||||
hooks.hooks.execute([
|
||||
|
|
|
@ -20,6 +20,7 @@ TO_PATCH = [
|
|||
|
||||
|
||||
class TestHorizonUtils(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestHorizonUtils, self).setUp(horizon_utils, TO_PATCH)
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ def get_default_config():
|
|||
|
||||
|
||||
class CharmTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self, obj, patches):
|
||||
super(CharmTestCase, self).setUp()
|
||||
self.patches = patches
|
||||
|
@ -64,6 +65,7 @@ class CharmTestCase(unittest.TestCase):
|
|||
|
||||
|
||||
class TestConfig(object):
|
||||
|
||||
def __init__(self):
|
||||
self.config = get_default_config()
|
||||
|
||||
|
@ -83,6 +85,7 @@ class TestConfig(object):
|
|||
|
||||
|
||||
class TestRelation(object):
|
||||
|
||||
def __init__(self, relation_data={}):
|
||||
self.relation_data = relation_data
|
||||
|
||||
|
|
Loading…
Reference in New Issue