| Solution | Filtering, paging, and formatting were added to Monitor API in FortiOS 6.4.2 and are almost equivalent to filtering, paging, and formatting for the configuration API. To filter results, include the 'filter' parameter in the request URL parameter: filter=[key][operator][pattern] The following is an example python request where the params dictionary handles the filtering, and the response is parsed as a JSON object. Curl example: curl -k -X GET "https://<FortiGate_IP>/api/v2/cmdb/firewall/policy?filter=srcintf=@port1=<API_TOKEN>" Python example: import requests import json # Connection Details fgt_ip = "10.1.1.1" api_token = "secret_token" url = f"https://{fgt_ip}/api/v2/cmdb/firewall/policy" # Filtering Logic # Policies where 'srcintf' contains 'port1' query_params = { "access_token": api_token, "filter": "srcintf=@port1" } response = requests.get(url, params=query_params, verify=False) # Parsing the JSON result if response.status_code == 200: data = response.json() print(json.dumps(data['results'], indent=4)) else: print(f"Error: {response.status_code}") The filter of 'srcintf=@port1' is used when calling firewall/policy, so only firewall policies that are matching port1 as the source interface are returned. =@ indicates to find the pattern found within the value. More information on key operators can be found here: Fortinet Developer Network. Example response: { "http_method": "GET", "results": [ { "policyid": 5, "name": "Web-Traffic", "srcintf": [{"name": "port1"}], "dstintf": [{"name": "wan1"}], "action": "accept", "status": "enable" } ], "vdom": "root", "path": "firewall", "name": "policy", "status": "success", "http_status": 200 } The following is an example of using the filter for firewall sessions: curl -k -X GET "https://<FortiGate_IP>/api/v2/monitor/firewall/session?filter=src==192.168.1.50&access_token=<API_TOKEN>" The API will run without errors, but because the format = x is not supported for firewall sessions, it will show all sessions: { "http_method": "GET", "results": [ { "session_id": 4915201, "proto": 6, "proto_state": "01", "src": "192.168.1.50", "sport": 54321, "dst": "8.8.8.8", "dport": 443, "policy_id": 12, "duration": 124, "timeout": 3600, "vdom": "root", "app": "HTTPS", "shaper_out": "none" } { "session_id": 4915202, "proto": 6, "proto_state": "01", "src": "192.168.1.51", "sport": 54322, "dst": "8.8.8.8", "dport": 443, "policy_id": 12, "duration": 126, "timeout": 3600, "vdom": "root", "app": "HTTPS", "shaper_out": "none" } ], "vdom": "root", "path": "firewall", "name": "session", "status": "success", "serial": "FGT60E0000000000", "version": "v7.4.x", "build": 2795 } If the JSON file is saved or the raw response from the API, there are various ways to parse the raw response or JSON response. An example of how to parse the data using a python script to see all sessions using Policy ID 5 and Port 443 is shown below. import json # Sample: Load the raw API response here raw_response = """ { "results": [ {"session_id": 101, "src": "192.168.1.50", "dst": "8.8.8.8", "dport": 443, "policy_id": 5, "proto": 6}, {"session_id": 102, "src": "192.168.1.50", "dst": "1.1.1.1", "dport": 53, "policy_id": 10, "proto": 17}, {"session_id": 103, "src": "192.168.1.20", "dst": "4.4.4.4", "dport": 443, "policy_id": 5, "proto": 6} ] } """ def filter_sessions(json_data, target_policy=None, target_port=None): data = json.loads(json_data) sessions = data.get("results", []) # Advanced local filtering using list comprehension filtered = [ s for s in sessions if (target_policy is None or s.get("policy_id") == target_policy) and (target_port is None or s.get("dport") == target_port) ] return filtered # --- Execution --- # Example: Find all sessions using Policy ID 5 AND Port 443 matches = filter_sessions(raw_response, target_policy=5, target_port=443) print(f"Found {len(matches)} matching sessions:") for item in matches: print(f"Session {item['session_id']}: {item['src']} -> {item['dst']} (Policy {item['policy_id']})") The FortiGate REST API is efficient, but the filter parameter in the URL is sometimes limited to basic exact matches or, as in this case, does not work at all. Local filtering of raw responses allows the user to use complex logic (like 'all ports except 80') that the FortiOS API Monitor might not support directly. |