nagios-charmers team mailing list archive
-
nagios-charmers team
-
Mailing list archive
-
Message #01113
[Merge] ~xavpaice/charm-nagios:lint-20.08 into charm-nagios:master
Xav Paice has proposed merging ~xavpaice/charm-nagios:lint-20.08 into charm-nagios:master with ~xavpaice/charm-nagios:blacken-20.08 as a prerequisite.
Commit message:
Extra Linting completed for 20.08 charm release
Requested reviews:
Nagios Charm developers (nagios-charmers)
For more details, see:
https://code.launchpad.net/~xavpaice/charm-nagios/+git/nagios-charm/+merge/388634
--
Your team Nagios Charm developers is requested to review the proposed merge of ~xavpaice/charm-nagios:lint-20.08 into charm-nagios:master.
diff --git a/hooks/common.py b/hooks/common.py
index 3bff942..b320880 100644
--- a/hooks/common.py
+++ b/hooks/common.py
@@ -1,17 +1,17 @@
-import subprocess
-import socket
import os
import os.path
import re
import shutil
+import socket
+import subprocess
import tempfile
from charmhelpers.core.hookenv import (
+ config,
log,
network_get,
network_get_primary_address,
unit_get,
- config,
)
from pynag import Model
@@ -28,16 +28,18 @@ 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):
try:
socket.inet_pton(socket.AF_INET, n)
+
return True
except socket.error:
try:
socket.inet_pton(socket.AF_INET6, n)
+
return True
except socket.error:
return False
@@ -48,10 +50,12 @@ def get_local_ingress_address(binding="website"):
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]
log(hostname)
+
return hostname
except NotImplementedError:
# We'll fallthrough to the Pre 2.3 code below.
@@ -66,29 +70,36 @@ def get_local_ingress_address(binding="website"):
hostname = unit_get("private-address")
log("Using unit_get private address")
log(hostname)
+
return hostname
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])
+
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)
+
if hostname is None or not len(hostname):
hostname = get_remote_relation_attr(remote_unit, "private-address", relation_id)
if hostname is None or not len(hostname):
log("relation-get failed")
+
return 2
+
if check_ip(hostname):
# Some providers don't provide hostnames, so use the remote unit name.
ip_address = hostname
else:
ip_address = socket.getaddrinfo(hostname, None)[0][4][0]
+
return (ip_address, remote_unit.replace("/", "-"))
@@ -98,11 +109,13 @@ def refresh_hostgroups(): # noqa:C901
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)
except ValueError:
continue
+
if service in hgroups:
hgroups[service].append(host)
else:
@@ -114,6 +127,7 @@ def refresh_hostgroups(): # noqa:C901
# Delete the ones not in hgroups
to_delete = set(auto_hgroups).difference(set(hgroups.keys()))
+
for hgroup_name in to_delete:
try:
hgroup = Model.Hostgroup.objects.get_by_shortname(hgroup_name)
@@ -138,7 +152,7 @@ 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)
@@ -147,6 +161,7 @@ def _make_check_command(args):
cmd.set_attribute("command_name", signature)
cmd.set_attribute("command_line", " ".join(args))
cmd.save()
+
return signature
@@ -163,19 +178,23 @@ def customize_http(service, name, extra):
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$"))
else:
cmd_args.extend(("-H", "$HOSTADDRESS$"))
check_timeout = config("check_timeout")
+
if check_timeout is not None:
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)
+
return True
@@ -183,16 +202,20 @@ def customize_mysql(service, name, extra):
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")
+
if check_timeout is not None:
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)
+
return True
@@ -201,11 +224,13 @@ def customize_pgsql(service, name, extra):
args = []
cmd_args = [plugin, "-H", "$HOSTADDRESS$"]
check_timeout = config("check_timeout")
+
if check_timeout is not None:
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)
+
return True
@@ -213,6 +238,7 @@ def customize_nrpe(service, name, extra):
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:
@@ -220,61 +246,77 @@ def customize_nrpe(service, name, extra):
else:
cmd_args.extend(("-c", extra))
check_timeout = config("check_timeout")
+
if check_timeout is not None:
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)
+
return True
def customize_rpc(service, name, extra):
- """ Customize the check_rpc plugin to check things like nfs."""
+ """Customize the check_rpc plugin to check things like nfs."""
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"]))
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)
+
return True
def customize_tcp(service, name, extra):
- """ Customize tcp can be used to check things like memcached. """
+ """Customize tcp can be used to check things like memcached."""
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")
+
if check_timeout is not None:
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)
+
return True
def customize_service(service, family, name, extra):
- """ The monitors.yaml names are mapped to methods that customize services. """
+ """Map names to service methods.
+
+ The monitors.yaml names are mapped to methods that customize services.
+ """
customs = {
"http": customize_http,
"mysql": customize_mysql,
@@ -283,17 +325,19 @@ def customize_service(service, family, name, extra):
"rpc": customize_rpc,
"pgsql": customize_pgsql,
}
+
if family in customs:
return customs[family](service, name, extra)
+
return False
def update_localhost():
- """ Update the localhost definition to use the ubuntu icons."""
-
+ """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")
+
for host in hosts:
host.icon_image = "base/ubuntu.png"
host.icon_image_alt = "Ubuntu Linux"
@@ -318,6 +362,7 @@ def get_pynag_host(target_id, owner_unit=None, owner_relation=None):
host.save()
host = Model.Host.objects.get_by_shortname(target_id)
apply_host_policy(target_id, owner_unit, owner_relation)
+
return host
@@ -325,6 +370,7 @@ def get_pynag_service(target_id, 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)
@@ -333,6 +379,7 @@ def get_pynag_service(target_id, service_name):
service.set_attribute("use", "generic-service")
else:
service = services[0]
+
return service
@@ -369,6 +416,7 @@ def initialize_inprogress_config():
shutil.rmtree(INPROGRESS_DIR)
shutil.copytree(MAIN_NAGIOS_DIR, INPROGRESS_DIR)
_replace_in_config(MAIN_NAGIOS_DIR, INPROGRESS_DIR)
+
if os.path.exists(CHARM_CFG):
os.unlink(CHARM_CFG)
@@ -376,10 +424,13 @@ def initialize_inprogress_config():
def flush_inprogress_config():
if not os.path.exists(INPROGRESS_DIR):
return
+
if os.path.exists(MAIN_NAGIOS_BAK):
shutil.rmtree(MAIN_NAGIOS_BAK)
+
if os.path.exists(MAIN_NAGIOS_DIR):
shutil.move(MAIN_NAGIOS_DIR, MAIN_NAGIOS_BAK)
shutil.move(INPROGRESS_DIR, MAIN_NAGIOS_DIR)
- # now that directory has been changed need to update the config file to reflect the real stuff..
+ # now that directory has been changed need to update the config file to
+ # reflect the real stuff..
_commit_in_config(INPROGRESS_DIR, MAIN_NAGIOS_DIR)
diff --git a/hooks/monitors_relation_changed.py b/hooks/monitors_relation_changed.py
index e3d5a5a..6df3303 100755
--- a/hooks/monitors_relation_changed.py
+++ b/hooks/monitors_relation_changed.py
@@ -16,36 +16,32 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import sys
import os
-import yaml
import re
+import sys
from collections import defaultdict
from charmhelpers.core.hookenv import (
- relation_get,
+ DEBUG,
ingress_address,
+ log,
related_units,
+ relation_get,
relation_ids,
- log,
- DEBUG,
)
from common import (
customize_service,
+ flush_inprogress_config,
get_pynag_host,
get_pynag_service,
- refresh_hostgroups,
initialize_inprogress_config,
- flush_inprogress_config,
+ refresh_hostgroups,
)
+import yaml
-REQUIRED_REL_DATA_KEYS = [
- "target-address",
- "monitors",
- "target-id",
-]
+REQUIRED_REL_DATA_KEYS = ["target-address", "monitors", "target-id"]
def _prepare_relation_data(unit, rid):
@@ -56,6 +52,7 @@ def _prepare_relation_data(unit, rid):
unit, rid
)
log(msg, level=DEBUG)
+
return {}
if rid.split(":")[0] == "nagios":
@@ -76,6 +73,7 @@ def _prepare_relation_data(unit, rid):
key, unit, rid
)
log(msg, level=DEBUG)
+
return {}
return relation_data
@@ -83,10 +81,12 @@ def _prepare_relation_data(unit, rid):
def _collect_relation_data():
all_relations = defaultdict(dict)
+
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)
+
if relation_data:
all_relations[relid][unit] = relation_data
@@ -98,8 +98,10 @@ def main(argv): # noqa: C901
# and target-address' so the hook can be tested without being in a hook
# context.
#
+
if len(argv) > 1:
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}}
@@ -108,11 +110,13 @@ def main(argv): # noqa: C901
# Hack to work around http://pad.lv/1025478
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"])
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:
@@ -124,11 +128,14 @@ def main(argv): # noqa: C901
initialize_inprogress_config()
# make a dict of machine ids to target-id hostnames
all_hosts = {}
+
for relid, units in all_relations.items():
for unit, relation_settings in units.iteritems():
machine_id = relation_settings.get("machine_id", None)
+
if machine_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()
@@ -142,10 +149,13 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901
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+")
+
if container_regex.search(machine_id):
parent_machine = container_regex.search(machine_id).group(1)
+
if parent_machine in all_hosts:
parent_host = all_hosts[parent_machine]
@@ -159,9 +169,11 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901
# Output nagios config
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)
+
if parent_host:
# We assume that we only want one parent and will overwrite any
# existing parents for this host.
@@ -172,6 +184,7 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901
for mon_name, mon in mons.iteritems():
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:
diff --git a/hooks/upgrade_charm.py b/hooks/upgrade_charm.py
index 5091f9a..ca410ef 100755
--- a/hooks/upgrade_charm.py
+++ b/hooks/upgrade_charm.py
@@ -3,25 +3,26 @@
# Rewritten from bash to python 3/2/2014 for charm helper inclusion
# of SSL-Everywhere!
import base64
-from jinja2 import Template
+import errno
import glob
+import grp
import os
-
-# import re
import pwd
-import grp
-import string
-import stat
-import errno
import shutil
+import stat
+import string
import subprocess
-import yaml
+
+from charmhelpers import fetch
from charmhelpers.contrib import ssl
from charmhelpers.core import hookenv, host
-from charmhelpers import fetch
from common import update_localhost
+from jinja2 import Template
+
+import yaml
+
# Gather facts
legacy_relations = hookenv.config("legacy")
extra_config = hookenv.config("extraconfig")
@@ -55,7 +56,7 @@ SSL_CONFIGURED = ssl_config in ["on", "only", "true"]
def warn_legacy_relations():
- """Checks the charm relations for legacy relations.
+ """Check the charm relations for legacy relations.
Inserts warnings into the log about legacy relations, as they will be removed
in the future
@@ -70,7 +71,7 @@ def warn_legacy_relations():
def parse_extra_contacts(yaml_string):
- """Parses a list of extra Nagios contacts from a YAML string.
+ """Parse a list of extra Nagios contacts from a YAML string.
Does basic sanitization only
"""
@@ -82,6 +83,7 @@ def parse_extra_contacts(yaml_string):
try:
extra_contacts_raw = yaml.load(yaml_string, Loader=yaml.SafeLoader) or []
+
if not isinstance(extra_contacts_raw, list):
raise ValueError("not a list")
@@ -90,6 +92,7 @@ def parse_extra_contacts(yaml_string):
hookenv.log(
"Contact {} is missing fields.".format(contact), hookenv.WARNING
)
+
continue
if set(contact["name"]) > set(valid_name_chars):
@@ -97,10 +100,12 @@ def parse_extra_contacts(yaml_string):
"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)
+
continue
contact["name"] = contact["name"].lower()
@@ -111,6 +116,7 @@ def parse_extra_contacts(yaml_string):
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, "
@@ -125,10 +131,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 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)
@@ -150,6 +158,7 @@ def fixpath(path):
if os.path.isdir(path):
st = os.stat(path)
os.chmod(path, st.st_mode | stat.S_IXOTH)
+
if path != "/":
fixpath(os.path.split(path)[0])
@@ -163,6 +172,7 @@ def enable_livestatus_config():
# Make the directory and fix perms on it
hookenv.log("Fixing perms on livestatus_path")
livestatus_dir = os.path.dirname(livestatus_path)
+
if not os.path.isdir(livestatus_dir):
hookenv.log("Making path for livestatus_dir")
mkdir_p(livestatus_dir)
@@ -202,16 +212,16 @@ def enable_pagerduty_config():
}
with open("hooks/templates/pagerduty_nagios_cfg.tmpl", "r") as f:
- templateDef = f.read()
+ template_def = f.read()
- t = Template(templateDef)
+ t = Template(template_def)
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:
- templateDef = f2.read()
+ template_def = f2.read()
- t2 = Template(templateDef)
+ t2 = Template(template_def)
with open(pagerduty_cron, "w") as f2:
f2.write(t2.render(template_values))
@@ -219,6 +229,7 @@ def enable_pagerduty_config():
shutil.copy("files/pagerduty_nagios.pl", "/usr/local/bin/pagerduty_nagios.pl")
# Create the pagerduty queue dir
+
if not os.path.isdir(pagerduty_path):
hookenv.log("Making path for pagerduty_path")
mkdir_p(pagerduty_path)
@@ -228,14 +239,18 @@ def enable_pagerduty_config():
os.chown(pagerduty_path, uid, gid)
else:
# Clean up the files if we don't want pagerduty
+
if os.path.isfile(pagerduty_cfg):
os.remove(pagerduty_cfg)
+
if os.path.isfile(pagerduty_cron):
os.remove(pagerduty_cron)
# Update contacts for admin
+
if enable_pagerduty:
# avoid duplicates
+
if "pagerduty" not in contactgroup_members:
forced_contactgroup_members.append("pagerduty")
@@ -249,6 +264,7 @@ def enable_traps_config():
if os.path.isfile(traps_cfg):
os.remove(traps_cfg)
hookenv.log("Send traps feature is disabled")
+
return
hookenv.log("Send traps feature is enabled, target address is %s" % send_traps_to)
@@ -259,9 +275,9 @@ def enable_traps_config():
template_values = {"send_traps_to": send_traps_to}
with open("hooks/templates/traps.tmpl", "r") as f:
- templateDef = f.read()
+ template_def = f.read()
- t = Template(templateDef)
+ t = Template(template_def)
with open(traps_cfg, "w") as f:
f.write(t.render(template_values))
@@ -271,17 +287,20 @@ def update_contacts():
admin_members = ""
contacts = []
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")
exit(1)
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]}]
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_alias = contact_name.capitalize()
@@ -292,6 +311,7 @@ def update_contacts():
admin_members = ", ".join([c["contact_name"] for c in contacts])
resulting_members = contactgroup_members
+
if admin_members:
# if multiple admin emails are passed ignore contactgroup_members
resulting_members = admin_members
@@ -338,8 +358,10 @@ def update_contacts():
def ssl_configured():
allowed_options = ["on", "only"]
+
if str(ssl_config).lower() in allowed_options:
return True
+
return False
@@ -359,8 +381,10 @@ chain_file = "/etc/ssl/certs/%s.csr" % (cert_domain)
def check_ssl_files():
key = os.path.exists(deploy_key_path)
cert = os.path.exists(deploy_cert_path)
+
if key is False or cert is False:
return False
+
return True
@@ -370,9 +394,11 @@ def decode_ssl_keys():
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"))))
@@ -382,10 +408,13 @@ 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"):
# bail if keys already exist
+
if os.path.exists(cert_file):
hookenv.log("Keys exist, not creating keys!", "WARNING")
+
return
# Generate a self signed key using CharmHelpers
hookenv.log("Generating Self Signed Certificate", "INFO")
@@ -405,6 +434,7 @@ def update_config():
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:
@@ -437,16 +467,16 @@ def update_config():
}
with open("hooks/templates/nagios-cfg.tmpl", "r") as f:
- templateDef = f.read()
+ template_def = f.read()
- t = Template(templateDef)
+ t = Template(template_def)
with open(nagios_cfg, "w") as f:
f.write(t.render(template_values))
with open("hooks/templates/localhost_nagios2.cfg.tmpl", "r") as f:
- templateDef = f.read()
+ template_def = f.read()
- t = Template(templateDef)
+ t = Template(template_def)
with open("/etc/nagios3/conf.d/localhost_nagios2.cfg", "w") as f:
f.write(t.render(template_values))
@@ -456,9 +486,9 @@ def update_config():
def update_cgi_config():
template_values = {"nagiosadmin": nagiosadmin, "ro_password": ro_password}
with open("hooks/templates/nagios-cgi.tmpl", "r") as f:
- templateDef = f.read()
+ template_def = f.read()
- t = Template(templateDef)
+ t = Template(template_def)
with open(nagios_cgi_cfg, "w") as f:
f.write(t.render(template_values))
@@ -472,12 +502,12 @@ def update_cgi_config():
# note: i tried to use cheetah, and it barfed, several times. It can go play
# in a fire. I'm jusing jinja2.
def update_apache():
- """
+ """Add SSL keys to default-ssl config.
+
Nagios3 is deployed as a global apache application from the archive.
We'll get a little funky and add the SSL keys to the default-ssl config
which sets our keys, including the self-signed ones, as the host keyfiles.
"""
-
# Start by Setting the ports.conf
with open("hooks/templates/ports-cfg.jinja2", "r") as f:
@@ -489,6 +519,7 @@ def update_apache():
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:
@@ -515,6 +546,7 @@ def update_apache():
# Configure the behavior of http sites
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]
Apache2Site(site).action(enabled=HTTP_ENABLED)
@@ -549,6 +581,7 @@ class Apache2Site:
def _enable(self):
hookenv.log("Apache2Site: Enabling %s..." % self.site, "INFO")
self._call(["a2ensite", self.site])
+
if self.port == 443:
self._call(["a2enmod", "ssl"])
hookenv.open_port(self.port)
@@ -562,6 +595,7 @@ class Apache2Site:
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"])
+
if password:
with open(account_file, "w") as f:
f.write(password)
@@ -580,6 +614,7 @@ write_extra_config()
# enable_traps_config and enable_pagerduty_config modify forced_contactgroup_members
# they need to run before update_contacts that will consume that global var.
enable_traps_config()
+
if ssl_configured():
enable_ssl()
enable_pagerduty_config()
@@ -591,8 +626,10 @@ update_localhost()
update_cgi_config()
update_contacts()
update_password("nagiosro", ro_password)
+
if password:
update_password(nagiosadmin, password)
+
if nagiosadmin != "nagiosadmin":
update_password("nagiosadmin", False)
diff --git a/hooks/website_relation_joined.py b/hooks/website_relation_joined.py
index 706a561..126e7cd 100755
--- a/hooks/website_relation_joined.py
+++ b/hooks/website_relation_joined.py
@@ -15,18 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import common
+from charmhelpers.core.hookenv import config, log, relation_set
-from charmhelpers.core.hookenv import (
- config,
- log,
- relation_set,
-)
+import common
def main():
relation_data = {"hostname": common.get_local_ingress_address()}
sslcfg = config()["ssl"]
+
if sslcfg == "only":
relation_data["port"] = 443
else:
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index a31034c..7ab5b1a 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -42,9 +42,11 @@ async def model(controller):
model = await controller.add_model(model_name)
yield model
await model.disconnect()
+
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)
@@ -60,7 +62,7 @@ async def current_model():
@pytest.fixture
async def get_app(model):
- """Return the application requested."""
+ """Return the application requested.""" # noqa D202
async def _get_app(name):
try:
@@ -73,11 +75,12 @@ async def get_app(model):
@pytest.fixture
async def get_unit(model):
- """Return the requested <app_name>/<unit_number> unit."""
+ """Return the requested <app_name>/<unit_number> unit.""" # noqa D202
async def _get_unit(name):
try:
(app_name, unit_number) = name.split("/")
+
return model.applications[app_name].units[unit_number]
except (KeyError, ValueError):
raise JujuError("Cannot find unit {}".format(name))
@@ -87,7 +90,7 @@ async def get_unit(model):
@pytest.fixture
async def get_entity(model, get_unit, get_app):
- """Return a unit or an application."""
+ """Return a unit or an application.""" # noqa D202
async def _get_entity(name):
try:
@@ -103,7 +106,7 @@ async def get_entity(model, get_unit, get_app):
@pytest.fixture
async def run_command(get_unit):
- """Run a command on a unit."""
+ """Run a command on a unit.""" # noqa D202
async def _run_command(cmd, target):
"""
@@ -114,6 +117,7 @@ async def run_command(get_unit):
"""
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
@@ -121,16 +125,16 @@ async def run_command(get_unit):
@pytest.fixture
async def file_stat(run_command):
- """
- Run stat on a file.
+ """Run stat on a file.
:param path: File path
:param target: Unit object or unit name string
- """
+ """ # noqa D202
async def _file_stat(path, target):
cmd = STAT_FILE % path
results = await run_command(cmd, target)
+
return json.loads(results["Stdout"])
return _file_stat
@@ -138,16 +142,17 @@ async def file_stat(run_command):
@pytest.fixture
async def file_contents(run_command):
- """Return the contents of a file."""
+ """Return the contents of a file.""" # noqa D202
async def _file_contents(path, target):
"""Return the contents of a file.
- :param path: File path
- :param target: Unit object or unit name string
+ :param path: File path
+ :param target: Unit object or unit name string
"""
cmd = "cat {}".format(path)
results = await run_command(cmd, target)
+
return results["Stdout"]
return _file_contents
@@ -155,7 +160,7 @@ async def file_contents(run_command):
@pytest.fixture
async def reconfigure_app(get_app, model):
- """Apply a different config to the requested app."""
+ """Apply a different config to the requested app.""" # noqa D202
async def _reconfigure_app(cfg, target):
application = (
@@ -172,7 +177,7 @@ async def reconfigure_app(get_app, model):
@pytest.fixture
async def create_group(run_command):
- """Create the UNIX group specified."""
+ """Create the UNIX group specified.""" # noqa D202
async def _create_group(group_name, target):
cmd = "sudo groupadd %s" % group_name
@@ -185,11 +190,7 @@ pytestmark = pytest.mark.asyncio
CHARM_BUILD_DIR = os.getenv("CHARM_BUILD_DIR", "..").rstrip("/")
-SERIES = [
- "trusty",
- "xenial",
- "bionic",
-]
+SERIES = ["trusty", "xenial", "bionic"]
############
@@ -210,6 +211,7 @@ async def relatives(model, series):
)
mysql = "mysql"
+
if series != "trusty":
mysql = "percona-cluster"
@@ -224,7 +226,7 @@ async def relatives(model, series):
)
await model.block_until(
lambda: mysql_app.units[0].workload_status == "active"
- and mysql_app.units[0].agent_status == "idle"
+ and mysql_app.units[0].agent_status == "idle" # noqa W503
)
yield {
@@ -256,10 +258,11 @@ async def deploy_app(relatives, model, series):
)
await model.block_until(
lambda: nagios_app.units[0].agent_status == "idle"
- and relatives["mysql"]["app"].units[0].agent_status == "idle"
+ and relatives["mysql"]["app"].units[0].agent_status == "idle" # noqa W503
)
yield nagios_app
+
if os.getenv("PYTEST_KEEP_MODEL"):
return
@@ -277,6 +280,7 @@ class Agent:
def is_active(self, status):
u = self.u
+
return u.agent_status == status and u.workload_status == "active"
async def block_until_or_timeout(self, lambda_f, **kwargs):
@@ -299,6 +303,7 @@ 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"))
+
return unit
@@ -306,4 +311,5 @@ 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()
diff --git a/tests/functional/test_config.py b/tests/functional/test_config.py
index 1b9310a..6bc36a6 100644
--- a/tests/functional/test_config.py
+++ b/tests/functional/test_config.py
@@ -1,5 +1,7 @@
from async_generator import asynccontextmanager
+
import pytest
+
import requests
pytestmark = pytest.mark.asyncio
@@ -18,8 +20,7 @@ async def config(unit, item, test_value, post_test):
@pytest.fixture(params=["on", "only"])
async def ssl(unit, request):
- """
- Enable SSL before a test, then disable after test
+ """Enable SSL before a test, then disable after test.
:param Agent unit: unit from the fixture
:param request: test parameters
@@ -30,8 +31,7 @@ async def ssl(unit, request):
@pytest.fixture
async def extra_config(unit):
- """
- Enable extraconfig for a test, and revert afterwards
+ """Enable extraconfig for a test, and revert afterwards.
:param Agent unit: unit from the fixture
"""
@@ -48,8 +48,7 @@ async def extra_config(unit):
@pytest.fixture
async def livestatus_path(unit):
- """
- Enable livestatus before a test, then disable after test
+ """Enable livestatus before a test, then disable after test.
:param Agent unit: unit from the fixture
"""
@@ -60,8 +59,7 @@ async def livestatus_path(unit):
@pytest.fixture()
async def enable_pagerduty(unit):
- """
- Enable enable_pagerduty before first test, then disable after last test
+ """Enable enable_pagerduty before first test, then disable after last test.
:param Agent unit: unit from the fixture
"""
diff --git a/tests/functional/test_deploy.py b/tests/functional/test_deploy.py
index 32503c2..efbafb7 100644
--- a/tests/functional/test_deploy.py
+++ b/tests/functional/test_deploy.py
@@ -1,4 +1,5 @@
import pytest
+
import requests
pytestmark = pytest.mark.asyncio
diff --git a/tests/unit/test_website_relation_joined.py b/tests/unit/test_website_relation_joined.py
index b4ca91a..7dff088 100644
--- a/tests/unit/test_website_relation_joined.py
+++ b/tests/unit/test_website_relation_joined.py
@@ -1,6 +1,7 @@
import unittest.mock as mock
import pytest
+
import website_relation_joined
diff --git a/tox.ini b/tox.ini
index 8f1b11b..17cb36f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -48,33 +48,7 @@ ignore = # TODO remove most of these
D101,
D102,
D103,
- D104,
D107,
- D202,
- D205,
- D208,
- D210,
- D400,
- D401,
- I100,
- I101,
- I201,
- I202,
- E201,
- E202,
- E231,
- E121,
- E126,
- E131,
- D201,
- E302,
- E501,
- N806,
- N816,
- W503,
- W504
-
-
max-line-length = 88
max-complexity = 10
Follow ups