Example #1
0
    def test_fetch_systems_missing_system(self):
        systems_to_fetch = [
            "243926fa-262f-11e9-a632-c85b761454fa",
            "264fb5b2-262f-11e9-9b12-c85b761454fa",
            "269a3da8-262f-11e9-8ee5-c85b761454fa",
        ]

        self._create_response_for_systems(
            "inventory_svc_url_is_not_set", ",".join(systems_to_fetch)
        )

        self._create_response_for_system_profiles(
            "inventory_svc_url_is_not_set", ",".join(systems_to_fetch)
        )
        self._create_response_for_system_tags(
            "inventory_svc_url_is_not_set", ",".join(systems_to_fetch)
        )

        with self.assertRaises(ItemNotReturned) as cm:
            inventory_service_interface.fetch_systems_with_profiles(
                systems_to_fetch, "my-auth-key", self.mock_logger, self.mock_counters
            )

        self.assertEqual(
            cm.exception.message,
            "ids [269a3da8-262f-11e9-8ee5-c85b761454fa] not available to display",
        )
Example #2
0
def _get_current_names_for_profiles(hsps):
    # make a unique list of inventory IDs
    inventory_ids = list({str(h.inventory_id) for h in hsps})

    auth_key = get_key_from_headers(request.headers)

    try:
        systems = fetch_systems_with_profiles(
            inventory_ids,
            auth_key,
            current_app.logger,
            _get_event_counters(),
        )
        message = "read systems"
        current_app.logger.audit(message, request=request, success=True)
    except RBACDenied as error:
        message = error.message
        current_app.logger.audit(message, request=request, success=False)
        raise HTTPError(HTTPStatus.FORBIDDEN, message=message)

    display_names = {
        system["id"]: system["display_name"]
        for system in systems
    }
    enriched_hsps = []
    for hsp in hsps:
        current_display_name = display_names[str(hsp.inventory_id)]
        hsp.system_profile["display_name"] = current_display_name
        enriched_hsps.append(hsp)

    return enriched_hsps
Example #3
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)
Example #4
0
 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
Example #5
0
    def test_fetch_systems_backend_service_error(self):
        systems_to_fetch = [
            "243926fa-262f-11e9-a632-c85b761454fa",
            "264fb5b2-262f-11e9-9b12-c85b761454fa",
            "269a3da8-262f-11e9-8ee5-c85b761454fa",
        ]

        self._create_500_response_for_systems("inventory_svc_url_is_not_set",
                                              ",".join(systems_to_fetch))

        self._create_500_response_for_system_profiles(
            "inventory_svc_url_is_not_set", ",".join(systems_to_fetch))

        with self.assertRaises(ServiceError) as cm:
            inventory_service_interface.fetch_systems_with_profiles(
                systems_to_fetch, "my-auth-key", self.mock_logger,
                self.mock_counters)

        self.assertEqual(cm.exception.message,
                         "Error received from backend service")
Example #6
0
    def test_fetch_systems_with_profiles(self):
        systems_to_fetch = [
            "243926fa-262f-11e9-a632-c85b761454fa",
            "264fb5b2-262f-11e9-9b12-c85b761454fa",
        ]

        self._create_response_for_systems("inventory_svc_url_is_not_set",
                                          ",".join(systems_to_fetch))
        self._create_response_for_system_profiles(
            "inventory_svc_url_is_not_set", ",".join(systems_to_fetch))

        systems = inventory_service_interface.fetch_systems_with_profiles(
            systems_to_fetch, "my-auth-key", self.mock_logger,
            self.mock_counters)
        found_system_ids = {system["id"] for system in systems}
        self.assertSetEqual(found_system_ids, set(systems_to_fetch))
def _get_current_names_for_profiles(hsps):
    # make a unique list of inventory IDs
    inventory_ids = list({str(h.inventory_id) for h in hsps})

    auth_key = get_key_from_headers(request.headers)

    systems = fetch_systems_with_profiles(
        inventory_ids, auth_key, current_app.logger, _get_event_counters(),
    )
    display_names = {system["id"]: system["display_name"] for system in systems}
    enriched_hsps = []
    for hsp in hsps:
        current_display_name = display_names[str(hsp.inventory_id)]
        hsp.system_profile["display_name"] = current_display_name
        enriched_hsps.append(hsp)

    return enriched_hsps
Example #8
0
def create_baseline(system_baseline_in):
    """
    create a baseline
    """
    ensure_rbac_write()
    account_number = view_helpers.get_account_number(request)

    if "values" in system_baseline_in and "value" in system_baseline_in:
        message = "'values' and 'value' cannot both be defined for system baseline"
        current_app.logger.audit(message, request=request, success=False)
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=message,
        )

    _check_for_existing_display_name(system_baseline_in["display_name"],
                                     account_number)
    _check_for_whitespace_in_display_name(system_baseline_in["display_name"])

    message = "counted baselines"
    current_app.logger.audit(message, request=request)

    baseline_facts = []
    if "baseline_facts" in system_baseline_in:
        if "inventory_uuid" in system_baseline_in:
            message = (
                "Both baseline facts and inventory id provided, can clone only one."
            )
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message=message,
            )
        if "hsp_uuid" in system_baseline_in:
            message = "Both baseline facts and hsp id provided, can clone only one."
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message=message,
            )
        baseline_facts = system_baseline_in["baseline_facts"]
    elif "hsp_uuid" in system_baseline_in:
        if "inventory_uuid" in system_baseline_in:
            message = "Both hsp id and system id provided, can clone only one."
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message=message,
            )
        validate_uuids([system_baseline_in["hsp_uuid"]])
        auth_key = get_key_from_headers(request.headers)
        try:
            hsp = fetch_historical_sys_profiles(
                [system_baseline_in["hsp_uuid"]],
                auth_key,
                current_app.logger,
                get_event_counters(),
            )[0]
            message = "read historical system profiles"
            current_app.logger.audit(message, request=request)
        except ItemNotReturned:
            message = "hsp UUID %s not available" % system_baseline_in[
                "hsp_uuid"]
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(
                HTTPStatus.NOT_FOUND,
                message=message,
            )
        except RBACDenied as error:
            message = error.message
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(HTTPStatus.FORBIDDEN, message=message)

        system_name = "clone_from_hsp_unused"
        baseline_facts = _parse_from_sysprofile(hsp["system_profile"],
                                                system_name,
                                                current_app.logger)
    elif "inventory_uuid" in system_baseline_in:
        validate_uuids([system_baseline_in["inventory_uuid"]])
        auth_key = get_key_from_headers(request.headers)
        try:
            system_with_profile = fetch_systems_with_profiles(
                [system_baseline_in["inventory_uuid"]],
                auth_key,
                current_app.logger,
                get_event_counters(),
            )[0]
            message = "read system with profiles"
            current_app.logger.audit(message, request=request)
        except ItemNotReturned:
            message = ("inventory UUID %s not available" %
                       system_baseline_in["inventory_uuid"])
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(
                HTTPStatus.NOT_FOUND,
                message=message,
            )
        except RBACDenied as error:
            message = error.message
            current_app.logger.audit(message, request=request, success=False)
            raise HTTPError(HTTPStatus.FORBIDDEN, message=message)

        system_name = profile_parser.get_name(system_with_profile)
        baseline_facts = _parse_from_sysprofile(
            system_with_profile["system_profile"], system_name,
            current_app.logger)

    try:
        _validate_facts(baseline_facts)
    except FactValidationError as error:
        message = error.message
        current_app.logger.audit(message, request=request, success=False)
        raise HTTPError(HTTPStatus.BAD_REQUEST, message=message)

    baseline = SystemBaseline(
        account=account_number,
        display_name=system_baseline_in["display_name"],
        baseline_facts=baseline_facts,
    )
    baseline.baseline_facts = _sort_baseline_facts(baseline.baseline_facts)
    db.session.add(baseline)

    db.session.commit(
    )  # commit now so we get a created/updated time before json conversion

    message = "creat baselines"
    current_app.logger.audit(message, request=request)

    return baseline.to_json()
