Skip to content

feat(admin): Allow system queries on allowlisted hosts - #8414

Merged
onewland merged 2 commits into
masterfrom
feat/admin-system-queries-allowlisted-hosts
Aug 28, 2026
Merged

feat(admin): Allow system queries on allowlisted hosts#8414
onewland merged 2 commits into
masterfrom
feat/admin-system-queries-allowlisted-hosts

Conversation

@onewland

@onewland onewland commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Follows #8411. System Queries' manual host entry can now target a host that is not a member of the storage's cluster, provided it is listed in admin.copy_tables_allowed_target_hosts — the same option copy-tables CREATE targets already use. That lets a node which has been provisioned but not yet added to Snuba cluster config be inspected.

The allowlist gates the EXPLAIN validation connection as well as the query connection: without that, validate_query rejects the query before the read ever reaches the node. Skipping validation also means the typed port is used verbatim instead of being rewritten to the cluster's Envoy/8123 port, which is what you want for a node that is not behind the cluster proxy yet.

Non-allowlisted hosts still go through _validate_node, and node-picker (non-clusterless) queries are untouched — the relaxation is limited to manual host entry.

Changes

  • common.py: host/port parsing and the allowlist lookup move out of copy_tables.py (ADMIN_ALLOWED_HOSTS_OPTION, parse_host, host_is_allowlisted) so both tools read one list. The option key value is unchanged, so no ops change is needed.
  • common.py: get_ro_clusterless_node_connection gains validate_node; the sudo variant already had it from feat(admin): Allow copy-tables CREATE on any target host #8411.
  • system_queries.py: _validate_clusterless_node gates _run_sql_query_on_host (sudo and read-only) and _run_explain_on_host.
  • Frontend: manual entry parses host:port (defaults to 8123), keeping the raw text in its own state so a half-typed port is not clobbered, plus help text naming the option.

Review notes

The validate_node=False path is the one to scrutinize. It is reached only after host_is_allowlisted returns true, and read-only clusterless queries still use the global readonly user, so a non-allowlisted host never receives credentials.

Open question: the option key still reads admin.copy_tables_allowed_target_hosts while now governing two tools. Only the schema description was updated here; renaming would need a coordinated options change.

Tests

tests/admin passes (172 + 80). New coverage: allowlisted vs. non-allowlisted hosts for sudo and read-only, the EXPLAIN path, and that non-clusterless mode ignores the allowlist. Copy-tables tests updated for the moved helpers.

Manual host entry in System Queries can now target a host that is not a
member of the storage's cluster, as long as it is listed in
admin.copy_tables_allowed_target_hosts — the same option copy-tables
CREATE targets already use. This lets a node that has been provisioned
but not yet added to Snuba cluster config be inspected.

The allowlist check gates the EXPLAIN validation connection as well as
the query connection, otherwise validation rejects the query before the
read reaches the node. Non-allowlisted hosts still go through
_validate_node, and node-picker (non-clusterless) queries are untouched.

The host/port parsing and allowlist lookup move from copy_tables.py to
common.py so both tools read one list.

Also restores the `# type: ignore[import-untyped]` on the sql_metadata
import that #8411 dropped; mypy fails on master without it.
@onewland
onewland marked this pull request as ready for review August 28, 2026 19:44
@onewland
onewland requested a review from a team as a code owner August 28, 2026 19:44
The previous commit re-added `# type: ignore[import-untyped]` because
mypy flagged the import locally. That was a stale local venv holding
sql_metadata 2.11.0; the lock pins 3.0.1, which ships py.typed, so CI
correctly reports the ignore as unused.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 17db68b. Configure here.

predefinedQueryOptions: Array<PredefinedQuery>;
}) {
const [nodeData, setNodeData] = useState<ClickhouseNodeData[]>([]);
const [manualHostInput, setManualHostInput] = useState<string>("");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual host input state desynchronizes

Medium Severity

The host field now renders manualHostInput while execute still reads query.host and query.port. Changing storage clears those query fields without clearing the input, so Execute stays disabled against a filled-looking field. Toggling to manual entry leaves the prior dropdown host in query state with an empty input, so Execute can run against a host that is not shown.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 17db68b. Configure here.

@onewland
onewland merged commit 20bd56e into master Aug 28, 2026
68 checks passed
@onewland
onewland deleted the feat/admin-system-queries-allowlisted-hosts branch August 28, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants