Skip to content

Commit 0ea091c

Browse files
authored
Merge pull request #1046 from SteveL-MSFT/secret-plain
Change secret extensions to emit secret without JSON wrapping
2 parents 48f2e06 + 97d30d0 commit 0ea091c

File tree

9 files changed

+71
-29
lines changed

9 files changed

+71
-29
lines changed

dsc/tests/dsc_functions_secret.tests.ps1 renamed to dsc/tests/dsc_extension_secret.tests.ps1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,19 @@ Describe 'Tests for the secret() function and extensions' {
116116
$out.results.Count | Should -Be 1
117117
$out.results[0].result.actualState.Output | Should -BeExactly 'SameSecret'
118118
}
119+
120+
It 'Secret with multiple lines' {
121+
$configYaml = @'
122+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
123+
resources:
124+
- name: Echo
125+
type: Microsoft.DSC.Debug/Echo
126+
properties:
127+
output: "[secret('MultiLine')]"
128+
'@
129+
dsc -l trace config get -i $configYaml 2> $TestDrive/error.log | ConvertFrom-Json
130+
$LASTEXITCODE | Should -Be 2
131+
$errorMessage = Get-Content -Raw -Path $TestDrive/error.log
132+
$errorMessage | Should -Match "Extension 'Test/Secret2' returned multiple lines which is not supported for secrets"
133+
}
119134
}

dsc_lib/locales/en-us.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,12 @@ discoverNoResults = "No results returned for discovery extension '%{extension}'"
181181
discoverNotAbsolutePath = "Resource path from extension '%{extension}' is not an absolute path: %{path}"
182182
extensionReturned = "Extension '%{extension}' returned line: %{line}"
183183
retrievingSecretFromExtension = "Retrieving secret '%{name}' from extension '%{extension}'"
184-
secretExtensionReturnedInvalidJson = "Extension '%{extension}' returned invalid JSON: %{error}"
185184
extensionReturnedSecret = "Extension '%{extension}' returned secret"
186185
extensionReturnedNoSecret = "Extension '%{extension}' did not return a secret"
187-
secretNoResults = "Extension '%{extension}' returned no output"
188186
importingFile = "Importing file '%{file}' with extension '%{extension}'"
189187
importNotSupported = "Import is not supported by extension '%{extension}' for file '%{file}'"
190188
importNoResults = "Extension '%{extension}' returned no results for import"
189+
secretMultipleLinesReturned = "Extension '%{extension}' returned multiple lines which is not supported for secrets"
191190

192191
[extensions.extension_manifest]
193192
extensionManifestSchemaTitle = "Extension manifest schema URI"

dsc_lib/src/extensions/dscextension.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,20 @@ use schemars::JsonSchema;
99
use std::{fmt::Display, path::Path};
1010
use tracing::{debug, info, trace};
1111

12-
use crate::{discovery::command_discovery::{load_manifest, ImportedManifest}, dscerror::DscError, dscresources::{command_resource::{invoke_command, process_args}, dscresource::DscResource}, extensions::{import::ImportArgKind, secret::SecretResult}};
12+
use crate::{
13+
discovery::command_discovery::{
14+
load_manifest, ImportedManifest
15+
},
16+
dscerror::DscError,
17+
dscresources::{
18+
command_resource::{
19+
invoke_command,
20+
process_args
21+
},
22+
dscresource::DscResource
23+
},
24+
extensions::import::ImportArgKind
25+
};
1326

1427
use super::{discover::DiscoverResult, extension_manifest::ExtensionManifest, secret::SecretArgKind};
1528

