Skip to content

feat(allocation_policies): per-tenant attachment via match blocks - #8393

Open
pbhandari wants to merge 8 commits into
masterfrom
prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks
Open

feat(allocation_policies): per-tenant attachment via match blocks#8393
pbhandari wants to merge 8 commits into
masterfrom
prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks

Conversation

@pbhandari

Copy link
Copy Markdown
Contributor

Stacked on #8387. Linear: EAP-726.

Summary

  • allocation_policy is a per-resource list of {match, policies, remove} blocks.
  • Match keys (organization_id, project_id, referrer) are always lists; AND across keys, OR within a key; match: {} always matches.
  • Matching blocks apply in file order: remove names, then add/replace policies by name.
  • EAP routing and SNQL db_query pass request tenant_ids into get_active_allocation_policies.
  • Drop unused required_tenant_types. Stop baking policies onto Table; attach at quota time from storage_key.

Testing

  • SNUBA_SETTINGS=test uv run pytest -q tests/query/allocation_policies/test_attachment.py tests/web/test__get_allocation_policy.py

@pbhandari
pbhandari requested review from a team as code owners August 25, 2026 17:41
@linear-code

linear-code Bot commented Aug 25, 2026

Copy link
Copy Markdown

EAP-726

Comment on lines +585 to +586
def _block_matches(match: Mapping[str, Any], tenant_ids: Mapping[str, str | int]) -> bool:
return all(key in tenant_ids and tenant_ids[key] in expected for key, expected in match.items())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The function _block_matches assumes match values are iterable. A scalar value (e.g., an integer) will cause an uncaught TypeError, crashing the request handler.
Severity: HIGH

Suggested Fix

Add a type check in _block_matches to ensure the expected value from the match dictionary is a list or other iterable. If it's not, either wrap it in a list to handle the scalar case gracefully or log a warning and skip the invalid policy, similar to how other malformed configuration entries are handled.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: snuba/query/allocation_policies/__init__.py#L585-L586

Potential issue: The `_block_matches` function assumes that values for keys in the
`match` dictionary of an allocation policy are always iterable. However, if a policy is
misconfigured with a scalar value (e.g., `{"organization_id": 123}`) instead of a list
(`{"organization_id": [123]}`), the expression `tenant_ids[key] in expected` will raise
a `TypeError`. This exception is not caught within the call stack
(`_resolve_policy_specs` -> `get_active_allocation_policies` ->
`_get_allocation_policies`). Since `_get_allocation_policies` is called outside the main
`try/except` block in `db_query`, this error will crash the request handler for any
query using that resource until the configuration is corrected.

Did we get this right? 👍 / 👎 to inform future reviews.

Comment thread snuba/query/allocation_policies/__init__.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-725-configure-allocation-policy-attachment-via-sentry-options branch from d2e969e to c109434 Compare August 25, 2026 19:34
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from 0b17c2c to 4d85c49 Compare August 26, 2026 14:30
Comment thread snuba/web/db_query.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from 4d85c49 to fa4a193 Compare August 26, 2026 14:46
Comment thread snuba/query/allocation_policies/__init__.py

@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.

Reviewed by Cursor Bugbot for commit fa4a193. Configure here.

Comment thread snuba/web/db_query.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from fa4a193 to b283a5d Compare August 27, 2026 13:44
Base automatically changed from prajjwalbhandari/eap-725-configure-allocation-policy-attachment-via-sentry-options to master August 27, 2026 14:36
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from b283a5d to c23cb58 Compare August 27, 2026 17:42
Comment thread snuba/web/db_query.py
@pbhandari
pbhandari force-pushed the prajjwalbhandari/eap-726-per-tenant-allocation-policy-attachment-via-match-blocks branch from aa36ffe to c66fdaa Compare August 28, 2026 20:13
tenant_ids or {},
resource,
)
return _construct_policies(specs_by_name, resource) or [_default_passthough_policy(resource)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: get_active_allocation_policies + its four helpers (_resolve_policy_specs, _block_matches, _apply_block, _construct_policies) are a self-contained unit. What if we put them in a class or even a module, e.g. allocation_policies/resolver.py,AllocationPolicyResolver ). This init is already pretty crowded. Non-blocking ofc.

Comment thread snuba/web/db_query.py
"""

allocation_policies = _get_allocation_policies(clickhouse_query)
allocation_policies = _get_allocation_policies(clickhouse_query, attribution_info.tenant_ids)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the downside in just passing the attribution_info around for maximal context?

@tryangul tryangul left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Logic seems good to me 🚢

Left a nit on adding some structure. I think it's worth exploring as a follow up, esp if we want to build on this thing / swap it out later.

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