diff --git a/charmhelpers/contrib/charmsupport/nrpe.py b/charmhelpers/contrib/charmsupport/nrpe.py index a5185c236..f79a7e9bf 100644 --- a/charmhelpers/contrib/charmsupport/nrpe.py +++ b/charmhelpers/contrib/charmsupport/nrpe.py @@ -528,7 +528,7 @@ def enable_sudo_for_openvswitch_checks(): sudoers_dir = "/etc/sudoers.d" sudoers_mode = 0o100440 ovs_sudoers_file = "99-check_openvswitch" - ovs_sudoers_entry = "nagios ALL=(root) NOPASSWD: /usr/bin/ovs-vsctl show" + ovs_sudoers_entry = "nagios ALL=(root) NOPASSWD: /usr/bin/ovs-vsctl --format=json list Interface" dest = os.path.join(sudoers_dir, ovs_sudoers_file) try: with open(dest, "w") as sudoer_file: diff --git a/charmhelpers/contrib/openstack/files/check_openvswitch.py b/charmhelpers/contrib/openstack/files/check_openvswitch.py index b9c373d28..7b26a4896 100755 --- a/charmhelpers/contrib/openstack/files/check_openvswitch.py +++ b/charmhelpers/contrib/openstack/files/check_openvswitch.py @@ -1,19 +1,20 @@ #!/usr/bin/env python3 # -*- coding: us-ascii -*- -"""Check for issues with NVME hardware devices.""" +"""Check for OVS interface errors.""" import argparse -import re +import json import subprocess import sys +# dependence on nagios_plugin3 being installed by charm-nrpe from nagios_plugin3 import CriticalError, UnknownError, try_check def parse_ovs_status(): """Check for errors in 'ovs-vsctl show' output.""" try: - cmd = ["/usr/bin/sudo", "/usr/bin/ovs-vsctl", "show"] + cmd = ["/usr/bin/sudo", "/usr/bin/ovs-vsctl", "--format=json", "list", "Interface"] ovs_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: raise UnknownError( @@ -21,19 +22,23 @@ def parse_ovs_status(): e.output.decode(errors="ignore").rstrip() ) ) + ovs_interfaces = json.loads(ovs_output.decode(errors="ignore")) + ovs_interface_errors = [] + for i in ovs_interfaces["data"]: + # OVSDB internal data is formatted per RFC 7047 5.1 + iface = dict(zip(ovs_interfaces["headings"], i)) + error = iface["error"] + if isinstance(error, list) and len(error) == 2 and error[0] == "set": + # deserialize the set data into csv string elements + error = ",".join(error[1]) + if error: + ovs_interface_errors.append("Error on iface {}: {}".format(iface["name"], error)) - ovs_vsctl_show_errors = [] - ovs_error_re = re.compile(r"^.*error: (?P.+)$", re.I) - for line in ovs_output.decode(errors="ignore").splitlines(): - m = ovs_error_re.match(line) - if m: - ovs_vsctl_show_errors.append(m.group("message")) - - if ovs_vsctl_show_errors: - numerrs = len(ovs_vsctl_show_errors) + if ovs_interface_errors: + numerrs = len(ovs_interface_errors) raise CriticalError( - "CRITICAL: Found {} error(s) in ovs-vsctl show: " - "{}".format(numerrs, ", ".join(ovs_vsctl_show_errors)) + "CRITICAL: Found {} error(s) in OVSDB: " + "{}".format(numerrs, ", ".join(ovs_interface_errors)) ) print("OK: no errors found in openvswitch")