示例#1
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
示例#2
0
 def test_system_tags_parsing_multiple_tag_values(self):
     tests = {
         "id":
         "548f28c4-752d-11ea-b35c-54e1add9c7a0",
         "tags": [
             {
                 "namespace": "insights-client",
                 "key": "Location",
                 "value": "gray rack",
             },
             {
                 "namespace": "insights-client",
                 "key": "Location",
                 "value": "basement",
             },
             {
                 "namespace": "insights-client",
                 "key": "Location",
                 "value": "somewhere else",
             },
         ],
     }
     parsed_profile = profile_parser.parse_profile(tests, "fake-name", None)
     self.assertEqual(
         parsed_profile["tags.insights-client.Location"],
         "basement, gray rack, somewhere else",
     )
 def test_running_process_parsing(self):
     profile = {"id": "1234", "running_processes": ["vim", "vim", "doom.exe"]}
     fake_plastic_tree = MagicMock()
     result = profile_parser.parse_profile(
         profile, "some_display_name", fake_plastic_tree
     )
     self.assertEqual(result["running_processes.vim"], "2")
     self.assertEqual(result["running_processes.doom.exe"], "1")
示例#4
0
def _parse_from_sysprofile(system_profile, system_name, logger):
    parsed_profile = profile_parser.parse_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]})

    return group_baselines(facts)
示例#5
0
 def test_system_tags_parsing(self):
     tests = {
         "id":
         "548f28c4-752d-11ea-b35c-54e1add9c7a0",
         "tags": [{
             "namespace": "insights-client",
             "key": "Zone",
             "value": "eastern time zone",
         }],
     }
     parsed_profile = profile_parser.parse_profile(tests, "fake-name", None)
     self.assertEqual(parsed_profile["tags.insights-client.Zone"],
                      "eastern time zone")
 def test_network_interface_parsing(self):
     profile = {
         "id": "1234",
         "network_interfaces": [
             {"mtu": 9876, "name": "fake-nic"},
             {"name": "no_mtu"},
         ],
     }
     fake_plastic_tree = MagicMock()
     result = profile_parser.parse_profile(
         profile, "some_display_name", fake_plastic_tree
     )
     self.assertEqual(result["network_interfaces.fake-nic.mtu"], "9876")
     self.assertEqual(result["network_interfaces.no_mtu.mtu"], "N/A")
示例#7
0
    def test_gpg_pubkey_parsing(self):
        tests = {
            "id":
            "548f28c4-752d-11ea-b35c-54e1add9c7a0",
            "installed_packages": [
                "gpg-pubkey-c481937a-5bc4662d",
                "bash-5.0.11-1.fc31.x86_64",
            ],
        }

        parsed_profiles = profile_parser.parse_profile(tests, "fake-name",
                                                       None)
        self.assertIn("installed_packages.bash", parsed_profiles)
        self.assertNotIn("installed_packages.gpg-pubkey", parsed_profiles)
示例#8
0
 def test_system_tags_parsing_two_namespaces(self):
     tests = {
         "id":
         "548f28c4-752d-11ea-b35c-54e1add9c7a0",
         "tags": [
             {
                 "namespace": "insights-client",
                 "key": "myTag",
                 "value": "Insights Client Namespace Tag",
             },
             {
                 "namespace": "satellite",
                 "key": "myTag",
                 "value": "Satellite Namespace Tag",
             },
         ],
     }
     parsed_profile = profile_parser.parse_profile(tests, "fake-name", None)
     self.assertEqual(
         parsed_profile["tags.insights-client.myTag"],
         "Insights Client Namespace Tag",
         self.assertEqual(parsed_profile["tags.satellite.myTag"],
                          "Satellite Namespace Tag"),
     )
示例#9
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
示例#10
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()
示例#11
0
    def test_cores_per_socket_parsing(self):
        tests = {"id": "548f28c4-752d-11ea-b35c-54e1add9c7a0"}

        parsed_profiles = profile_parser.parse_profile(tests, "fake-name",
                                                       None)
        self.assertEqual(parsed_profiles["cores_per_socket"], "N/A")
示例#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()