PiHoleV6
PiHole V6 integration using the new REST API. PiHole is a network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole.
IT Services · PiHole
Details
| ID | PiHoleV6 |
|---|---|
| Provider | Open Source |
| Category | IT Services |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
PiHole v6 integration using the new REST API. PiHole is a network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server, intended for use on a private network.
This integration was integrated and tested with PiHole v6.0 API.
Configure PiHole v6 in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | Server URL (e.g. https://192.168.1.25) | True |
| password | PiHole admin password for API authentication | True |
| insecure | Trust any certificate (not secure) | False |
| proxy | Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
pihole-get-summary
Get overview of PiHole activity including query stats, client counts, and gravity info.
Base Command
pihole-get-summary
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Summary.queries | Unknown | Query statistics including total, blocked, cached, forwarded counts. |
| PiHoleV6.Summary.clients | Unknown | Client statistics. |
| PiHoleV6.Summary.gravity | Unknown | Gravity list statistics. |
pihole-get-top-domains
Get top permitted or blocked domains.
Base Command
pihole-get-top-domains
Input
| Argument Name | Description | Required |
|---|---|---|
| count | Number of top domains to return. Default is 10. | Optional |
| blocked | If true, return top blocked domains instead of top permitted domains. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.TopDomains.domains | Unknown | Array of top domains with counts. |
| PiHoleV6.TopDomains.total_queries | Number | Total number of queries. |
pihole-get-top-clients
Get top clients by query count.
Base Command
pihole-get-top-clients
Input
| Argument Name | Description | Required |
|---|---|---|
| count | Number of top clients to return. Default is 10. | Optional |
| blocked | If true, return top blocked clients instead of top active clients. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.TopClients.clients | Unknown | Array of top clients with counts. |
| PiHoleV6.TopClients.total_queries | Number | Total number of queries. |
pihole-get-upstreams
Get metrics about upstream DNS destinations.
Base Command
pihole-get-upstreams
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Upstreams.upstreams | Unknown | Array of upstream destinations with query counts and response times. |
| PiHoleV6.Upstreams.forwarded_queries | Number | Number of forwarded queries. |
pihole-get-query-types
Get breakdown of DNS query types.
Base Command
pihole-get-query-types
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.QueryTypes.types | Unknown | Query type counts (A, AAAA, MX, etc). |
pihole-get-recent-blocked
Get most recently blocked domain(s).
Base Command
pihole-get-recent-blocked
Input
| Argument Name | Description | Required |
|---|---|---|
| count | Number of recently blocked domains to return. Default is 1. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.RecentBlocked.blocked | Unknown | List of recently blocked domains. |
pihole-get-history
Get activity graph data (queries over time).
Base Command
pihole-get-history
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.History.history | Unknown | Activity over time data with timestamps, total, cached, blocked, forwarded counts. |
pihole-get-history-clients
Get per-client activity graph data.
Base Command
pihole-get-history-clients
Input
| Argument Name | Description | Required |
|---|---|---|
| N | Maximum number of clients to return. 0 returns all. Default is 20. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.HistoryClients.clients | Unknown | Client information with query counts. |
| PiHoleV6.HistoryClients.history | Unknown | Per-client activity over time. |
pihole-get-queries
Get DNS query log with optional filtering.
Base Command
pihole-get-queries
Input
| Argument Name | Description | Required |
|---|---|---|
| length | Number of queries to return. Default is 100. | Optional |
| domain | Filter by domain (wildcards supported). | Optional |
| client_ip | Filter by client IP (wildcards supported). | Optional |
| client_name | Filter by client hostname (wildcards supported). | Optional |
| upstream | Filter by upstream server. | Optional |
| type | Filter by query type (A, AAAA, etc). | Optional |
| status | Filter by status (GRAVITY, FORWARDED, CACHE, etc). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Queries.queries | Unknown | Array of DNS query records. |
| PiHoleV6.Queries.recordsTotal | Number | Total number of available queries. |
pihole-get-blocking-status
Get current PiHole blocking status.
Base Command
pihole-get-blocking-status
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Blocking.blocking | String | Current blocking status (enabled/disabled). |
| PiHoleV6.Blocking.timer | Number | Remaining seconds until blocking mode changes automatically. Null if permanent. |
pihole-set-blocking
Enable or disable PiHole blocking, optionally with a timer.
Base Command
pihole-set-blocking
Input
| Argument Name | Description | Required |
|---|---|---|
| blocking | Enable or disable blocking. Possible values are: true, false. | Required |
| timer | Seconds until blocking mode automatically reverts. Leave empty for permanent change. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Blocking.blocking | String | New blocking status. |
| PiHoleV6.Blocking.timer | Number | Timer value if set. |
pihole-get-domains
Get domains from allow/deny lists. Filter by type and kind.
Base Command
pihole-get-domains
Input
| Argument Name | Description | Required |
|---|---|---|
| type | Domain type filter. Possible values are: allow, deny. | Optional |
| kind | Domain kind filter. Possible values are: exact, regex. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Domains.domains | Unknown | Array of domain entries. |
pihole-add-domain
Add a domain to allow/deny list.
Base Command
pihole-add-domain
Input
| Argument Name | Description | Required |
|---|---|---|
| type | Domain type. Possible values are: allow, deny. | Required |
| kind | Domain kind. Possible values are: exact, regex. | Required |
| domain | Domain to add. | Required |
| comment | Optional comment. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Domains.domains | Unknown | Added domain details. |
pihole-delete-domain
Delete a domain from allow/deny list.
Base Command
pihole-delete-domain
Input
| Argument Name | Description | Required |
|---|---|---|
| type | Domain type. Possible values are: allow, deny. | Required |
| kind | Domain kind. Possible values are: exact, regex. | Required |
| domain | Domain to delete. | Required |
Context Output
There is no context output for this command.
pihole-get-version
Get PiHole component versions.
Base Command
pihole-get-version
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Version | Unknown | Version information for all PiHole components. |
pihole-get-system-info
Get system information from PiHole host.
Base Command
pihole-get-system-info
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.SystemInfo | Unknown | System information (CPU, memory, disk, uptime, etc). |
pihole-get-ftl-info
Get FTL (Faster Than Light) engine information.
Base Command
pihole-get-ftl-info
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.FTLInfo | Unknown | FTL engine information. |
pihole-get-host-info
Get host information.
Base Command
pihole-get-host-info
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.HostInfo | Unknown | Host information. |
pihole-get-sensors
Get sensor information from PiHole host.
Base Command
pihole-get-sensors
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Sensors | Unknown | Sensor readings (temperature, etc). |
pihole-run-gravity
Update PiHole gravity (pull latest adlists).
Base Command
pihole-run-gravity
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Gravity.output | String | Gravity update output. |
pihole-restart-dns
Restart the pihole-FTL DNS service.
Base Command
pihole-restart-dns
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.RestartDNS | Unknown | Restart result. |
pihole-flush-logs
Flush DNS logs and purge last 24 hours from database.
Base Command
pihole-flush-logs
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.FlushLogs | Unknown | Flush result. |
pihole-flush-network
Flush the network table (remove all known devices and addresses).
Base Command
pihole-flush-network
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.FlushNetwork | Unknown | Flush result. |
pihole-get-network-devices
Get network devices known to PiHole.
Base Command
pihole-get-network-devices
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.NetworkDevices | Unknown | Network device information. |
pihole-get-network-gateway
Get network gateway information.
Base Command
pihole-get-network-gateway
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Gateway | Unknown | Gateway information. |
pihole-search-domain
Search for a domain across all PiHole lists and configuration.
Base Command
pihole-search-domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | Domain to search for. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Search | Unknown | Search results showing where the domain appears in PiHole configuration. |
pihole-get-dhcp-leases
Get current DHCP leases.
Base Command
pihole-get-dhcp-leases
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.DHCPLeases | Unknown | DHCP lease information. |
pihole-get-groups
Get all groups.
Base Command
pihole-get-groups
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Groups | Unknown | Group information. |
pihole-add-group
Create a new group.
Base Command
pihole-add-group
Input
| Argument Name | Description | Required |
|---|---|---|
| name | Group name. | Required |
| comment | Optional comment. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Groups | Unknown | Created group details. |
pihole-delete-group
Delete a group.
Base Command
pihole-delete-group
Input
| Argument Name | Description | Required |
|---|---|---|
| name | Group name to delete. | Required |
Context Output
There is no context output for this command.
pihole-get-lists
Get all configured adlists.
Base Command
pihole-get-lists
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Lists | Unknown | Adlist information. |
pihole-add-list
Add a new adlist.
Base Command
pihole-add-list
Input
| Argument Name | Description | Required |
|---|---|---|
| address | URL of the adlist to add. | Required |
| comment | Optional comment. | Optional |
| enabled | Whether the list should be enabled. Possible values are: true, false. Default is true. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| PiHoleV6.Lists | Unknown | Added list details. |
pihole-delete-list
Delete an adlist.
Base Command
pihole-delete-list
Input
| Argument Name | Description | Required |
|---|---|---|
| address | URL of the adlist to delete. | Required |
Context Output
There is no context output for this command.
Configuration parameters
url— Server URL (required)password— Password (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (33)
-
pihole-add-domainAdd a domain to allow/deny list.
-
pihole-add-groupCreate a new group.
-
pihole-add-listAdd a new adlist.
-
pihole-delete-domainDelete a domain from allow/deny list.
-
pihole-delete-groupDelete a group.
-
pihole-delete-listDelete an adlist.
-
pihole-flush-logsFlush DNS logs and purge last 24 hours from database.
-
pihole-flush-networkFlush the network table (remove all known devices and addresses).
-
pihole-get-blocking-statusGet current PiHole blocking status.
-
pihole-get-dhcp-leasesGet current DHCP leases.
-
pihole-get-domainsGet domains from allow/deny lists. Filter by type and kind.
-
pihole-get-ftl-infoGet FTL (Faster Than Light) engine information.
-
pihole-get-groupsGet all groups.
-
pihole-get-historyGet activity graph data (queries over time).
-
pihole-get-history-clientsGet per-client activity graph data.
-
pihole-get-host-infoGet host information.
-
pihole-get-listsGet all configured adlists.
-
pihole-get-network-devicesGet network devices known to PiHole.
-
pihole-get-network-gatewayGet network gateway information.
-
pihole-get-queriesGet DNS query log with optional filtering.
-
pihole-get-query-typesGet breakdown of DNS query types.
-
pihole-get-recent-blockedGet most recently blocked domain(s).
-
pihole-get-sensorsGet sensor information from PiHole host.
-
pihole-get-summaryGet overview of PiHole activity including query stats, client counts, and gravity info.
-
pihole-get-system-infoGet system information from PiHole host.
-
pihole-get-top-clientsGet top clients by query count.
-
pihole-get-top-domainsGet top permitted or blocked domains.
-
pihole-get-upstreamsGet metrics about upstream DNS destinations.
-
pihole-get-versionGet PiHole component versions.
-
pihole-restart-dnsRestart the pihole-FTL DNS service.
-
pihole-run-gravityUpdate PiHole gravity (pull latest adlists).
-
pihole-search-domainSearch for a domain across all PiHole lists and configuration.
-
pihole-set-blockingEnable or disable PiHole blocking, optionally with a timer.
import demistomock as demisto from CommonServerPython import * """ IMPORTS """ import urllib3 # Disable insecure warnings urllib3.disable_warnings() class PiHoleV6Client(BaseClient): """Client class to interact with the PiHole v6 API.""" def __init__(self, base_url: str, password: str, verify: bool, proxy: bool): super().__init__(base_url=base_url, verify=verify, proxy=proxy) self.password = password self.sid: str | None = None def authenticate(self) -> None: """Authenticate with PiHole v6 and obtain a session ID.""" result = self._http_request("POST", "/auth", json_data={"password": self.password}) session = result.get("session", {}) if session.get("valid"): self.sid = session.get("sid") else: raise DemistoException(f"Authentication failed: {session.get('message', 'Unknown error')}") def logout(self) -> None: """Delete the current session.""" if self.sid: try: self._http_request("DELETE", "/auth", headers={"sid": self.sid}, resp_type="response") except Exception: pass def api_request( self, method: str, url_suffix: str, params: dict | None = None, json_data: dict | None = None, resp_type: str = "json" ) -> Any: """Make an authenticated API request.""" if not self.sid: self.authenticate() headers = {"sid": self.sid} return self._http_request(method, url_suffix, headers=headers, params=params, json_data=json_data, resp_type=resp_type) def results_return(command: str, data: Any, title: str = "", headers: list[str] | None = None) -> None: if not title: title = f"PiHole V6 - {command}" table_data: Any = data if isinstance(data, dict): # Find the best key to use for the table for key in data: if isinstance(data[key], list): table_data = data[key] break readable = tableToMarkdown(title, table_data, headers=headers, removeNull=True) return_results( CommandResults(outputs_prefix=f"PiHoleV6.{command}", outputs_key_field="", outputs=data, readable_output=readable) ) def test_module(client: PiHoleV6Client) -> str: """Test connectivity and authentication.""" client.authenticate() client.logout() return "ok" # --- Stats Commands --- def get_summary_command(client: PiHoleV6Client) -> None: data = client.api_request("GET", "/stats/summary") queries = data.get("queries", {}) gravity = data.get("gravity", {}) table = [ { "Total Queries": queries.get("total"), "Blocked": queries.get("blocked"), "Cached": queries.get("cached"), "Forwarded": queries.get("forwarded"), "Gravity Domains": gravity.get("domains_being_blocked"), } ] readable = tableToMarkdown("PiHole V6 - Summary", table, removeNull=True) return_results( CommandResults(outputs_prefix="PiHoleV6.Summary", outputs_key_field="", outputs=data, readable_output=readable) ) def get_top_domains_command(client: PiHoleV6Client, args: dict) -> None: params: dict = {} if args.get("count"): params["count"] = int(args["count"]) if args.get("blocked"): params["blocked"] = argToBoolean(args["blocked"]) results_return("TopDomains", client.api_request("GET", "/stats/top_domains", params=params), title="PiHole V6 - Top Domains") def get_top_clients_command(client: PiHoleV6Client, args: dict) -> None: params: dict = {} if args.get("count"): params["count"] = int(args["count"]) if args.get("blocked"): params["blocked"] = argToBoolean(args["blocked"]) results_return("TopClients", client.api_request("GET", "/stats/top_clients", params=params), title="PiHole V6 - Top Clients") def get_upstreams_command(client: PiHoleV6Client) -> None: results_return("Upstreams", client.api_request("GET", "/stats/upstreams"), title="PiHole V6 - Upstreams") def get_query_types_command(client: PiHoleV6Client) -> None: results_return("QueryTypes", client.api_request("GET", "/stats/query_types"), title="PiHole V6 - Query Types") def get_recent_blocked_command(client: PiHoleV6Client, args: dict) -> None: params: dict = {} if args.get("count"): params["count"] = int(args["count"]) results_return( "RecentBlocked", client.api_request("GET", "/stats/recent_blocked", params=params), title="PiHole V6 - Recently Blocked" ) # --- History Commands --- def get_history_command(client: PiHoleV6Client) -> None: results_return("History", client.api_request("GET", "/history"), title="PiHole V6 - History") def get_history_clients_command(client: PiHoleV6Client, args: dict) -> None: params: dict = {} if args.get("N"): params["N"] = int(args["N"]) results_return( "HistoryClients", client.api_request("GET", "/history/clients", params=params), title="PiHole V6 - History Clients" ) # --- Queries Commands --- def get_queries_command(client: PiHoleV6Client, args: dict) -> None: params: dict = {} for key in ["length", "domain", "client_ip", "client_name", "upstream", "type", "status"]: if args.get(key): params[key] = args[key] if args.get("length"): params["length"] = int(args["length"]) results_return("Queries", client.api_request("GET", "/queries", params=params), title="PiHole V6 - Queries") # --- DNS Blocking Commands --- def get_blocking_status_command(client: PiHoleV6Client) -> None: data = client.api_request("GET", "/dns/blocking") table = [{"Blocking": data.get("blocking"), "Timer": data.get("timer")}] readable = tableToMarkdown("PiHole V6 - Blocking Status", table, removeNull=True) return_results( CommandResults(outputs_prefix="PiHoleV6.Blocking", outputs_key_field="", outputs=data, readable_output=readable) ) def set_blocking_command(client: PiHoleV6Client, args: dict) -> None: blocking = argToBoolean(args.get("blocking", "true")) json_data: dict = {"blocking": blocking} timer = args.get("timer") if timer: json_data["timer"] = int(timer) else: json_data["timer"] = None data = client.api_request("POST", "/dns/blocking", json_data=json_data) table = [{"Blocking": data.get("blocking"), "Timer": data.get("timer")}] readable = tableToMarkdown("PiHole V6 - Set Blocking", table, removeNull=True) return_results( CommandResults(outputs_prefix="PiHoleV6.Blocking", outputs_key_field="", outputs=data, readable_output=readable) ) # --- Domain Management Commands --- def get_domains_command(client: PiHoleV6Client, args: dict) -> None: domain_type = args.get("type", "") kind = args.get("kind", "") suffix = "/domains" if domain_type: suffix += f"/{domain_type}" if kind: suffix += f"/{kind}" results_return("Domains", client.api_request("GET", suffix), title="PiHole V6 - Domains") def add_domain_command(client: PiHoleV6Client, args: dict) -> None: domain_type = args.get("type") kind = args.get("kind") domain = args.get("domain") comment = args.get("comment") json_data: dict = {"domain": domain} if comment: json_data["comment"] = comment results_return( "Domains", client.api_request("POST", f"/domains/{domain_type}/{kind}", json_data=json_data), title=f"PiHole V6 - Domain Added ({domain_type}/{kind})", ) def delete_domain_command(client: PiHoleV6Client, args: dict) -> None: domain_type = args.get("type") kind = args.get("kind") domain = args.get("domain") client.api_request("DELETE", f"/domains/{domain_type}/{kind}/{domain}", resp_type="response") return_results(CommandResults(readable_output=f"### Domain '{domain}' deleted from {domain_type}/{kind}.")) # --- Info Commands --- def get_version_command(client: PiHoleV6Client) -> None: data = client.api_request("GET", "/info/version") table = [ { "Core": data.get("core", {}).get("local", {}).get("version"), "Web": data.get("web", {}).get("local", {}).get("version"), "FTL": data.get("ftl", {}).get("local", {}).get("version"), } ] readable = tableToMarkdown("PiHole V6 - Version", table, removeNull=True) return_results( CommandResults(outputs_prefix="PiHoleV6.Version", outputs_key_field="", outputs=data, readable_output=readable) ) def get_system_info_command(client: PiHoleV6Client) -> None: results_return("SystemInfo", client.api_request("GET", "/info/system"), title="PiHole V6 - System Info") def get_ftl_info_command(client: PiHoleV6Client) -> None: results_return("FTLInfo", client.api_request("GET", "/info/ftl"), title="PiHole V6 - FTL Info") def get_host_info_command(client: PiHoleV6Client) -> None: results_return("HostInfo", client.api_request("GET", "/info/host"), title="PiHole V6 - Host Info") def get_sensors_command(client: PiHoleV6Client) -> None: results_return("Sensors", client.api_request("GET", "/info/sensors"), title="PiHole V6 - Sensors") # --- Action Commands --- def run_gravity_command(client: PiHoleV6Client) -> None: result = client.api_request("POST", "/action/gravity", resp_type="text") return_results( CommandResults( outputs_prefix="PiHoleV6.Gravity", outputs_key_field="", outputs={"output": result}, readable_output=f"### PiHole V6 - Gravity Update\n{result}", ) ) def restart_dns_command(client: PiHoleV6Client) -> None: results_return("RestartDNS", client.api_request("POST", "/action/restartdns"), title="PiHole V6 - Restart DNS") def flush_logs_command(client: PiHoleV6Client) -> None: results_return("FlushLogs", client.api_request("POST", "/action/flush/logs"), title="PiHole V6 - Flush Logs") def flush_network_command(client: PiHoleV6Client) -> None: results_return("FlushNetwork", client.api_request("POST", "/action/flush/network"), title="PiHole V6 - Flush Network") # --- Network Commands --- def get_network_devices_command(client: PiHoleV6Client) -> None: results_return("NetworkDevices", client.api_request("GET", "/network/devices"), title="PiHole V6 - Network Devices") def get_network_gateway_command(client: PiHoleV6Client) -> None: results_return("Gateway", client.api_request("GET", "/network/gateway"), title="PiHole V6 - Gateway") # --- Search Command --- def search_domain_command(client: PiHoleV6Client, args: dict) -> None: domain = args.get("domain") results_return("Search", client.api_request("GET", f"/search/{domain}"), title=f"PiHole V6 - Search: {domain}") # --- DHCP Commands --- def get_dhcp_leases_command(client: PiHoleV6Client) -> None: results_return("DHCPLeases", client.api_request("GET", "/dhcp/leases"), title="PiHole V6 - DHCP Leases") # --- Groups Commands --- def get_groups_command(client: PiHoleV6Client) -> None: results_return("Groups", client.api_request("GET", "/groups"), title="PiHole V6 - Groups") def add_group_command(client: PiHoleV6Client, args: dict) -> None: json_data: dict = {"name": args.get("name")} if args.get("comment"): json_data["comment"] = args["comment"] results_return("Groups", client.api_request("POST", "/groups", json_data=json_data), title="PiHole V6 - Group Added") def delete_group_command(client: PiHoleV6Client, args: dict) -> None: name = args.get("name") client.api_request("DELETE", f"/groups/{name}", resp_type="response") return_results(CommandResults(readable_output=f"### Group '{name}' deleted.")) # --- Lists (Adlists) Commands --- def get_lists_command(client: PiHoleV6Client) -> None: results_return("Lists", client.api_request("GET", "/lists"), title="PiHole V6 - Adlists") def add_list_command(client: PiHoleV6Client, args: dict) -> None: json_data: dict = {"address": args.get("address")} if args.get("comment"): json_data["comment"] = args["comment"] if args.get("enabled") is not None: json_data["enabled"] = argToBoolean(args["enabled"]) results_return("Lists", client.api_request("POST", "/lists", json_data=json_data), title="PiHole V6 - List Added") def delete_list_command(client: PiHoleV6Client, args: dict) -> None: address = args.get("address") client.api_request("DELETE", f"/lists/{address}", resp_type="response") return_results(CommandResults(readable_output=f"### List '{address}' deleted.")) def main(): """PARSE AND VALIDATE INTEGRATION PARAMS""" password = demisto.params().get("password") base_url = urljoin(demisto.params()["url"], "/api") verify_certificate = not demisto.params().get("insecure", False) proxy = demisto.params().get("proxy", False) LOG(f"Command being called is {demisto.command()}") client = PiHoleV6Client(base_url=base_url, password=password, verify=verify_certificate, proxy=proxy) try: command = demisto.command() args = demisto.args() if command == "test-module": result = test_module(client) demisto.results(result) # Stats elif command == "pihole-get-summary": get_summary_command(client) elif command == "pihole-get-top-domains": get_top_domains_command(client, args) elif command == "pihole-get-top-clients": get_top_clients_command(client, args) elif command == "pihole-get-upstreams": get_upstreams_command(client) elif command == "pihole-get-query-types": get_query_types_command(client) elif command == "pihole-get-recent-blocked": get_recent_blocked_command(client, args) # History elif command == "pihole-get-history": get_history_command(client) elif command == "pihole-get-history-clients": get_history_clients_command(client, args) # Queries elif command == "pihole-get-queries": get_queries_command(client, args) # DNS Blocking elif command == "pihole-get-blocking-status": get_blocking_status_command(client) elif command == "pihole-set-blocking": set_blocking_command(client, args) # Domain Management elif command == "pihole-get-domains": get_domains_command(client, args) elif command == "pihole-add-domain": add_domain_command(client, args) elif command == "pihole-delete-domain": delete_domain_command(client, args) # Info elif command == "pihole-get-version": get_version_command(client) elif command == "pihole-get-system-info": get_system_info_command(client) elif command == "pihole-get-ftl-info": get_ftl_info_command(client) elif command == "pihole-get-host-info": get_host_info_command(client) elif command == "pihole-get-sensors": get_sensors_command(client) # Actions elif command == "pihole-run-gravity": run_gravity_command(client) elif command == "pihole-restart-dns": restart_dns_command(client) elif command == "pihole-flush-logs": flush_logs_command(client) elif command == "pihole-flush-network": flush_network_command(client) # Network elif command == "pihole-get-network-devices": get_network_devices_command(client) elif command == "pihole-get-network-gateway": get_network_gateway_command(client) # Search elif command == "pihole-search-domain": search_domain_command(client, args) # DHCP elif command == "pihole-get-dhcp-leases": get_dhcp_leases_command(client) # Groups elif command == "pihole-get-groups": get_groups_command(client) elif command == "pihole-add-group": add_group_command(client, args) elif command == "pihole-delete-group": delete_group_command(client, args) # Lists (Adlists) elif command == "pihole-get-lists": get_lists_command(client) elif command == "pihole-add-list": add_list_command(client, args) elif command == "pihole-delete-list": delete_list_command(client, args) else: raise NotImplementedError(f"Command {command} is not implemented.") except Exception as e: return_error(f"Failed to execute {demisto.command()} command. Error: {e!s}") finally: client.logout() if __name__ in ("__main__", "__builtin__", "builtins"): main()