Beispiel #1
0
def comparison_report(
    system_ids,
    baseline_ids,
    historical_sys_profile_ids,
    reference_id,
    auth_key,
    data_format,
):
    """
    return a comparison report
    """
    if len(system_ids) > len(set(system_ids)):
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="duplicate UUID specified in system_ids list",
        )

    if len(baseline_ids) > len(set(baseline_ids)):
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="duplicate UUID specified in baseline_ids list",
        )

    _validate_uuids(system_ids)
    _validate_uuids(baseline_ids)

    try:
        systems_with_profiles = fetch_systems_with_profiles(
            system_ids, auth_key, current_app.logger, get_event_counters()
        )

        baseline_results = fetch_baselines(baseline_ids, auth_key, current_app.logger)
        ensure_correct_system_count(baseline_ids, baseline_results)

        comparisons = info_parser.build_comparisons(
            systems_with_profiles,
            baseline_results,
            fetch_historical_sys_profiles(
                historical_sys_profile_ids,
                auth_key,
                current_app.logger,
                get_event_counters(),
            ),
            reference_id,
        )
        metrics.systems_compared.observe(len(system_ids))
        if data_format == "csv":
            output = make_response(_csvify(comparisons))
            output.headers["Content-Disposition"] = "attachment; filename=export.csv"
            output.headers["Content-type"] = "text/csv"
            return output
        else:
            return jsonify(comparisons)

    except ItemNotReturned as error:
        raise HTTPError(HTTPStatus.NOT_FOUND, message=error.message)
Beispiel #2
0
def comparison_report():
    system_ids = request.args.getlist('system_ids[]')
    auth_key = get_key_from_headers(request.headers)

    fact_namespace = FACT_NAMESPACE
    if config.return_mock_data:
        fact_namespace = MOCK_FACT_NAMESPACE

    try:
        comparisons = info_parser.build_comparisons(fetch_systems(system_ids, auth_key,
                                                                  current_app.logger),
                                                    fact_namespace)
        return jsonify(comparisons)
    except SystemNotReturned as error:
        raise HTTPError(HTTPStatus.BAD_REQUEST, message=error.message)
Beispiel #3
0
def comparison_report():
    system_ids = request.args.getlist('system_ids[]')
    auth_key = get_key_from_headers(request.headers)

    if len(system_ids) > len(set(system_ids)):
        raise HTTPError(HTTPStatus.BAD_REQUEST,
                        message="duplicate UUID specified in system_ids list")

    _validate_uuids(system_ids)

    try:
        comparisons = info_parser.build_comparisons(
            fetch_systems_with_profiles(system_ids, auth_key,
                                        current_app.logger))
        return jsonify(comparisons)
    except SystemNotReturned as error:
        raise HTTPError(HTTPStatus.BAD_REQUEST, message=error.message)
Beispiel #4
0
with open(args.conf_file, "r") as conf_fh:
    conf = toml.load(conf_fh)

print("Testing report generation...")

# TODO: remove need to initialize flask app
app = create_app()
app.app.app_context().push()

for report in conf:
    systems_with_profiles, baselines, hsps, expected_output = _read_inputs(
        **conf[report])
    comparisons = info_parser.build_comparisons(
        systems_with_profiles,
        baselines,
        hsps,
        None,
        False,
    )
    if args.write:
        outpath = conf[report]["expected_output_path"]
        with open(outpath, "w") as outfile:
            json.dump(comparisons, outfile, indent=4, sort_keys=True)
        print(f"output written to {outpath}")
    else:
        result = json.dumps(comparisons, indent=4, sort_keys=True).splitlines()
        if result != expected_output:
            raise RuntimeError(
                "expected report differed from generated report")
        else:
            print("OK")
Beispiel #5
0
def comparison_report(
    system_ids,
    baseline_ids,
    historical_sys_profile_ids,
    reference_id,
    auth_key,
    data_format,
    short_circuit,
):
    """
    return a comparison report

    If short_circuit is true, this is a call to see if a single system has
    drifted from a single baseline in order to trigger a Notification if
    necessary, so the only facts that will be compared will be those present
    on the baseline.  If the system has drifted from the baseline, the report
    will contain the key 'drift_event_notify' set to True, otherwise False.
    """
    if len(system_ids + baseline_ids + historical_sys_profile_ids) == 0:
        message = "must specify at least one of system, baseline, or HSP"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )
    if len(system_ids) > len(set(system_ids)):
        message = "duplicate UUID specified in system_ids list"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )

    if len(baseline_ids) > len(set(baseline_ids)):
        message = "duplicate UUID specified in baseline_ids list"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )

    if system_ids:
        validate_uuids(system_ids)
    if baseline_ids:
        validate_uuids(baseline_ids)
    if historical_sys_profile_ids:
        validate_uuids(historical_sys_profile_ids)
    if reference_id:
        validate_uuids([reference_id])
        if reference_id not in (system_ids + baseline_ids +
                                historical_sys_profile_ids):
            message = "reference id %s does not match any ids from query" % reference_id
            current_app.logger.audit(
                str(HTTPStatus.BAD_REQUEST) + " " + message,
                request=request,
                success=False,
            )
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message=message,
            )

    try:
        systems_with_profiles = []
        baseline_results = []
        hsp_results = []

        with PT_CR_API_REQUESTS.time():
            try:
                if system_ids:
                    # can raise RBACDenied exception
                    message = "reading systems with profiles"
                    current_app.logger.audit(message, request=request)
                    systems_with_profiles = fetch_systems_with_profiles(
                        system_ids, auth_key, current_app.logger,
                        get_event_counters())

                if baseline_ids:
                    # can raise RBACDenied exception
                    message = "reading baselines"
                    current_app.logger.audit(message, request=request)
                    baseline_results = fetch_baselines(baseline_ids, auth_key,
                                                       current_app.logger)
                    ensure_correct_system_count(baseline_ids, baseline_results)

                if historical_sys_profile_ids:
                    # can raise RBACDenied exception
                    message = "reading historical system profiles"
                    current_app.logger.audit(message, request=request)
                    hsp_results = fetch_historical_sys_profiles(
                        historical_sys_profile_ids,
                        auth_key,
                        current_app.logger,
                        get_event_counters(),
                    )
            except RBACDenied as error:
                message = error.message
                current_app.logger.audit(str(HTTPStatus.FORBIDDEN) + " " +
                                         message,
                                         request=request)
                raise HTTPError(HTTPStatus.FORBIDDEN, message=message)

        with PT_CR_BUILD_COMPARISON.time():
            comparisons = info_parser.build_comparisons(
                systems_with_profiles,
                baseline_results,
                hsp_results,
                reference_id,
                short_circuit,
            )

        metrics.systems_compared.observe(len(system_ids))
        if data_format == "csv":
            output = make_response(_csvify(comparisons))
            output.headers[
                "Content-Disposition"] = "attachment; filename=export.csv"
            output.headers["Content-type"] = "text/csv"
            return output
        else:
            return jsonify(comparisons)

    except ItemNotReturned as error:
        message = error.message
        current_app.logger.audit(str(HTTPStatus.NOT_FOUND) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(HTTPStatus.NOT_FOUND, message=message)
Beispiel #6
0
def comparison_report(
    system_ids,
    baseline_ids,
    historical_sys_profile_ids,
    reference_id,
    auth_key,
    data_format,
):
    """
    return a comparison report
    """
    if len(system_ids + baseline_ids + historical_sys_profile_ids) == 0:
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="must specify at least one of system, baseline, or HSP",
        )
    if len(system_ids) > len(set(system_ids)):
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="duplicate UUID specified in system_ids list",
        )

    if len(baseline_ids) > len(set(baseline_ids)):
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="duplicate UUID specified in baseline_ids list",
        )

    if system_ids:
        validate_uuids(system_ids)
    if baseline_ids:
        validate_uuids(baseline_ids)
    if historical_sys_profile_ids:
        validate_uuids(historical_sys_profile_ids)
    if reference_id:
        validate_uuids([reference_id])
        if reference_id not in (system_ids + baseline_ids +
                                historical_sys_profile_ids):
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message="reference id %s does not match any ids from query" %
                reference_id,
            )

    try:
        systems_with_profiles = []
        baseline_results = []
        hsp_results = []

        if system_ids:
            systems_with_profiles = fetch_systems_with_profiles(
                system_ids, auth_key, current_app.logger, get_event_counters())

        if baseline_ids:
            baseline_results = fetch_baselines(baseline_ids, auth_key,
                                               current_app.logger)
            ensure_correct_system_count(baseline_ids, baseline_results)

        if historical_sys_profile_ids:
            hsp_results = fetch_historical_sys_profiles(
                historical_sys_profile_ids,
                auth_key,
                current_app.logger,
                get_event_counters(),
            )

        comparisons = info_parser.build_comparisons(systems_with_profiles,
                                                    baseline_results,
                                                    hsp_results, reference_id)
        metrics.systems_compared.observe(len(system_ids))
        if data_format == "csv":
            output = make_response(_csvify(comparisons))
            output.headers[
                "Content-Disposition"] = "attachment; filename=export.csv"
            output.headers["Content-type"] = "text/csv"
            return output
        else:
            return jsonify(comparisons)

    except ItemNotReturned as error:
        raise HTTPError(HTTPStatus.NOT_FOUND, message=error.message)
Beispiel #7
0
def comparison_report(
    system_ids,
    baseline_ids,
    historical_sys_profile_ids,
    reference_id,
    auth_key,
    data_format,
    short_circuit,
):
    """
    return a comparison report

    If short_circuit is true, this is a call to see if a single system has
    drifted from a single baseline in order to trigger a Notification if
    necessary, so the only facts that will be compared will be those present
    on the baseline.  If the system has drifted from the baseline, the report
    will contain the key 'drift_event_notify' set to True, otherwise False.
    """
    if len(system_ids + baseline_ids + historical_sys_profile_ids) == 0:
        message = "must specify at least one of system, baseline, or HSP"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )
    if len(system_ids) > len(set(system_ids)):
        message = "duplicate UUID specified in system_ids list"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )

    if len(baseline_ids) > len(set(baseline_ids)):
        message = "duplicate UUID specified in baseline_ids list"
        current_app.logger.audit(str(HTTPStatus.BAD_REQUEST) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )

    with PT_CR_VALIDATE_UUID.time():
        if system_ids:
            validate_uuids(system_ids)
        if baseline_ids:
            validate_uuids(baseline_ids)
        if historical_sys_profile_ids:
            validate_uuids(historical_sys_profile_ids)
        if reference_id:
            validate_uuids([reference_id])
            if reference_id not in (system_ids + baseline_ids +
                                    historical_sys_profile_ids):
                message = "reference id %s does not match any ids from query" % reference_id
                current_app.logger.audit(
                    str(HTTPStatus.BAD_REQUEST) + " " + message,
                    request=request,
                    success=False,
                )
                raise HTTPError(
                    HTTPStatus.BAD_REQUEST,
                    message=message,
                )

    def get_systems_with_profiles(app, timer, system_ids, auth_key, logger,
                                  counters):
        with timer.time():
            with app.app_context():
                # can raise RBACDenied exception
                message = "reading systems with profiles"
                current_app.logger.audit(message, request=request)
                systems_with_profiles = fetch_systems_with_profiles(
                    system_ids, auth_key, current_app.logger, counters)
        return systems_with_profiles

    def get_baselines(app, timer, baseline_ids, auth_key, logger):
        with timer.time():
            with app.app_context():
                # can raise RBACDenied exception
                message = "reading baselines"
                current_app.logger.audit(message, request=request)
                baseline_results = fetch_baselines(baseline_ids, auth_key,
                                                   logger)
                ensure_correct_system_count(baseline_ids, baseline_results)
        return baseline_results

    def get_historical_sys_profiles(app, timer, historical_sys_profile_ids,
                                    auth_key, logger, counters):
        with timer.time():
            with app.app_context():
                # can raise RBACDenied exception
                message = "reading historical system profiles"
                current_app.logger.audit(message, request=request)
                hsp_results = fetch_historical_sys_profiles(
                    historical_sys_profile_ids,
                    auth_key,
                    logger,
                    counters,
                )
        return hsp_results

    try:
        api_results = {}
        http_errors = []
        other_errors = []

        with PT_CR_API_REQUESTS.time():
            futures = {}
            with concurrent.futures.ThreadPoolExecutor() as executor:
                app = current_app._get_current_object()
                if system_ids:
                    # can raise RBACDenied exception
                    future = executor.submit(
                        get_systems_with_profiles,
                        app,
                        PT_CR_API_SYSTEM_PROFILE_REQUESTS,
                        system_ids,
                        auth_key,
                        current_app.logger,
                        get_event_counters(),
                    )
                    futures[future] = "systems_with_profiles"
                if baseline_ids:
                    # can raise RBACDenied exception
                    future = executor.submit(
                        get_baselines,
                        app,
                        PT_CR_API_BASELINE_REQUESTS,
                        baseline_ids,
                        auth_key,
                        current_app.logger,
                    )
                    futures[future] = "baseline_results"
                if historical_sys_profile_ids:
                    # can raise RBACDenied exception
                    future = executor.submit(
                        get_historical_sys_profiles,
                        app,
                        PT_CR_API_HSP_REQUESTS,
                        historical_sys_profile_ids,
                        auth_key,
                        current_app.logger,
                        get_event_counters(),
                    )
                    futures[future] = "hsp_results"

                for future in concurrent.futures.as_completed(futures):
                    try:
                        api_results[futures[future]] = future.result()
                    except RBACDenied as error:
                        message = error.message
                        current_app.logger.audit(str(HTTPStatus.FORBIDDEN) +
                                                 " " + message,
                                                 request=request)
                        raise HTTPError(HTTPStatus.FORBIDDEN, message=message)
                    except HTTPError as error:
                        http_errors.append(error)
                    except (ItemNotReturned, ServiceError) as error:
                        other_errors.append(error)

            handle_errors(http_errors=http_errors,
                          other_errors=other_errors)  # raises merged error

        systems_with_profiles = api_results.get("systems_with_profiles", [])
        baseline_results = api_results.get("baseline_results", [])
        hsp_results = api_results.get("hsp_results", [])

        with PT_CR_BUILD_COMPARISON.time():
            comparisons = info_parser.build_comparisons(
                systems_with_profiles,
                baseline_results,
                hsp_results,
                reference_id,
                short_circuit,
            )

        metrics.systems_compared.observe(len(system_ids))
        if data_format == "csv":
            output = make_response(_csvify(comparisons))
            output.headers[
                "Content-Disposition"] = "attachment; filename=export.csv"
            output.headers["Content-type"] = "text/csv"
            return output
        else:
            return jsonify(comparisons)

    except ItemNotReturned as error:
        message = error.message
        current_app.logger.audit(str(HTTPStatus.NOT_FOUND) + " " + message,
                                 request=request,
                                 success=False)
        raise HTTPError(HTTPStatus.NOT_FOUND, message=message)