yandex_cloud/
lib.rs

1//! This module provides low-level generated gRPC clients for the
2//! Yandex Cloud APIs.
3//!
4//! The clients are generated using the [tonic][] and [prost][]
5//! crates and have default configuration.
6//!
7//! Documentation present in the protos is retained into the generated
8//! Rust types, but for detailed API information you should visit the
9//! official Yandex Cloud Documentation pages:
10//!
11//! * [in English](https://cloud.yandex.com/en-ru/docs/overview/api)
12//! * [in Russian](https://cloud.yandex.ru/docs/overview/api)
13//!
14//! The proto sources are available on the [Yandex Cloud GitHub][protos].
15//!
16//! [tonic]: https://docs.rs/tonic/latest/tonic/
17//! [prost]: https://docs.rs/prost/latest/prost/
18//! [protos]: https://github.com/yandex-cloud/cloudapi
19//!
20//! The majority of user-facing structures can be found in the
21//! [`yandex::cloud`] module.
22//!
23//! ## Usage
24//!
25//! Typically to use these APIs, you need to provide an authentication
26//! credential and an endpoint to connect to. The full list of
27//! Yandex's endpoints is [available online][endpoints] and you should
28//! look up the service you plan to use and pick the correct endpoint
29//! from the list.
30//!
31//! Authentication is done via an HTTP header using an IAM token,
32//! which can be done in Tonic using [interceptors][]. The
33//! [`AuthInterceptor`] provided by this crate can be used for that
34//! purpose.
35//!
36//! Full usage examples are [available here][examples].
37//!
38//! [endpoints]: https://cloud.yandex.com/en/docs/api-design-guide/concepts/endpoints
39//! [interceptors]: https://docs.rs/tonic/latest/tonic/service/trait.Interceptor.html
40//! [examples]: https://code.tvl.fyi/tree/ops/yandex-cloud-rs/examples
41
42use tonic::metadata::{Ascii, MetadataValue};
43use tonic::service::Interceptor;
44
45/// Publicly re-export some types from tonic which users might need
46/// for implementing traits, or for naming concrete client types.
47pub mod tonic_exports {
48    pub use tonic::service::interceptor::InterceptedService;
49    pub use tonic::transport::Channel;
50    pub use tonic::transport::Endpoint;
51    pub use tonic::Status;
52}
53
54/// Helper trait for types or closures that can provide authentication
55/// tokens for Yandex Cloud.
56pub trait TokenProvider {
57    /// Fetch a currently valid authentication token for Yandex Cloud.
58    fn get_token<'a>(&'a mut self) -> Result<&'a str, tonic::Status>;
59}
60
61impl TokenProvider for String {
62    fn get_token<'a>(&'a mut self) -> Result<&'a str, tonic::Status> {
63        Ok(self.as_str())
64    }
65}
66
67impl TokenProvider for &'static str {
68    fn get_token(&mut self) -> Result<&'static str, tonic::Status> {
69        Ok(*self)
70    }
71}
72
73/// Interceptor for adding authentication headers to gRPC requests.
74/// This is constructed with a callable that returns authentication
75/// tokens.
76///
77/// This callable is responsible for ensuring that the returned tokens
78/// are valid at the given time, i.e. it should take care of
79/// refreshing and so on.
80pub struct AuthInterceptor<T: TokenProvider> {
81    token_provider: T,
82}
83
84impl<T: TokenProvider> AuthInterceptor<T> {
85    pub fn new(token_provider: T) -> Self {
86        Self { token_provider }
87    }
88}
89
90impl<T: TokenProvider> Interceptor for AuthInterceptor<T> {
91    fn call(
92        &mut self,
93        mut request: tonic::Request<()>,
94    ) -> Result<tonic::Request<()>, tonic::Status> {
95        let token: MetadataValue<Ascii> = format!("Bearer {}", self.token_provider.get_token()?)
96            .try_into()
97            .map_err(|_| {
98                tonic::Status::invalid_argument("authorization token contained invalid characters")
99            })?;
100
101        request.metadata_mut().insert("authorization", token);
102
103        Ok(request)
104    }
105}
106
107// The rest of this file is generated by the build script at ../build.rs.
108include!("includes.rs");