Skip to content

daemon: refactor network-list filtering code; unify list and prune filter terms#50843

Closed
corhere wants to merge 5 commits intomoby:masterfrom
corhere:network-filter-idorname
Closed

daemon: refactor network-list filtering code; unify list and prune filter terms#50843
corhere wants to merge 5 commits intomoby:masterfrom
corhere:network-filter-idorname

Conversation

@corhere
Copy link
Copy Markdown
Contributor

@corhere corhere commented Aug 28, 2025

- What I did

  • Replaced the buggy internal uses of the hidden idOrName term (which matched all networks irrespective of value, as if the term wasn't present) with an implementation that actually works as intended
  • Moved network filter term validation from the api module to the daemon
  • Unified the set of available filter terms for list-networks and prune-networks APIs
  • Filtered networks before converting so cycles aren't wasted converting a struct that won't be returned to the client

- How I did it
See individual commit messages.

- How to verify it
Existing tests.

- Human readable description for the release notes

 - The `GET /networks` API has been extended with support for the `label!` and `until` filters.
 - The `POST /networks/prune` API has been extended with support for the `driver`, `name` and `scope` filters.

- A picture of a cute animal (not mandatory but encouraged)

@corhere corhere added area/api API kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny area/networking Networking impact/changelog impact/documentation kind/refactor PR's that refactor, or clean-up code labels Aug 28, 2025
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the network list filtering code by moving filter validation from the API layer to the daemon layer and unifying filter terms between list-networks and prune-networks APIs. It also fixes a bug with the hidden idOrName filter term that was matching all networks regardless of the provided value.

  • Replaced the buggy idOrName filter term with a working implementation using id filter with IDAlsoMatchesName flag
  • Moved network filter validation from api/types/network package to daemon/network package
  • Added support for label! and until filters to the list-networks API and driver, name, scope filters to prune-networks API

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
daemon/server/router/network/network_routes.go Updates network routes to use new daemon-level filter validation and dnetwork.Filter type
daemon/server/router/network/backend.go Changes backend interface signatures to use dnetwork.Filter instead of filters.Args
daemon/prune.go Refactors pruning logic to use the new filter system and removes duplicate filter validation
daemon/network/filter_test.go Updates tests to use mock objects and new filter interface
daemon/network/filter.go Implements new Filter type with unified validation and matching logic
daemon/network.go Refactors GetNetworks to filter before conversion and use new filter interface
daemon/libnetwork/network.go Adds Driver() and ContainerAttachments() methods to support filter interface
daemon/libnetwork/agent.go Adds ServiceAttachments() method to support filter interface
daemon/cluster/networks.go Updates cluster network handling to use new filter system
daemon/cluster/convert/network.go Adds FilterNetwork adapter for swarmapi networks
daemon/cluster.go Updates interface to use dnetwork.Filter
api/types/network/network.go Removes network filter validation (moved to daemon)
api/swagger.yaml Updates API documentation to reflect new supported filters

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@corhere corhere force-pushed the network-filter-idorname branch from edc0241 to 71e7fdf Compare August 28, 2025 22:34
@corhere corhere added this to the 29.0.0 milestone Aug 28, 2025
Internally a network is represented by either a libnetwork.Network or a
swarmapi.Network. The daemon functions backing the API server map
these values to the Engine API network.Inspect type on demand. Since
they have to convert, the functions to get a list of networks have to
loop over the slice of Networks and append them to a slice of
network.Inspect values.

The function used to filter the list of networks by a user-supplied
predicate takes a []network.Inspect and returns a shorter slice.
Therefore the daemon functions backing the API server have to loop
through the list twice; once to convert, and again inside the
FilterNetworks function to prune networks from the slice. Each time an
item is deleted from a slice, all items at higher indices need to be
copied to lower indices in the backing array.

Replace FilterNetworks with a function that accepts a single network
summary and returns a boolean. The daemon network-list functions can
filter in the conversion loop, which cuts down on a nontrivial amount of
copying. Split the validation of the filter predicate from filter
evaluation to both make it more ergonomic to use inside loops, and to
make invalid states (a filter with an ill-formed predicate)
unrepresentable.

This change also future-proofs the network filter for when we change
network.Inspect to a distinct type that embeds a network.Summary.
Callers that need to build a filtered list of network.Inspect values
will be able to evaluate the filter on the embedded Summary then append
the full Inspect value of matching networks to the output slice.

Signed-off-by: Cory Snider <csnider@mirantis.com>
The network filter has an hidden 'idOrName' term. API clients cannot use
this term as it will not pass ValidateFilters: it is not listed in the
acceptedFilters set. And it's a good thing, too: it is completely broken
and not fit for purpose. When a filter contains an idOrName term, the
term values are ignored and instead the filter tests whether the 'id' or
'name' terms match the Name field of the network. Unless the filter
contains both 'id' and 'name' terms, the match will evaluate to true!
None of the daemon-internal users of 'idOrName' set either term,
therefore it has the same effect as if the filter did not contain the
term in the first place.

Filtering networks by id-or-name is a quirky thing that the daemon needs
to do to uphold its end of the Engine API contract, not something that
would be of use to clients. Instead of fixing up the idOrName filter,
add an exported field to the Filter struct to enable the internal-only
behaviour of having the 'id' term match on either the network Name or
ID.

Signed-off-by: Cory Snider <csnider@mirantis.com>
Modify network.Filter to evaluate an interface-valued parameter which
both libnetwork.Network and swarmapi.Network (with a small adapter)
implement. Filter the objects before converting them to API
network.Inspect struct values.

Signed-off-by: Cory Snider <csnider@mirantis.com>
Filter-term validation does not belong in the API module. Clients should
not be making any assumptions about which terms the daemon understands.
Users should not need to upgrade their clients to use filter terms
introduced in a newer daemon. Move the network filter validation from
the api module into the daemon.

Have network.NewFilter validate the filter terms, enforcing the
invariant that any network.Filter is a well-formed filter for networks.
Lift the conversion from filters.Args to network.Filter into the API
endpoint handlers so that validation errors continue to be returned
separately from errors that occur when listing networks. As a side
benefit, this also affords the API handlers configuration of the filter
options (IDAlsoMatchesName) without additional plumbing.

Unify the filter terms available when listing networks and pruning
networks. Support filtering on the absence of a label or network
creation time when listing networks. And support all the network listing
filter terms when pruning networks.

Signed-off-by: Cory Snider <csnider@mirantis.com>
The semantics of Swarmkit filters doesn't seem to align with the
semantics of Moby filters very well. Revert to listing all Swarm
networks and filtering in the daemon, as we were (unintentionally) doing
before the idOrName fix.

Signed-off-by: Cory Snider <csnider@mirantis.com>
@corhere corhere force-pushed the network-filter-idorname branch from 9d55e3a to baaf9de Compare August 29, 2025 19:40
@corhere corhere marked this pull request as draft August 30, 2025 00:06
@corhere corhere changed the title daemon: refactor network-list filtering code daemon: refactor network-list filtering code; unify list and prune filter terms Aug 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api API area/networking Networking impact/changelog impact/documentation kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny kind/refactor PR's that refactor, or clean-up code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants