flowey_lib_common/
ado_task_azure_key_vault.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! ADO Task Wrapper: `AzureKeyVault@2`
5
6use flowey::node::prelude::*;
7use std::collections::BTreeMap;
8
9flowey_request! {
10    pub struct Request {
11        /// Select the service connection for the Azure subscription containing the Azure Key Vault instance, or create a new connection.
12        pub subscription: String,
13        /// The name of the Azure Key Vault that contains the secrets to download.
14        pub key_vault_name: String,
15        /// Downloads the specified secret
16        pub secret: String,
17        /// Handle to the resolved secret
18        pub resolved_secret: WriteVar<String>,
19    }
20}
21
22new_flow_node!(struct Node);
23
24impl FlowNode for Node {
25    type Request = Request;
26
27    fn imports(_ctx: &mut ImportCtx<'_>) {
28        // no deps
29    }
30
31    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
32        let mut vaults_with_secrets: BTreeMap<_, BTreeMap<_, Vec<_>>> = BTreeMap::new();
33        for Request {
34            subscription,
35            key_vault_name,
36            secret,
37            resolved_secret,
38        } in requests
39        {
40            vaults_with_secrets
41                .entry((subscription, key_vault_name))
42                .or_default()
43                .entry(secret)
44                .or_default()
45                .push(resolved_secret);
46        }
47
48        let vaults_with_secrets = vaults_with_secrets;
49
50        // -- end of req processing -- //
51
52        for ((subscription, key_vault_name), secrets_and_vars) in vaults_with_secrets {
53            let secrets = secrets_and_vars
54                .keys()
55                .cloned()
56                .collect::<Vec<_>>()
57                .join(",");
58
59            ctx.emit_ado_step(
60                format!(
61                    "Downloading secrets from key vault {}/{}",
62                    subscription, key_vault_name
63                ),
64                move |ctx| {
65                    let secrets_and_vars = secrets_and_vars.claim(ctx);
66
67                    move |rt| {
68                        for (secret, out_vars) in secrets_and_vars {
69                            for var in out_vars {
70                                rt.set_var(
71                                    var,
72                                    AdoRuntimeVar::dangerous_from_global(secret.clone(), true),
73                                )
74                            }
75                        }
76
77                        format!(
78                            r#"
79                                - task: AzureKeyVault@2
80                                  inputs:
81                                    azureSubscription: '{subscription}'
82                                    KeyVaultName: '{key_vault_name}'
83                                    SecretsFilter: '{secrets}'
84                            "#
85                        )
86                    }
87                },
88            );
89        }
90
91        Ok(())
92    }
93}