@@ -229,21 +242,18 @@ impl DscExtension {
229242
extension.exit_codes.as_ref(),
230243
)?;
231244
if stdout.is_empty() {
232-
info!("{}", t!("extensions.dscextension.secretNoResults", extension = self.type_name));
245+
debug!("{}", t!("extensions.dscextension.extensionReturnedNoSecret", extension = self.type_name));
233246
Ok(None)
234247
} else {
235-
let result: SecretResult = match serde_json::from_str(&stdout) {
236-
Ok(value) => value,
237-
Err(err) => {
238-
return Err(DscError::Extension(t!("extensions.dscextension.secretExtensionReturnedInvalidJson", extension = self.type_name, error = err).to_string()));
239-
}
240-
};
241-
if result.secure_string.is_some() {
242-
debug!("{}", t!("extensions.dscextension.extensionReturnedSecret", extension = self.type_name));
248+
// see if multiple lines were returned
249+
let secret = if stdout.lines().count() > 1 {
250+
return Err(DscError::NotSupported(t!("extensions.dscextension.secretMultipleLinesReturned", extension = self.type_name).to_string()));
243251
} else {
244-
debug!("{}", t!("extensions.dscextension.extensionReturnedNoSecret", extension = self.type_name));
245-
}
246-
Ok(result.secure_string)
252+
debug!("{}", t!("extensions.dscextension.extensionReturnedSecret", extension = self.type_name));
253+
// remove any trailing newline characters
254+
stdout.trim_end_matches('\n').to_string()
255+
};
256+
Ok(Some(secret))
247257
}
248258
} else {
249259
Err(DscError::UnsupportedCapability(

dsc_lib/src/extensions/secret.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,3 @@ pub struct SecretMethod {
3030
/// The arguments to pass to the command to perform a Get.
3131
pub args: Option<Vec<SecretArgKind>>,
3232
}
33-
34-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
35-
pub struct SecretResult {
36-
#[serde(rename = "secureString")]
37-
pub secure_string: Option<String>,
38-
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
3+
"type": "Microsoft.Azure.CLI/KeyVault",
4+
"version": "1.0.0",
5+
"description": "Retrieve secrets from Azure KeyVault. Requires AzCLI to already be installed.",
6+
"secret": {
7+
"executable": "az.cmd",
8+
"outputKind": "PlainText",
9+
"args": [
10+
"keyvault",
11+
"secret",
12+
"show",
13+
{
14+
"vaultArg": "--vault-name"
15+
},
16+
{
17+
"nameArg": "--name"
18+
},
19+
"--query",
20+
"value",
21+
"--output",
22+
"tsv"
23+
]
24+
}
25+
}

extensions/bicep/bicep.dsc.extension.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
2+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
33
"type": "Microsoft.DSC.Extension/Bicep",
44
"version": "0.1.0",
55
"description": "Enable passing Bicep file directly to DSC, but requires bicep executable to be available.",

extensions/test/secret/secret.ps1

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ $secretTwo = @{
2727
DifferentSecret = 'Hello2'
2828
DuplicateSecret = 'World2'
2929
DuplicateSame = 'SameSecret'
30+
MultiLine = "This`nis`nmultiline"
3031
}
3132
}
3233

@@ -43,10 +44,8 @@ function get-secret($hashtable, $name, $vault) {
4344
return $null
4445
}
4546

46-
$secret = if ($Second) {
47+
if ($Second) {
4748
get-secret -hashtable $secretTwo -name $Name -vault $Vault
4849
} else {
4950
get-secret -hashtable $secretsOne -name $Name -vault $Vault
5051
}
51-
52-
@{ secureString = $secret } | ConvertTo-Json -Compress | Write-Output

extensions/test/secret/testSecret.dsc.extension.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
2+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
33
"type": "Test/Secret",
44
"version": "0.1.0",
5-
"description": "Example secret resource for testing.",
5+
"description": "Example secret extension for testing.",
66
"secret": {
77
"executable": "pwsh",
88
"args": [

extensions/test/secret/testSecret2.dsc.extension.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
2+
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/extension/manifest.json",
33
"type": "Test/Secret2",
44
"version": "0.1.0",
5-
"description": "Duplicate secret resource for testing.",
5+
"description": "Duplicate secret extension for testing.",
66
"secret": {
77
"executable": "pwsh",
88
"args": [

0 commit comments

Comments
 (0)