OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Clients

python-manilaclient — Interactions

Interactions — python-manilaclient — branch stable/2026.2

Branch stable/2026.2 @ d18a7e966 (6.3.0 + 2 maintenance commits) — repository https://opendev.org/openstack/python-manilaclient — analysed on 2026-11-01

There is no database, message bus or cache. The only network peers are Keystone, Manila and, for a few options, Neutron. Everything marked [observed] was seen against the local stub, which is not Manila.

1. Client stack

flowchart LR
  cmd[manilaclient/osc/v2 command] --> mgr[manilaclient/v2 manager]
  mgr --> sc[httpclient.SessionClient]
  sc --> ksa[keystoneauth1 session]
  ksa -->|HTTPS + X-Auth-Token| manila[Manila]
  ksa -->|password or other auth plugin| ks[Keystone]
  cmd -->|identity_client| ksc[python-keystoneclient]
  ksc --> ksa
  cmd -->|client_manager.network| sdk[openstacksdk]
  sdk --> ksa
  ksa -->|find network and subnet| neutron[Neutron]
  • Commands call share_client.<manager>.<method> and methods of Resource objects (manilaclient/osc/v2/share.py:1712).
  • Managers build URLs and bodies. Each microversion variant is a separate function chosen by api_versions.wraps (manilaclient/api_versions.py:420).
  • **SessionClient** is a keystoneauth LegacyJsonAdapter. It keeps the microversion as default_microversion, and turns any status >= 400 into a manilaclient exception (manilaclient/common/httpclient.py:65, manilaclient/common/httpclient.py:97-99).
  • **HTTPClient** is a second, requests-based client, created only when a caller passes input_auth_token (manilaclient/v2/client.py:169-189). make_client never does (manilaclient/osc/plugin.py:85-96), so no OSC command uses it. It matters only to Python API users.

2. Keystone

ExchangeWhenSource
GET /identity/, POST /identity/v3/auth/tokensfirst authenticated call of the processkeystoneauth, through the OSC client manager
GET /projects/{name}, then GET /projects?name=, GET /projects--project, positional project of share quota *, share group type access *manilaclient/osc/v2/quotas.py:286, manilaclient/osc/v2/share.py:666
GET /users/{name}, GET /users?name=--usermanilaclient/osc/v2/quotas.py:180

Those lookups use python-keystoneclient, not the SDK. Two helpers behave differently when Keystone refuses them [observed, cases quota-show-forbidden and list-project-forbidden]:

HelperCommandsOn a 403 from Keystone
osc_lib.utils.find_resourceshare quota set, show, deletethe command fails with the 403 message, exit 1 (manilaclient/osc/v2/quotas.py:370)
identity_common.find_projectshare list, share network list, share server list, share lock list, share group list, share group type access *the name is used as the project ID, and the request goes on (manilaclient/osc/v2/share.py:666)

So a user who cannot read Keystone projects cannot run share quota show, even for their own project, unless Keystone allows the lookup [inferred from the stub's 403; Keystone's real policy was not exercised].

3. Catalog and endpoint

StepBehaviourSource
Override--os-endpoint-override, or OS_SHARED_FILE_SYSTEM_ENDPOINT_OVERRIDE, OS_ENDPOINT_OVERRIDE, OS_MANILA_BYPASS_URL, MANILACLIENT_BYPASS_URL, skips the catalogmanilaclient/osc/plugin.py:136-149, manilaclient/osc/plugin.py:69-74
Lookupservice type shared-file-system, then sharev2manilaclient/osc/plugin.py:41-55, manilaclient/common/constants.py:135
Nothing foundpublic endpoint for shared-file-system service in RegionOne region not found, exit 1 [observed]. The plugin's own EndpointNotFound message at manilaclient/osc/plugin.py:56 was not seencase catalog-none
sharev2 onlyworks, requests unchanged [observed]case catalog-sharev2

Discovery uses the path of the endpoint. _get_base_url cuts the URL before /vN (manilaclient/common/httpclient.py:70-83). A catalog URL without /vN gives the root of the host: with --os-endpoint-override http://host/somewhere, discovery goes to GET http://host/, while requests go to /somewhere/shares/detail [observed, case override-unversioned]. A deployment behind a path prefix must keep /v2 in the URL.

4. Microversion negotiation

Every command that touches client_manager.share runs this once [observed: one discovery request per command, on all 154].

flowchart TD
  a[Requested: --os-share-api-version, OS_SHARE_API_VERSION, or 2.98] --> b[GET base URL, sent at 2.98]
  b --> c{entry with status CURRENT and a non-empty version}
  c -- no --> d[version 1.0, then refused: not in API_VERSIONS]
  c -- yes --> e{requested within min..max}
  e -- yes --> f[use requested]
  e -- requested above max --> g[use server max, debug log only]
  e -- requested below min --> h[UnsupportedVersion]
RuleSourceEvidence
Client maximum 2.98, minimum 2.0. Manila's maximum on this branch is 2.99manilaclient/api_versions.py:32-33, manila:manila/api/openstack/api_version_request.py:229
The option accepts 2.0 to 2.98 only; 2.99 exits 2manilaclient/osc/plugin.py:35-37, manilaclient/osc/plugin.py:128-135[observed] version-refused
The environment variable skips that check: OS_SHARE_API_VERSION=2.99 fails later with Invalid share client version '2.99'. must be one of: …, OS_SHARE_API_VERSION=2 fails with Invalid format of client version '2'manilaclient/api_versions.py:54-67, manilaclient/osc/plugin.py:95-97[observed] env-version-above, env-version-major
Discovery reads versions[].status, .version, .min_versionmanilaclient/api_versions.py:244-261[observed]
A body without versions is read as "no microversions", then refused, because 1.0 is not in API_VERSIONSmanilaclient/v2/services.py:108-109, manilaclient/api_versions.py:280-286, manilaclient/osc/plugin.py:35-37[observed] disc-empty, disc-html, disc-bad-version
A 404 on discovery stops the command with the 404 messagemanilaclient/v2/services.py:108-109 catches only LookupError[observed] disc-404
Requested above the server maximum: silently lowered to the server maximummanilaclient/api_versions.py:312-329[observed] disc-requested-above, requested 2.70, sent 2.50
Requested below the server minimum: errormanilaclient/api_versions.py:331-340[observed] disc-requested-below

Headers

Every request to Manila carries these [observed, case headers-sample]:

X-Auth-Token: <token>
User-Agent: python-manilaclient
Accept: application/json
OpenStack-API-Version: shared-file-system 2.98
X-OpenStack-Manila-API-Version: 2.98

Manila reads only X-OpenStack-Manila-API-Version (manila:manila/api/openstack/wsgi.py:53, manila:manila/api/openstack/wsgi.py:226). keystoneauth adds both (keystoneauth:keystoneauth1/session.py:730, manilaclient/common/httpclient.py:65).

Experimental header

X-OpenStack-Manila-API-Experimental: true is set by experimental_api (manilaclient/api_versions.py:404-417) on the client object, so it stays on every later request of that process [observed: share backup create sends the GET of the share without it, and the POST with it]. It is sent:

FeatureUp toSource
Share backupsalways (2.80 and above)manilaclient/v2/share_backups.py:35
Share server migration, server task statealways (2.57 and above)manilaclient/v2/share_servers.py:278
Share migration2.95, graduated at 2.96manilaclient/common/constants.py:184
Share replicas2.55, graduated at 2.56manilaclient/common/constants.py:179
Share groups, group types, group snapshots2.54, graduated at 2.55manilaclient/v2/share_groups.py:27

A service must accept the header on any route, and must answer experimental routes when it is present (manila:manila/api/openstack/wsgi.py:245-248).

5. Manila REST calls

