예제 #1
0
def _system_mapping(system):
    """
    create a header mapping for one system
    """
    system_profile_exists = system["system_profile"]["system_profile_exists"]
    system_stale = _check_system_stale(system)
    insights_installed = False
    insights_enabled = False
    captured_or_updated = system.get("updated", None)
    if system_profile_exists:
        if "captured_date" in system["system_profile"]:
            captured_or_updated = system["system_profile"]["captured_date"]

        if "installed_packages" in system["system_profile"]:
            try:
                insights_installed_string = next(
                    s for s in system["system_profile"]["installed_packages"]
                    if "insights-client" in s)
            except StopIteration:
                insights_installed_string = ""
            insights_installed = "insights-client" in insights_installed_string

        if "enabled_services" in system["system_profile"]:
            insights_enabled = "insights-client" in system["system_profile"][
                "enabled_services"]
    return {
        "id": system[SYSTEM_ID_KEY],
        "display_name": profile_parser.get_name(system),
        "system_profile_exists": system_profile_exists,
        "last_updated": captured_or_updated,
        "insights_installed": insights_installed,
        "insights_enabled": insights_enabled,
        "system_stale": system_stale,
    }
예제 #2
0
def _select_applicable_info(systems_with_profiles, baselines,
                            historical_sys_profiles, reference_id):
    """
    Take a list of systems with profiles, and output a "pivoted" list of
    profile facts, where each fact key has a dict of systems and their values. This is
    useful when comparing facts across systems.
    """
    # create dicts of id + info
    parsed_system_profiles = []

    for system_with_profile in systems_with_profiles:
        system_name = profile_parser.get_name(system_with_profile)
        parsed_system_profile = profile_parser.parse_profile(
            system_with_profile["system_profile"], system_name,
            current_app.logger)
        parsed_system_profiles.append({
            **parsed_system_profile, "is_baseline":
            False
        })

    for historical_sys_profile in historical_sys_profiles:
        historical_sys_profile_name = historical_sys_profile["display_name"]
        parsed_historical_sys_profile = profile_parser.parse_profile(
            historical_sys_profile["system_profile"],
            historical_sys_profile_name,
            current_app.logger,
        )
        parsed_system_profiles.append({
            **parsed_historical_sys_profile, "is_baseline":
            False
        })

    # add baselines into parsed_system_profiles
    for baseline in baselines:
        baseline_facts = {
            "id": baseline["id"],
            "name": baseline["display_name"]
        }
        for baseline_fact in baseline["baseline_facts"]:
            if "value" in baseline_fact:
                baseline_facts[baseline_fact["name"]] = baseline_fact["value"]
            elif "values" in baseline_fact:
                prefix = baseline_fact["name"]
                for nested_fact in baseline_fact["values"]:
                    baseline_facts[prefix + "." +
                                   nested_fact["name"]] = nested_fact["value"]
        parsed_system_profiles.append({**baseline_facts, "is_baseline": True})

    # find the set of all keys to iterate over
    all_keys = set()
    for parsed_system_profile in parsed_system_profiles:
        all_keys = all_keys.union(set(parsed_system_profile.keys()))

    info_comparisons = [
        _create_comparison(parsed_system_profiles, key, reference_id)
        for key in all_keys
    ]
    return info_comparisons
예제 #3
0
def _system_mapping(system):
    """
    create a header mapping for one system
    """
    system_profile_exists = system["system_profile"]["system_profile_exists"]
    captured_or_updated = system.get("updated", None)
    if system_profile_exists:
        if "captured_date" in system["system_profile"]:
            captured_or_updated = system["system_profile"]["captured_date"]
    return {
        "id": system[SYSTEM_ID_KEY],
        "display_name": profile_parser.get_name(system),
        "system_profile_exists": system_profile_exists,
        "last_updated": captured_or_updated,
    }
예제 #4
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()
예제 #5
0
def _select_applicable_info(
    systems_with_profiles,
    baselines,
    historical_sys_profiles,
    reference_id,
    short_circuit,
):
    """
    Take a list of systems with profiles, and output a "pivoted" list of
    profile facts, where each fact key has a dict of systems and their values. This is
    useful when comparing facts across systems.

    Unless short_circuit is True, then we don't need a full comparison report, only one for
    facts present on a single baseline that is being compared with a single system for
    notifications if a newly checked in hsp system has drifted from an associated baseline.
    If the key 'drifted_from_baseline' is True, the system has drifted, else False.
    """
    # create dicts of id + info
    parsed_system_profiles = []

    for system_with_profile in systems_with_profiles:
        system_name = profile_parser.get_name(system_with_profile)
        parsed_system_profile = profile_parser.parse_profile(
            system_with_profile["system_profile"], system_name, current_app.logger
        )
        parsed_system_profiles.append({**parsed_system_profile, "is_baseline": False})

    for historical_sys_profile in historical_sys_profiles:
        historical_sys_profile_name = historical_sys_profile["display_name"]
        parsed_historical_sys_profile = profile_parser.parse_profile(
            historical_sys_profile["system_profile"],
            historical_sys_profile_name,
            current_app.logger,
        )
        parsed_system_profiles.append({**parsed_historical_sys_profile, "is_baseline": False})

    # add baselines into parsed_system_profiles
    for baseline in baselines:
        baseline_facts = {"id": baseline["id"], "name": baseline["display_name"]}
        for baseline_fact in baseline["baseline_facts"]:
            if "value" in baseline_fact:
                baseline_facts[baseline_fact["name"]] = baseline_fact["value"]
            elif "values" in baseline_fact:
                prefix = baseline_fact["name"]
                for nested_fact in baseline_fact["values"]:
                    baseline_facts[prefix + "." + nested_fact["name"]] = nested_fact["value"]
        parsed_system_profiles.append({**baseline_facts, "is_baseline": True})

    # find the set of all keys to iterate over
    # if short_circuit is True, we only want the facts present in this baseline
    # since we are comparing one baseline to one system for notifications only
    all_keys = set()
    if short_circuit:
        for parsed_system_profile in parsed_system_profiles:
            if parsed_system_profile["is_baseline"]:
                all_keys = set(parsed_system_profile.keys())
    else:
        for parsed_system_profile in parsed_system_profiles:
            all_keys = all_keys.union(set(parsed_system_profile.keys()))

    # prepare regexes for obfuscated values matching
    obfuscated_regexes = {}
    for key in OBFUSCATED_FACTS_PATTERNS.keys():
        obfuscated_regexes[key] = re.compile(OBFUSCATED_FACTS_PATTERNS[key])

    info_comparisons = []
    for key in all_keys:

        # obfuscated information type - key
        for obfuscated_key in obfuscated_regexes.keys():
            if obfuscated_key in key:
                for system in parsed_system_profiles:
                    system["obfuscation"] = {}
                    system["obfuscation"][key] = False
                    obfuscated_regex = obfuscated_regexes[obfuscated_key]
                    value = system.get(key)
                    # only if value is present and matches with obfuscated pattern
                    if value and obfuscated_regex.match(value):
                        system["obfuscation"][key] = True

        current_comparison = _create_comparison(
            parsed_system_profiles,
            key,
            reference_id,
            len(systems_with_profiles),
            short_circuit,
        )
        if current_comparison:
            # if short_circuit is True, and there was a change, i.e. this system
            # has drifted from this associated baseline, then set the key on the
            # comparison 'drifted_from_baseline' to True to trigger a notification
            # else set it to False.
            if short_circuit and current_comparison["state"] == COMPARISON_DIFFERENT:
                current_comparison["drifted_from_baseline"] = True
            else:
                current_comparison["drifted_from_baseline"] = False
            info_comparisons.append(current_comparison)
    return info_comparisons
예제 #6
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()
예제 #7
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()