alien_bindings/providers/service_account/
azure_managed_identity.rs1use crate::error::{ErrorData, Result};
2use crate::traits::{
3 AzureServiceAccountInfo, Binding, ImpersonationRequest, ServiceAccount, ServiceAccountInfo,
4};
5use alien_azure_clients::{AzureClientConfig, AzureClientConfigExt};
6use alien_core::bindings::AzureServiceAccountBinding;
7use alien_core::{AzureClientConfig as CoreAzureClientConfig, ClientConfig};
8use alien_error::Context;
9use async_trait::async_trait;
10use std::collections::HashMap;
11
12#[derive(Debug)]
19pub struct AzureManagedIdentityServiceAccount {
20 config: AzureClientConfig,
21 binding: AzureServiceAccountBinding,
22}
23
24impl AzureManagedIdentityServiceAccount {
25 pub fn new(config: AzureClientConfig, binding: AzureServiceAccountBinding) -> Self {
26 Self { config, binding }
27 }
28
29 fn get_client_id(&self) -> Result<String> {
31 self.binding
32 .client_id
33 .clone()
34 .into_value("service-account", "client_id")
35 .context(ErrorData::BindingConfigInvalid {
36 binding_name: "service-account".to_string(),
37 reason: "Failed to resolve client_id from binding".to_string(),
38 })
39 }
40
41 fn get_resource_id(&self) -> Result<String> {
43 self.binding
44 .resource_id
45 .clone()
46 .into_value("service-account", "resource_id")
47 .context(ErrorData::BindingConfigInvalid {
48 binding_name: "service-account".to_string(),
49 reason: "Failed to resolve resource_id from binding".to_string(),
50 })
51 }
52
53 fn get_principal_id(&self) -> Result<String> {
55 self.binding
56 .principal_id
57 .clone()
58 .into_value("service-account", "principal_id")
59 .context(ErrorData::BindingConfigInvalid {
60 binding_name: "service-account".to_string(),
61 reason: "Failed to resolve principal_id from binding".to_string(),
62 })
63 }
64}
65
66impl Binding for AzureManagedIdentityServiceAccount {}
67
68#[async_trait]
69impl ServiceAccount for AzureManagedIdentityServiceAccount {
70 async fn get_info(&self) -> Result<ServiceAccountInfo> {
71 let client_id = self.get_client_id()?;
72 let resource_id = self.get_resource_id()?;
73 let principal_id = self.get_principal_id()?;
74
75 Ok(ServiceAccountInfo::Azure(AzureServiceAccountInfo {
76 client_id,
77 resource_id,
78 principal_id,
79 }))
80 }
81
82 async fn impersonate(&self, _request: ImpersonationRequest) -> Result<ClientConfig> {
83 let client_id = self.get_client_id()?;
84
85 let mut env_vars: HashMap<String, String> = std::env::vars().collect();
97
98 env_vars.insert("AZURE_CLIENT_ID".to_string(), client_id.clone());
100
101 let impersonated_config =
103 CoreAzureClientConfig::from_env(&env_vars)
104 .await
105 .context(ErrorData::Other {
106 message: format!(
107 "Failed to create Azure config for impersonation with client_id: {}",
108 client_id
109 ),
110 })?;
111
112 Ok(ClientConfig::Azure(Box::new(impersonated_config)))
113 }
114
115 fn as_any(&self) -> &dyn std::any::Any {
116 self
117 }
118}