Fix: do not use charmhelpers in non-charm context

In change I60141397f39e3b1b0274230db8d984934c98a08d charmhelper
library is being used in the rabbitmq queue nrpe check. This is
problematic as the check does not actually run in a charm context and
therefore does not have access to the charm environment such as the
current config. Additionally an issue in collating check results had
been introduced.

This change aims to fix these issues. Instead of using the charmhelper
library, the cronspec is read out from the cron job definition
itself, and the series is probed from /etc/lsb-release

Change-Id: I952aeda31e997ccadb6cff62e3b0d46349650979
This commit is contained in:
Peter Sabaini 2020-12-05 17:27:25 +01:00
parent 3a473381e5
commit ab79c3ee6c
2 changed files with 42 additions and 15 deletions

View File

@ -12,13 +12,20 @@ import argparse
import os
import sys
from charmhelpers.core.hookenv import config
from charmhelpers.core.host import CompareHostReleases, get_distrib_codename
if CompareHostReleases(get_distrib_codename()) > 'trusty':
lsb_dict = {}
with open("/etc/lsb-release") as f:
lsb = [s.split("=") for s in f.readlines()]
lsb_dict = dict([(k, v.strip()) for k, v in lsb])
if lsb_dict.get("DISTRIB_CODENAME") != "trusty":
# Trusty doesn't have croniter
from croniter import croniter
CRONJOB = "/etc/cron.d/rabbitmq-stats"
def gen_data_lines(filename):
with open(filename, "rt") as fin:
for line in fin:
@ -85,6 +92,12 @@ def get_cron_interval(cronspec, base):
return it.get_next(datetime) - it.get_prev(datetime)
def get_stats_cron_schedule():
with open(CRONJOB) as f:
cronjob = f.read()
return cronjob.split("root")[0].strip()
def check_stats_file_freshness(stats_file, asof=None):
"""Check if a rabbitmq stats file is fresh
@ -97,7 +110,7 @@ def check_stats_file_freshness(stats_file, asof=None):
if asof is None:
asof = datetime.now()
file_mtime = datetime.fromtimestamp(os.path.getmtime(stats_file))
cronspec = config("stats_cron_schedule")
cronspec = get_stats_cron_schedule()
interval = get_cron_interval(cronspec, asof)
# We expect the file to be modified in the last 2 cron intervals
cutoff_time = asof - (2 * interval)
@ -147,7 +160,7 @@ if __name__ == "__main__":
if "croniter" in sys.modules.keys(): # not on trusty and imported croniter
freshness_results = [check_stats_file_freshness(f)
for f in args.stats_file]
criticals.append(
criticals.extend(
msg for status, msg in freshness_results if status == "CRIT"
)

View File

@ -13,18 +13,32 @@
# limitations under the License.
from datetime import datetime, timedelta
from tempfile import NamedTemporaryFile
from pathlib import Path
from tempfile import NamedTemporaryFile, TemporaryDirectory
import unittest
from mock import MagicMock, patch
import check_rabbitmq_queues
class CheckRabbitTest(unittest.TestCase):
@patch(
"check_rabbitmq_queues.config",
MagicMock(return_value="*/5 * * * *"),
)
@classmethod
def setUpClass(cls):
cls.tmpdir = TemporaryDirectory()
cronjob = Path(cls.tmpdir.name) / "rabbitmq-stats"
with cronjob.open('w') as f:
f.write("*/5 * * * * root timeout -k 10s -s SIGINT 300 "
"/usr/local/bin/collect_rabbitmq_stats.sh 2>&1 | "
"logger -p local0.notice")
cls.old_cron = check_rabbitmq_queues.CRONJOB
check_rabbitmq_queues.CRONJOB = str(cronjob)
@classmethod
def tearDownClass(cls):
"""Tear down class fixture."""
cls.tmpdir.cleanup()
check_rabbitmq_queues.CRONJOB = cls.old_cron
def test_check_stats_file_freshness_fresh(self):
with NamedTemporaryFile() as stats_file:
results = check_rabbitmq_queues.check_stats_file_freshness(
@ -32,10 +46,6 @@ class CheckRabbitTest(unittest.TestCase):
)
self.assertEqual(results[0], "OK")
@patch(
"check_rabbitmq_queues.config",
MagicMock(return_value="*/5 * * * *"),
)
def test_check_stats_file_freshness_nonfresh(self):
with NamedTemporaryFile() as stats_file:
next_hour = datetime.now() + timedelta(hours=1)
@ -43,3 +53,7 @@ class CheckRabbitTest(unittest.TestCase):
stats_file.name, asof=next_hour
)
self.assertEqual(results[0], "CRIT")
def test_get_stats_cron_schedule(self):
schedule = check_rabbitmq_queues.get_stats_cron_schedule()
self.assertEqual(schedule, "*/5 * * * *")