1use crate::Platform;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
15#[serde(rename_all = "camelCase", deny_unknown_fields)]
16pub struct AwsServiceOverrides {
17 pub endpoints: HashMap<String, String>,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
25#[serde(rename_all = "camelCase", deny_unknown_fields)]
26pub struct AwsImpersonationConfig {
27 pub role_arn: String,
29 pub session_name: Option<String>,
31 pub duration_seconds: Option<i32>,
33 pub external_id: Option<String>,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
40#[serde(rename_all = "camelCase", deny_unknown_fields)]
41pub struct AwsWebIdentityConfig {
42 pub role_arn: String,
44 pub session_name: Option<String>,
46 pub web_identity_token_file: String,
48 pub duration_seconds: Option<i32>,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
55#[serde(rename_all = "camelCase", tag = "type")]
56pub enum AwsCredentials {
57 AccessKeys {
59 access_key_id: String,
61 secret_access_key: String,
63 session_token: Option<String>,
65 },
66 WebIdentity {
68 config: AwsWebIdentityConfig,
70 },
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
75#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
76#[serde(rename_all = "camelCase", deny_unknown_fields)]
77pub struct AwsClientConfig {
78 pub account_id: String,
80 pub region: String,
82 pub credentials: AwsCredentials,
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub service_overrides: Option<AwsServiceOverrides>,
87}
88
89#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
91#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
92#[serde(rename_all = "camelCase", deny_unknown_fields)]
93pub struct GcpServiceOverrides {
94 pub endpoints: HashMap<String, String>,
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
102#[serde(rename_all = "camelCase", tag = "type")]
103pub enum GcpCredentials {
104 AccessToken { token: String },
106
107 ServiceAccountKey { json: String },
110
111 ServiceMetadata,
113
114 ProjectedServiceAccount {
116 token_file: String,
118 service_account_email: String,
120 },
121
122 AuthorizedUser {
125 client_id: String,
127 client_secret: String,
129 refresh_token: String,
131 },
132}
133
134#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
136#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
137#[serde(rename_all = "camelCase", deny_unknown_fields)]
138pub struct GcpImpersonationConfig {
139 pub service_account_email: String,
141 pub scopes: Vec<String>,
143 pub delegates: Option<Vec<String>>,
145 pub lifetime: Option<String>,
147}
148
149impl Default for GcpImpersonationConfig {
150 fn default() -> Self {
151 Self {
152 service_account_email: String::new(),
153 scopes: vec!["https://www.googleapis.com/auth/cloud-platform".to_string()],
154 delegates: None,
155 lifetime: Some("3600s".to_string()),
156 }
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
163#[serde(rename_all = "camelCase", deny_unknown_fields)]
164pub struct GcpClientConfig {
165 pub project_id: String,
167 pub region: String,
169 pub credentials: GcpCredentials,
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub service_overrides: Option<GcpServiceOverrides>,
174}
175
176#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
178#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
179#[serde(rename_all = "camelCase", deny_unknown_fields)]
180pub struct AzureServiceOverrides {
181 pub endpoints: HashMap<String, String>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
188#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
189#[serde(rename_all = "camelCase", tag = "type")]
190pub enum AzureCredentials {
191 ServicePrincipal {
193 client_id: String,
195 client_secret: String,
197 },
198 AccessToken {
200 token: String,
202 },
203 WorkloadIdentity {
205 client_id: String,
207 tenant_id: String,
209 federated_token_file: String,
211 authority_host: String,
213 },
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
218#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
219#[serde(rename_all = "camelCase", deny_unknown_fields)]
220pub struct AzureImpersonationConfig {
221 pub client_id: String,
223 pub scope: String,
225 pub tenant_id: Option<String>,
227}
228
229impl Default for AzureImpersonationConfig {
230 fn default() -> Self {
231 Self {
232 client_id: String::new(),
233 scope: "https://management.azure.com/.default".to_string(),
234 tenant_id: None,
235 }
236 }
237}
238
239#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
241#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
242#[serde(rename_all = "camelCase", deny_unknown_fields)]
243pub struct AzureClientConfig {
244 pub subscription_id: String,
246 pub tenant_id: String,
248 pub region: Option<String>,
250 pub credentials: AzureCredentials,
252 #[serde(skip_serializing_if = "Option::is_none")]
254 pub service_overrides: Option<AzureServiceOverrides>,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
259#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
260#[serde(rename_all = "camelCase", tag = "mode")]
261pub enum KubernetesClientConfig {
262 InCluster {
264 #[serde(skip_serializing_if = "Option::is_none")]
266 namespace: Option<String>,
267 #[serde(skip_serializing_if = "Option::is_none")]
269 additional_headers: Option<HashMap<String, String>>,
270 },
271 Kubeconfig {
273 #[serde(skip_serializing_if = "Option::is_none")]
275 kubeconfig_path: Option<String>,
276 #[serde(skip_serializing_if = "Option::is_none")]
278 context: Option<String>,
279 #[serde(skip_serializing_if = "Option::is_none")]
281 cluster: Option<String>,
282 #[serde(skip_serializing_if = "Option::is_none")]
284 user: Option<String>,
285 #[serde(skip_serializing_if = "Option::is_none")]
287 namespace: Option<String>,
288 #[serde(skip_serializing_if = "Option::is_none")]
290 additional_headers: Option<HashMap<String, String>>,
291 },
292 Manual {
294 server_url: String,
296 certificate_authority_data: Option<String>,
298 insecure_skip_tls_verify: Option<bool>,
300 client_certificate_data: Option<String>,
302 client_key_data: Option<String>,
304 token: Option<String>,
306 username: Option<String>,
308 password: Option<String>,
310 namespace: Option<String>,
312 additional_headers: HashMap<String, String>,
314 },
315}
316
317#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
319#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
320#[serde(rename_all = "camelCase", tag = "platform")]
321pub enum ImpersonationConfig {
322 Aws(AwsImpersonationConfig),
323 Gcp(GcpImpersonationConfig),
324 Azure(AzureImpersonationConfig),
325 }
327
328#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
330#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
331#[serde(rename_all = "camelCase", tag = "platform")]
332pub enum ClientConfig {
333 Aws(Box<AwsClientConfig>),
334 Gcp(Box<GcpClientConfig>),
335 Azure(Box<AzureClientConfig>),
336 Kubernetes(Box<KubernetesClientConfig>),
337 Local {
338 state_directory: String,
340 #[serde(skip_serializing_if = "Option::is_none")]
344 artifact_registry_config: Option<crate::ArtifactRegistryConfig>,
345 },
346 #[serde(skip)]
348 Test,
349}
350
351impl ClientConfig {
352 pub fn platform(&self) -> Platform {
354 match self {
355 ClientConfig::Aws(_) => Platform::Aws,
356 ClientConfig::Gcp(_) => Platform::Gcp,
357 ClientConfig::Azure(_) => Platform::Azure,
358 ClientConfig::Kubernetes(_) => Platform::Kubernetes,
359 ClientConfig::Local { .. } => Platform::Local,
360 ClientConfig::Test => Platform::Test,
361 }
362 }
363
364 pub fn aws_config(&self) -> Option<&AwsClientConfig> {
366 match self {
367 ClientConfig::Aws(config) => Some(config),
368 _ => None,
369 }
370 }
371
372 pub fn gcp_config(&self) -> Option<&GcpClientConfig> {
374 match self {
375 ClientConfig::Gcp(config) => Some(config),
376 _ => None,
377 }
378 }
379
380 pub fn azure_config(&self) -> Option<&AzureClientConfig> {
382 match self {
383 ClientConfig::Azure(config) => Some(config),
384 _ => None,
385 }
386 }
387
388 pub fn kubernetes_config(&self) -> Option<&KubernetesClientConfig> {
390 match self {
391 ClientConfig::Kubernetes(config) => Some(config),
392 _ => None,
393 }
394 }
395}