Metadata identity + unary command RPCs part 1#1918
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1918 +/- ##
========================================
+ Coverage 61.0% 61.2% +0.1%
========================================
Files 182 185 +3
Lines 14881 15019 +138
========================================
+ Hits 9083 9194 +111
- Misses 5798 5825 +27
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
|
I took the liberty to reformatted for the PR template, this should make the description more readable. |
| client_call_details.metadata.add(USER_AGENT_KEY, self.user_agent) | ||
|
|
||
|
|
||
| class IdentityClientUnaryUnaryInterceptor(UnaryUnaryClientInterceptor, BaseIdentityClientInterceptor): |
There was a problem hiding this comment.
Do we really need to child classes here? To me it looks like these only differ in parameters, and this won't matter for python as long as the number of parameters remain the same.
It would be nice if we can simplify this to one class that implements the logic.
There was a problem hiding this comment.
grpc.aio.Channel sorts interceptors into per-RPC-type lists using isinstance(), so we would still need separate unary-unary and stream-stream interceptor classes.
There was a problem hiding this comment.
But we could just have a IdentityClientInterceptor(UnaryUnaryClientInterceptor, StreamStreamClientInterceptor) or is there something baring that on the gRPC side?
Edit: Does not look like it, the gRPC example uses a similar pattern: https://github.com/grpc/grpc/blob/b86a3460af2160cd7a02bd51014bc9fa036b91ff/examples/python/interceptors/default_value/default_value_client_interceptor.py#L48
|
During the review of this PR yesterday it came up that we are missing a good justification for separate unary RPC instead of extending the |
|
Hey @Emantor , Thanks for sharing the concern. The primary motivation for this came out of our work on the Labgrid fleeting plugin, and the more we thought about it the more sense it made. At the moment ClientStream is doing two jobs: it is both a watch/update mechanism and part of the session/identity for independent RPCs. That coupling is what we are trying to remove. A service, CI worker, web backend, or short-lived tool should be able to make a bounded RPC with identity/auth metadata on that RPC, get a response, and finish. This also matters for production/distributed deployments. If every client has to establish and maintain a ClientStream session, then coordinator endpoint changes, load balancer migration, reconnects, and horizontally scaled services all need to manage stream/session recovery. In many cases those clients gain no benefit from a long-lived session. The intent here is to decouple those concerns: clients that need ClientStream for live updates can still use it. A stream also makes auth harder as the coordinator has to continuously filter updates for each client and ensure no unauthorised state is ever sent. For unary RPCs, the auth decision is scoped to one operation and one response. If you feel this is useful context I can add this to the discussion as needed. Thanks |
8291b0e to
604b887
Compare
|
@Emantor as discussed I've updated this PR to only include the client stream decoupling |
| logging.debug("client identity provided in gRPC metadata") | ||
| logging.debug(identity) | ||
| self.clients[peer] = ClientSession(self, peer, identity.id, out_msg_queue, identity.user_agent) | ||
|
|
There was a problem hiding this comment.
The ClientSession creation can be moved into the startup handling, new clients will sent both for a release (old coordinators use the old StartupDone message, new ones the identity). The coordinator uses the identity for new clients and warns for connections of older clients.
With the introduction of auth we can than abort for older clients, which are not supported with auth.
There was a problem hiding this comment.
updated in latest commit
Add client and server interceptors which attach labgrid identity metadata to gRPC calls and expose it to coordinator RPC handlers. Use the metadata identity to register client and exporter stream sessions while keeping startup-message handling as a deprecated fallback for older clients and exporters. Signed-off-by: Asher Pemberton <asher.pemberton@arm.com> Reviewed-by: Asher Pemberton <asher.pemberton@arm.com> # gatekeeper Co-authored-by: Luke Beardsmore <luke.beardsmore2@arm.com>
Allow AcquirePlace, ReleasePlace and CreateReservation to identify the caller from gRPC metadata instead of requiring identity to come only from an established ClientStream session. Keep the existing ClientStream session lookup as a fallback so older clients which still send startup messages on the stream continue to work. Signed-off-by: Asher Pemberton <asher.pemberton@arm.com> Reviewed-by: Asher Pemberton <asher.pemberton@arm.com> # gatekeeper Co-authored-by: Luke Beardsmore <luke.beardsmore2@arm.com>
Send StartupDone alongside identity metadata so new clients and exporters remain compatible with older coordinators. Create sessions immediately from identity metadata when available, while retaining StartupDone as a deprecated fallback. Signed-off-by: Asher Pemberton <asher.pemberton@arm.com> Reviewed-by: Asher Pemberton <asher.pemberton@arm.com> # gatekeeper
604b887 to
04a49f6
Compare
Description
This is the first part of the coordinator unary-RPC rework. It introduces metadata-based identity for clients and exporters, reducing the coordinator’s dependency on startup messages sent through the long-lived streams.
This PR:
Motivation
Decouple ClientStream’s live-update role from identity and independent RPCs, allowing services and short-lived tools to perform bounded authenticated operations without maintaining stream state. This simplifies client implementations, reconnection handling, horizontal scaling, and per-operation authorization.
Compatibility note
Old clients and exporters remain compatible with the new coordinator through the startup-message fallback.
However, new clients and exporters stop sending startup identity messages and are therefore incompatible with coordinators predating this change. Those coordinators cannot establish the required stream session.
See also
Discussion on the gRPC unary rework: #1881
Follow-up RPC changes: #1919
The List RPC changes: #1933