← Back to team overview

nagios-charmers team mailing list archive

[Merge] ~xavpaice/charm-nagios:blacken-20.08 into charm-nagios:master

 

Xav Paice has proposed merging ~xavpaice/charm-nagios:blacken-20.08 into charm-nagios:master with ~xavpaice/charm-nagios:makefile-20.08 as a prerequisite.

Commit message:
Blackened repository, fix tests

Requested reviews:
  Nagios Charm developers (nagios-charmers)

For more details, see:
https://code.launchpad.net/~xavpaice/charm-nagios/+git/nagios-charm/+merge/388626
-- 
Your team Nagios Charm developers is requested to review the proposed merge of ~xavpaice/charm-nagios:blacken-20.08 into charm-nagios:master.
diff --git a/hooks/common.py b/hooks/common.py
index ec34670..3bff942 100644
--- a/hooks/common.py
+++ b/hooks/common.py
@@ -16,19 +16,19 @@ from charmhelpers.core.hookenv import (
 
 from pynag import Model
 
-INPROGRESS_DIR = '/etc/nagios3-inprogress'
-INPROGRESS_CFG = '/etc/nagios3-inprogress/nagios.cfg'
-INPROGRESS_CONF_D = '/etc/nagios3-inprogress/conf.d'
-CHARM_CFG = '/etc/nagios3-inprogress/conf.d/charm.cfg'
-MAIN_NAGIOS_BAK = '/etc/nagios3.bak'
-MAIN_NAGIOS_DIR = '/etc/nagios3'
-MAIN_NAGIOS_CFG = '/etc/nagios3/nagios.cfg'
-PLUGIN_PATH = '/usr/lib/nagios/plugins'
+INPROGRESS_DIR = "/etc/nagios3-inprogress"
+INPROGRESS_CFG = "/etc/nagios3-inprogress/nagios.cfg"
+INPROGRESS_CONF_D = "/etc/nagios3-inprogress/conf.d"
+CHARM_CFG = "/etc/nagios3-inprogress/conf.d/charm.cfg"
+MAIN_NAGIOS_BAK = "/etc/nagios3.bak"
+MAIN_NAGIOS_DIR = "/etc/nagios3"
+MAIN_NAGIOS_CFG = "/etc/nagios3/nagios.cfg"
+PLUGIN_PATH = "/usr/lib/nagios/plugins"
 
 Model.cfg_file = INPROGRESS_CFG
 Model.pynag_directory = INPROGRESS_CONF_D
 
-reduce_RE = re.compile(r'[\W_]')
+reduce_RE = re.compile(r"[\W_]")
 
 
 def check_ip(n):
@@ -43,14 +43,14 @@ def check_ip(n):
             return False
 
 
-def get_local_ingress_address(binding='website'):
+def get_local_ingress_address(binding="website"):
     # using network-get to retrieve the address details if available.
-    log('Getting hostname for binding %s' % binding)
+    log("Getting hostname for binding %s" % binding)
     try:
         network_info = network_get(binding)
-        if network_info is not None and 'ingress-addresses' in network_info:
-            log('Using ingress-addresses')
-            hostname = network_info['ingress-addresses'][0]
+        if network_info is not None and "ingress-addresses" in network_info:
+            log("Using ingress-addresses")
+            hostname = network_info["ingress-addresses"][0]
             log(hostname)
             return hostname
     except NotImplementedError:
@@ -60,11 +60,11 @@ def get_local_ingress_address(binding='website'):
     # Pre 2.3 output
     try:
         hostname = network_get_primary_address(binding)
-        log('Using primary-addresses')
+        log("Using primary-addresses")
     except NotImplementedError:
         # pre Juju 2.0
-        hostname = unit_get('private-address')
-        log('Using unit_get private address')
+        hostname = unit_get("private-address")
+        log("Using unit_get private address")
     log(hostname)
     return hostname
 
@@ -72,14 +72,14 @@ def get_local_ingress_address(binding='website'):
 def get_remote_relation_attr(remote_unit, attr_name, relation_id=None):
     args = ["relation-get", attr_name, remote_unit]
     if relation_id is not None:
-        args.extend(['-r', relation_id])
+        args.extend(["-r", relation_id])
     return subprocess.check_output(args).strip()
 
 
 def get_ip_and_hostname(remote_unit, relation_id=None):
-    hostname = get_remote_relation_attr(remote_unit, 'ingress-address', relation_id)
+    hostname = get_remote_relation_attr(remote_unit, "ingress-address", relation_id)
     if hostname is None or not len(hostname):
-        hostname = get_remote_relation_attr(remote_unit, 'private-address', relation_id)
+        hostname = get_remote_relation_attr(remote_unit, "private-address", relation_id)
 
     if hostname is None or not len(hostname):
         log("relation-get failed")
@@ -89,18 +89,18 @@ def get_ip_and_hostname(remote_unit, relation_id=None):
         ip_address = hostname
     else:
         ip_address = socket.getaddrinfo(hostname, None)[0][4][0]
-    return (ip_address, remote_unit.replace('/', '-'))
+    return (ip_address, remote_unit.replace("/", "-"))
 
 
 def refresh_hostgroups():  # noqa:C901
     """ Not the most efficient thing but since we're only
         parsing what is already on disk here its not too bad """
-    hosts = [x['host_name'] for x in Model.Host.objects.all if x['host_name']]
+    hosts = [x["host_name"] for x in Model.Host.objects.all if x["host_name"]]
 
     hgroups = {}
     for host in hosts:
         try:
-            (service, unit_id) = host.rsplit('-', 1)
+            (service, unit_id) = host.rsplit("-", 1)
         except ValueError:
             continue
         if service in hgroups:
@@ -109,8 +109,8 @@ def refresh_hostgroups():  # noqa:C901
             hgroups[service] = [host]
 
     # Find existing autogenerated
-    auto_hgroups = Model.Hostgroup.objects.filter(notes__contains='#autogenerated#')
-    auto_hgroups = [x.get_attribute('hostgroup_name') for x in auto_hgroups]
+    auto_hgroups = Model.Hostgroup.objects.filter(notes__contains="#autogenerated#")
+    auto_hgroups = [x.get_attribute("hostgroup_name") for x in auto_hgroups]
 
     # Delete the ones not in hgroups
     to_delete = set(auto_hgroups).difference(set(hgroups.keys()))
@@ -127,10 +127,10 @@ def refresh_hostgroups():  # noqa:C901
         except (ValueError, KeyError):
             hgroup = Model.Hostgroup()
             hgroup.set_filename(CHARM_CFG)
-            hgroup.set_attribute('hostgroup_name', hgroup_name)
-            hgroup.set_attribute('notes', '#autogenerated#')
+            hgroup.set_attribute("hostgroup_name", hgroup_name)
+            hgroup.set_attribute("notes", "#autogenerated#")
 
-        hgroup.set_attribute('members', ','.join(members))
+        hgroup.set_attribute("members", ",".join(members))
         hgroup.save()
 
 
@@ -138,15 +138,14 @@ def _make_check_command(args):
     args = [str(arg) for arg in args]
     # There is some worry of collision, but the uniqueness of the initial
     # command should be enough.
-    signature = reduce_RE.sub('_', ''.join(
-                [os.path.basename(arg) for arg in args]))
+    signature = reduce_RE.sub("_", "".join([os.path.basename(arg) for arg in args]))
     Model.Command.objects.reload_cache()
     try:
         cmd = Model.Command.objects.get_by_shortname(signature)
     except (ValueError, KeyError):
         cmd = Model.Command()
-        cmd.set_attribute('command_name', signature)
-        cmd.set_attribute('command_line', ' '.join(args))
+        cmd.set_attribute("command_name", signature)
+        cmd.set_attribute("command_line", " ".join(args))
         cmd.save()
     return signature
 
@@ -159,130 +158,131 @@ def _extend_args(args, cmd_args, switch, value):
 def customize_http(service, name, extra):
     args = []
     cmd_args = []
-    plugin = os.path.join(PLUGIN_PATH, 'check_http')
-    port = extra.get('port', 80)
-    path = extra.get('path', '/')
+    plugin = os.path.join(PLUGIN_PATH, "check_http")
+    port = extra.get("port", 80)
+    path = extra.get("path", "/")
     args = [port, path]
-    cmd_args = [plugin, '-p', '"$ARG1$"', '-u', '"$ARG2$"']
-    if 'status' in extra:
-        _extend_args(args, cmd_args, '-e', extra['status'])
-    if 'host' in extra:
-        _extend_args(args, cmd_args, '-H', extra['host'])
-        cmd_args.extend(('-I', '$HOSTADDRESS$'))
+    cmd_args = [plugin, "-p", '"$ARG1$"', "-u", '"$ARG2$"']
+    if "status" in extra:
+        _extend_args(args, cmd_args, "-e", extra["status"])
+    if "host" in extra:
+        _extend_args(args, cmd_args, "-H", extra["host"])
+        cmd_args.extend(("-I", "$HOSTADDRESS$"))
     else:
-        cmd_args.extend(('-H', '$HOSTADDRESS$'))
-    check_timeout = config('check_timeout')
+        cmd_args.extend(("-H", "$HOSTADDRESS$"))
+    check_timeout = config("check_timeout")
     if check_timeout is not None:
-        cmd_args.extend(('-t', check_timeout))
+        cmd_args.extend(("-t", check_timeout))
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_mysql(service, name, extra):
-    plugin = os.path.join(PLUGIN_PATH, 'check_mysql')
+    plugin = os.path.join(PLUGIN_PATH, "check_mysql")
     args = []
-    cmd_args = [plugin, '-H', '$HOSTADDRESS$']
-    if 'user' in extra:
-        _extend_args(args, cmd_args, '-u', extra['user'])
-    if 'password' in extra:
-        _extend_args(args, cmd_args, '-p', extra['password'])
-    check_timeout = config('check_timeout')
+    cmd_args = [plugin, "-H", "$HOSTADDRESS$"]
+    if "user" in extra:
+        _extend_args(args, cmd_args, "-u", extra["user"])
+    if "password" in extra:
+        _extend_args(args, cmd_args, "-p", extra["password"])
+    check_timeout = config("check_timeout")
     if check_timeout is not None:
-        cmd_args.extend(('-t', check_timeout))
+        cmd_args.extend(("-t", check_timeout))
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_pgsql(service, name, extra):
-    plugin = os.path.join(PLUGIN_PATH, 'check_pgsql')
+    plugin = os.path.join(PLUGIN_PATH, "check_pgsql")
     args = []
-    cmd_args = [plugin, '-H', '$HOSTADDRESS$']
-    check_timeout = config('check_timeout')
+    cmd_args = [plugin, "-H", "$HOSTADDRESS$"]
+    check_timeout = config("check_timeout")
     if check_timeout is not None:
-        cmd_args.extend(('-t', check_timeout))
+        cmd_args.extend(("-t", check_timeout))
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_nrpe(service, name, extra):
-    plugin = os.path.join(PLUGIN_PATH, 'check_nrpe')
+    plugin = os.path.join(PLUGIN_PATH, "check_nrpe")
     args = []
-    cmd_args = [plugin, '-H', '$HOSTADDRESS$']
-    if name in ('mem', 'swap'):
-        cmd_args.extend(('-c', 'check_%s' % name))
-    elif 'command' in extra:
-        cmd_args.extend(('-c', extra['command']))
+    cmd_args = [plugin, "-H", "$HOSTADDRESS$"]
+    if name in ("mem", "swap"):
+        cmd_args.extend(("-c", "check_%s" % name))
+    elif "command" in extra:
+        cmd_args.extend(("-c", extra["command"]))
     else:
-        cmd_args.extend(('-c', extra))
-    check_timeout = config('check_timeout')
+        cmd_args.extend(("-c", extra))
+    check_timeout = config("check_timeout")
     if check_timeout is not None:
-        cmd_args.extend(('-t', check_timeout))
+        cmd_args.extend(("-t", check_timeout))
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_rpc(service, name, extra):
     """ Customize the check_rpc plugin to check things like nfs."""
-    plugin = os.path.join(PLUGIN_PATH, 'check_rpc')
+    plugin = os.path.join(PLUGIN_PATH, "check_rpc")
     args = []
     # /usr/lib/nagios/plugins/check_rpc -H <host> -C <rpc_command>
-    cmd_args = [plugin, '-H', '$HOSTADDRESS$']
-    if 'rpc_command' in extra:
-        cmd_args.extend(('-C', extra['rpc_command']))
-    if 'program_version' in extra:
-        cmd_args.extend(('-c', extra['program_version']))
+    cmd_args = [plugin, "-H", "$HOSTADDRESS$"]
+    if "rpc_command" in extra:
+        cmd_args.extend(("-C", extra["rpc_command"]))
+    if "program_version" in extra:
+        cmd_args.extend(("-c", extra["program_version"]))
 
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_tcp(service, name, extra):
     """ Customize tcp can be used to check things like memcached. """
-    plugin = os.path.join(PLUGIN_PATH, 'check_tcp')
+    plugin = os.path.join(PLUGIN_PATH, "check_tcp")
     args = []
     # /usr/lib/nagios/plugins/check_tcp -H <host> -E
-    cmd_args = [plugin, '-H', '$HOSTADDRESS$', '-E']
-    if 'port' in extra:
-        cmd_args.extend(('-p', extra['port']))
-    if 'string' in extra:
-        cmd_args.extend(('-s', "'{}'".format(extra['string'])))
-    if 'expect' in extra:
-        cmd_args.extend(('-e', extra['expect']))
-    if 'warning' in extra:
-        cmd_args.extend(('-w', extra['warning']))
-    if 'critical' in extra:
-        cmd_args.extend(('-c', extra['critical']))
-    if 'timeout' in extra:
-        cmd_args.extend(('-t', extra['timeout']))
-    check_timeout = config('check_timeout')
+    cmd_args = [plugin, "-H", "$HOSTADDRESS$", "-E"]
+    if "port" in extra:
+        cmd_args.extend(("-p", extra["port"]))
+    if "string" in extra:
+        cmd_args.extend(("-s", "'{}'".format(extra["string"])))
+    if "expect" in extra:
+        cmd_args.extend(("-e", extra["expect"]))
+    if "warning" in extra:
+        cmd_args.extend(("-w", extra["warning"]))
+    if "critical" in extra:
+        cmd_args.extend(("-c", extra["critical"]))
+    if "timeout" in extra:
+        cmd_args.extend(("-t", extra["timeout"]))
+    check_timeout = config("check_timeout")
     if check_timeout is not None:
-        cmd_args.extend(('-t', check_timeout))
+        cmd_args.extend(("-t", check_timeout))
 
     check_command = _make_check_command(cmd_args)
-    cmd = '%s!%s' % (check_command, '!'.join([str(x) for x in args]))
-    service.set_attribute('check_command', cmd)
+    cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args]))
+    service.set_attribute("check_command", cmd)
     return True
 
 
 def customize_service(service, family, name, extra):
     """ The monitors.yaml names are mapped to methods that customize services. """
-    customs = {'http': customize_http,
-               'mysql': customize_mysql,
-               'nrpe': customize_nrpe,
-               'tcp': customize_tcp,
-               'rpc': customize_rpc,
-               'pgsql': customize_pgsql,
-               }
+    customs = {
+        "http": customize_http,
+        "mysql": customize_mysql,
+        "nrpe": customize_nrpe,
+        "tcp": customize_tcp,
+        "rpc": customize_rpc,
+        "pgsql": customize_pgsql,
+    }
     if family in customs:
         return customs[family](service, name, extra)
     return False
@@ -292,14 +292,13 @@ def update_localhost():
     """ Update the localhost definition to use the ubuntu icons."""
 
     Model.cfg_file = MAIN_NAGIOS_CFG
-    Model.pynag_directory = os.path.join(MAIN_NAGIOS_DIR, 'conf.d')
-    hosts = Model.Host.objects.filter(host_name='localhost',
-                                      object_type='host')
+    Model.pynag_directory = os.path.join(MAIN_NAGIOS_DIR, "conf.d")
+    hosts = Model.Host.objects.filter(host_name="localhost", object_type="host")
     for host in hosts:
-        host.icon_image = 'base/ubuntu.png'
-        host.icon_image_alt = 'Ubuntu Linux'
-        host.vrml_image = 'ubuntu.png'
-        host.statusmap_image = 'base/ubuntu.gd2'
+        host.icon_image = "base/ubuntu.png"
+        host.icon_image_alt = "Ubuntu Linux"
+        host.vrml_image = "ubuntu.png"
+        host.statusmap_image = "base/ubuntu.gd2"
         host.save()
 
 
@@ -309,13 +308,13 @@ def get_pynag_host(target_id, owner_unit=None, owner_relation=None):
     except (ValueError, KeyError):
         host = Model.Host()
         host.set_filename(CHARM_CFG)
-        host.set_attribute('host_name', target_id)
-        host.set_attribute('use', 'generic-host')
+        host.set_attribute("host_name", target_id)
+        host.set_attribute("use", "generic-host")
         # Adding the ubuntu icon image definitions to the host.
-        host.set_attribute('icon_image', 'base/ubuntu.png')
-        host.set_attribute('icon_image_alt', 'Ubuntu Linux')
-        host.set_attribute('vrml_image', 'ubuntu.png')
-        host.set_attribute('statusmap_image', 'base/ubuntu.gd2')
+        host.set_attribute("icon_image", "base/ubuntu.png")
+        host.set_attribute("icon_image_alt", "Ubuntu Linux")
+        host.set_attribute("vrml_image", "ubuntu.png")
+        host.set_attribute("statusmap_image", "base/ubuntu.gd2")
         host.save()
         host = Model.Host.objects.get_by_shortname(target_id)
     apply_host_policy(target_id, owner_unit, owner_relation)
@@ -323,22 +322,23 @@ def get_pynag_host(target_id, owner_unit=None, owner_relation=None):
 
 
 def get_pynag_service(target_id, service_name):
-    services = Model.Service.objects.filter(host_name=target_id,
-                                            service_description=service_name)
+    services = Model.Service.objects.filter(
+        host_name=target_id, service_description=service_name
+    )
     if len(services) == 0:
         service = Model.Service()
         service.set_filename(CHARM_CFG)
-        service.set_attribute('service_description', service_name)
-        service.set_attribute('host_name', target_id)
-        service.set_attribute('use', 'generic-service')
+        service.set_attribute("service_description", service_name)
+        service.set_attribute("host_name", target_id)
+        service.set_attribute("use", "generic-service")
     else:
         service = services[0]
     return service
 
 
 def apply_host_policy(target_id, owner_unit, owner_relation):
-    ssh_service = get_pynag_service(target_id, 'SSH')
-    ssh_service.set_attribute('check_command', 'check_ssh')
+    ssh_service = get_pynag_service(target_id, "SSH")
+    ssh_service.set_attribute("check_command", "check_ssh")
     ssh_service.save()
 
 
