Scenarios — python-neutronclient — branch stable/2026.2
Branch
stable/2026.2@596a9d99b188(14.0.0+ 2 maintenance commits) — repository https://opendev.org/openstack/python-neutronclient — analysed on 2026-11-01
Sequences were seen on the local stub [observed], under the run IDs of [_rewrite/defect-repros_stable-2026.2.json](_rewrite/defect-repros_stable-2026.2.json). The stub is not Neutron, so what happens after the response, in a real service, is not covered.
1. Loading the plugin
The process builds its command table before any network call. This is what decides that a command exists.
sequenceDiagram
autonumber
actor U as User
participant S as openstack shell
participant E as Python entry points
participant P as neutronclient.osc.plugin
U->>S: openstack network log list
S->>E: load group openstack.cli.extension
E->>P: import module
S->>P: read API_NAME, API_VERSION_OPTION, DEFAULT_API_VERSION
S->>S: read network_api_version from the cloud config (default 2)
alt version major is 2
S->>E: load group openstack.neutronclient.v2 (34 commands)
E-->>S: entries, IGNORED_MODULES matches none
S-->>U: runs the command
else --os-network-api-version 3
S->>E: load group openstack.neutronclient.v3 (empty)
S-->>U: warning, then not an openstack command, exit 2
endDiagnostics: openstack command list --group neutronclient lists the group. Sources: openstackclient:openstackclient/shell.py:101, openstackclient:openstackclient/shell.py:150, cliff:cliff/commandmanager.py:135, neutronclient/osc/plugin.py:26.
2. Creating a network log (Python binding)
sequenceDiagram
autonumber
actor U as User
participant C as CreateNetworkLog
participant N as Client
participant KA as keystoneauth session
participant KS as Keystone
participant Q as Neutron
U->>C: network log create n --resource-type SECURITY_GROUP --resource y --event drop
C->>C: lower-case the type, upper-case the event, check the choices
C->>N: Client(session, region_name, endpoint_type)
Note over N: warning on stderr: python binding is deprecated
C->>N: find_resource(security_group, y)
N->>KA: GET /v2.0/security-groups?name=y
KA->>KS: POST /v3/auth/tokens, first request only
KS-->>KA: token, catalog
KA->>Q: GET /network/v2.0/security-groups?name=y
alt no match
Q-->>N: 200 security_groups empty
N-->>U: Unable to find security_group with name or id, exit 1
else two matches
Q-->>N: 200 with 2 entries
N-->>U: Multiple security_group matches found, exit 1
else one match
Q-->>N: 200 with 1 entry
C->>N: create_network_log with envelope log
N->>Q: POST /network/v2.0/log/logs
Q-->>N: 201 log
N-->>U: table, exit 0
endDiagnostics: an error shown as a Python dict means a NeutronError without detail. 'Client' object has no attribute 'list_foos' means that the resource type has no method in the class, and that no request went out. Run: log-create-sg. Sources: neutronclient/osc/v2/logging/network_log.py:69-105, neutronclient/v2_0/client.py:476.
3. Appending to a port chain (SDK, read-modify-write)
sequenceDiagram
autonumber
actor U as User
participant C as SetSfcPortChain
participant S as openstacksdk
participant Q as Neutron
U->>C: sfc port chain set x --port-pair-group y --flow-classifier z
C->>S: find_sfc_port_chain(x)
S->>Q: GET /sfc/port_chains/x
C->>S: find y, then z, in _get_common_attrs
S->>Q: GET /sfc/port_pair_groups/y
S->>Q: GET /sfc/flow_classifiers/z
C->>S: find x, read flow_classifiers
S->>Q: GET /sfc/port_chains/x
C->>S: find z again
S->>Q: GET /sfc/flow_classifiers/z
C->>S: find x, read port_pair_groups
S->>Q: GET /sfc/port_chains/x
C->>S: find y again
S->>Q: GET /sfc/port_pair_groups/y
C->>S: update_sfc_port_chain(id, full lists)
S->>Q: PUT /sfc/port_chains/{id}
alt conflict
Q-->>C: 409
C-->>U: Failed to update port chain, exit 1
else success
Q-->>C: 200
C-->>U: nothing, exit 0
endDiagnostics: seven GET for one change is the normal cost. Without If-Match, a change made between the read and the write is overwritten. With a name unknown to the server, the first GET is followed by ?name=. Run: pc-set-append. Sources: neutronclient/osc/v2/sfc/sfc_port_chain.py:204-256.
4. Creating a service graph (client-side checks)
sequenceDiagram
autonumber
actor U as User
participant C as CreateSfcServiceGraph
participant S as openstacksdk
participant Q as Neutron
U->>C: sfc service graph create g --branching-point a:b --branching-point b:c --branching-point c:a
loop each branching point
C->>C: colon present, no duplicate destination
C->>S: find source chain
S->>Q: GET /sfc/port_chains/a
C->>S: find destination chain
S->>Q: GET /sfc/port_chains/b
C->>C: _check_cycle, adding the edge
end
alt two-node cycle or self-loop
C-->>U: Error Service graph contains a cycle, exit 1
else longer cycle, not detected
C->>S: create_sfc_service_graph
S->>Q: POST /sfc/service_graphs
Q-->>U: the server decides
endDiagnostics: the client check is partial, see defect 2 of 02 § 4. Whether a real server refuses the graph was not tested. Runs: graph-cycle-2-detected, graph-cycle-3-missed. Sources: neutronclient/osc/v2/sfc/sfc_service_graph.py:210-272.
5. A service using the library: Nova and Neutron errors
This scenario was read, not run: no consumer was started. Only find_resourceid_by_name_or_id was exercised, on the stub.
sequenceDiagram
autonumber
participant N as nova-api
participant W as ClientWrapper
participant C as Client
participant Q as Neutron
N->>W: get_client(context)
W->>C: Client(session, auth, global_request_id, connect_retries, ...)
N->>W: show_port(id)
W->>C: show_port(id)
C->>Q: GET /v2.0/ports/{id}, X-OpenStack-Request-ID
alt 200
Q-->>N: port dict with request_ids
else 404 with type PortNotFound
Q-->>C: NeutronError
C-->>N: PortNotFoundClient, handled per call site
else 401
Q-->>C: Unauthorized
C-->>W: Unauthorized
W-->>N: exception.Unauthorized for a user, NeutronAdminCredentialConfigurationInvalid for an admin client
endDiagnostics: Nova's mapping depends on the type string in the body. A service sending another type gives the generic NotFound, and Nova's except PortNotFoundClient no longer matches. Sources: nova:nova/network/neutron.py:164-205, nova:nova/network/neutron.py:701, neutronclient/v2_0/client.py:70, neutronclient/common/exceptions.py:143.
Source: reverse-spec-python-neutronclient/04-scenarios_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.