ydb_unofficial/auth/
cli.rs

1use std::sync::{RwLock, Arc};
2use std::time::Duration;
3use crate::AsciiValue;
4use super::{Credentials, UpdatableToken};
5
6#[derive(Debug, Clone)]
7/// An automaitc updatable token.
8/// Updates every 11 hours by run command `yc iam create-token`.
9/// To use that you need [Yandex Cloud CLI](https://cloud.yandex.ru/docs/cli/operations/install-cli) installed
10pub struct Cli {
11    token: Arc<RwLock<AsciiValue>>,
12}
13
14impl Credentials for Cli {
15    fn token(&self) -> AsciiValue {
16        self.token.read().unwrap().clone()
17    }
18}
19
20impl Into<UpdatableToken> for Cli {
21    fn into(self) -> UpdatableToken {
22        let Self{ token} = self;
23        UpdatableToken { token }
24    }
25}
26
27impl Cli {
28    pub async fn new() -> Self {
29        let token = Self::create_token().await;
30        let token = Arc::new(RwLock::new(token));
31        let update_me = Arc::downgrade(&token);
32        tokio::spawn(async move {
33            let mut timer = tokio::time::interval(Duration::from_secs(60*60*11));
34            loop {
35                timer.tick().await;
36                if let Some(update_me) = update_me.upgrade() {
37                    let token = Self::create_token().await;
38                    *update_me.write().unwrap() = token;
39                } else {
40                    break;
41                }
42            }
43        });
44        Self {token}
45    }
46    async fn create_token() -> AsciiValue {
47        let out = tokio::process::Command::new("yc").arg("iam").arg("create-token").output().await.expect("cannot run `yc iam create-token`");
48        let stdout = out.stdout.as_slice();
49        let stdout = &stdout[0..stdout.len() - 1];
50        AsciiValue::try_from(stdout).unwrap()
51    }
52}