Skip to content

Commit ab293a7

Browse files
committed
Add condition support to resources within config
1 parent a711158 commit ab293a7

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
BeforeDiscovery {
5+
$configYaml = @'
6+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
7+
resources:
8+
- name: test
9+
type: Microsoft.DSC.Debug/Echo
10+
condition: "[equals('skip', 'yes')]"
11+
properties:
12+
output: "This should not be executed"
13+
- name: test2
14+
type: Microsoft.DSC.Debug/Echo
15+
condition: "[equals('no', 'no')]"
16+
properties:
17+
output: "This should be executed"
18+
'@
19+
20+
}
21+
22+
Describe 'Resource condition tests' {
23+
It 'resource should be skipped for <operation>' -TestCases @(
24+
@{ operation = 'get'; property = 'actualState' },
25+
@{ operation = 'set'; property = 'afterState' },
26+
@{ operation = 'test'; property = 'actualState' }
27+
) {
28+
param($operation, $property)
29+
$out = dsc config $operation -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
30+
$LASTEXITCODE | Should -Be 0
31+
$out.results.count | Should -Be 1
32+
$out.results[0].result.$property.Output | Should -BeExactly "This should be executed"
33+
}
34+
35+
It 'resource should be skipped for export' {
36+
$out = dsc config export -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
37+
$LASTEXITCODE | Should -Be 0
38+
$out.resources.count | Should -Be 1
39+
$out.resources[0].type | Should -BeExactly 'Microsoft.DSC.Debug/Echo'
40+
$out.resources[0].properties.output | Should -BeExactly "This should be executed"
41+
}
42+
}

dsc_lib/locales/en-us.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ _version = 1
33
[configure.config_doc]
44
configurationDocumentSchemaTitle = "Configuration document schema URI"
55
configurationDocumentSchemaDescription = "Defines the JSON Schema the configuration document adheres to."
6+
skippingResource = "Skipping resource '%{name}' due to condition '%{condition}' with result '%{result}'"
67

78
[configure.constraints]
89
minLengthIsNull = "Parameter '%{name}' has minimum length constraint but is null"

dsc_lib/src/configure/config_doc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ pub struct Resource {
160160
pub properties: Option<Map<String, Value>>,
161161
#[serde(skip_serializing_if = "Option::is_none")]
162162
pub metadata: Option<Metadata>,
163+
#[serde(skip_serializing_if = "Option::is_none")]
164+
pub condition: Option<String>,
163165
}
164166

165167
impl Default for Configuration {
@@ -217,6 +219,7 @@ impl Resource {
217219
kind: None,
218220
properties: None,
219221
metadata: None,
222+
condition: None,
220223
}
221224
}
222225
}

dsc_lib/src/configure/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,14 @@ impl Configurator {
311311
for resource in resources {
312312
progress.set_resource(&resource.name, &resource.resource_type);
313313
progress.write_activity(format!("Get '{}'", resource.name).as_str());
314+
if let Some(condition) = &resource.condition {
315+
let condition_result = self.statement_parser.parse_and_execute(condition, &self.context)?;
316+
if condition_result != Value::Bool(true) {
317+
info!("{}", t!("configure.config_doc.skippingResource", name = resource.name, condition = condition, result = condition_result));
318+
progress.write_increment(1);
319+
continue;
320+
}
321+
}
314322
let Some(dsc_resource) = discovery.find_resource(&resource.resource_type) else {
315323
return Err(DscError::ResourceNotFound(resource.resource_type));
316324
};
@@ -387,6 +395,14 @@ impl Configurator {
387395
for resource in resources {
388396
progress.set_resource(&resource.name, &resource.resource_type);
389397
progress.write_activity(format!("Set '{}'", resource.name).as_str());
398+
if let Some(condition) = &resource.condition {
399+
let condition_result = self.statement_parser.parse_and_execute(condition, &self.context)?;
400+
if condition_result != Value::Bool(true) {
401+
info!("{}", t!("configure.config_doc.skippingResource", name = resource.name, condition = condition, result = condition_result));
402+
progress.write_increment(1);
403+
continue;
404+
}
405+
}
390406
let Some(dsc_resource) = discovery.find_resource(&resource.resource_type) else {
391407
return Err(DscError::ResourceNotFound(resource.resource_type));
392408
};
@@ -535,6 +551,14 @@ impl Configurator {
535551
for resource in resources {
536552
progress.set_resource(&resource.name, &resource.resource_type);
537553
progress.write_activity(format!("Test '{}'", resource.name).as_str());
554+
if let Some(condition) = &resource.condition {
555+
let condition_result = self.statement_parser.parse_and_execute(condition, &self.context)?;
556+
if condition_result != Value::Bool(true) {
557+
info!("{}", t!("configure.config_doc.skippingResource", name = resource.name, condition = condition, result = condition_result));
558+
progress.write_increment(1);
559+
continue;
560+
}
561+
}
538562
let Some(dsc_resource) = discovery.find_resource(&resource.resource_type) else {
539563
return Err(DscError::ResourceNotFound(resource.resource_type));
540564
};
@@ -608,6 +632,14 @@ impl Configurator {
608632
for resource in &resources {
609633
progress.set_resource(&resource.name, &resource.resource_type);
610634
progress.write_activity(format!("Export '{}'", resource.name).as_str());
635+
if let Some(condition) = &resource.condition {
636+
let condition_result = self.statement_parser.parse_and_execute(condition, &self.context)?;
637+
if condition_result != Value::Bool(true) {
638+
info!("{}", t!("configure.config_doc.skippingResource", name = resource.name, condition = condition, result = condition_result));
639+
progress.write_increment(1);
640+
continue;
641+
}
642+
}
611643
let Some(dsc_resource) = discovery.find_resource(&resource.resource_type) else {
612644
return Err(DscError::ResourceNotFound(resource.resource_type.clone()));
613645
};

dscecho/echo.dsc.resource.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@
3030
}
3131
]
3232
},
33+
"export": {
34+
"executable": "dscecho",
35+
"args": [
36+
{
37+
"jsonInputArg": "--input",
38+
"mandatory": true
39+
}
40+
]
41+
},
3342
"schema": {
3443
"command": {
3544
"executable": "dscecho"

0 commit comments

Comments
 (0)