Skip to content

Percent-encode resource ids in URL paths - #152

Open
fivetime wants to merge 1 commit into
gnocchixyz:masterfrom
fivetime:fix/encode-resource-id
Open

Percent-encode resource ids in URL paths#152
fivetime wants to merge 1 commit into
gnocchixyz:masterfrom
fivetime:fix/encode-resource-id

Conversation

@fivetime

@fivetime fivetime commented Sep 1, 2026

Copy link
Copy Markdown

Problem

Resource ids are free-form strings on the server side (non-UUID ids get hashed into a UUID), and real-world ids contain characters that are significant in a URL. Cinder reports storage pools as <host>@<backend>#<pool>; the client splices that id raw into the path, so everything from # on becomes a URL fragment and the server sees /v1/resource/volume_provider_pool/<host>@<backend> — a different, usually nonexistent resource → 404.

Observed with Ceilometer's gnocchi publisher on volume.provider.pool.capacity.* samples: creation works (the id travels in the batch body), but every attribute update is rejected:

PATCH /v1/resource/volume_provider_pool/ceph-aa@hdd-rep3#hdd-rep3   (client)
PATCH /v1/resource/volume_provider_pool/ceph-aa@hdd-rep3            (what the server receives) → 404

Fix

Add utils.encode_resource_id() (urllib.parse.quote(..., safe="")) and apply it wherever a resource id is spliced into a path: ResourceManager.get/history/update/delete and the MetricManager resource-scoped paths (get, create, delete, get_measures, add_measures, set_measures). UUID ids are unchanged; the server decodes percent-encoding, verified against Gnocchi 4.7:

PATCH /v1/resource/volume_provider_pool/ceph-aa%40hdd-rep3%23hdd-rep3 → 200

Note safe="" also encodes @ (→ %40); harmless for the server, but happy to switch to safe="@" if you prefer minimal encoding.

Tests

gnocchiclient/tests/unit/test_resource_id_encoding.py pins the encoding and the URLs produced by each affected method. Unit suite and flake8 (with the repo's ignore list) pass.

Co-authored with Claude (Anthropic); reviewed and tested by a human.

Resource ids are free-form strings server-side (anything that is not a
UUID gets hashed into one), and real-world ids contain characters that
are significant in a URL. Cinder reports storage pools as
"<host>@<backend>#<pool>"; putting that id raw into the path turns
everything from '#' on into a URL fragment, so resource show/update/
delete and metric-by-resource requests land on "<host>@<backend>" -- a
different, usually nonexistent resource -- and fail with 404.

The Ceilometer gnocchi publisher hits this on every polled
volume.provider.pool.capacity.* sample that carries resource attributes:
the initial creation works (the id travels in the batch body) but the
attribute update never does.

Add utils.encode_resource_id() (urllib.parse.quote with safe="") and
apply it wherever a resource id is spliced into a path.

Co-Authored-By: Claude Fable 5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant