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

Reverse-spec · Clients

osc-placement — Cli commands

CLI commands — osc-placement — branch stable/2026.2

Branch stable/2026.2 @ 402610a21872 (4.9.1 + 2 maintenance commits) — repository https://opendev.org/openstack/osc-placement — analysed on 2026-10-28

osc-placement exposes no API: it is a **plugin of the openstack command line** (python-openstackclient) that turns 31 commands into calls to the Placement REST API. Its "interface" is therefore its commands, and its contract with the outside world is the HTTP requests it sends to Placement (see interactions and client contract).

1. Shared mechanics

  • Plugin loading: entry point openstack.cli.extension = placement (osc_placement/plugin.py). The commands are declared in setup.cfg ([entry_points] openstack.placement.v1), one per class.
  • Microversion choice: the --os-placement-api-version option (env OS_PLACEMENT_API_VERSION), default 1 (osc_placement/plugin.py:46-58).
    • With **1, the client **negotiates: it sends GET / with OpenStack-API-Version: placement 1.29 (MAX_VERSION_NO_GAP). On a 406, it falls back to the max_version that the server returns in errors[0] (osc_placement/http.py:69-86, osc_placement/version.py:57-61).
    • Consequence: by default the CLI uses 1.29 at most. The 1.38 (consumer types) and 1.39 (in: for traits) features need an explicit version.
  • Supported versions: 1.0 to 1.29, 1.37, 1.38, 1.39 (osc_placement/version.py:21-55). Any other value is refused by osc-lib before any call [inferred: utils.get_client_class with API_VERSIONS].
  • Client-side checks: each command checks the microversion before any HTTP call, through @version.check(version.ge('X')) or check_version(), which raise ValueError with "Operation or argument is not supported with version X; requires at least version Y" (osc_placement/version.py:119-147). Many options are enabled or required depending on the version (required=self.compare_version(...)).
  • Every request carries OpenStack-API-Version: placement <version> and Accept: application/json. The endpoint comes from the Keystone catalog (service_type=placement, region and interface of the CLI) (osc_placement/http.py:55-67, osc_placement/plugin.py:29-43).

2. Functional description by family

Resource providers (resource provider create|list|show|set|delete)

  • create (osc_placement/resources/resource_provider.py:26-73): POST /resource_providers, then **GET on the returned Location** to show the provider. --parent-provider needs 1.14.
  • list (osc_placement/resources/resource_provider.py:75-219): filters translated into query parameters, each with its minimum microversion: | Filter | Minimum microversion | |---|---| | --uuid, --name | 1.0 | | --member-of | 1.3 | | --resource | 1.4 | | --in-tree | 1.14 | | --required | 1.18, and 1.39 for A,B (in:) | | --forbidden | 1.22 | | --aggregate-uuid | 1.3 |
  • set (osc_placement/resources/resource_provider.py:259-310): PUT /resource_providers/{uuid} with name and parent (1.14).
  • show with --allocations adds GET /resource_providers/{uuid}/allocations.

Inventories (resource provider inventory set|class set|list|show|delete)

  • set (osc_placement/resources/inventory.py:101-252):
    • replaces the whole inventory, or adds to it with --amend, which first reads it (GET, then PUT with the generation read);
    • --aggregate (1.3) applies the same inventory to every provider of an aggregate: it continues on failure, then reports "Failed to set inventory for N of M resource providers.";
    • --dry-run shows without writing;
    • resource syntax: CLASS=total or CLASS:field=value (osc_placement/resources/inventory.py:80-99).
  • class set: PUT of a single class, with the provider's generation read first (osc_placement/resources/inventory.py:254-305).
  • delete: one class, or all of them with --resource-class omitted (1.5+, DELETE /resource_providers/{uuid}/inventories).

Allocations (resource provider allocation set|unset|show|delete)

  • set (osc_placement/resources/allocation.py:47-176):
    • --allocation rp=<uuid>,VCPU=2,... is parsed (osc_placement/resources/allocation.py:23-44);
    • format: a list before 1.12, a dict after;
    • --project-id and --user-id are required from 1.8, and --consumer-type from 1.38;
    • from 1.28, read-modify-write: GET /allocations/{consumer} to read consumer_generation, then PUT, then GET again to show. There is no retry: if the consumer is changed between the GET and the PUT, the user gets the 409 from Placement.
  • unset (1.12+, osc_placement/resources/allocation.py:178-300): removes some providers or resource classes from the existing allocations. From 1.28 it PUTs an empty dict; before that it uses DELETE.

Resource classes, traits, aggregates, usages, candidates

  • resource class (1.2+; set 1.7+ = idempotent PUT).
  • trait and resource provider trait (1.6+). resource provider trait set reads the provider to get its generation (osc_placement/resources/trait.py:182-223).
  • resource provider aggregate set|list (1.1+; from 1.19 with the provider generation, --generation required, osc_placement/resources/aggregate.py:22-89).
  • resource usage show (1.9+, per project and user); resource provider usage show.
  • allocation candidate list (1.10+, osc_placement/resources/allocation_candidate.py:43-288):
    • --group (1.25) groups the options that follow it into one numbered request group;
    • --limit (1.16), --required (1.17; A,B → in: 1.39), --forbidden (1.22), --member-of (1.21), --group-policy (1.25);
    • the list of required parameters is built by get_required_query_param_from_args (osc_placement/resources/common.py:41-58).

