Add opt-in gathered-state filtering for loopback and local users#391
Add opt-in gathered-state filtering for loopback and local users#391deekpand-cisco wants to merge 4 commits into
Conversation
Adds the nd_links module for ND 4.2 with manage / one_manage link scopes, template models, endpoints, orchestrator, strategies and fabric inventory support, plus integration tests.
Add server-side Lucene candidate filtering for gathered loopback interfaces with pagination, deduplication, and final local matching. Support gather-all and login-ID filtering for local users while rejecting unsupported gathered criteria. Add unit and integration coverage for filtering, validation, secrecy, and reusable output.
7a31104 to
3a3e41b
Compare
| Returned objects remain in API shape for NDConfigCollection.from_api_response(). | ||
| """ | ||
|
|
||
| if not filters: |
There was a problem hiding this comment.
Should we still deduplicate the results when no filters are provided? Right now this returns before the deduplication logic runs.
There was a problem hiding this comment.
Removed the early return so deduplication now runs unconditionally. The to_config() function is only called when active filters exist to avoid unnecessary work.
| query_kwargs["gathered_filters"] = raw_config | ||
|
|
||
| response_data = self.model_orchestrator.query_all(**query_kwargs) | ||
|
|
There was a problem hiding this comment.
Can we validate the gathered filters before calling query_all()? Otherwise, an invalid filter may make unnecessary API calls before it fails.
There was a problem hiding this comment.
Added a validate_gathered_filters() function as a pre-flight check in the state machine, called before query_all(). Invalid filters now fail fast without making API calls.
| meta = result.get("meta") or {} | ||
| counts = meta.get("counts") or {} | ||
| try: | ||
| remaining = int(counts.get("remaining", 0)) |
There was a problem hiding this comment.
If remaining is missing or invalid, this treats it as zero and stops pagination. Could this return incomplete gathered results when the first page is full? Or, may be continue based on the page size or fail instead of returning partial data?
- Remove early return in filter_gathered_response() so deduplication runs unconditionally regardless of whether filters are provided - Add validate_gathered_filters() pre-flight check called before query_all() to reject invalid filters without wasted API calls
Note
This is a stacked draft that depends on #312.
PR #312 is based on
shrsr/ansible-nd:nd_links, so its source branch is notavailable as a base branch in the official
CiscoDevNet/ansible-ndrepository. This draft therefore temporarily targets
develop.Once #312 is merged, I will rebase this branch onto
developso the PR diffcontains only the gathered-filtering changes.
Related Issue(s)
Related to #340.
Depends on #312.
Proposed Changes
This PR introduces an opt-in gathered-state filtering framework for modules
using
NDStateMachineand enables it for:cisco.nd.nd_interface_loopbackcisco.nd.nd_local_userThe goal of this draft is to get early feedback on the shared filtering
architecture and module-specific behavior before enabling additional
NDStateMachine-backed modules.Shared gathered-filtering framework
The shared implementation:
state: gathered;supports_gathered_filtering;configas partial filter criteria for supported gathered operations;matching;
normalize_gathered_filter;matches_gathered_filter;proposedconfiguration;processing;
The generic local filter remains the final correctness layer. Endpoint-specific
filtering is used only to reduce the number of API candidates where the
endpoint safely supports it.
Loopback-interface filtering
The loopback module supports gather-all and partial gathered filters across
switches in a fabric.
Gathered loopback queries use the interface-list endpoint and its Lucene
filterquery parameter:interfaceType:loopbackandpolicyType:loopback;switch_ipis resolved to a switch serial number and limits the query tothat switch;
switch_ipqueries all switches in the fabric;interface_nameis translated into an exact-match Lucene term;queries for that switch;
maxandoffsetuntil the API reports no remainingresults;
deduplicated.
Lucene expressions are built only from structured module input. Raw Lucene
expressions are not accepted from users.
The module continues to enforce its resource-ownership boundary:
interfaceTypemust beloopback;policyTypemust beloopback;underlayLoopbackinterfaces are excluded;ipfmLoopbackanduserDefinedpolicies are excluded.Nested criteria such as IP address, description, administrative state, VRF,
IPv6 address, extra configuration, and route-map tag are evaluated by the
generic final local filter.
Interface names supplied as filters are normalized to lowercase to match the
existing model and Nexus Dashboard API behavior.
Local-user filtering
The local-user endpoint does not expose documented server-side Lucene
filtering. Gather-all retrieves the available local users, and optional
login_idcriteria are evaluated through the shared final local-matchinglayer.
Only
login_idis supported as a gathered-state filter for local users.Other configuration fields are rejected with a validation error.
Multiple login-ID filter items use OR semantics. Login-ID matching is
case-sensitive.
Local-user passwords are not returned by Nexus Dashboard and remain excluded
from gathered output. Gathered output for an existing user can be reused as
configuration, but recreating a deleted user still requires a new password.
Argument validation and gathered output
For both modules:
configcan be omitted for gather-all operations;configremains required for write states throughrequired_if;resources;
reused as
config;changed: false.For loopback gathered operations,
switch_ip,interface_name, and nestedconfiguration fields can be supplied as partial filtering criteria.
For local-user gathered operations, each supplied filter item must contain
login_id. Other local-user fields are not supported as gathered filters.Compatibility and rollout
Test Notes
Completed validation:
Unit coverage includes Lucene expression construction and escaping, query
planning, pagination, deduplication, local matching, gathered/write-state
isolation, local-user login-ID filtering, validation, and password secrecy.
Integration coverage was added for gather-all, exact and multiple filters,
no-match behavior, invalid filters, pagination-related behavior, password
secrecy, and gathered-output reuse.
Cisco Nexus Dashboard Version
Cisco Nexus Dashboard 4.2 lab environment.
The exact patch/build version will be added before this draft is marked ready
for final review.
Related ND API Resource Category
The loopback-interface module uses the Manage API, while the local-user module
uses the Infra AAA API.
Checklist
The rebase/conflict item remains unchecked because this is currently a stacked
draft depending on #312. The branch will be rebased onto
developafter #312is merged.