The complete list is generated: [_rewrite/api-surface_stable-2026.2.md](_rewrite/api-surface_stable-2026.2.md), with the microversion range of each route, and [_rewrite/manager-routes_stable-2026.2.json](_rewrite/manager-routes_stable-2026.2.json), per manager method and variant. Conventions that hold across them:

ConventionDetailSource
ListsGET /<resource>/detail or GET /<resource>, answer {"<plural>": [...]}. If count is in the body, the manager returns a tuplemanilaclient/base.py:70-113
ShowGET /<resource>/{id}, answer {"<singular>": {...}}manilaclient/base.py:182-189
CreatePOST /<resource>, body {"<singular>": {...}}manilaclient/base.py:202-210
UpdatePUT /<resource>/{id}; the answer may be emptymanilaclient/base.py:218-225
ActionsPOST /<resource>/{id}/action, body {"<action>": <args or null>}manilaclient/v2/shares.py:1093-1104
Query stringsorted, and falsy values are dropped, so --limit 0 and False filters are not sentmanilaclient/base.py:227-231
~never percent-encodedmanilaclient/utils.py:69
Dict filtersmetadata and extra_specs are sent as a Python dict repr, for example metadata=%7B%27k%27%3A+%27v%27%7D [observed]. Manila parses them with ast.literal_evalmanilaclient/base.py:229, manila:manila/api/v2/shares.py:1526
Old routesbelow 2.7 the managers use os- names (/os-services, /os-quota-sets, os-force_delete)manilaclient/v2/services.py:19, manilaclient/v2/shares.py:825

Name lookup is expensive

apiutils.find_resource tries, in order, an integer ID, a UUID, then find(human_id=…) and find(name=…) (manilaclient/common/apiclient/utils.py:39-69). find lists the whole collection with all_tenants=1 and filters on the client (manilaclient/base.py:253-279). From 2.69, shares are listed a second time with is_soft_deleted=True (manilaclient/base.py:264-269).

So share show <name> sends four listings before the show [observed, case name-lookup]:

GET /shares/detail?all_tenants=1&is_public=True
GET /shares/detail?all_tenants=1&is_public=True&is_soft_deleted=True
GET /shares/detail?all_tenants=1&is_public=True
GET /shares/detail?all_tenants=1&is_public=True&is_soft_deleted=True
GET /shares/{id}/export_locations

osc_lib.utils.find_resource, used by the newer commands, tries GET /<resource>/{name} first (osc-lib:osc_lib/utils/__init__.py:234), then find. Both forms exist in the plugin, and the choice is per command (manilaclient/osc/v2/share.py:807, manilaclient/osc/v2/share_backups.py:300).

6. Neutron

CommandBehaviourSource
share network create, share network subnet createwith --neutron-net-id and --neutron-subnet-id, resolves names through the SDK: GET /networks/{name}, GET /subnets/{name} [observed]. Any failure reads Neutron network 'x' not found.manilaclient/osc/v2/share_networks.py:347-366, manilaclient/osc/v2/share_network_subnets.py:146-164
share network setsends the values unchanged [observed]manilaclient/osc/v2/share_networks.py:592-595

7. Other

ItemDetailSource
Timeouts and retriesnone set by the plugin: make_client passes no timeout or retries, so retries is 0. keystoneauth and the OSC global options applymanilaclient/osc/plugin.py:85-96, manilaclient/common/httpclient.py:58
Retry loopexists in _cs_request, with doubling delay, when retries is set by a Python API usermanilaclient/common/httpclient.py:102-125
Local filessee 05manilaclient/base.py:116
Configurationmanilaclient/config.py is an oslo.config file for the functional tests only, not read by commandsmanilaclient/tests/functional/osc/base.py:19, pyproject.toml:34
Binaries, socketsnone. getpass exists in manilaclient/common/cliutils.py:232, no command calls get_password
Secretsshare security service create --password puts the password on the command line, and share transfer create prints the auth_keymanilaclient/osc/v2/security_services.py:118, manilaclient/osc/v2/share_transfers.py:73

Source: reverse-spec-python-manilaclient/03-interactions_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.