aws_sdk_manager/
sts.rs

1use crate::errors::{Error::API, Result};
2use aws_sdk_sts::{types::SdkError, Client};
3use aws_types::SdkConfig as AwsSdkConfig;
4use log::info;
5use serde::{Deserialize, Serialize};
6
7/// Implements AWS STS manager.
8#[derive(Debug, Clone)]
9pub struct Manager {
10    #[allow(dead_code)]
11    shared_config: AwsSdkConfig,
12    cli: Client,
13}
14
15impl Manager {
16    pub fn new(shared_config: &AwsSdkConfig) -> Self {
17        let cloned = shared_config.clone();
18        let cli = Client::new(shared_config);
19        Self {
20            shared_config: cloned,
21            cli,
22        }
23    }
24
25    /// Queries the AWS caller identity from the default AWS configuration.
26    pub async fn get_identity(&self) -> Result<Identity> {
27        info!("fetching caller identity");
28        let ret = self.cli.get_caller_identity().send().await;
29        let resp = match ret {
30            Ok(v) => v,
31            Err(e) => {
32                return Err(API {
33                    message: format!("failed get_caller_identity {:?}", e),
34                    is_retryable: is_error_retryable(&e),
35                });
36            }
37        };
38
39        Ok(Identity::new(
40            resp.account().unwrap_or(""),
41            resp.arn().unwrap_or(""),
42            resp.user_id().unwrap_or(""),
43        ))
44    }
45}
46
47/// Represents the caller identity.
48#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
49pub struct Identity {
50    pub account_id: String,
51    pub role_arn: String,
52    pub user_id: String,
53}
54
55impl Identity {
56    pub fn new(account_id: &str, role_arn: &str, user_id: &str) -> Self {
57        // ref. https://doc.rust-lang.org/1.0.0/style/ownership/constructors.html
58        Self {
59            account_id: String::from(account_id),
60            role_arn: String::from(role_arn),
61            user_id: String::from(user_id),
62        }
63    }
64}
65
66#[inline]
67pub fn is_error_retryable<E>(e: &SdkError<E>) -> bool {
68    match e {
69        SdkError::TimeoutError(_) | SdkError::ResponseError { .. } => true,
70        SdkError::DispatchFailure(e) => e.is_timeout() || e.is_io(),
71        _ => false,
72    }
73}