3. Commands, sources and Placement calls

The calls and statuses come from the recording of the functional tests (client contract). "Minimum microversion" is the @version.check of the class; the options may require more.

CommandClassMinimum microversionPlacement operationsStatuses seen in tests
openstack allocation candidate listosc_placement/resources/allocation_candidate.py:431.10GET /allocation_candidates200, 400
openstack resource class createosc_placement/resources/resource_class.py:461.2POST /resource_classes201, 400
openstack resource class deleteosc_placement/resources/resource_class.py:1281.2DELETE /resource_classes/{name}204, 400, 404
openstack resource class listosc_placement/resources/resource_class.py:241.2GET /resource_classes200
openstack resource class setosc_placement/resources/resource_class.py:701.7PUT /resource_classes/{name}201, 204
openstack resource class showosc_placement/resources/resource_class.py:1001.2GET /resource_classes/{name}200, 404
openstack resource provider aggregate listosc_placement/resources/aggregate.py:911.1GET /resource_providers/{uuid}/aggregates200, 404
openstack resource provider aggregate setosc_placement/resources/aggregate.py:221.1PUT /resource_providers/{uuid}/aggregates200, 400, 409
openstack resource provider allocation deleteosc_placement/resources/allocation.py:3481.0DELETE /allocations/{consumer_uuid}204, 404
openstack resource provider allocation setosc_placement/resources/allocation.py:471.0GET /allocations/{consumer_uuid}
PUT /allocations/{consumer_uuid}
200, 204
openstack resource provider allocation showosc_placement/resources/allocation.py:3021.0GET /allocations/{consumer_uuid}200
openstack resource provider allocation unsetosc_placement/resources/allocation.py:1781.12DELETE /allocations/{consumer_uuid}
GET /allocations/{consumer_uuid}
PUT /allocations/{consumer_uuid}
200, 204
openstack resource provider createosc_placement/resources/resource_provider.py:261.0GET /resource_providers/{uuid}
POST /resource_providers
200, 201
openstack resource provider deleteosc_placement/resources/resource_provider.py:3121.0DELETE /resource_providers/{uuid}204, 404, 409
openstack resource provider inventory class setosc_placement/resources/inventory.py:2541.0GET /resource_providers/{uuid}
PUT /resource_providers/{uuid}/inventories/{resource_class}
200
openstack resource provider inventory deleteosc_placement/resources/inventory.py:3071.0DELETE /resource_providers/{uuid}/inventories
DELETE /resource_providers/{uuid}/inventories/{resource_class}
204, 404
openstack resource provider inventory listosc_placement/resources/inventory.py:3901.0GET /resource_providers/{uuid}/inventories
GET /resource_providers/{uuid}/usages
200
openstack resource provider inventory setosc_placement/resources/inventory.py:1011.0GET /resource_providers
GET /resource_providers/{uuid}
GET /resource_providers/{uuid}/inventories
PUT /resource_providers/{uuid}/inventories
200, 400, 409
openstack resource provider inventory showosc_placement/resources/inventory.py:3501.0GET /resource_providers/{uuid}/inventories/{resource_class}
GET /resource_providers/{uuid}/usages
200, 404
openstack resource provider listosc_placement/resources/resource_provider.py:751.0GET /resource_providers200
openstack resource provider setosc_placement/resources/resource_provider.py:2591.0PUT /resource_providers/{uuid}200, 400, 404
openstack resource provider showosc_placement/resources/resource_provider.py:2211.0GET /resource_providers/{uuid}
GET /resource_providers/{uuid}/allocations
200, 404
openstack resource provider trait deleteosc_placement/resources/trait.py:2251.6DELETE /resource_providers/{uuid}/traits204
openstack resource provider trait listosc_placement/resources/trait.py:1551.6GET /resource_providers/{uuid}/traits200, 404
openstack resource provider trait setosc_placement/resources/trait.py:1821.6GET /resource_providers/{uuid}
PUT /resource_providers/{uuid}/traits
200, 400
openstack resource provider usage showosc_placement/resources/usage.py:681.0GET /resource_providers/{uuid}/usages200, 404
openstack resource usage showosc_placement/resources/usage.py:241.9GET /usages200
openstack trait createosc_placement/resources/trait.py:981.6PUT /traits/{name}201
openstack trait deleteosc_placement/resources/trait.py:1281.6DELETE /traits/{name}204, 404
openstack trait listosc_placement/resources/trait.py:241.6GET /traits200
openstack trait showosc_placement/resources/trait.py:701.6GET /traits/{name}204, 404

Source: reverse-spec-osc-placement/01-cli-commands_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.