def test_run_command(tmpdir): d = tmpdir / "etc" d.mkdir() p = d / "redhat-release" p.write(REDHAT_RELEASE) g = tmpdir / "insights_commands" g.mkdir() r = g / "uname_-a" r.write(UNAME) broker = run([always_fires.report, never_fires.report]) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT broker = run( [Specs.redhat_release, always_fires.report, never_fires.report], root=tmpdir.strpath) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT assert Specs.redhat_release in broker assert broker[Specs.redhat_release].content == [REDHAT_RELEASE] testargs = ["insights-run", "-p", "insights.plugins"] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT testargs = ["insights-run", "-p", "insights.plugins", tmpdir.strpath] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT assert Specs.uname in broker assert broker[Specs.uname].content == [UNAME]
def get_tree(root=None): """ This is a helper function to get a multipath configuration component for your local machine or an archive. It's for use in interactive sessions. """ from insights import run return run(MultipathConfTree, root=root).get(MultipathConfTree)
def main(): module_args = { "plugins": { "type": "dict", "required": True } } module = AnsibleModule(argument_spec=module_args) plugins = module.params["plugins"] or {} components = [] for p, meta in plugins.items(): plugin = dr.get_component(p) components.append(plugin) if meta: dr.COMPONENT_METADATA[plugin] = meta results = run(components) response = {} for p in components: r = results.get(p) if r: response.update(serialize(p, r)) result = {"ansible_facts": {"insights": response}} module.exit_json(changed=False, **result)
def test_bare_files(tmpdir): d = tmpdir / "bare" d.mkdir() p = d / 'sample.log' p.write(SAMPLE_LOG) data = [l.strip() for l in SAMPLE_LOG.splitlines()] testargs = [ "insights-run", "-t", "-m", "-b", 'insights.tests.spec_tests.TSpecs.sample_multioutput_file={fname}'. format(fname=os.path.join(tmpdir.strpath, 'bare', 'sample.log')), "-p", "insights.tests.spec_tests" ] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert report_multioutput in broker assert broker[report_multioutput] == make_fail('MO_SPEC', data=data, number=1) testargs = [ "insights-run", "-t", "-m", "-b", 'insights.tests.spec_tests.TSpecs.sample_nonexistent={fname}'.format( fname=os.path.join(tmpdir.strpath, 'bare', 'sample.log')), "-p", "insights.tests.spec_tests" ] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert report_nonexistent in broker assert broker[report_nonexistent] == make_fail('NE_SPEC', data=data) testargs = [ "insights-run", "-t", "-m", "-b", 'insights.tests.spec_tests.TSpecs.sample_raw_file={fname}'.format( fname=os.path.join(tmpdir.strpath, 'bare', 'sample.log')), "-p", "insights.tests.spec_tests" ] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert report_raw in broker with open(os.path.join(tmpdir.strpath, 'bare', 'sample.log'), 'rb') as fh: data_b = fh.read() assert broker[report_raw] == make_fail('RA_SPEC', data=data_b)
async def extract_facts(archive): facts = {} with extract(archive) as ex: broker = run(root=ex.tmp_dir) for k, v in CANONICAL_FACTS.items(): facts[k] = ('\n'.join(broker[v].content)) return facts
def get_canonical_facts(path=None): set_enabled(canonical_facts, True) set_enabled(SubscriptionManagerID, True) set_enabled(IPs, True) br = run(canonical_facts, root=path) d = br[canonical_facts] del d["type"] return d
def get_performance_profile(report_url): with _download_and_extract_report(report_url) as archive: try: broker = run(performance_profile, root=archive.tmp_dir) result = broker[performance_profile] del result["type"] return result except Exception as e: LOG.error("Failed to extract performance_profile: %s", e)
def test_run_command(): broker = run([always_fires.report, never_fires.report]) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT test_archive = os.path.join(os.path.dirname(insights.__file__), 'archive/repository/base_archives/rhel7') broker = run([Specs.redhat_release, always_fires.report, never_fires.report], root=test_archive) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT assert Specs.redhat_release in broker assert broker[Specs.redhat_release].content == [REDHAT_RELEASE] testargs = ["insights-run", "-p", "insights.plugins"] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT testargs = ["insights-run", "-p", "insights.plugins", test_archive] with patch.object(sys, 'argv', testargs): broker = run(print_summary=True) assert broker is not None assert always_fires.report in broker assert never_fires.report in broker assert broker[always_fires.report] == ALWAYS_FIRES_RESULT assert broker[never_fires.report] == NEVER_FIRES_RESULT assert Specs.uname in broker assert broker[Specs.uname].content == [UNAME]
def run_profile(): args = None import argparse import os import sys p = argparse.ArgumentParser(add_help=False) p.add_argument("archive", nargs="?", help="Archive to analyze.") args = p.parse_args() root = args.archive if root: root = os.path.realpath(root) try: broker = run(system_profile, root=root) result = broker[system_profile] print(result) except Exception as e: print("something went wrong: %s" % e) sys.exit(1)
def get_performance_profile(report_url, account_number, custom_prefix=prefix): with _download_and_extract_report(report_url, account_number, custom_prefix=custom_prefix) as archive: try: LOG.debug( "%s - Extracting performance profile from the report present at %s.\n", custom_prefix, report_url) broker = run(performance_profile, root=archive.tmp_dir) result = broker[performance_profile] del result["type"] LOG.debug( "%s - Extracted performance profile from the report successfully present at %s.\n", custom_prefix, report_url) return result except Exception as e: processor_requests_failures.labels( reporter='INVENTORY EVENTS', account_number=account_number).inc() LOG.error( "%s - Failed to extract performance_profile from the report present at %s. ERROR - %s\n", custom_prefix, report_url, e)
canonical_facts = [ Specs.machine_id, Specs.hostname, Specs.redhat_release, Specs.uname, ] def get_archive_name(): import sys import os if len(sys.argv) < 2: print("Need archive name") sys.exit(1) archive_name = sys.argv[1] if not os.path.exists(archive_name): print(f"Invalid archive path: {archive_name}") sys.exit(1) return archive_name if __name__ == "__main__": with extract(get_archive_name()) as ex: broker = run(root=ex.tmp_dir) for fact in canonical_facts: print("\n".join(broker[fact].content))
from insights.core.dr import SkipComponent from insights import rule from insights.parsers.redhat_release import RedhatRelease from insights.core.plugins import make_none @rule(RedhatRelease) def report_none(u): return @rule(RedhatRelease) def report_make_none(u): return make_none() @rule(RedhatRelease) def report_skip_exception(u): raise SkipComponent() if __name__ == "__main__": from insights import run broker = run([report_none, report_make_none], print_summary=True)
def get_tree(root=None): """ This is a helper function to get an httpd configuration component for your local machine or an archive. Use it in interactive sessions. """ return run(HttpdConfTree, root=root).get(HttpdConfTree)
name="salog") @parser(activeconfig) class ActiveConfig(Parser): def parse_content(self, content): doc = json.loads(content) self.data = doc["result"] @parser(sacfg) class StandAloneXML(Parser): def parse_content(self, content): self.root = ET.fromstring(content) @rule(salog, StandAloneXML) def report(log, cfg): return make_response("SOMETHING_HAPPENED") @rule(StandAloneXML) def report2(cfg): return make_response("SOMETHING_ELSE_HAPPENED") if __name__ == "__main__": run(print_summary=True, run_context=JBossContext, archive_context=JDRContext)
def get_canonical_facts(path=None): br = run(canonical_facts, root=path) d = br[canonical_facts] del d["type"] return d
$ python bash_bug.py """ from insights import rule, make_pass, make_fail from insights.parsers.installed_rpms import InstalledRpm, InstalledRpms ERROR_KEY_BASH_BUG = "BASH_BUG" CONTENT = {ERROR_KEY_BASH_BUG: "{{found}}{{bash}}"} @rule(InstalledRpms) def check_bash_bug(rpms): bug_version = InstalledRpm.from_package('bash-4.4.14-1.any') fix_version = InstalledRpm.from_package('bash-4.4.18-1.any') current_version = rpms.get_max('bash') if bug_version <= current_version < fix_version: found = "Bash bug found! Version: " return make_fail(ERROR_KEY_BASH_BUG, bash=current_version.nvr, found=found) else: not_found = "Bash bug not found: " return make_pass(ERROR_KEY_BASH_BUG, bash=current_version.nvr, found=not_found) if __name__ == "__main__": from insights import run run(check_bash_bug, print_summary=True)
return {"hostname": host.fqdn} @rule(bash_version, get_hostname, cluster=True) def bash_rule(bash, hostnames): """ Cluster rule to process bash and hostname info ``bash`` and ``hostnames`` are Pandas DataFrames for the facts collected for each host in the cluster. See https://pandas.pydata.org/pandas-docs/stable/api.html#dataframe for information on available attributes and methods. Arguments: bash (pandas.DataFrame): Includes facts from ``bash_version`` fact with columns "name" and "version" and one row per host in the cluster. hostnames (pandas.DataFrame): Includes facts from ``get_hostname`` fact with column "hostname" and one row per host in the cluster. """ if isinstance(bash, dict): return make_fail('bash_rule', error_message="Run this rule with a cluster archive") return make_pass('bash_rule', bash=bash, hostname=hostnames) if __name__ == "__main__": run(bash_rule, print_summary=True)
def post(self): """Answer POST request. curl -X POST -F "file=@./file.tar.gz" http://localhost:8100/api/v1/upload curl -X POST -F "file=@./file.tar.gz" -H "x-upload-multiplier: 10" http://localhost:8100/api/v1/upload """ if self.request.files and "file" in self.request.files: sha1 = hashlib.sha1( self.request.files["file"][0]["body"]).hexdigest() file_name = "%s.tar.gz" % sha1 file_path = os.path.join(STORAGE_PATH, file_name) if not os.path.exists(file_path): with open(file_path, "wb") as open_file: open_file.write(self.request.files["file"][0]["body"]) if sha1 in self.application.archive_to_profile_cache: profile = self.application.archive_to_profile_cache[sha1] else: broker = run(system_profile, root=file_path) profile = broker[system_profile] self.application.archive_to_profile_cache[sha1] = profile self.application.inventory_id_to_profile_cache[profile.get( "id", None)] = profile download_url = "http://platform_mock:8000/api/v1/download/%s" % file_name rh_account = self._get_rh_account() timestamp = datetime.now(timezone.utc).isoformat() upload_message = { "host": { "id": profile.get("id", None), "account": rh_account, "display_name": sha1 + ".example.com", "system_profile": { "installed_packages": profile["installed_packages"], "yum_repos": [{ "id": r, "name": r, "enabled": True } for r in profile["yum_repos"]], "dnf_modules": profile["dnf_modules"], "insights_client_version": "3.0.13-1" }, "insights_id": "0" }, "platform_metadata": { "request_id": str(uuid.uuid1()), "url": download_url, "b64_identity": self.request.headers.get("x-rh-identity", "") }, "timestamp": timestamp, "type": "created" } for _ in range(self._get_upload_multiplier()): self.application.queue.send(upload_message) with DatabasePoolConnection() as conn: with conn.cursor() as cur: cur.execute( """ insert into inventory.hosts_v1_1 values (%s, 0, %s, '[]', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '2030-07-21 05:35:53.682554+00', '{}') on conflict (id) do update set display_name = EXCLUDED.display_name, updated = CURRENT_TIMESTAMP """, (upload_message["host"]["id"], upload_message["host"]["display_name"])) conn.commit() LOGGER.info("New upload: %s", upload_message) else: self.set_status(400) self.finish()
hp (ParserFedoraHosts): Parser object for the custom parser in this module. This parser will only fire if the content is from a Fedora server """ if len(hp.hosts) > 1: return make_fail("TOO_MANY_HOSTS", num=len(hp.hosts)) return make_pass("TOO_MANY_HOSTS", num=len(hp.hosts)) # This rule will only fire for `Rhel 6 or 7 Hosts' because the parser is short circuited # for any host except `Rhel 6 or 7` @rule(ParseRhelAll, content=CONTENT) def report_rhel_others(hp): """ Rule reports a response if there is more than 1 host entry defined in the /etc/hosts file. Arguments: hp (HostParser): Parser object for the custom parser in this module. """ if len(hp.hosts) > 1: return make_fail("TOO_MANY_HOSTS", num=len(hp.hosts)) return make_pass("TOO_MANY_HOSTS", num=len(hp.hosts)) if __name__ == "__main__": run(report_rhel8, print_summary=True) run(report_rhel_others, print_summary=True)
#!/usr/bin/env python from insights import run from insights.parsers.installed_rpms import InstalledRpms from insights.combiners.hostname import hostname from insights.core.plugins import fact, rule @fact(InstalledRpms) def bash_version(rpms): rpm = rpms.get_max("bash") return {"name": rpm.name, "version": rpm.nvr} @fact(hostname) def get_hostname(hn): return {"hostname": hn.fqdn} @rule(bash_version, get_hostname, cluster=True) def bash_rule(bash, hn): pass if __name__ == "__main__": run(bash_version, print_summary=True)
def get_system_profile(path=None): broker = run(system_profile, root=path) result = broker[system_profile] del result["type"] # drop metadata key return result
from insights import run if __name__ == "__main__": run(print_summary=True)
def bash_affected(rpms): rpm = rpms.get_max("bash") if rpm and rpm >= LOWER and rpm < UPPER: return make_response("BASH_AFFECTED", version=rpm.nvr) elif rpm: return make_response("BASH_UNAFFECTED", version=rpm.nvr) else: return make_response("NO_BASH") if __name__ == "__main__": from sys import argv RULE_NAMES = ["bash_installed", "bash_affected"] if len(argv) < 2: print("Pass a rule name as an argument. Valid rules: {}".format( RULE_NAMES)) exit(1) rule_name = argv[1] if rule_name not in RULE_NAMES: print("{} is not a valid rule name. Valid rules: {}".format( rule_name, RULE_NAMES)) exit(2) rule_func = globals()[rule_name] result = run(rule_func) print(result[rule_func])
{% for idx, row in good.iterrows() -%} {{row.machine_id}}: {{GREEN}}[passed]{{NC}} {% endfor %} {% for idx, row in bad.iterrows() -%} {{row.machine_id}}: {{RED}}[failed]{{NC}} - reason: {{row.cpu_count}} is less than the expected {{nocpu_expected}} cores {% endfor %} """.strip() NODE_CONTENT = """ {% for idx, row in infos.iterrows() %} {{row.machine_id}}: CPUS: {{row.cpu_count}} {%- if row.pods_per_core_customized -%} {{YELLOW}} pods-per-core customized: {{row.pods_per_core}}{{NC}} {% endif %} {%- if row.max_pods_customized -%} {{YELLOW}} max-pods customized: {{row.max_pods}}{{NC}} {% endif %} max pods: {{row.max_pods}} {% endfor %} """.strip() CONTENT = { "MASTER_ETCD": MASTER_CONTENT, "INFRA": NODE_CONTENT, "NODES": NODE_CONTENT + """ ================================ max app pods cluster: {{max_pod_cluster}} """.strip() } if __name__ == "__main__": from insights import run run([report_master, report_etcd, report_infra, report_nodes], print_summary=True)
#!/usr/bin/env python from insights.core.plugins import make_response, rule from insights.parsers.redhat_release import RedhatRelease @rule(RedhatRelease) def report(rel): """Fires if the machine is running Fedora.""" if "Fedora" in rel.product: return make_response("IS_FEDORA") else: return make_response("IS_NOT_FEDORA") if __name__ == "__main__": from insights import run run(report, print_summary=True)
class _NginxConf(ConfigParser): def parse_doc(self, content): return parse_doc("\n".join(content), ctx=self) @combiner(_NginxConf) class NginxConfTree(ConfigCombiner): """ Exposes nginx configuration through the configtree interface. See the :py:class:`insights.core.ConfigComponent` class for example usage. """ def __init__(self, confs): super(NginxConfTree, self).__init__(confs, "nginx.conf", eq("include")) @property def conf_path(self): return os.path.dirname(self.main.file_path) def get_tree(root=None): """ This is a helper function to get an nginx configuration component for your local machine or an archive. It's for use in interactive sessions. """ return run(NginxConfTree, root=root).get(NginxConfTree) if __name__ == "__main__": run(NginxConfTree, print_summary=True)
res = self.main.find("ServerRoot") return res.value if res else "/opt/rh/jbcs-httpd24/root/etc/httpd" def get_tree(root=None): """ This is a helper function to get an httpd configuration component for your local machine or an archive. Use it in interactive sessions. """ return run(HttpdConfTree, root=root).get(HttpdConfTree) is_private = pred(lambda x: ip_address(six.u(x)).is_private) """ Predicate to check if an ip address is private. Example: conf["VirtualHost", in_network("128.39.0.0/16")] """ in_network = pred2(lambda x, y: (ip_address(six.u(x)) in ip_network(six.u(y)))) """ Predicate to check if an ip address is in a given network. Example: conf["VirtualHost", in_network("128.39.0.0/16")] """ if __name__ == "__main__": run(HttpdConfTree, print_summary=True)
def get_tree(root=None): """ This is a helper function to get an nginx configuration component for your local machine or an archive. It's for use in interactive sessions. """ return run(NginxConfTree, root=root).get(NginxConfTree)
def run(self): from insights import run if "" not in sys.path: sys.path.insert(0, "") run(print_summary=True)
This function is registered globally with insights core to watch fact_set components as they're evaluated. """ if component in broker: system_id = None value = broker[component] if Specs.machine_id in broker: system_id = broker[Specs.machine_id].content[0] if isinstance(value, list): for v in value: v.system_id = system_id session.add_all(value) else: value.system_id = system_id session.add(value) session.commit() # register the saver above to watch fact_sets dr.add_observer(saver, fact_set) dr.add_finished_loading_callback(loading_finished) # run our components if __name__ == "__main__": dr.load_components("insights_facts.plugins") comps = dr.COMPONENTS_BY_TYPE[fact_set] run(comps, print_summary=True)