diff --git a/reports/nova_usage_audit.py b/reports/nova_usage_audit.py index b4ed71c..a690e13 100644 --- a/reports/nova_usage_audit.py +++ b/reports/nova_usage_audit.py @@ -190,14 +190,18 @@ def _launch_audit_for_period(beginning, ending): return launch_to_exists_fails, new_launches.count(), len(old_launches_dict) -def audit_for_period(beginning, ending): +def audit_for_period(beginning, ending, ums=False): beginning_decimal = dt.dt_to_decimal(beginning) ending_decimal = dt.dt_to_decimal(ending) + if ums: + verifier_audit_func = usage_audit._verifier_audit_for_day_ums + else: + verifier_audit_func = usage_audit._verifier_audit_for_day + (verify_summary, - verify_detail) = usage_audit._verifier_audit_for_day(beginning_decimal, - ending_decimal, - models.InstanceExists) + verify_detail) = verifier_audit_func(beginning_decimal, ending_decimal, + models.InstanceExists) detail, new_count, old_count = _launch_audit_for_period(beginning_decimal, ending_decimal) @@ -218,14 +222,14 @@ def audit_for_period(beginning, ending): return summary, details -def store_results(start, end, summary, details): +def store_results(start, end, summary, details, ums=False): values = { 'json': make_json_report(summary, details), 'created': dt.dt_to_decimal(datetime.datetime.utcnow()), 'period_start': start, 'period_end': end, 'version': 6, - 'name': 'nova usage audit' + 'name': 'nova usage audit' if not ums else 'nova usage audit ums' } report = models.JsonReport(**values) @@ -267,8 +271,15 @@ if __name__ == '__main__': help="Location of the reconciler config file", type=str, default='/etc/stacktach/reconciler-config.json') + parser.add_argument('--ums', + help="Use query to match UMS", + action='store_true') args = parser.parse_args() + if args.ums and args.period_length != 'day': + print "UMS query can only be used with period_length of 'day'." + sys.exit(0) + stacklog.set_default_logger_name('nova_usage_audit') parent_logger = stacklog.get_logger('nova_usage_audit', is_parent=True) log_listener = stacklog.LogListener(parent_logger) @@ -286,9 +297,9 @@ if __name__ == '__main__': start, end = usage_audit.get_previous_period(time, args.period_length) - summary, details = audit_for_period(start, end) + summary, details = audit_for_period(start, end, ums=args.ums) if not args.store: print make_json_report(summary, details) else: - store_results(start, end, summary, details) + store_results(start, end, summary, details, ums=args.ums) diff --git a/reports/usage_audit.py b/reports/usage_audit.py index 4d62ac4..94f9921 100644 --- a/reports/usage_audit.py +++ b/reports/usage_audit.py @@ -1,5 +1,6 @@ import datetime from django.db.models import F +from django.db.models import Q from stacktach import models @@ -101,6 +102,39 @@ def _verifier_audit_for_day(beginning, ending, exists_model): detail.append(['Exist', exist.id, exist.fail_reason]) return summary, detail + +def _verifier_audit_for_day_ums(beginning, ending, exists_model): + summary = {} + + # NOTE(apmelton): + # This is the UMS query we're trying to match. + # where ( + # (created_date between sysdate-1||'12.00.00.000000000 AM' and + # sysdate-1||'04.00.00.000000000 AM' and + # audit_period_begin_timestamp >= sysdate-1||'12.00.00.000000000 AM') + # OR (created_date > sysdate-1||'04.00.00.000000000 AM' and + # audit_period_begin_timestamp < sysdate||'12.00.00.000000000 AM' )) + ums = (Q(raw__when__gte=beginning, raw__when__lte=beginning + (4*60*60), + audit_period_beginning__gte=beginning) | + Q(raw__when__gt=beginning + (4*60*60), + audit_period_beginning__lt=ending)) + + periodic_range = Q(audit_period_ending=(F('audit_period_beginning') + + (60*60*24))) + periodic_exists = exists_model.objects.filter(ums & periodic_range) + summary['periodic'] = _audit_for_exists(periodic_exists) + + instant_range = Q(audit_period_ending__lt=(F('audit_period_beginning') + + (60*60*24))) + instant_exists = exists_model.objects.filter(ums & instant_range) + summary['instantaneous'] = _audit_for_exists(instant_exists) + + failed_query = Q(status=exists_model.FAILED) + failed = exists_model.objects.filter(ums & failed_query) + detail = [['Exist', e.id, e.fail_reason] for e in failed] + return summary, detail + + def get_previous_period(time, period_length): if period_length == 'day': last_period = time - datetime.timedelta(days=1)