Invitations
When RADKit Service is connected to RADKit Cloud, it automatically informs the cloud which of its remote users are allowed to access it. This mechanism is called an invitation: for every remote user that has cloud connectivity enabled and is currently active, the Service pushes an invitation to RADKit Cloud containing that user’s username, context labels, and expiration.
A RADKit Client only ever sees the invitations addressed to its own identity. The Client still has to fetch that information from RADKit Cloud (see Client operation below). The Service does not get polled or queried for it directly.
Note
Invitations are only pushed while service.connectivity.enable_cloud is
enabled on the Service, and only for remote users with
connection_mode_cloud_active set. See
service.connectivity.enable_cloud for that setting, and
Remote users for the remote user fields.
Note
RADKit Cloud automatically expires (deletes) an invitation approximately one hour after it was last (re-)published. The Service periodically republishes every active invitation well before that TTL elapses (see service.invitations_sync_interval) so that, as long as the Service stays connected to the cloud, a still-valid invitation never disappears from a Client’s view.
How invitations stay in sync
The Service keeps invitations in sync with its own remote-users and labels tables automatically, without any user action required:
Creating, updating, or deleting a remote user immediately updates or removes its invitation.
Renaming a label immediately updates the invitations of every remote user referencing that label.
A remote user’s expiration timestamp elapsing (without any other change) is detected through a periodic reconciliation, so an expired remote user’s invitation is eventually removed even if nothing else changed.
Service configuration
Invitations are pushed automatically for any remote user that has cloud connectivity enabled. No separate configuration is needed beyond creating the remote user and making sure the Service itself has cloud connectivity enabled.
For example, using the Control API reference:
>>> from radkit_service.control_api import ControlAPI, NewRemoteUser
>>> control_api = ControlAPI.create(...)
>>> control_api.create_remote_user(
... NewRemoteUser(
... username="alice@cisco.com",
... fullname="Alice",
... description="",
... connection_mode_cloud_active=True,
... )
... )
[SUCCESS] APIResult[StoredRemoteUser](status='SUCCESS')
------ --------------------------------------------------------------------------------
result StoredRemoteUser(username=alice@cisco.com, connection_mode_cloud_active=True...
------ --------------------------------------------------------------------------------
As soon as this remote user is created, the Service pushes an invitation for
alice@cisco.com to RADKit Cloud.
Disabling cloud connectivity for a remote user, or deleting it altogether, removes its invitation just as quickly:
>>> from radkit_service.control_api import UpdateRemoteUser
>>> control_api.update_remote_user(
... UpdateRemoteUser(
... username="alice@cisco.com",
... connection_mode_cloud_active=False,
... )
... )
[SUCCESS] APIResult[StoredRemoteUser](status='SUCCESS')
------ --------------------------------------------------------------------------------
result StoredRemoteUser(username=alice@cisco.com, connection_mode_cloud_active=False..
------ --------------------------------------------------------------------------------
Client operation
A Client can inspect its own invitations through client.invitations. Call
.update() to refresh it with the latest invitations from RADKit Cloud:
>>> client.invitations.update()
>>> client.invitations
{'RADKIT_CLOUD-xxxx-yyyy-zzzz-node-1': [ACTIVE] Invitation(service_id='xxxx-yyyy-zzzz')}
>>> invitation = client.invitations['RADKIT_CLOUD-xxxx-yyyy-zzzz-node-1']
>>> invitation.service_id
'xxxx-yyyy-zzzz'
>>> invitation.domain
'RADKIT_CLOUD'
>>> invitation.labels
['network-team']
>>> invitation.expires_at
Every entry in client.invitations corresponds to a Service the Client’s
own identity has been invited to. Use .service() to get the actual
Service object for that
invitation, which can then be used to connect:
>>> service = invitation.service()
>>> service.wait()
[READY] Service(service_id='xxxx-yyyy-zzzz')
Since invitations are kept in sync automatically, an application can simply
poll client.invitations (calling .update() each time) to discover new
services becoming available, or existing ones disappearing, without needing
any direct interaction with the Service that issued them.