Files
puppetboard/puppetboard/dailychart.py
2017-02-03 12:13:33 +01:00

82 lines
2.9 KiB
Python

from datetime import datetime, timedelta
from pypuppetdb.utils import UTC
from pypuppetdb.QueryBuilder import (
ExtractOperator, FunctionOperator, AndOperator,
GreaterEqualOperator, LessOperator, EqualsOperator,
)
DATE_FORMAT = "%Y-%m-%d"
DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
def _iter_dates(days_number, reverse=False):
"""Return a list of datetime pairs AB, BC, CD, ... that represent the
24hs time ranges of today (until this midnight) and the
previous days.
"""
one_day = timedelta(days=1)
today = datetime.utcnow().replace(hour=0, minute=0, second=0,
microsecond=0, tzinfo=UTC())
days_list = list(today + one_day * (1 - i) for i in range(days_number + 1))
if reverse:
days_list.reverse()
return zip(days_list, days_list[1:])
return zip(days_list[1:], days_list)
def _build_query(env, start, end, certname=None):
"""Build a extract query with optional certname and environment."""
query = ExtractOperator()
query.add_field(FunctionOperator('count'))
query.add_field('status')
subquery = AndOperator()
subquery.add(GreaterEqualOperator('start_time', start))
subquery.add(LessOperator('start_time', end))
if certname is not None:
subquery.add(EqualsOperator('certname', certname))
if env != '*':
subquery.add(EqualsOperator('environment', env))
query.add_query(subquery)
query.add_group_by("status")
return query
def _format_report_data(day, query_output):
"""Format the output of the query to a simpler dict."""
result = {'day': day, 'changed': 0, 'unchanged': 0, 'failed': 0}
for out in query_output:
if out['status'] == 'changed':
result['changed'] = out['count']
elif out['status'] == 'unchanged':
result['unchanged'] = out['count']
elif out['status'] == 'failed':
result['failed'] = out['count']
return result
def get_daily_reports_chart(db, env, days_number, certname=None):
"""Return the sum of each report status (changed, unchanged, failed)
per day, for today and the previous N days.
This information is used to present a chart.
:param db: The puppetdb.
:param env: Sum up the reports in this environment.
:param days_number: How many days to sum, including today.
:param certname: If certname is passed, only the reports of that
certname will be added. If certname is not passed, all reports in
the database will be considered.
"""
result = []
for start, end in _iter_dates(days_number, reverse=True):
query = _build_query(
env=env,
start=start.strftime(DATETIME_FORMAT),
end=end.strftime(DATETIME_FORMAT),
certname=certname,
)
day = start.strftime(DATE_FORMAT)
output = db._query('reports', query=query)
result.append(_format_report_data(day, output))
return result