diff --git a/backend/src/api/nft_manager.py b/backend/src/api/nft_manager.py index 614ea26..1505ec6 100644 --- a/backend/src/api/nft_manager.py +++ b/backend/src/api/nft_manager.py @@ -69,79 +69,6 @@ class NftManager: raise NftError(f"nft list ruleset failed: {res['stderr']}") return res["stdout"] or "" - def list_chain_text(self, family: str, table: str, chain: str) -> str: - cmd = f"list chain {family} {table} {chain}" - json_toggled = False - res = {"rc": -1, "stdout": "", "stderr": "unknown"} - try: - if hasattr(self.nft, "set_json_output"): - try: - self.nft.set_json_output(False) - json_toggled = True - except Exception: - logger.debug("could not toggle set_json_output(False)") - res = self.cmd(cmd) - finally: - if json_toggled and hasattr(self.nft, "set_json_output"): - try: - self.nft.set_json_output(True) - except Exception: - logger.debug("could not restore set_json_output(True)") - - if res["rc"] != 0: - raise NftError(f"nft {cmd} failed: {res['stderr']}") - - # If returned output is JSON-formatted (rare), we try to derive textual lines, - # otherwise return raw textual output. - out = res["stdout"] or "" - s = out.strip() - if s.startswith("{") or s.startswith("["): - try: - parsed = json.loads(s) - lines: List[str] = [] - records = parsed.get("nftables") if isinstance(parsed, dict) else parsed - if not isinstance(records, list): - records = [] - for rec in records: - if "rule" in rec: - r = rec["rule"] - expr = r.get("expr") - if isinstance(expr, list): - # summarized tokenization - toks: List[str] = [] - for part in expr: - if isinstance(part, dict) and "match" in part: - m = part["match"] - left = m.get("left") - right = m.get("right") - if isinstance(left, dict) and "payload" in left and isinstance(right, (str, int)): - p = left["payload"] - prot = p.get("protocol") - field = p.get("field") - if prot and field: - toks.append(f"{prot} {field} {right}") - continue - toks.append("match") - elif isinstance(part, dict) and "drop" in part: - toks.append("drop") - elif isinstance(part, dict) and "accept" in part: - toks.append("accept") - elif isinstance(part, dict) and "counter" in part: - toks.append("counter") - else: - if isinstance(part, dict): - toks.append("+".join(part.keys())) - else: - toks.append(str(part)) - lines.append(" ".join(toks)) - else: - lines.append(json.dumps(r)) - if lines: - return "\n".join(lines) - except Exception: - logger.debug("fallback json->text derivation failed; returning raw output") - - return out def delete_rule_by_handle_text(self, family: str, table: str, chain: str, handle: int) -> None: if not isinstance(handle, int) or handle <= 0: @@ -212,8 +139,6 @@ class RulesetOut(BaseModel): # ---------- Helpers ---------- -_handle_re = re.compile(r"\s+#\s*handle\s+\d+\s*$") - def parse_priority(val: Any) -> Optional[int]: if val is None: