template restructure
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import Dict, List, Set, Optional, Any
|
||||
from ipaddress import ip_address
|
||||
|
||||
@dataclass
|
||||
class PortFinding:
|
||||
@@ -16,7 +16,6 @@ class PortFinding:
|
||||
state: str
|
||||
service: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class HostResult:
|
||||
"""
|
||||
@@ -28,3 +27,68 @@ class HostResult:
|
||||
address: str
|
||||
host: Optional[str] = None
|
||||
ports: List[PortFinding] = field(default_factory=list)
|
||||
|
||||
@dataclass
|
||||
class HostReport:
|
||||
"""
|
||||
Delta result for a single host.
|
||||
"""
|
||||
ip: str
|
||||
unexpected_tcp: List[int]
|
||||
missing_tcp: List[int]
|
||||
unexpected_udp: List[int]
|
||||
missing_udp: List[int]
|
||||
|
||||
def has_issues(self) -> bool:
|
||||
"""
|
||||
Returns True if any delta list is non-empty.
|
||||
"""
|
||||
if self.unexpected_tcp:
|
||||
return True
|
||||
if self.missing_tcp:
|
||||
return True
|
||||
if self.unexpected_udp:
|
||||
return True
|
||||
if self.missing_udp:
|
||||
return True
|
||||
return False
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Convert to a plain dict for JSON/Jinja contexts.
|
||||
"""
|
||||
return asdict(self)
|
||||
|
||||
@dataclass
|
||||
class GroupedReports:
|
||||
"""
|
||||
Final, template-friendly structure:
|
||||
- issues: list of HostReport with any deltas (sorted by IP)
|
||||
- expected: list of HostReport with no deltas (sorted by IP)
|
||||
- by_ip: mapping for random access if needed
|
||||
"""
|
||||
issues: List[HostReport]
|
||||
expected: List[HostReport]
|
||||
by_ip: Dict[str, HostReport]
|
||||
|
||||
def to_context(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Produce plain-dict context for Jinja render() if you prefer dicts.
|
||||
"""
|
||||
issues_dicts: List[Dict[str, Any]] = []
|
||||
for hr in self.issues:
|
||||
issues_dicts.append(hr.to_dict())
|
||||
|
||||
expected_dicts: List[Dict[str, Any]] = []
|
||||
for hr in self.expected:
|
||||
expected_dicts.append(hr.to_dict())
|
||||
|
||||
by_ip_dict: Dict[str, Dict[str, Any]] = {}
|
||||
for ip, hr in self.by_ip.items():
|
||||
by_ip_dict[ip] = hr.to_dict()
|
||||
|
||||
return {
|
||||
"issues": issues_dicts,
|
||||
"expected": expected_dicts,
|
||||
"by_ip": by_ip_dict,
|
||||
}
|
||||
Reference in New Issue
Block a user