Example #9
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)
Example #10
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)
Example #11
0
def create_baseline(system_baseline_in):
    """
    create a baseline
    """
    account_number = view_helpers.get_account_number(request)

    if "values" in system_baseline_in and "value" in system_baseline_in:
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=
            "'values' and 'value' cannot both be defined for system baseline",
        )

    query = SystemBaseline.query.filter(
        SystemBaseline.account == account_number,
        SystemBaseline.display_name == system_baseline_in["display_name"],
    )

    if query.count() > 0:
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message="display_name '%s' already used for this account" %
            system_baseline_in["display_name"],
        )

    baseline_facts = []
    if "baseline_facts" in system_baseline_in:
        baseline_facts = system_baseline_in["baseline_facts"]
    elif "inventory_uuid" in system_baseline_in:
        auth_key = get_key_from_headers(request.headers)
        system_with_profile = fetch_systems_with_profiles(
            [system_baseline_in["inventory_uuid"]],
            auth_key,
            current_app.logger,
            get_event_counters(),
        )[0]

        system_name = profile_parser.get_name(system_with_profile)
        parsed_profile = profile_parser.parse_profile(
            system_with_profile["system_profile"], system_name,
            current_app.logger)
        facts = []
        for fact in parsed_profile:
            if fact not in ["id", "name"] and parsed_profile[fact] not in [
                    "N/A",
                    "None",
                    None,
            ]:
                facts.append({"name": fact, "value": parsed_profile[fact]})

        baseline_facts = group_baselines(facts)

    baseline = SystemBaseline(
        account=account_number,
        display_name=system_baseline_in["display_name"],
        baseline_facts=baseline_facts,
    )
    db.session.add(baseline)
    db.session.commit(
    )  # commit now so we get a created/updated time before json conversion

    return baseline.to_json()
Example #12
0
def create_baseline(system_baseline_in):
    """
    create a baseline
    """
    account_number = view_helpers.get_account_number(request)

    if "values" in system_baseline_in and "value" in system_baseline_in:
        raise HTTPError(
            HTTPStatus.BAD_REQUEST,
            message=
            "'values' and 'value' cannot both be defined for system baseline",
        )

    _check_for_existing_display_name(system_baseline_in["display_name"],
                                     account_number)

    baseline_facts = []
    if "baseline_facts" in system_baseline_in:
        baseline_facts = system_baseline_in["baseline_facts"]
    elif "inventory_uuid" in system_baseline_in:
        _validate_uuids([system_baseline_in["inventory_uuid"]])
        auth_key = get_key_from_headers(request.headers)
        try:
            system_with_profile = fetch_systems_with_profiles(
                [system_baseline_in["inventory_uuid"]],
                auth_key,
                current_app.logger,
                get_event_counters(),
            )[0]
        except ItemNotReturned:
            raise HTTPError(
                HTTPStatus.BAD_REQUEST,
                message="inventory UUID %s not available" %
                system_baseline_in["inventory_uuid"],
            )

        system_name = profile_parser.get_name(system_with_profile)
        parsed_profile = profile_parser.parse_profile(
            system_with_profile["system_profile"], system_name,
            current_app.logger)
        facts = []
        for fact in parsed_profile:
            if fact not in ["id", "name"] and parsed_profile[fact] not in [
                    "N/A",
                    "None",
                    None,
            ]:
                facts.append({"name": fact, "value": parsed_profile[fact]})

        baseline_facts = group_baselines(facts)

    try:
        _validate_facts(baseline_facts)
    except FactValidationError as e:
        raise HTTPError(HTTPStatus.BAD_REQUEST, message=e.message)

    baseline = SystemBaseline(
        account=account_number,
        display_name=system_baseline_in["display_name"],
        baseline_facts=baseline_facts,
    )
    baseline.baseline_facts = _sort_baseline_facts(baseline.baseline_facts)
    db.session.add(baseline)
    db.session.commit(
    )  # commit now so we get a created/updated time before json conversion

    return baseline.to_json()