No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Max Mitschke 47bbc54513
fix: detect controller logs in managed Azure must-gather flat structure (#4)
Managed Azure must-gathers use a flat pod structure where all container
logs are combined into a single file (pods/<pod>/logs/logs.txt) with
delimiter headers separating each container's output:

    ==== START logs for container <name> of pod <pod> ====

Previously, only hub logs were discovered because hub-web pods retain the
standard OCP container directory structure (web/web/logs/). Controller
pods use the flat structure, causing their logs to be completely missed
— no ComponentReport was created and direct-access hits were not reported.

This occurred due to three compounding defects:

1. The _is_web_container() gate rejected the "logs/" directory name,
   causing the entire pod to be skipped via continue

2. The file extension filter only accepted .log and .log.gz, which would
   have rejected logs.txt even if discovered

3. No logic existed to parse container delimiter headers and filter out
   non-web container sections (redis, rsyslog, etc.)

This fix adds:

- A _filter_by_container_delimiter() helper that recognizes delimiter
  headers and filters to only web container sections

- Auto-detection in _open_log_file() that transparently applies delimiter
  filtering when the pattern is detected

- A flat-structure fallback in _find_must_gather_logs() that activates
  only when no standard container directories are found, accepting .txt
  files and using _component_from_pod_name() for classification

- Five comprehensive test cases covering flat structure scenarios,
  backward compatibility, and edge cases

The changes maintain full backward compatibility — standard OCP
must-gathers continue to work unchanged, and all 64 existing tests pass
along with the 5 new tests (69 total).

Signed-off-by: Max Mitschke <mmitschk@redhat.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-02 10:35:15 +02:00
src/aap_detect_direct_component_access fix: detect controller logs in managed Azure must-gather flat structure (#4) 2026-06-02 10:35:15 +02:00
tests fix: detect controller logs in managed Azure must-gather flat structure (#4) 2026-06-02 10:35:15 +02:00
.gitignore [AAP-64061] Implement CLI detection tool for direct API access 2026-02-12 13:56:02 -05:00
pyproject.toml [AAP-64061] Implement CLI detection tool for direct API access 2026-02-12 13:56:02 -05:00
README.md [AAP-64061] Name output files based on input path 2026-03-11 12:00:40 -04:00

aap-detect-direct-component-access

Detect direct API access to Ansible Automation Platform (AAP) components by analyzing nginx access logs.

AAP 2.7 requires all API traffic to flow through the AAP Gateway. This tool scans nginx access logs from Controller, Hub, and EDA components to identify requests that bypass the gateway — i.e. requests that arrive without the X-Trusted-Proxy header and without a DAB JWT token.

Requirements

  • Python 3.6+ (no third-party dependencies)

Installation

uvx --from "git+https://github.com/ansible/aap-detect-direct-component-access" aap-detect-direct-component-access /path/to/sosreport

With pip

pip install "git+https://github.com/ansible/aap-detect-direct-component-access"
aap-detect-direct-component-access /path/to/sosreport

Without installing

python -m aap_detect_direct_component_access /path/to/sosreport

Or run the script directly:

python src/aap_detect_direct_component_access/detect.py /path/to/sosreport

Usage

aap-detect-direct-component-access [-h] [-o OUTPUT_DIR] [--include-filtered] [-V] input

Arguments

Argument Description
input Path to a SOSReport directory, must-gather directory, or individual nginx access log file
-o, --output-dir Directory to write report files (default: .)
--include-filtered Include health checks and probe requests in the report
-V, --version Show version and exit

Input formats

The tool auto-detects the input format:

  • SOSReport — detected by var/log/containers/ or var/log/pods/ directory structure
  • must-gather — detected by namespaces/ directory structure (OpenShift)
  • Log file — any individual nginx access log file (plain text or gzipped)

Expected nginx log format

The tool requires nginx logs with the ANSTRAT-1840 marker fields appended:

$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent
"$http_referer" "$http_user_agent" "$http_x_forwarded_for"
$trusted_proxy_present $dab_jwt_present

If logs use the legacy format (without the trailing marker fields), the tool will report them as "legacy format" and exit with code 3.

Output

  1. stdout — summary with total requests, direct access count per component
  2. <input-name>.report.txt — detailed breakdown by path and source IP
  3. <input-name>.raw.log — raw nginx log lines flagged as direct access

Exit codes

Code Meaning
0 No direct access detected
1 Error (bad input path, no logs found)
2 Direct access detected
3 Legacy log format (cannot determine)

Filtered requests

By default, the following are excluded from the direct-access report since they represent expected internal traffic:

  • Health check endpoints (/api/v2/ping, /healthz, /readyz, etc.)
  • Static assets (/static/, /favicon.ico)
  • Kubernetes probes (identified by kube-probe user-agent)
  • Internal monitoring (/nginx_status, /_debug/)

Use --include-filtered to include these in the report.

Running tests

python -m pytest tests/

Or without pytest:

python -m unittest discover -s tests

License

Apache-2.0