diff --git a/humitifier/db/queries.sql b/humitifier/db/queries.sql index d02be54..5254e40 100644 --- a/humitifier/db/queries.sql +++ b/humitifier/db/queries.sql @@ -1,13 +1,20 @@ -- name: bulk_insert_host_facts*! insert into - host_facts (host, timestamp, facts, exceptions) + host_facts (host, timestamp, raw_output, facts, exceptions) values - (:host, :timestamp, :facts, :exceptions); + ( + :host, + :timestamp, + :raw_output, + :facts, + :exceptions + ); -- name: get_latest_host_facts select host, timestamp, + raw_output, facts, exceptions from diff --git a/humitifier/db/schema.sql b/humitifier/db/schema.sql index f262369..e2b7691 100644 --- a/humitifier/db/schema.sql +++ b/humitifier/db/schema.sql @@ -3,6 +3,7 @@ create table if not exists host_facts ( id integer primary key autoincrement, host text, timestamp integer, + raw_output text, facts text, exceptions text ); \ No newline at end of file diff --git a/humitifier/infra/facts/__init__.py b/humitifier/infra/facts/__init__.py index e7a6138..6fc0db7 100644 --- a/humitifier/infra/facts/__init__.py +++ b/humitifier/infra/facts/__init__.py @@ -1,5 +1,4 @@ import asyncio -import time from .blocks import Blocks from .groups import Groups from .hostnamectl import HostnameCtl @@ -66,11 +65,11 @@ async def element_to_fact(el: str) -> Fact: try: fact = FACT_TABLE[alias] except KeyError as e: - return str(e) + return f"ParseError(KeyError): {str(e)}" try: return fact.from_stdout(stdout) except Exception as e: - return str(e) + return f"ParseError: {str(e)}" async def query_inventory_outputs(hosts) -> list[HostOutput]: diff --git a/humitifier/infra/models/hostfacts.py b/humitifier/infra/models/hostfacts.py index 6dadc93..252f560 100644 --- a/humitifier/infra/models/hostfacts.py +++ b/humitifier/infra/models/hostfacts.py @@ -11,11 +11,12 @@ class HostFacts: fqdn: str timestamp: int + raw_output: str facts: dict exceptions: list[str] | None = None @classmethod - async def from_output(cls, output: HostOutput, ts) -> "HostFacts": + async def from_output(cls, output: HostOutput, ts: int) -> "HostFacts": if output.exception: return cls(output.host, ts, {}, [str(output.exception)]) stdout = "\n".join(list(output.stdout)).strip() @@ -24,7 +25,7 @@ async def from_output(cls, output: HostOutput, ts) -> "HostFacts": parsed = await asyncio.gather(*tasks) facts = [f for f in parsed if not isinstance(f, str)] excpetions = [f for f in parsed if isinstance(f, str)] - return cls(output.host, ts, {f.alias: f for f in facts}, excpetions or None) + return cls(output.host, ts, stdout, {f.alias: f for f in facts}, excpetions or None) @property async def sql_row(self) -> str: @@ -32,15 +33,16 @@ async def sql_row(self) -> str: return ( self.fqdn, self.timestamp, + self.raw_output, json.dumps(fact_data), json.dumps(self.exceptions), ) @classmethod async def from_sql_row(cls, row) -> "HostFacts": - fqdn, timestamp, facts, exceptions = row + fqdn, timestamp, raw_output, facts, exceptions = row fact_data = {k: FACT_TABLE[k].from_sql(v) for k, v in json.loads(facts).items()} - return cls(fqdn, timestamp, fact_data, json.loads(exceptions)) + return cls(fqdn, timestamp, raw_output, fact_data, json.loads(exceptions)) @property def last_scan(self) -> str: