[PR #20579] [MERGED] Fixes #20541: Enhance GraphQL filter methods with dynamic prefixing #15973

Closed
opened 2025-12-30 00:25:05 +01:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbox-community/netbox/pull/20579
Author: @pheus
Created: 10/15/2025
Status: Merged
Merged: 10/24/2025
Merged by: @jnovinger

Base: mainHead: 20541-make-filter-methods-prefix-aware-for-nested-graphql-filter


📝 Commits (1)

  • b959b37 feat(ipam): Enhance filter methods with dynamic prefixing

📊 Changes

2 files changed (+250 additions, -18 deletions)

View changed files

📝 netbox/ipam/graphql/filters.py (+49 -18)
📝 netbox/ipam/tests/test_api.py (+201 -0)

📄 Description

Fixes: #20541

Refactors filter methods to enable dynamic query prefixing for greater flexibility in nested queries. Improves error handling for invalid network inputs and ensures consistency across IPAM filter implementations.


Context

This follows the discussion in Bug #20466 and builds on PR #20538 (which addressed IPAddressFilter.assigned). The goal here is to complete the prefixing/validation sweep within ipam.graphql.filters only and ensure nested filters consistently target the correct related model.

Summary of changes

  • Prefix-aware Q objects (nested filtering):
    Standardize construction of lookups as Q(**{f"{prefix}…": …}) in custom filter methods so nested queries are resolved against the intended model path.
  • Input safeguards:
    contains/parent-style helpers now guard network parsing with try/except, skipping invalid entries rather than failing the entire filter.
  • Targeted refactors for clarity/consistency:
    Minor internal tidy-ups (e.g., shared helper for device-based lookups) while preserving existing behavior.

🚨 Breaking change (GraphQL): AggregateFilter

Aggregate.prefix is a concrete field, not a relation. To avoid double-qualifying lookups in nested contexts, this PR proposes:

  • Replace the nested filter with a field lookup:
    prefix: FilterLookup[str] | None
    
  • Add a field-level contains(value: [CIDR]) that applies prefix__net_contains to the Aggregate field itself.

Client impact (input shape changed for Aggregates only):

  • Before
    aggregate_list(filters: { prefix: { contains: "10.0.0.0/8" } }) { prefix }
    
  • After
    • containment:
      aggregate_list(filters: { contains: ["10.0.0.0/8"] }) { prefix }
      
    • equality:
      aggregate_list(filters: { prefix: { exact: "10.0.0.0/8" } }) { prefix }
      

No other GraphQL inputs are changed.

Files/areas touched (IPAM only)

  • ipam.graphql.filters.AggregateFilter
    • prefix now a FilterLookup[str] on the field.
    • New contains([...]) uses prefix__net_contains.
  • ipam.graphql.filters.PrefixFilter
    • contains([...]) remains relation-aware; lookups are prefixed via f"{prefix}prefix__net_contains".
  • ipam.graphql.filters.IPRangeFilter
    • parent([...]) and contains([...]) use prefixed lookups with input validation.
  • ipam.graphql.filters.IPAddressFilter
    • parent([...]) uses prefixed lookups with input validation.
    • (Note: assigned was handled in PR #20538 per Bug #20466.)

Upgrade notes

  • Breaking (Aggregates only): Update GraphQL clients to use:
    • aggregate_list(filters: { contains: ["<cidr>"] }) for containment, and
    • aggregate_list(filters: { prefix: { exact: "<cidr>" } }) for equality.
  • No changes required for other IPAM GraphQL filters.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbox-community/netbox/pull/20579 **Author:** [@pheus](https://github.com/pheus) **Created:** 10/15/2025 **Status:** ✅ Merged **Merged:** 10/24/2025 **Merged by:** [@jnovinger](https://github.com/jnovinger) **Base:** `main` ← **Head:** `20541-make-filter-methods-prefix-aware-for-nested-graphql-filter` --- ### 📝 Commits (1) - [`b959b37`](https://github.com/netbox-community/netbox/commit/b959b37cdb3e1c00220b2e76e0644c123e030e9d) feat(ipam): Enhance filter methods with dynamic prefixing ### 📊 Changes **2 files changed** (+250 additions, -18 deletions) <details> <summary>View changed files</summary> 📝 `netbox/ipam/graphql/filters.py` (+49 -18) 📝 `netbox/ipam/tests/test_api.py` (+201 -0) </details> ### 📄 Description <!-- Thank you for your interest in contributing to NetBox! Please note that our contribution policy requires that a feature request or bug report be approved and assigned prior to opening a pull request. This helps avoid waste time and effort on a proposed change that we might not be able to accept. IF YOUR PULL REQUEST DOES NOT REFERENCE AN ISSUE WHICH HAS BEEN ASSIGNED TO YOU, IT WILL BE CLOSED AUTOMATICALLY. Please specify your assigned issue number on the line below. --> ### Fixes: #20541 Refactors filter methods to enable dynamic query prefixing for greater flexibility in nested queries. Improves error handling for invalid network inputs and ensures consistency across IPAM filter implementations. --- ### Context This follows the discussion in **Bug #20466** and builds on **PR #20538** (which addressed `IPAddressFilter.assigned`). The goal here is to complete the prefixing/validation sweep within **`ipam.graphql.filters` only** and ensure nested filters consistently target the correct related model. ### Summary of changes - **Prefix-aware Q objects (nested filtering):** Standardize construction of lookups as `Q(**{f"{prefix}…": …})` in custom filter methods so nested queries are resolved against the intended model path. - **Input safeguards:** `contains`/`parent`-style helpers now guard network parsing with `try/except`, **skipping invalid entries** rather than failing the entire filter. - **Targeted refactors for clarity/consistency:** Minor internal tidy-ups (e.g., shared helper for device-based lookups) while preserving existing behavior. ### 🚨 Breaking change (GraphQL): `AggregateFilter` `Aggregate.prefix` is a **concrete field**, not a relation. To avoid double-qualifying lookups in nested contexts, this PR proposes: - Replace the nested filter with a field lookup: ```py prefix: FilterLookup[str] | None ``` - Add a field-level `contains(value: [CIDR])` that applies `prefix__net_contains` to the **Aggregate** field itself. **Client impact (input shape changed for Aggregates only):** - **Before** ```graphql aggregate_list(filters: { prefix: { contains: "10.0.0.0/8" } }) { prefix } ``` - **After** - containment: ```graphql aggregate_list(filters: { contains: ["10.0.0.0/8"] }) { prefix } ``` - equality: ```graphql aggregate_list(filters: { prefix: { exact: "10.0.0.0/8" } }) { prefix } ``` No other GraphQL inputs are changed. ### Files/areas touched (IPAM only) - `ipam.graphql.filters.AggregateFilter` - `prefix` now a `FilterLookup[str]` on the **field**. - New `contains([...])` uses `prefix__net_contains`. - `ipam.graphql.filters.PrefixFilter` - `contains([...])` remains relation-aware; lookups are prefixed via `f"{prefix}prefix__net_contains"`. - `ipam.graphql.filters.IPRangeFilter` - `parent([...])` and `contains([...])` use prefixed lookups with input validation. - `ipam.graphql.filters.IPAddressFilter` - `parent([...])` uses prefixed lookups with input validation. - (Note: `assigned` was handled in **PR #20538** per **Bug #20466**.) ### Upgrade notes - **Breaking (Aggregates only):** Update GraphQL clients to use: - `aggregate_list(filters: { contains: ["<cidr>"] })` for containment, and - `aggregate_list(filters: { prefix: { exact: "<cidr>" } })` for equality. - No changes required for other IPAM GraphQL filters. ### Related - Bug: #20466 - Prior fix: #20538 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2025-12-30 00:25:05 +01:00
adam closed this issue 2025-12-30 00:25:05 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#15973