diff --git a/hooks/monitors_relation_changed.py b/hooks/monitors_relation_changed.py
index 5e4f664..d541f2a 100755
--- a/hooks/monitors_relation_changed.py
+++ b/hooks/monitors_relation_changed.py
@@ -28,7 +28,7 @@ from charmhelpers.core.hookenv import (
     related_units,
     relation_ids,
     log,
-    DEBUG
+    DEBUG,
 )
 
 from common import (
@@ -37,14 +37,14 @@ from common import (
     get_pynag_service,
     refresh_hostgroups,
     initialize_inprogress_config,
-    flush_inprogress_config
+    flush_inprogress_config,
 )
 
 
 REQUIRED_REL_DATA_KEYS = [
-    'target-address',
-    'monitors',
-    'target-id',
+    "target-address",
+    "monitors",
+    "target-id",
 ]
 
 
@@ -52,20 +52,19 @@ def _prepare_relation_data(unit, rid):
     relation_data = relation_get(unit=unit, rid=rid)
 
     if not relation_data:
-        msg = (
-            'no relation data found for unit {} in relation {} - '
-            'skipping'.format(unit, rid)
+        msg = "no relation data found for unit {} in relation {} - " "skipping".format(
+            unit, rid
         )
         log(msg, level=DEBUG)
         return {}
 
-    if rid.split(':')[0] == 'nagios':
+    if rid.split(":")[0] == "nagios":
         # Fake it for the more generic 'nagios' relation
-        relation_data['target-id'] = unit.replace('/', '-')
-        relation_data['monitors'] = {'monitors': {'remote': {}}}
+        relation_data["target-id"] = unit.replace("/", "-")
+        relation_data["monitors"] = {"monitors": {"remote": {}}}
 
-    if not relation_data.get('target-address'):
-        relation_data['target-address'] = ingress_address(unit=unit, rid=rid)
+    if not relation_data.get("target-address"):
+        relation_data["target-address"] = ingress_address(unit=unit, rid=rid)
 
     for key in REQUIRED_REL_DATA_KEYS:
         if not relation_data.get(key):
@@ -73,9 +72,8 @@ def _prepare_relation_data(unit, rid):
             # the relation at first (e.g. gnocchi). After a few hook runs,
             # though, they add the key. For this reason I think using a logging
             # level higher than DEBUG could be misleading
-            msg = (
-                '{} not found for unit {} in relation {} - '
-                'skipping'.format(key, unit, rid)
+            msg = "{} not found for unit {} in relation {} - " "skipping".format(
+                key, unit, rid
             )
             log(msg, level=DEBUG)
             return {}
@@ -85,7 +83,7 @@ def _prepare_relation_data(unit, rid):
 
 def _collect_relation_data():
     all_relations = defaultdict(dict)
-    for relname in ['nagios', 'monitors']:
+    for relname in ["nagios", "monitors"]:
         for relid in relation_ids(relname):
             for unit in related_units(relid):
                 relation_data = _prepare_relation_data(unit=unit, rid=relid)
@@ -101,11 +99,10 @@ def main(argv):  # noqa: C901
     # context.
     #
     if len(argv) > 1:
-        relation_settings = {'monitors': open(argv[1]).read(),
-                             'target-id': argv[2]}
+        relation_settings = {"monitors": open(argv[1]).read(), "target-id": argv[2]}
         if len(argv) > 3:
-            relation_settings['target-address'] = argv[3]
-        all_relations = {'monitors:99': {'testing/0': relation_settings}}
+            relation_settings["target-address"] = argv[3]
+        all_relations = {"monitors:99": {"testing/0": relation_settings}}
     else:
         all_relations = _collect_relation_data()
 
@@ -113,12 +110,12 @@ def main(argv):  # noqa: C901
     targets_with_addresses = set()
     for relid, units in all_relations.iteritems():
         for unit, relation_settings in units.items():
-            if 'target-id' in relation_settings:
-                targets_with_addresses.add(relation_settings['target-id'])
+            if "target-id" in relation_settings:
+                targets_with_addresses.add(relation_settings["target-id"])
     new_all_relations = {}
     for relid, units in all_relations.iteritems():
         for unit, relation_settings in units.items():
-            if relation_settings['target-id'] in targets_with_addresses:
+            if relation_settings["target-id"] in targets_with_addresses:
                 if relid not in new_all_relations:
                     new_all_relations[relid] = {}
                 new_all_relations[relid][unit] = relation_settings
@@ -129,21 +126,21 @@ def main(argv):  # noqa: C901
     all_hosts = {}
     for relid, units in all_relations.items():
         for unit, relation_settings in units.iteritems():
-            machine_id = relation_settings.get('machine_id', None)
+            machine_id = relation_settings.get("machine_id", None)
             if machine_id:
-                all_hosts[machine_id] = relation_settings['target-id']
+                all_hosts[machine_id] = relation_settings["target-id"]
     for relid, units in all_relations.items():
         apply_relation_config(relid, units, all_hosts)
     refresh_hostgroups()
     flush_inprogress_config()
-    os.system('service nagios3 reload')
+    os.system("service nagios3 reload")
 
 
-def apply_relation_config(relid, units, all_hosts):   # noqa: C901
+def apply_relation_config(relid, units, all_hosts):  # noqa: C901
     for unit, relation_settings in units.iteritems():
-        monitors = relation_settings['monitors']
-        target_id = relation_settings['target-id']
-        machine_id = relation_settings.get('machine_id', None)
+        monitors = relation_settings["monitors"]
+        target_id = relation_settings["target-id"]
+        machine_id = relation_settings.get("machine_id", None)
         parent_host = None
         if machine_id:
             container_regex = re.compile(r"(\d+)/lx[cd]/\d+")
@@ -155,7 +152,7 @@ def apply_relation_config(relid, units, all_hosts):   # noqa: C901
         # If not set, we don't mess with it, as multiple services may feed
         # monitors in for a particular address. Generally a primary will set
         # this to its own private-address
-        target_address = relation_settings.get('target-address', None)
+        target_address = relation_settings.get("target-address", None)
 
         if type(monitors) != dict:
             monitors = yaml.safe_load(monitors)
@@ -164,23 +161,24 @@ def apply_relation_config(relid, units, all_hosts):   # noqa: C901
         host = get_pynag_host(target_id)
         if not target_address:
             raise Exception("No Target Address provied by NRPE service!")
-        host.set_attribute('address', target_address)
+        host.set_attribute("address", target_address)
         if parent_host:
             # We assume that we only want one parent and will overwrite any
             # existing parents for this host.
-            host.set_attribute('parents', parent_host)
+            host.set_attribute("parents", parent_host)
         host.save()
 
-        for mon_family, mons in monitors['monitors']['remote'].iteritems():
+        for mon_family, mons in monitors["monitors"]["remote"].iteritems():
             for mon_name, mon in mons.iteritems():
-                service_name = '%s-%s' % (target_id, mon_name)
+                service_name = "%s-%s" % (target_id, mon_name)
                 service = get_pynag_service(target_id, service_name)
                 if customize_service(service, mon_family, mon_name, mon):
                     service.save()
                 else:
-                    print('Ignoring %s due to unknown family %s' % (mon_name,
-                                                                    mon_family))
+                    print(
+                        "Ignoring %s due to unknown family %s" % (mon_name, mon_family)
+                    )
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main(sys.argv)
diff --git a/hooks/upgrade_charm.py b/hooks/upgrade_charm.py
index 20957ba..5091f9a 100755
--- a/hooks/upgrade_charm.py
+++ b/hooks/upgrade_charm.py
@@ -6,6 +6,7 @@ import base64
 from jinja2 import Template
 import glob
 import os
+
 # import re
 import pwd
 import grp
@@ -22,27 +23,27 @@ from charmhelpers import fetch
 from common import update_localhost
 
 # Gather facts
-legacy_relations = hookenv.config('legacy')
-extra_config = hookenv.config('extraconfig')
-enable_livestatus = hookenv.config('enable_livestatus')
-livestatus_path = hookenv.config('livestatus_path')
-enable_pagerduty = hookenv.config('enable_pagerduty')
-pagerduty_key = hookenv.config('pagerduty_key')
-pagerduty_path = hookenv.config('pagerduty_path')
-notification_levels = hookenv.config('pagerduty_notification_levels')
-nagios_user = hookenv.config('nagios_user')
-nagios_group = hookenv.config('nagios_group')
-ssl_config = str(hookenv.config('ssl')).lower()
-charm_dir = os.environ['CHARM_DIR']
-cert_domain = hookenv.unit_get('public-address')
+legacy_relations = hookenv.config("legacy")
+extra_config = hookenv.config("extraconfig")
+enable_livestatus = hookenv.config("enable_livestatus")
+livestatus_path = hookenv.config("livestatus_path")
+enable_pagerduty = hookenv.config("enable_pagerduty")
+pagerduty_key = hookenv.config("pagerduty_key")
+pagerduty_path = hookenv.config("pagerduty_path")
+notification_levels = hookenv.config("pagerduty_notification_levels")
+nagios_user = hookenv.config("nagios_user")
+nagios_group = hookenv.config("nagios_group")
+ssl_config = str(hookenv.config("ssl")).lower()
+charm_dir = os.environ["CHARM_DIR"]
+cert_domain = hookenv.unit_get("public-address")
 nagios_cfg = "/etc/nagios3/nagios.cfg"
 nagios_cgi_cfg = "/etc/nagios3/cgi.cfg"
 pagerduty_cfg = "/etc/nagios3/conf.d/pagerduty_nagios.cfg"
 traps_cfg = "/etc/nagios3/conf.d/traps.cfg"
 pagerduty_cron = "/etc/cron.d/nagios-pagerduty-flush"
-password = hookenv.config('password')
-ro_password = hookenv.config('ro-password')
-nagiosadmin = hookenv.config('nagiosadmin') or 'nagiosadmin'
+password = hookenv.config("password")
+ro_password = hookenv.config("ro-password")
+nagiosadmin = hookenv.config("nagiosadmin") or "nagiosadmin"
 contactgroup_members = hookenv.config("contactgroup-members")
 
 # this global var will collect contactgroup members that must be forced
@@ -60,11 +61,12 @@ def warn_legacy_relations():
     in the future
     """
     if legacy_relations is not None:
-        hookenv.log("Relations have been radically changed."
-                    " The monitoring interface is not supported anymore.",
-                    "WARNING")
-    hookenv.log("Please use the generic juju-info or the monitors interface",
-                "WARNING")
+        hookenv.log(
+            "Relations have been radically changed."
+            " The monitoring interface is not supported anymore.",
+            "WARNING",
+        )
+    hookenv.log("Please use the generic juju-info or the monitors interface", "WARNING")
 
 
 def parse_extra_contacts(yaml_string):
@@ -76,40 +78,44 @@ def parse_extra_contacts(yaml_string):
     extra_contacts = []
 
     # Valid characters for contact names
-    valid_name_chars = string.ascii_letters + string.digits + '_-'
+    valid_name_chars = string.ascii_letters + string.digits + "_-"
 
     try:
         extra_contacts_raw = yaml.load(yaml_string, Loader=yaml.SafeLoader) or []
         if not isinstance(extra_contacts_raw, list):
-            raise ValueError('not a list')
+            raise ValueError("not a list")
 
         for contact in extra_contacts_raw:
-            if {'name', 'host', 'service'} > set(contact.keys()):
-                hookenv.log('Contact {} is missing fields.'.format(contact),
-                            hookenv.WARNING)
+            if {"name", "host", "service"} > set(contact.keys()):
+                hookenv.log(
+                    "Contact {} is missing fields.".format(contact), hookenv.WARNING
+                )
                 continue
 
-            if set(contact['name']) > set(valid_name_chars):
-                hookenv.log('Contact name {} is illegal'.format(contact['name']),
-                            hookenv.WARNING)
+            if set(contact["name"]) > set(valid_name_chars):
+                hookenv.log(
+                    "Contact name {} is illegal".format(contact["name"]),
+                    hookenv.WARNING,
+                )
                 continue
 
-            if '\n' in (contact['host'] + contact['service']):
-                hookenv.log('Line breaks not allowed in commands', hookenv.WARNING)
+            if "\n" in (contact["host"] + contact["service"]):
+                hookenv.log("Line breaks not allowed in commands", hookenv.WARNING)
                 continue
 
-            contact['name'] = contact['name'].lower()
-            contact['alias'] = contact['name'].capitalize()
+            contact["name"] = contact["name"].lower()
+            contact["alias"] = contact["name"].capitalize()
             extra_contacts.append(contact)
 
     except (ValueError, yaml.error.YAMLError) as e:
-        hookenv.log('Invalid "extra_contacts" configuration: {}'.format(e),
-                    hookenv.WARNING)
+        hookenv.log(
+            'Invalid "extra_contacts" configuration: {}'.format(e), hookenv.WARNING
+        )
     if len(extra_contacts_raw) != len(extra_contacts):
         hookenv.log(
-            'Invalid extra_contacts config, found {} contacts defined, '
-            'only {} were valid, check unit logs for '
-            'detailed errors'.format(len(extra_contacts_raw), len(extra_contacts))
+            "Invalid extra_contacts config, found {} contacts defined, "
+            "only {} were valid, check unit logs for "
+            "detailed errors".format(len(extra_contacts_raw), len(extra_contacts))
         )
 
     return extra_contacts
@@ -119,12 +125,12 @@ def parse_extra_contacts(yaml_string):
 # proper nagios3 configuration file, otherwise remove the config
 def write_extra_config():
     # Be predjudice about this - remove the file always.
-    if host.file_hash('/etc/nagios3/conf.d/extra.cfg') is not None:
-        os.remove('/etc/nagios3/conf.d/extra.cfg')
+    if host.file_hash("/etc/nagios3/conf.d/extra.cfg") is not None:
+        os.remove("/etc/nagios3/conf.d/extra.cfg")
     # If we have a config, then write it. the hook reconfiguration will
     # handle the details
     if extra_config is not None:
-        host.write_file('/etc/nagios3/conf.d/extra.cfg', extra_config)
+        host.write_file("/etc/nagios3/conf.d/extra.cfg", extra_config)
 
 
 # Equivalent of mkdir -p, since we can't rely on
@@ -152,7 +158,7 @@ def enable_livestatus_config():
     if enable_livestatus:
         hookenv.log("Livestatus is enabled")
         fetch.apt_update()
-        fetch.apt_install('check-mk-livestatus')
+        fetch.apt_install("check-mk-livestatus")
 
         # Make the directory and fix perms on it
         hookenv.log("Fixing perms on livestatus_path")
@@ -170,8 +176,10 @@ def enable_livestatus_config():
         os.chown(livestatus_dir, uid, gid)
         st = os.stat(livestatus_path)
         os.chmod(livestatus_path, st.st_mode | stat.S_IRGRP)
-        os.chmod(livestatus_dir, st.st_mode | stat.S_IRGRP |
-                 stat.S_ISGID | stat.S_IXUSR | stat.S_IXGRP)
+        os.chmod(
+            livestatus_dir,
+            st.st_mode | stat.S_IRGRP | stat.S_ISGID | stat.S_IXUSR | stat.S_IXGRP,
+        )
 
 
 def enable_pagerduty_config():
@@ -180,34 +188,35 @@ def enable_pagerduty_config():
     if enable_pagerduty:
         hookenv.log("Pagerduty is enabled")
         fetch.apt_update()
-        fetch.apt_install('libhttp-parser-perl')
+        fetch.apt_install("libhttp-parser-perl")
         env = os.environ
-        proxy = env.get('JUJU_CHARM_HTTPS_PROXY') or env.get('https_proxy')
-        proxy_switch = '--proxy {}'.format(proxy) if proxy else ''
+        proxy = env.get("JUJU_CHARM_HTTPS_PROXY") or env.get("https_proxy")
+        proxy_switch = "--proxy {}".format(proxy) if proxy else ""
 
         # Ship the pagerduty_nagios.cfg file
-        template_values = {'pagerduty_key': pagerduty_key,
-                           'pagerduty_path': pagerduty_path,
-                           'proxy_switch': proxy_switch,
-                           'notification_levels': notification_levels}
-
-        with open('hooks/templates/pagerduty_nagios_cfg.tmpl', 'r') as f:
+        template_values = {
+            "pagerduty_key": pagerduty_key,
+            "pagerduty_path": pagerduty_path,
+            "proxy_switch": proxy_switch,
+            "notification_levels": notification_levels,
+        }
+
+        with open("hooks/templates/pagerduty_nagios_cfg.tmpl", "r") as f:
             templateDef = f.read()
 
         t = Template(templateDef)
-        with open(pagerduty_cfg, 'w') as f:
+        with open(pagerduty_cfg, "w") as f:
             f.write(t.render(template_values))
 
-        with open('hooks/templates/nagios-pagerduty-flush-cron.tmpl', 'r') as f2:
+        with open("hooks/templates/nagios-pagerduty-flush-cron.tmpl", "r") as f2:
             templateDef = f2.read()
 
         t2 = Template(templateDef)
-        with open(pagerduty_cron, 'w') as f2:
+        with open(pagerduty_cron, "w") as f2:
             f2.write(t2.render(template_values))
 
         # Ship the pagerduty_nagios.pl script
-        shutil.copy('files/pagerduty_nagios.pl',
-                    '/usr/local/bin/pagerduty_nagios.pl')
+        shutil.copy("files/pagerduty_nagios.pl", "/usr/local/bin/pagerduty_nagios.pl")
 
         # Create the pagerduty queue dir
         if not os.path.isdir(pagerduty_path):
@@ -228,13 +237,13 @@ def enable_pagerduty_config():
     if enable_pagerduty:
         # avoid duplicates
         if "pagerduty" not in contactgroup_members:
-            forced_contactgroup_members.append('pagerduty')
+            forced_contactgroup_members.append("pagerduty")
 
 
 def enable_traps_config():
     global forced_contactgroup_members
 
-    send_traps_to = hookenv.config('send_traps_to')
+    send_traps_to = hookenv.config("send_traps_to")
 
     if not send_traps_to:
         if os.path.isfile(traps_cfg):
@@ -245,25 +254,23 @@ def enable_traps_config():
     hookenv.log("Send traps feature is enabled, target address is %s" % send_traps_to)
 
     if "managementstation" not in contactgroup_members:
-        forced_contactgroup_members.append('managementstation')
+        forced_contactgroup_members.append("managementstation")
 
-    template_values = { 'send_traps_to': send_traps_to }
+    template_values = {"send_traps_to": send_traps_to}
 
-    with open('hooks/templates/traps.tmpl','r') as f:
+    with open("hooks/templates/traps.tmpl", "r") as f:
         templateDef = f.read()
 
     t = Template(templateDef)
-    with open(traps_cfg, 'w') as f:
+    with open(traps_cfg, "w") as f:
         f.write(t.render(template_values))
 
 
 def update_contacts():
     # Multiple Email Contacts
-    admin_members = ''
+    admin_members = ""
     contacts = []
-    admin_email = list(
-        filter(None, set(hookenv.config('admin_email').split(',')))
-    )
+    admin_email = list(filter(None, set(hookenv.config("admin_email").split(","))))
     if len(admin_email) == 0:
         hookenv.log("admin_email is unset, this isn't valid config")
         hookenv.status_set("blocked", "admin_email is not configured")
@@ -271,26 +278,18 @@ def update_contacts():
     hookenv.status_set("active", "ready")
     if len(admin_email) == 1:
         hookenv.log("Setting one admin email address '%s'" % admin_email[0])
-        contacts = [{
-            'contact_name': 'root',
-            'alias': 'Root',
-            'email': admin_email[0]
-        }]
+        contacts = [{"contact_name": "root", "alias": "Root", "email": admin_email[0]}]
     elif len(admin_email) > 1:
         hookenv.log("Setting %d admin email addresses" % len(admin_email))
         contacts = []
         for email in admin_email:
-            contact_name = email.replace('@', '').replace('.','').lower()
+            contact_name = email.replace("@", "").replace(".", "").lower()
             contact_alias = contact_name.capitalize()
-            contacts.append({
-                'contact_name': contact_name,
-                'alias': contact_alias,
-                'email': email
-            })
+            contacts.append(
+                {"contact_name": contact_name, "alias": contact_alias, "email": email}
+            )
 
-        admin_members = ', '.join([
-            c['contact_name'] for c in contacts
-        ])
+        admin_members = ", ".join([c["contact_name"] for c in contacts])
 
     resulting_members = contactgroup_members
     if admin_members:
@@ -301,26 +300,40 @@ def update_contacts():
         resulting_members = ",".join([resulting_members] + forced_contactgroup_members)
 
     # Parse extra_contacts
-    extra_contacts = parse_extra_contacts(hookenv.config('extra_contacts'))
-
-    template_values = {'admin_service_notification_period': hookenv.config('admin_service_notification_period'),
-                       'admin_host_notification_period': hookenv.config('admin_host_notification_period'),
-                       'admin_service_notification_options': hookenv.config('admin_service_notification_options'),
-                       'admin_host_notification_options': hookenv.config('admin_host_notification_options'),
-                       'admin_service_notification_commands': hookenv.config('admin_service_notification_commands'),
-                       'admin_host_notification_commands': hookenv.config('admin_host_notification_commands'),
-                       'contacts': contacts,
-                       'contactgroup_members': resulting_members,
-                       'extra_contacts': extra_contacts}
-
-    with open('hooks/templates/contacts-cfg.tmpl', 'r') as f:
+    extra_contacts = parse_extra_contacts(hookenv.config("extra_contacts"))
+
+    template_values = {
+        "admin_service_notification_period": hookenv.config(
+            "admin_service_notification_period"
+        ),
+        "admin_host_notification_period": hookenv.config(
+            "admin_host_notification_period"
+        ),
+        "admin_service_notification_options": hookenv.config(
+            "admin_service_notification_options"
+        ),
+        "admin_host_notification_options": hookenv.config(
+            "admin_host_notification_options"
+        ),
+        "admin_service_notification_commands": hookenv.config(
+            "admin_service_notification_commands"
+        ),
+        "admin_host_notification_commands": hookenv.config(
+            "admin_host_notification_commands"
+        ),
+        "contacts": contacts,
+        "contactgroup_members": resulting_members,
+        "extra_contacts": extra_contacts,
+    }
+
+    with open("hooks/templates/contacts-cfg.tmpl", "r") as f:
         template_def = f.read()
 
     t = Template(template_def)
-    with open('/etc/nagios3/conf.d/contacts_nagios2.cfg', 'w') as f:
+    with open("/etc/nagios3/conf.d/contacts_nagios2.cfg", "w") as f:
         f.write(t.render(template_values))
 
-    host.service_reload('nagios3')
+    host.service_reload("nagios3")
 
 
 def ssl_configured():
@@ -331,13 +344,13 @@ def ssl_configured():
 
 
 # Gather local facts for SSL deployment
-deploy_key_path = os.path.join(charm_dir, 'data', '%s.key' % (cert_domain))
-deploy_cert_path = os.path.join(charm_dir, 'data', '%s.crt' % (cert_domain))
-deploy_csr_path = os.path.join(charm_dir, 'data', '%s.csr' % (cert_domain))
+deploy_key_path = os.path.join(charm_dir, "data", "%s.key" % (cert_domain))
+deploy_cert_path = os.path.join(charm_dir, "data", "%s.crt" % (cert_domain))
+deploy_csr_path = os.path.join(charm_dir, "data", "%s.csr" % (cert_domain))
 # set basename for SSL key locations
-cert_file = '/etc/ssl/certs/%s.pem' % (cert_domain)
-key_file = '/etc/ssl/private/%s.key' % (cert_domain)
-chain_file = '/etc/ssl/certs/%s.csr' % (cert_domain)
+cert_file = "/etc/ssl/certs/%s.pem" % (cert_domain)
+key_file = "/etc/ssl/private/%s.key" % (cert_domain)
+chain_file = "/etc/ssl/certs/%s.csr" % (cert_domain)
 
 
 # Check for key and certificate, since the CSR is optional
@@ -353,23 +366,23 @@ def check_ssl_files():
 
 # Decode the SSL keys from their base64 encoded values in the configuration
 def decode_ssl_keys():
-    if hookenv.config('ssl_key'):
+    if hookenv.config("ssl_key"):
         hookenv.log("Writing key from config ssl_key: %s" % key_file)
-        with open(key_file, 'w') as f:
-            f.write(str(base64.b64decode(hookenv.config('ssl_key'))))
-    if hookenv.config('ssl_cert'):
-        with open(cert_file, 'w') as f:
-            f.write(str(base64.b64decode(hookenv.config('ssl_cert'))))
-    if hookenv.config('ssl_chain'):
-        with open(chain_file, 'w') as f:
-            f.write(str(base64.b64decode(hookenv.config('ssl_cert'))))
+        with open(key_file, "w") as f:
+            f.write(str(base64.b64decode(hookenv.config("ssl_key"))))
+    if hookenv.config("ssl_cert"):
+        with open(cert_file, "w") as f:
+            f.write(str(base64.b64decode(hookenv.config("ssl_cert"))))
+    if hookenv.config("ssl_chain"):
+        with open(chain_file, "w") as f:
+            f.write(str(base64.b64decode(hookenv.config("ssl_cert"))))
 
 
 def enable_ssl():
     # Set the basename of all ssl files
 
     # Validate that we have configs, and generate a self signed certificate.
-    if not hookenv.config('ssl_cert'):
+    if not hookenv.config("ssl_cert"):
         # bail if keys already exist
         if os.path.exists(cert_file):
             hookenv.log("Keys exist, not creating keys!", "WARNING")
@@ -388,69 +401,69 @@ def nagios_bool(value):
 
 
 def update_config():
-    host_context = hookenv.config('nagios_host_context')
-    local_host_name = 'nagios'
+    host_context = hookenv.config("nagios_host_context")
+    local_host_name = "nagios"
     principal_unitname = hookenv.principal_unit()
     # Fallback to using "primary" if it exists.
     if principal_unitname:
         local_host_name = principal_unitname
     else:
-        local_host_name = hookenv.local_unit().replace('/', '-')
-    template_values = {'nagios_user': nagios_user,
-                       'nagios_group': nagios_group,
-                       'enable_livestatus': enable_livestatus,
-                       'livestatus_path': livestatus_path,
-                       'livestatus_args': hookenv.config('livestatus_args'),
-                       'check_external_commands': hookenv.config('check_external_commands'),
-                       'command_check_interval': hookenv.config('command_check_interval'),
-                       'command_file': hookenv.config('command_file'),
-                       'debug_file': hookenv.config('debug_file'),
-                       'debug_verbosity': hookenv.config('debug_verbosity'),
-                       'debug_level': hookenv.config('debug_level'),
-                       'daemon_dumps_core': hookenv.config('daemon_dumps_core'),
-                       'flap_detection': nagios_bool(hookenv.config('flap_detection')),
-                       'admin_email': hookenv.config('admin_email'),
-                       'admin_pager': hookenv.config('admin_pager'),
-                       'log_rotation_method': hookenv.config('log_rotation_method'),
-                       'log_archive_path': hookenv.config('log_archive_path'),
-                       'use_syslog': hookenv.config('use_syslog'),
-                       'monitor_self': hookenv.config('monitor_self'),
-                       'nagios_hostname': "{}-{}".format(host_context, local_host_name),
-                       'load_monitor': hookenv.config('load_monitor'),
-                       'is_container': host.is_container(),
-                       'service_check_timeout': hookenv.config('service_check_timeout'),
-                       'service_check_timeout_state': hookenv.config('service_check_timeout_state'),
-                       }
-
-    with open('hooks/templates/nagios-cfg.tmpl', 'r') as f:
+        local_host_name = hookenv.local_unit().replace("/", "-")
+    template_values = {
+        "nagios_user": nagios_user,
+        "nagios_group": nagios_group,
+        "enable_livestatus": enable_livestatus,
+        "livestatus_path": livestatus_path,
+        "livestatus_args": hookenv.config("livestatus_args"),
+        "check_external_commands": hookenv.config("check_external_commands"),
+        "command_check_interval": hookenv.config("command_check_interval"),
+        "command_file": hookenv.config("command_file"),
+        "debug_file": hookenv.config("debug_file"),
+        "debug_verbosity": hookenv.config("debug_verbosity"),
+        "debug_level": hookenv.config("debug_level"),
+        "daemon_dumps_core": hookenv.config("daemon_dumps_core"),
+        "flap_detection": nagios_bool(hookenv.config("flap_detection")),
+        "admin_email": hookenv.config("admin_email"),
+        "admin_pager": hookenv.config("admin_pager"),
+        "log_rotation_method": hookenv.config("log_rotation_method"),
+        "log_archive_path": hookenv.config("log_archive_path"),
+        "use_syslog": hookenv.config("use_syslog"),
+        "monitor_self": hookenv.config("monitor_self"),
+        "nagios_hostname": "{}-{}".format(host_context, local_host_name),
+        "load_monitor": hookenv.config("load_monitor"),
+        "is_container": host.is_container(),
+        "service_check_timeout": hookenv.config("service_check_timeout"),
+        "service_check_timeout_state": hookenv.config("service_check_timeout_state"),
+    }
+
+    with open("hooks/templates/nagios-cfg.tmpl", "r") as f:
         templateDef = f.read()
 
     t = Template(templateDef)
-    with open(nagios_cfg, 'w') as f:
+    with open(nagios_cfg, "w") as f:
         f.write(t.render(template_values))
 
-    with open('hooks/templates/localhost_nagios2.cfg.tmpl', 'r') as f:
+    with open("hooks/templates/localhost_nagios2.cfg.tmpl", "r") as f:
         templateDef = f.read()
 
     t = Template(templateDef)
-    with open('/etc/nagios3/conf.d/localhost_nagios2.cfg', 'w') as f:
+    with open("/etc/nagios3/conf.d/localhost_nagios2.cfg", "w") as f:
         f.write(t.render(template_values))
 
-    host.service_reload('nagios3')
+    host.service_reload("nagios3")
 
 
 def update_cgi_config():
-    template_values = {'nagiosadmin': nagiosadmin,
-                       'ro_password': ro_password}
-    with open('hooks/templates/nagios-cgi.tmpl', 'r') as f:
+    template_values = {"nagiosadmin": nagiosadmin, "ro_password": ro_password}
+    with open("hooks/templates/nagios-cgi.tmpl", "r") as f:
         templateDef = f.read()
 
     t = Template(templateDef)
-    with open(nagios_cgi_cfg, 'w') as f:
+    with open(nagios_cgi_cfg, "w") as f:
         f.write(t.render(template_values))
 
-    host.service_reload('nagios3')
-    host.service_reload('apache2')
+    host.service_reload("nagios3")
+    host.service_reload("apache2")
 
 
 # Nagios3 is deployed as a global apache application from the archive.
@@ -467,33 +480,35 @@ def update_apache():
 
     # Start by Setting the ports.conf
 
-    with open('hooks/templates/ports-cfg.jinja2', 'r') as f:
+    with open("hooks/templates/ports-cfg.jinja2", "r") as f:
         template_def = f.read()
     t = Template(template_def)
-    ports_conf = '/etc/apache2/ports.conf'
+    ports_conf = "/etc/apache2/ports.conf"
 
-    with open(ports_conf, 'w') as f:
-        f.write(t.render({'enable_http': HTTP_ENABLED}))
+    with open(ports_conf, "w") as f:
+        f.write(t.render({"enable_http": HTTP_ENABLED}))
 
     # Next setup the default-ssl.conf
     if os.path.exists(chain_file) and os.path.getsize(chain_file) > 0:
         ssl_chain = chain_file
     else:
         ssl_chain = None
-    template_values = {'ssl_key': key_file,
-                       'ssl_cert': cert_file,
-                       'ssl_chain': ssl_chain}
-    with open('hooks/templates/default-ssl.tmpl', 'r') as f:
+    template_values = {
+        "ssl_key": key_file,
+        "ssl_cert": cert_file,
+        "ssl_chain": ssl_chain,
+    }
+    with open("hooks/templates/default-ssl.tmpl", "r") as f:
         template_def = f.read()
 
     t = Template(template_def)
-    ssl_conf = '/etc/apache2/sites-available/default-ssl.conf'
-    with open(ssl_conf, 'w') as f:
+    ssl_conf = "/etc/apache2/sites-available/default-ssl.conf"
+    with open(ssl_conf, "w") as f:
         f.write(t.render(template_values))
 
     # Create directory for extra *.include files installed by subordinates
     try:
-        os.makedirs('/etc/apache2/vhost.d/')
+        os.makedirs("/etc/apache2/vhost.d/")
     except OSError:
         pass
 
@@ -501,20 +516,20 @@ def update_apache():
     sites = glob.glob("/etc/apache2/sites-available/*.conf")
     non_ssl = set(sites) - {ssl_conf}
     for each in non_ssl:
-        site = os.path.basename(each).rsplit('.', 1)[0]
+        site = os.path.basename(each).rsplit(".", 1)[0]
         Apache2Site(site).action(enabled=HTTP_ENABLED)
 
     # Configure the behavior of https site
     Apache2Site("default-ssl").action(enabled=SSL_CONFIGURED)
 
     # Finally, restart apache2
-    host.service_reload('apache2')
+    host.service_reload("apache2")
 
 
 class Apache2Site:
     def __init__(self, site):
         self.site = site
-        self.is_ssl = 'ssl' in site.lower()
+        self.is_ssl = "ssl" in site.lower()
         self.port = 443 if self.is_ssl else 80
 
     def action(self, enabled):
@@ -524,36 +539,40 @@ class Apache2Site:
         try:
             subprocess.check_output(args, stderr=subprocess.STDOUT)
         except subprocess.CalledProcessError as e:
-            hookenv.log("Apache2Site: `{}`, returned {}, stdout:\n{}"
-                        .format(e.cmd, e.returncode, e.output), "ERROR")
+            hookenv.log(
+                "Apache2Site: `{}`, returned {}, stdout:\n{}".format(
+                    e.cmd, e.returncode, e.output
+                ),
+                "ERROR",
+            )
 
     def _enable(self):
         hookenv.log("Apache2Site: Enabling %s..." % self.site, "INFO")
-        self._call(['a2ensite', self.site])
+        self._call(["a2ensite", self.site])
         if self.port == 443:
-            self._call(['a2enmod', 'ssl'])
+            self._call(["a2enmod", "ssl"])
         hookenv.open_port(self.port)
 
     def _disable(self):
         hookenv.log("Apache2Site: Disabling %s..." % self.site, "INFO")
-        self._call(['a2dissite', self.site])
+        self._call(["a2dissite", self.site])
         hookenv.close_port(self.port)
 
 
 def update_password(account, password):
     """Update the charm and Apache's record of the password for the supplied account."""
-    account_file = ''.join(['/var/lib/juju/nagios.', account, '.passwd'])
+    account_file = "".join(["/var/lib/juju/nagios.", account, ".passwd"])
     if password:
-        with open(account_file, 'w') as f:
+        with open(account_file, "w") as f:
             f.write(password)
             os.fchmod(f.fileno(), 0o0400)
-        subprocess.call(['htpasswd', '-b', '/etc/nagios3/htpasswd.users',
-                         account, password])
+        subprocess.call(
+            ["htpasswd", "-b", "/etc/nagios3/htpasswd.users", account, password]
+        )
     else:
         """ password was empty, it has been removed. We should delete the account """
         os.path.isfile(account_file) and os.remove(account_file)
-        subprocess.call(['htpasswd', '-D', '/etc/nagios3/htpasswd.users',
-                         account])
+        subprocess.call(["htpasswd", "-D", "/etc/nagios3/htpasswd.users", account])
 
 
 warn_legacy_relations()
@@ -571,12 +590,12 @@ update_apache()
 update_localhost()
 update_cgi_config()
 update_contacts()
-update_password('nagiosro', ro_password)
+update_password("nagiosro", ro_password)
 if password:
     update_password(nagiosadmin, password)
-if nagiosadmin != 'nagiosadmin':
-    update_password('nagiosadmin', False)
+if nagiosadmin != "nagiosadmin":
+    update_password("nagiosadmin", False)
 
-subprocess.call(['scripts/postfix_loopback_only.sh'])
-subprocess.call(['hooks/mymonitors-relation-joined'])
-subprocess.call(['hooks/monitors-relation-changed'])
+subprocess.call(["scripts/postfix_loopback_only.sh"])
+subprocess.call(["hooks/mymonitors-relation-joined"])
+subprocess.call(["hooks/monitors-relation-changed"])
diff --git a/hooks/website_relation_joined.py b/hooks/website_relation_joined.py
index 984ae80..706a561 100755
--- a/hooks/website_relation_joined.py
+++ b/hooks/website_relation_joined.py
@@ -25,15 +25,15 @@ from charmhelpers.core.hookenv import (
 
 
 def main():
-    relation_data = {'hostname': common.get_local_ingress_address()}
-    sslcfg = config()['ssl']
-    if sslcfg == 'only':
-        relation_data['port'] = 443
+    relation_data = {"hostname": common.get_local_ingress_address()}
+    sslcfg = config()["ssl"]
+    if sslcfg == "only":
+        relation_data["port"] = 443
     else:
-        relation_data['port'] = 80
-    log('website-relation-joined data %s' % relation_data)
+        relation_data["port"] = 80
+    log("website-relation-joined data %s" % relation_data)
     relation_set(None, **relation_data)
 
 
-if __name__ == '__main__':  # pragma: no cover
+if __name__ == "__main__":  # pragma: no cover
     main()
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index 484e3a4..a31034c 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -15,7 +15,7 @@ import pytest
 STAT_FILE = "python3 -c \"import json; import os; s=os.stat('%s'); print(json.dumps({'uid': s.st_uid, 'gid': s.st_gid, 'mode': oct(s.st_mode), 'size': s.st_size}))\""  # noqa: E501
 
 
-@pytest.yield_fixture(scope='session')
+@pytest.yield_fixture(scope="session")
 def event_loop(request):
     """Override the default pytest event loop to allow for broaded scopedv fixtures."""
     loop = asyncio.get_event_loop_policy().new_event_loop()
@@ -26,7 +26,7 @@ def event_loop(request):
     asyncio.set_event_loop(None)
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 async def controller():
     """Connect to the current controller."""
     controller = Controller()
@@ -35,21 +35,21 @@ async def controller():
     await controller.disconnect()
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 async def model(controller):
     """Create a model that lives only for the duration of the test."""
     model_name = "functest-{}".format(uuid.uuid4())
     model = await controller.add_model(model_name)
     yield model
     await model.disconnect()
-    if os.getenv('PYTEST_KEEP_MODEL'):
+    if os.getenv("PYTEST_KEEP_MODEL"):
         return
     await controller.destroy_model(model_name)
     while model_name in await controller.list_models():
         await asyncio.sleep(1)
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 async def current_model():
     """Return the current model, does not create or destroy it."""
     model = Model()
@@ -61,29 +61,34 @@ async def current_model():
 @pytest.fixture
 async def get_app(model):
     """Return the application requested."""
+
     async def _get_app(name):
         try:
             return model.applications[name]
         except KeyError:
             raise JujuError("Cannot find application {}".format(name))
+
     return _get_app
 
 
 @pytest.fixture
 async def get_unit(model):
     """Return the requested <app_name>/<unit_number> unit."""
+
     async def _get_unit(name):
         try:
-            (app_name, unit_number) = name.split('/')
+            (app_name, unit_number) = name.split("/")
             return model.applications[app_name].units[unit_number]
         except (KeyError, ValueError):
             raise JujuError("Cannot find unit {}".format(name))
+
     return _get_unit
 
 
 @pytest.fixture
 async def get_entity(model, get_unit, get_app):
     """Return a unit or an application."""
+
     async def _get_entity(name):
         try:
             return await get_unit(name)
@@ -92,12 +97,14 @@ async def get_entity(model, get_unit, get_app):
                 return await get_app(name)
             except JujuError:
                 raise JujuError("Cannot find entity {}".format(name))
+
     return _get_entity
 
 
 @pytest.fixture
 async def run_command(get_unit):
     """Run a command on a unit."""
+
     async def _run_command(cmd, target):
         """
         Run a command on a unit.
@@ -105,13 +112,10 @@ async def run_command(get_unit):
         :param cmd: Command to be run
         :param target: Unit object or unit name string
         """
-        unit = (
-            target
-            if type(target) is juju.unit.Unit
-            else await get_unit(target)
-        )
+        unit = target if type(target) is juju.unit.Unit else await get_unit(target)
         action = await unit.run(cmd)
         return action.results
+
     return _run_command
 
 
@@ -123,31 +127,36 @@ async def file_stat(run_command):
     :param path: File path
     :param target: Unit object or unit name string
     """
+
     async def _file_stat(path, target):
         cmd = STAT_FILE % path
         results = await run_command(cmd, target)
-        return json.loads(results['Stdout'])
+        return json.loads(results["Stdout"])
+
     return _file_stat
 
 
 @pytest.fixture
 async def file_contents(run_command):
     """Return the contents of a file."""
+
     async def _file_contents(path, target):
         """Return the contents of a file.
 
             :param path: File path
             :param target: Unit object or unit name string
         """
-        cmd = 'cat {}'.format(path)
+        cmd = "cat {}".format(path)
         results = await run_command(cmd, target)
-        return results['Stdout']
+        return results["Stdout"]
+
     return _file_contents
 
 
 @pytest.fixture
 async def reconfigure_app(get_app, model):
     """Apply a different config to the requested app."""
+
     async def _reconfigure_app(cfg, target):
         application = (
             target
@@ -156,16 +165,19 @@ async def reconfigure_app(get_app, model):
         )
         await application.set_config(cfg)
         await application.get_config()
-        await model.block_until(lambda: application.status == 'active')
+        await model.block_until(lambda: application.status == "active")
+
     return _reconfigure_app
 
 
 @pytest.fixture
 async def create_group(run_command):
     """Create the UNIX group specified."""
+
     async def _create_group(group_name, target):
         cmd = "sudo groupadd %s" % group_name
         await run_command(cmd, target)
+
     return _create_group
 
 
@@ -183,20 +195,18 @@ SERIES = [
 ############
 # FIXTURES #
 ############
-@pytest.fixture(scope='session', params=SERIES)
+@pytest.fixture(scope="session", params=SERIES)
 def series(request):
     """Return ubuntu version (i.e. xenial) in use in the test."""
     return request.param
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 async def relatives(model, series):
     nrpe = "nrpe"
     nrpe_name = "nrpe-{}".format(series)
     nrpe_app = await model.deploy(
-        'cs:' + nrpe, application_name=nrpe_name,
-        series=series, config={},
-        num_units=0
+        "cs:" + nrpe, application_name=nrpe_name, series=series, config={}, num_units=0
     )
 
     mysql = "mysql"
@@ -205,50 +215,52 @@ async def relatives(model, series):
 
     mysql_name = "mysql-{}".format(series)
     mysql_app = await model.deploy(
-        'cs:' + mysql, application_name=mysql_name,
-        series=series, config={}
+        "cs:" + mysql, application_name=mysql_name, series=series, config={}
     )
 
-    await model.add_relation('{}:nrpe-external-master'.format(mysql_name),
-                             '{}:nrpe-external-master'.format(nrpe_name))
+    await model.add_relation(
+        "{}:nrpe-external-master".format(mysql_name),
+        "{}:nrpe-external-master".format(nrpe_name),
+    )
     await model.block_until(
-        lambda: mysql_app.units[0].workload_status == "active" and
-        mysql_app.units[0].agent_status == "idle"
+        lambda: mysql_app.units[0].workload_status == "active"
+        and mysql_app.units[0].agent_status == "idle"
     )
 
     yield {
         "mysql": {"name": mysql_name, "app": mysql_app},
-        "nrpe": {"name": nrpe_name, "app": nrpe_app}
+        "nrpe": {"name": nrpe_name, "app": nrpe_app},
     }
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 async def deploy_app(relatives, model, series):
     """Return application of the charm under test."""
     app_name = "nagios-{}".format(series)
 
     """Deploy the nagios app."""
     nagios_app = await model.deploy(
-        os.path.join(CHARM_BUILD_DIR, 'nagios'),
+        os.path.join(CHARM_BUILD_DIR, "nagios"),
         application_name=app_name,
         series=series,
         config={
-            'enable_livestatus': False,
-            'ssl': 'off',
-            'extraconfig': '',
-            'enable_pagerduty': False
-        }
+            "enable_livestatus": False,
+            "ssl": "off",
+            "extraconfig": "",
+            "enable_pagerduty": False,
+        },
     )
 
-    await model.add_relation('{}:monitors'.format(relatives["nrpe"]["name"]),
-                             '{}:monitors'.format(app_name))
+    await model.add_relation(
+        "{}:monitors".format(relatives["nrpe"]["name"]), "{}:monitors".format(app_name)
+    )
     await model.block_until(
-        lambda: nagios_app.units[0].agent_status == "idle" and
-                relatives["mysql"]["app"].units[0].agent_status == "idle"
+        lambda: nagios_app.units[0].agent_status == "idle"
+        and relatives["mysql"]["app"].units[0].agent_status == "idle"
     )
 
     yield nagios_app
-    if os.getenv('PYTEST_KEEP_MODEL'):
+    if os.getenv("PYTEST_KEEP_MODEL"):
         return
 
     for relative in list(relatives.values()):
@@ -270,8 +282,9 @@ class Agent:
     async def block_until_or_timeout(self, lambda_f, **kwargs):
         await self.block_until(lambda_f, ignore_timeout=True, **kwargs)
 
-    async def block_until(self, lambda_f, timeout=120, wait_period=5,
-                          ignore_timeout=False):
+    async def block_until(
+        self, lambda_f, timeout=120, wait_period=5, ignore_timeout=False
+    ):
         try:
             await self.model.block_until(
                 lambda_f, timeout=timeout, wait_period=wait_period
@@ -285,7 +298,7 @@ class Agent:
 async def unit(model, deploy_app):
     """Return the unit we've deployed."""
     unit = Agent(deploy_app.units[0], deploy_app)
-    await unit.block_until(lambda: unit.is_active('idle'))
+    await unit.block_until(lambda: unit.is_active("idle"))
     return unit
 
 
@@ -293,4 +306,4 @@ async def unit(model, deploy_app):
 async def auth(file_contents, unit):
     """Return the basic auth credentials."""
     nagiospwd = await file_contents("/var/lib/juju/nagios.passwd", unit.u)
-    return 'nagiosadmin', nagiospwd.strip()
+    return "nagiosadmin", nagiospwd.strip()
diff --git a/tests/functional/test_config.py b/tests/functional/test_config.py
index b64f8a6..8f83bdd 100644
--- a/tests/functional/test_config.py
+++ b/tests/functional/test_config.py
@@ -1,6 +1,7 @@
 from async_generator import asynccontextmanager
 import pytest
 import requests
+
 pytestmark = pytest.mark.asyncio
 
 
@@ -8,18 +9,18 @@ pytestmark = pytest.mark.asyncio
 async def config(unit, item, test_value, post_test):
     await unit.application.set_config({item: test_value})
     await unit.block_until_or_timeout(
-        lambda: unit.is_active('executing'), timeout=5,
+        lambda: unit.is_active("executing"), timeout=5,
     )
-    await unit.block_until(lambda: unit.is_active('idle'))
+    await unit.block_until(lambda: unit.is_active("idle"))
     yield test_value
     await unit.application.set_config({item: post_test})
     await unit.block_until_or_timeout(
-        lambda: unit.is_active('executing'), timeout=5,
+        lambda: unit.is_active("executing"), timeout=5,
     )
-    await unit.block_until(lambda: unit.is_active('idle'))
+    await unit.block_until(lambda: unit.is_active("idle"))
 
 
-@pytest.fixture(params=['on', 'only'])
+@pytest.fixture(params=["on", "only"])
 async def ssl(unit, request):
     """
     Enable SSL before a test, then disable after test
@@ -27,7 +28,7 @@ async def ssl(unit, request):
     :param Agent unit:              unit from the fixture
     :param request:                 test parameters
     """
-    async with config(unit, 'ssl', request.param, 'off') as value:
+    async with config(unit, "ssl", request.param, "off") as value:
         yield value
 
 
@@ -58,7 +59,7 @@ async def livestatus_path(unit):
     """
     async with config(unit, "enable_livestatus", "true", "false"):
         app_config = await unit.application.get_config()
-        yield app_config['livestatus_path']['value']
+        yield app_config["livestatus_path"]["value"]
 
 
 @pytest.fixture()
@@ -70,20 +71,24 @@ async def enable_pagerduty(unit):
     """
     async with config(unit, "enable_pagerduty", "true", "false"):
         app_config = await unit.application.get_config()
-        yield app_config['pagerduty_path']['value']
+        yield app_config["pagerduty_path"]["value"]
+
 
 @pytest.fixture
 async def set_extra_contacts(unit):
     """Set extra contacts."""
     name = "contact_name_1"
-    extra_contacts = '''
+    extra_contacts = """
     - name: {}
       host: /custom/command/for/host $HOSTNAME$
       service: /custom/command/for/service $SERVICENAME$
-    '''.format(name)
+    """.format(
+        name
+    )
     async with config(unit, "extra_contacts", extra_contacts, ""):
         yield name
 
+
 @pytest.fixture
 async def set_multiple_admins(unit):
     admins = "admin1@localhost,admin2@localhost"
@@ -96,7 +101,7 @@ async def set_multiple_admins(unit):
 #########
 async def test_web_interface_with_ssl(auth, unit, ssl):
     http_url = "http://%s/nagios3/"; % unit.u.public_address
-    if ssl == 'only':
+    if ssl == "only":
         with pytest.raises(requests.ConnectionError):
             requests.get(http_url, auth=auth)
     else:
@@ -108,57 +113,63 @@ async def test_web_interface_with_ssl(auth, unit, ssl):
     assert r.status_code == 200, "HTTPs Admin login failed"
 
 
-@pytest.mark.usefixtures('extra_config')
+@pytest.mark.usefixtures("extra_config")
 async def test_extra_config(auth, unit):
-    host_url = "http://%s/cgi-bin/nagios3/status.cgi?"; \
-              "hostgroup=all&style=hostdetail" % unit.u.public_address
+    host_url = (
+        "http://%s/cgi-bin/nagios3/status.cgi?";
+        "hostgroup=all&style=hostdetail" % unit.u.public_address
+    )
     r = requests.get(host_url, auth=auth)
-    assert 'extra_config' in r.text, "Nagios is not monitoring extra_config"
+    assert "extra_config" in r.text, "Nagios is not monitoring extra_config"
 
 
 async def test_live_status(unit, livestatus_path, file_stat):
     stat = await file_stat(livestatus_path, unit.u)
-    assert stat['size'] == 0, (
-        "File %s didn't match expected size" % livestatus_path
-    )
+    assert stat["size"] == 0, "File %s didn't match expected size" % livestatus_path
 
 
 async def test_pager_duty(unit, enable_pagerduty, file_stat):
     stat = await file_stat(enable_pagerduty, unit.u)
-    assert stat['size'] != 0, (
-        "Directory %s wasn't a non-zero size" % enable_pagerduty
-    )
-    stat = await file_stat('/etc/nagios3/conf.d/pagerduty_nagios.cfg', unit.u)
-    assert stat['size'] != 0, "pagerduty_config wasn't a non-zero sized file"
+    assert stat["size"] != 0, "Directory %s wasn't a non-zero size" % enable_pagerduty
+    stat = await file_stat("/etc/nagios3/conf.d/pagerduty_nagios.cfg", unit.u)
+    assert stat["size"] != 0, "pagerduty_config wasn't a non-zero sized file"
 
 
 async def test_extra_contacts(auth, unit, set_extra_contacts):
-    contancts_url = "http://%s/cgi-bin/nagios3/config.cgi?"; \
-                    "type=contacts" % unit.u.public_address
+    contancts_url = (
+        "http://%s/cgi-bin/nagios3/config.cgi?"; "type=contacts" % unit.u.public_address
+    )
     contact_name = set_extra_contacts
     r = requests.get(contancts_url, auth=auth)
     assert r.status_code == 200, "Get Nagios config request failed"
     assert contact_name in r.text, "Nagios is not loading the extra contact."
-    assert contact_name.capitalize() in r.text, "Contact name alias is not " \
-                                                "the capitalized name."
-    contactgroups_url = "http://%s/cgi-bin/nagios3/config.cgi"; \
-                        "?type=contactgroups" % unit.u.public_address
+    assert contact_name.capitalize() in r.text, (
+        "Contact name alias is not " "the capitalized name."
+    )
+    contactgroups_url = (
+        "http://%s/cgi-bin/nagios3/config.cgi";
+        "?type=contactgroups" % unit.u.public_address
+    )
 
     r = requests.get(contactgroups_url, auth=auth)
     assert r.status_code == 200, "Get Nagios config request failed"
-    assert contact_name in r.text, "Extra contact is not " \
-                                   "added to the contact groups."
+    assert contact_name in r.text, (
+        "Extra contact is not " "added to the contact groups."
+    )
+
 
 async def test_multiple_admin_contacts(auth, unit, set_multiple_admins):
-    contancts_url = "http://%s/cgi-bin/nagios3/config.cgi?"; \
-                    "type=contacts" % unit.u.public_address
+    contancts_url = (
+        "http://%s/cgi-bin/nagios3/config.cgi?"; "type=contacts" % unit.u.public_address
+    )
     admins = set_multiple_admins
     r = requests.get(contancts_url, auth=auth)
     assert r.status_code == 200, "Get Nagios config request failed"
-    admins = admins.split(',')
+    admins = admins.split(",")
     for admin in admins:
-        admin = admin.replace('@', '').replace('.', '').lower()
+        admin = admin.replace("@", "").replace(".", "").lower()
         admin_alias = admin.capitalize()
         assert admin in r.text, "Nagios is not loading contact {}.".format(admin)
-        assert admin_alias in r.text, "Nagios is not loading alias " \
-                                      "for contact {}.".format(admin)
+        assert (
+            admin_alias in r.text
+        ), "Nagios is not loading alias " "for contact {}.".format(admin)
diff --git a/tests/functional/test_deploy.py b/tests/functional/test_deploy.py
index b8e9f40..e4131d6 100644
--- a/tests/functional/test_deploy.py
+++ b/tests/functional/test_deploy.py
@@ -1,5 +1,6 @@
 import pytest
 import requests
+
 pytestmark = pytest.mark.asyncio
 
 
@@ -22,17 +23,15 @@ async def test_web_interface_is_protected(auth, unit):
 
 
 async def test_hosts_being_monitored(auth, unit):
-    host_url = ("http://%s/cgi-bin/nagios3/status.cgi?";
-                "hostgroup=all&style=hostdetail") % unit.u.public_address
+    host_url = (
+        "http://%s/cgi-bin/nagios3/status.cgi?"; "hostgroup=all&style=hostdetail"
+    ) % unit.u.public_address
     r = requests.get(host_url, auth=auth)
-    assert 'mysql' in r.text, "Nagios is not monitoring the hosts it supposed to."
+    assert "mysql" in r.text, "Nagios is not monitoring the hosts it supposed to."
 
 
 async def test_nrpe_monitors_config(relatives, unit, file_contents):
     # look for disk root check in nrpe config
-    mysql_unit = relatives['mysql']['app'].units[0]
-    contents = await file_contents(
-            '/etc/nagios/nrpe.d/check_disk_root.cfg',
-            mysql_unit
-        )
+    mysql_unit = relatives["mysql"]["app"].units[0]
+    contents = await file_contents("/etc/nagios/nrpe.d/check_disk_root.cfg", mysql_unit)
     assert contents, "disk root check config not found."
diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
index f6fceac..0c6a597 100644
--- a/tests/unit/conftest.py
+++ b/tests/unit/conftest.py
@@ -1,5 +1,5 @@
 import os
 import sys
 
-HOOKS = os.path.join(os.path.dirname(__file__), '..', '..', 'hooks')
+HOOKS = os.path.join(os.path.dirname(__file__), "..", "..", "hooks")
 sys.path.append(HOOKS)
diff --git a/tests/unit/test_monitor_relation_changed.py b/tests/unit/test_monitor_relation_changed.py
index 3a7f5d6..f2f0e1d 100644
--- a/tests/unit/test_monitor_relation_changed.py
+++ b/tests/unit/test_monitor_relation_changed.py
@@ -4,4 +4,4 @@ import monitors_relation_changed
 def test_has_main():
     # THIS IS A REALLY LAME TEST -- but it's a start for where there was nothing
     # if you add tests later, please do better than me
-    assert hasattr(monitors_relation_changed, 'main')
+    assert hasattr(monitors_relation_changed, "main")
diff --git a/tests/unit/test_website_relation_joined.py b/tests/unit/test_website_relation_joined.py
index 3164428..b4ca91a 100644
--- a/tests/unit/test_website_relation_joined.py
+++ b/tests/unit/test_website_relation_joined.py
@@ -4,16 +4,16 @@ import pytest
 import website_relation_joined
 
 
-@mock.patch('common.get_local_ingress_address')
-@mock.patch('website_relation_joined.config')
-@mock.patch('website_relation_joined.relation_set')
-@pytest.mark.parametrize('ssl', [
-    ('only', 443),
-    ('on', 80),
-    ('off', 80)
-], ids=['ssl=only', 'ssl=on', 'ssl=off'])
+@mock.patch("common.get_local_ingress_address")
+@mock.patch("website_relation_joined.config")
+@mock.patch("website_relation_joined.relation_set")
+@pytest.mark.parametrize(
+    "ssl",
+    [("only", 443), ("on", 80), ("off", 80)],
+    ids=["ssl=only", "ssl=on", "ssl=off"],
+)
 def test_main(relation_set, config, get_local_ingress_address, ssl):
-    get_local_ingress_address.return_value = 'example.com'
-    config.return_value = {'ssl': ssl[0]}
+    get_local_ingress_address.return_value = "example.com"
+    config.return_value = {"ssl": ssl[0]}
     website_relation_joined.main()
-    relation_set.assert_called_with(None, port=ssl[1], hostname='example.com')
+    relation_set.assert_called_with(None, port=ssl[1], hostname="example.com")
diff --git a/tox.ini b/tox.ini
index a98700a..8f1b11b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -25,7 +25,7 @@ passenv =
 [testenv:lint]
 commands =
     flake8
-# TODO    black --check --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod|bin)/" .
+    black --check --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod|bin)/" .
 deps =
     black
     flake8
@@ -59,6 +59,7 @@ ignore =  # TODO remove most of these
     I100,
     I101,
     I201,
+    I202,
     E201,
     E202,
     E231,
@@ -70,6 +71,7 @@ ignore =  # TODO remove most of these
     E501,
     N806,
     N816,
+    W503,
     W504
 
 

Follow ups