Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions dsc/tests/dsc_extension_secret.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,20 @@ Describe 'Tests for the secret() function and extensions' {
$env:DSC_RESTRICTED_PATH = $oldRestrictedPath
}
}

It 'secureObject can be returned' {
$configYaml = @'
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Secure Object
type: Microsoft.DSC.Debug/Echo
properties:
output: "[secret('SecretObject', 'Vault2')]"
showSecrets: true
'@
$out = dsc -l trace config get -i $configYaml 2> $TestDrive/error.log | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$out.results.Count | Should -Be 1
$out.results[0].result.actualState.Output.Hello | Should -BeExactly 'World'
}
}
3 changes: 3 additions & 0 deletions extensions/test/secret/secret.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ $secretsOne = @{
}
Vault2 = @{
AnotherSecret = 'Foo'
SecretObject = @{
Hello = 'World'
} | ConvertTo-Json -Compress
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/dsc-lib/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,6 @@ multipleSecrets = "Multiple secrets with the same name '%{name}' and different v
extensionReturnedError = "Extension '%{extension}': %{error}"
noExtensions = "No extensions supporting secrets was found"
secretNotFound = "Secret '%{name}' not found"
invalidSecretFormat = "Invalid secret format returned for secret '%{name}'"

[functions.shallowMerge]
description = "Combines an array of objects where only the top-level objects are merged"
Expand Down
6 changes: 3 additions & 3 deletions lib/dsc-lib/src/configure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::configure::config_doc::{ExecutionInformation, ResourceDirective};
use crate::configure::context::{Context, ProcessMode};
use crate::configure::parameters::{SecureObject, SecureString, import_parameters};
use crate::configure::parameters::{SecureObject, SecureString, import_parameters, is_secure_value};
use crate::configure::{config_doc::{ExecutionKind, IntOrExpression, Metadata, Parameter, Resource, ResourceDiscoveryMode, RestartRequired, ValueOrCopy}};
use crate::discovery::discovery_trait::DiscoveryFilter;
use crate::dscerror::DscError;
Expand Down Expand Up @@ -1217,12 +1217,12 @@ impl Configurator {
default_value.clone()
};

if parameter.parameter_type == DataType::SecureString && value.is_string() {
if parameter.parameter_type == DataType::SecureString && value.is_string() && !is_secure_value(&value){
let secure_string = SecureString {
secure_string: value.as_str().unwrap().to_string(),
};
value = serde_json::to_value(secure_string)?;
} else if parameter.parameter_type == DataType::SecureObject && value.is_object() {
} else if parameter.parameter_type == DataType::SecureObject && value.is_object() && !is_secure_value(&value) {
let secure_object = SecureObject {
secure_object: value.clone(),
};
Expand Down
13 changes: 10 additions & 3 deletions lib/dsc-lib/src/extensions/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

use crate::{
configure::parameters::SecureString,
configure::parameters::{SecureString, SecureObject},
dscerror::DscError,
dscresources::{
command_resource::invoke_command,
Expand Down Expand Up @@ -404,7 +404,7 @@ impl DscExtension {
/// # Errors
///
/// This function will return an error if the secret retrieval fails or if the extension does not support the secret capability.
pub fn secret(&self, name: &str, vault: Option<&str>) -> Result<Option<String>, DscError> {
pub(crate) fn secret(&self, name: &str, vault: Option<&str>) -> Result<Option<Value>, DscError> {
if self.capabilities.contains(&Capability::Secret) {
debug!("{}", t!("extensions.dscextension.retrievingSecretFromExtension", name = name, extension = self.type_name));
let extension = match serde_json::from_value::<ExtensionManifest>(self.manifest.clone()) {
Expand Down Expand Up @@ -440,10 +440,17 @@ impl DscExtension {
// remove any trailing newline characters
stdout.trim_end_matches('\n').to_string()
};
// if the secret is a valid JSON object, we wrap it as a SecureObject
if let Ok(json_value) = serde_json::from_str::<Value>(&secret) && json_value.is_object() {
let secure_object = SecureObject {
secure_object: json_value.clone(),
};
return Ok(Some(serde_json::to_value(&secure_object)?));
Comment thread
SteveL-MSFT marked this conversation as resolved.
Comment thread
SteveL-MSFT marked this conversation as resolved.
}
let secure_string = SecureString {
secure_string: secret.clone(),
};
Ok(Some(serde_json::to_string(&secure_string)?))
Ok(Some(serde_json::to_value(&secure_string)?))
}
} else {
Err(DscError::UnsupportedCapability(
Expand Down
7 changes: 3 additions & 4 deletions lib/dsc-lib/src/functions/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

use crate::DscError;
use crate::configure::{context::Context, parameters::SecureString};
use crate::configure::context::Context;
use crate::extensions::dscextension::Capability;
use crate::functions::{FunctionArgKind, FunctionCategory, FunctionMetadata};
use rust_i18n::t;
Expand Down Expand Up @@ -48,7 +48,7 @@ impl Function for Secret {
.filter(|ext| ext.capabilities.contains(&Capability::Secret))
.collect::<Vec<_>>();
let mut secret_returned = false;
let mut result: String = String::new();
let mut result: Value = Value::Null;
if extensions.is_empty() {
return Err(DscError::Function("secret".to_string(), t!("functions.secret.noExtensions").to_string()));
}
Expand All @@ -69,8 +69,7 @@ impl Function for Secret {
}
}
if secret_returned {
let secure_string = serde_json::from_str::<SecureString>(&result).map_err(|_err| DscError::Function("secret".to_string(), t!("functions.secret.invalidSecretFormat", name = secret_name.clone()).to_string()))?;
Ok(serde_json::to_value(secure_string)?)
Ok(result)
} else {
Err(DscError::Function("secret".to_string(), t!("functions.secret.secretNotFound", name = secret_name).to_string()))
}
Expand Down
Loading