05 — Rulebase Queries (05_rulebase_queries.py)¶
Demonstrates policy package discovery (client.get_policy_packages()), hierarchical SmartConsole numbering (client.get_package_rulebase(), client.get_layer_rulebase()), reverse UID lookup (client.locate_rules()), and local rulebase filtering (client.filter_rulebase(), including output_format="cpcrud").
Source Code (examples/05_rulebase_queries.py)¶
examples/05_rulebase_queries.py
"""Example 05 — Rulebase introspection, hierarchical SmartConsole numbering, and local filtering.
Run:
uv run examples/05_rulebase_queries.py
Demonstrates:
1. `client.get_policy_packages(mgmt_name, domain)` — list cached policy packages and layers.
2. `client.get_package_rulebase(mgmt_name, domain, package)` — hierarchical SmartConsole rule
numbers (`1`, `2.1`, `2.2.1`) across ordered Global/Domain layers and inline sub-layers.
3. `client.locate_rules(mgmt_name, domain, rule_uids=[...])` — reverse lookup from rule UID to
SmartConsole rule numbers across packages.
4. `client.filter_rulebase(...)` — local rulebase query evaluation (`src:`, `dst:`, `svc:`,
`action:`, free text, CIDR containment) rendered in `markdown` or `model_friendly` format.
"""
from __future__ import annotations
import asyncio
import os
import time
from dotenv import load_dotenv
load_dotenv(".env.lib", override=True)
load_dotenv(".env.secrets", override=True)
from arodonata import ArodonataClient, ArodonataSettings # noqa: E402
async def main() -> None:
"""Inspect policy packages, numbered rulebases, rule locations, and local rule filtering."""
settings = ArodonataSettings()
t0 = time.perf_counter()
async with ArodonataClient(settings=settings) as client:
print("[Step 1/5] Resolving target domain (get_domains)...", flush=True)
domains = await client.get_domains()
if not domains:
print("No domains discovered.")
return
dom = next((d for d in domains if d.name == os.getenv("EXAMPLE_DOMAIN")), domains[0])
mgmt_name = dom.mgmt_name
domain_name = dom.name
print(f"[Step 2/5] Ensuring rulebase cache for {mgmt_name}:{domain_name} (refresh_rulebases)...", flush=True)
await client.refresh_rulebases(mgmt_name=mgmt_name, domains=[domain_name], mode="smart")
print(f"[Step 3/5] Listing policy packages in {domain_name} (get_policy_packages)...", flush=True)
packages = await client.get_policy_packages(mgmt_name, domain_name, cache_mode="cache")
if not packages:
print(f"No policy packages cached in {domain_name}.")
return
pkg = packages[0]
print(f"\nPolicy Package: {pkg.name} (uid={pkg.uid})")
print(f" Access layers: {[lay.layer_name for lay in pkg.access_layers]}")
print(
f"\n[Step 4/5] Computing hierarchical SmartConsole rule numbers for {pkg.name!r} (get_package_rulebase)...",
flush=True,
)
pkg_rb = await client.get_package_rulebase(
mgmt_name,
domain_name,
pkg.name,
rulebase_type="access",
cache_mode="cache",
)
for layer in pkg_rb.layers:
print(f"\nLayer {layer.layer_name!r} (prefix={layer.prefix!r}, rules={len(layer.rules)}):")
for nr in layer.rules[:5]:
print(f" #{nr.rule_number:<6} {nr.name or '(unnamed)':<28} action={nr.action} enabled={nr.enabled}")
access_rules = await client.get_access_rules(mgmt_name, domain_name)
if access_rules:
sample = access_rules[0]
locs = await client.locate_rules(
mgmt_name,
domain_name,
rule_uids=[sample.uid],
cache_mode="cache",
)
print(f"\nLocated rule UID {sample.uid}: {locs.rule_locations.get(sample.uid)}")
print("\n[Step 5/5] Filtering rulebase locally (filter_rulebase)...", flush=True)
filtered = await client.filter_rulebase(
mgmt_name,
domain_name,
package=pkg.name,
rulebase_type="access",
filter_query=os.getenv("EXAMPLE_RULE_FILTER", "action:Accept"),
output_format="markdown",
cache_mode="cache",
)
print(f"\nFiltered rulebase ({filtered.matched_count}/{filtered.total_rules} matching rules):")
print("\n".join(filtered.rendered_text.splitlines()[:15]))
print(f"\nCompleted in {time.perf_counter() - t0:.2f}s")
if __name__ == "__main__":
asyncio.run(main())