Skip to content

Commit bab4712

Browse files
authored
Merge branch 'main' into wmi-set-operation
2 parents 652aa44 + 90b4e2a commit bab4712

24 files changed

+1376
-11
lines changed

build.ps1

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ $filesForWindowsPackage = @(
5353
'osinfo.dsc.resource.json',
5454
'powershell.dsc.resource.json',
5555
'psDscAdapter/',
56+
'psscript.ps1',
57+
'psscript.dsc.resource.json',
58+
'winpsscript.dsc.resource.json',
5659
'reboot_pending.dsc.resource.json',
5760
'reboot_pending.resource.ps1',
5861
'registry.dsc.resource.json',
@@ -87,6 +90,8 @@ $filesForLinuxPackage = @(
8790
'osinfo.dsc.resource.json',
8891
'powershell.dsc.resource.json',
8992
'psDscAdapter/',
93+
'psscript.ps1',
94+
'psscript.dsc.resource.json',
9095
'RunCommandOnSet.dsc.resource.json',
9196
'runcommandonset',
9297
'sshdconfig',
@@ -109,6 +114,8 @@ $filesForMacPackage = @(
109114
'osinfo.dsc.resource.json',
110115
'powershell.dsc.resource.json',
111116
'psDscAdapter/',
117+
'psscript.ps1',
118+
'psscript.dsc.resource.json',
112119
'RunCommandOnSet.dsc.resource.json',
113120
'runcommandonset',
114121
'sshdconfig',
@@ -300,6 +307,7 @@ if (!$SkipBuild) {
300307
"dscecho",
301308
"osinfo",
302309
"powershell-adapter",
310+
'resources/PSScript',
303311
"process",
304312
"runcommandonset",
305313
"sshdconfig",
@@ -422,7 +430,8 @@ if (!$SkipBuild) {
422430
Copy-Item "*.dsc.resource.json" $target -Force -ErrorAction Ignore
423431
}
424432
else { # don't copy WindowsPowerShell resource manifest
425-
Copy-Item "*.dsc.resource.json" $target -Exclude 'windowspowershell.dsc.resource.json' -Force -ErrorAction Ignore
433+
$exclude = @('windowspowershell.dsc.resource.json', 'winpsscript.dsc.resource.json')
434+
Copy-Item "*.dsc.resource.json" $target -Exclude $exclude -Force -ErrorAction Ignore
426435
}
427436

428437
# be sure that the files that should be executable are executable

dsc/examples/psscript.dsc.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Example configuration using PowerShell script resource and using parameters and input
2+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
3+
parameters:
4+
myName:
5+
type: string
6+
defaultValue: Steve
7+
myObject:
8+
type: object
9+
defaultValue:
10+
color: green
11+
number: 10
12+
resources:
13+
- name: Use PS script
14+
type: Microsoft.DSC.Transitional/PowerShellScript
15+
properties:
16+
input:
17+
- name: "[parameters('myName')]"
18+
- object: "[parameters('myObject')]"
19+
getScript: |
20+
param($inputArray)
21+
22+
Write-Warning "This is a warning message"
23+
# any output will be collected and returned
24+
"My name is " + $inputArray[0].name
25+
"My color is " + $inputArray[1].object.color

dsc/src/args.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,5 @@ pub enum SchemaType {
289289
ExtensionManifest,
290290
ExtensionDiscoverResult,
291291
FunctionDefinition,
292+
RestartRequired
292293
}

dsc/src/util.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ use dsc_lib::extensions::discover::DiscoverResult;
88
use dsc_lib::extensions::extension_manifest::ExtensionManifest;
99
use dsc_lib::{
1010
configure::{
11-
config_doc::Configuration,
11+
config_doc::{
12+
Configuration,
13+
RestartRequired,
14+
},
1215
config_result::{
1316
ConfigurationGetResult,
1417
ConfigurationSetResult,
@@ -187,6 +190,9 @@ pub fn get_schema(schema: SchemaType) -> RootSchema {
187190
},
188191
SchemaType::FunctionDefinition => {
189192
schema_for!(FunctionDefinition)
193+
},
194+
SchemaType::RestartRequired => {
195+
schema_for!(RestartRequired)
190196
}
191197
}
192198
}

dsc/tests/dsc_expressions.tests.ps1

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,35 @@ resources:
107107
$LASTEXITCODE | Should -Be 0
108108
$out.results[0].result[1].result.actualState.output.family | Should -BeExactly $out.results[0].result[0].result.actualState.family
109109
}
110+
111+
It 'Logical functions work: <expression>' -TestCases @(
112+
@{ expression = "[equals('a', 'a')]"; expected = $true }
113+
@{ expression = "[equals('a', 'b')]"; expected = $false }
114+
@{ expression = "[not(equals('a', 'b'))]"; expected = $true }
115+
@{ expression = "[and(true, true)]"; expected = $true }
116+
@{ expression = "[and(true, false)]"; expected = $false }
117+
@{ expression = "[or(false, true)]"; expected = $true }
118+
@{ expression = "[or(false, false)]"; expected = $false }
119+
@{ expression = "[not(true)]"; expected = $false }
120+
@{ expression = "[not(or(true, false))]"; expected = $false }
121+
@{ expression = "[bool('TRUE')]" ; expected = $true }
122+
@{ expression = "[bool('False')]" ; expected = $false }
123+
@{ expression = "[bool(1)]" ; expected = $true }
124+
@{ expression = "[not(bool(0))]" ; expected = $true }
125+
@{ expression = "[true()]" ; expected = $true }
126+
@{ expression = "[false()]" ; expected = $false }
127+
) {
128+
param($expression, $expected)
129+
$yaml = @"
130+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
131+
resources:
132+
- name: echo
133+
type: Microsoft.DSC.Debug/Echo
134+
properties:
135+
output: "$expression"
136+
"@
137+
$out = dsc config get -i $yaml 2>$TestDrive/error.log | ConvertFrom-Json
138+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content $TestDrive/error.log -Raw | Out-String)
139+
$out.results[0].result.actualState.output | Should -Be $expected -Because ($out | ConvertTo-Json -Depth 10| Out-String)
140+
}
110141
}

dsc/tests/dsc_metadata.tests.ps1

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,73 @@ Describe 'metadata tests' {
7171
$out.results[0].metadata.Microsoft.DSC | Should -BeNullOrEmpty
7272
(Get-Content $TestDrive/error.log) | Should -BeLike "*WARN*Resource returned '_metadata' property 'Microsoft.DSC' which is ignored*"
7373
}
74+
75+
It 'resource returning _restartRequired metadata is handled' {
76+
$configYaml = @'
77+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
78+
resources:
79+
- name: one
80+
type: Test/Metadata
81+
properties:
82+
_metadata:
83+
_restartRequired:
84+
- system: mySystem
85+
- service: myService
86+
- name: two
87+
type: Test/Metadata
88+
properties:
89+
_metadata:
90+
_restartRequired:
91+
- service: sshd
92+
- name: three
93+
type: Test/Metadata
94+
properties:
95+
_metadata:
96+
_restartRequired:
97+
- process:
98+
name: myProcess
99+
id: 1234
100+
- process:
101+
name: anotherProcess
102+
id: 5678
103+
'@
104+
$out = dsc config get -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
105+
$LASTEXITCODE | Should -Be 0
106+
$out.results.count | Should -Be 3
107+
$out.results[0].metadata._restartRequired.count | Should -Be 2
108+
$out.results[0].metadata._restartRequired[0].system | Should -BeExactly 'mySystem'
109+
$out.results[0].metadata._restartRequired[1].service | Should -BeExactly 'myService'
110+
$out.results[1].metadata._restartRequired.count | Should -Be 1
111+
$out.results[1].metadata._restartRequired[0].service | Should -BeExactly 'sshd'
112+
$out.results[2].metadata._restartRequired.count | Should -Be 2
113+
$out.results[2].metadata._restartRequired[0].process.name | Should -BeExactly 'myProcess'
114+
$out.results[2].metadata._restartRequired[0].process.id | Should -Be 1234
115+
$out.results[2].metadata._restartRequired[1].process.name | Should -BeExactly 'anotherProcess'
116+
$out.results[2].metadata._restartRequired[1].process.id | Should -Be 5678
117+
$out.metadata.'Microsoft.DSC'.restartRequired.count | Should -Be 5
118+
$out.metadata.'Microsoft.DSC'.restartRequired[0].system | Should -BeExactly 'mySystem'
119+
$out.metadata.'Microsoft.DSC'.restartRequired[1].service | Should -BeExactly 'myService'
120+
$out.metadata.'Microsoft.DSC'.restartRequired[2].service | Should -BeExactly 'sshd'
121+
$out.metadata.'Microsoft.DSC'.restartRequired[3].process.name | Should -BeExactly 'myProcess'
122+
$out.metadata.'Microsoft.DSC'.restartRequired[3].process.id | Should -Be 1234
123+
$out.metadata.'Microsoft.DSC'.restartRequired[4].process.name | Should -BeExactly 'anotherProcess'
124+
$out.metadata.'Microsoft.DSC'.restartRequired[4].process.id | Should -Be 5678
125+
}
126+
127+
It 'invalid item in _restartRequired metadata is a warning' {
128+
$configYaml = @'
129+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
130+
resources:
131+
- name: test
132+
type: Test/Metadata
133+
properties:
134+
_metadata:
135+
_restartRequired:
136+
- invalid: item
137+
'@
138+
$out = dsc config get -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
139+
$LASTEXITCODE | Should -Be 0
140+
(Get-Content $TestDrive/error.log) | Should -BeLike "*WARN*Resource returned '_metadata' property '_restartRequired' which contains invalid value: ``[{`"invalid`":`"item`"}]*"
141+
$out.results[0].metadata._restartRequired | Should -BeNullOrEmpty
142+
}
74143
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
Describe 'Resource condition tests' {
5+
BeforeAll {
6+
$configYaml = @'
7+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
8+
resources:
9+
- name: test
10+
type: Microsoft.DSC.Debug/Echo
11+
condition: "[equals('skip', 'yes')]"
12+
properties:
13+
output: "This should not be executed"
14+
- name: test2
15+
type: Microsoft.DSC.Debug/Echo
16+
condition: "[equals('no', 'no')]"
17+
properties:
18+
output: "This should be executed"
19+
'@
20+
}
21+
22+
It 'resource should be skipped for <operation>' -TestCases @(
23+
@{ operation = 'get'; property = 'actualState' },
24+
@{ operation = 'set'; property = 'afterState' },
25+
@{ operation = 'test'; property = 'actualState' }
26+
) {
27+
param($operation, $property)
28+
$out = dsc config $operation -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
29+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content $TestDrive/error.log -Raw | Out-String)
30+
$out.results.count | Should -Be 1
31+
$out.results[0].result.$property.Output | Should -BeExactly "This should be executed"
32+
}
33+
34+
It 'resource should be skipped for export' {
35+
$out = dsc config export -i $configYaml 2>$TestDrive/error.log | ConvertFrom-Json
36+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content $TestDrive/error.log -Raw | Out-String)
37+
$out.resources.count | Should -Be 1
38+
$out.resources[0].type | Should -BeExactly 'Microsoft.DSC.Debug/Echo'
39+
$out.resources[0].properties.output | Should -BeExactly "This should be executed"
40+
}
41+
}

dsc_lib/locales/en-us.toml

Lines changed: 26 additions & 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"
@@ -69,6 +70,7 @@ invokeExpression = "Invoke property expression for %{name}: %{value}"
6970
propertyNotString = "Property '%{name}' with value '%{value}' is not a string"
7071
metadataMicrosoftDscIgnored = "Resource returned '_metadata' property 'Microsoft.DSC' which is ignored"
7172
metadataNotObject = "Resource returned '_metadata' property which is not an object"
73+
metadataRestartRequiredInvalid = "Resource returned '_metadata' property '_restartRequired' which contains invalid value: %{value}"
7274

7375
[discovery.commandDiscovery]
7476
couldNotReadSetting = "Could not read 'resourcePath' setting"
@@ -204,9 +206,17 @@ noStringArgs = "Function '%{name}' does not accept string arguments, accepted ty
204206
description = "Adds two or more numbers together"
205207
invoked = "add function"
206208

209+
[functions.and]
210+
description = "Evaluates if all arguments are true"
211+
invoked = "and function"
212+
207213
[functions.base64]
208214
description = "Encodes a string to Base64 format"
209215

216+
[functions.bool]
217+
description = "Converts a string or number to a boolean"
218+
invoked = "bool function"
219+
210220
[functions.concat]
211221
description = "Concatenates two or more strings or arrays"
212222
invoked = "concat function"
@@ -234,6 +244,10 @@ notFound = "Environment variable not found"
234244
[functions.equals]
235245
description = "Evaluates if the two values are the same"
236246

247+
[functions.false]
248+
description = "Returns the boolean value false"
249+
invoked = "false function"
250+
237251
[functions.format]
238252
description = "Formats a string using the given arguments"
239253
experimental = "`format()` function is experimental"
@@ -274,6 +288,14 @@ divideByZero = "Cannot divide by zero"
274288
description = "Multiplies two or more numbers together"
275289
invoked = "mul function"
276290

291+
[functions.not]
292+
description = "Negates a boolean value"
293+
invoked = "not function"
294+
295+
[functions.or]
296+
description = "Evaluates if any arguments are true"
297+
invoked = "or function"
298+
277299
[functions.parameters]
278300
description = "Retrieves parameters from the configuration"
279301
invoked = "parameters function"
@@ -314,6 +336,10 @@ invoked = "sub function"
314336
description = "Returns the system root path"
315337
invoked = "systemRoot function"
316338

339+
[functions.true]
340+
description = "Returns the boolean value true"
341+
invoked = "true function"
342+
317343
[functions.variables]
318344
description = "Retrieves the value of a variable"
319345
invoked = "variables function"

dsc_lib/src/configure/config_doc.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ pub enum ExecutionKind {
3434
WhatIf,
3535
}
3636

37+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
38+
#[serde(rename_all = "camelCase")]
39+
pub struct Process {
40+
pub name: String,
41+
pub id: u32,
42+
}
43+
44+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
45+
#[serde(rename_all = "camelCase")]
46+
pub enum RestartRequired {
47+
System(String),
48+
Service(String),
49+
Process(Process),
50+
}
51+
3752
#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
3853
pub struct MicrosoftDscMetadata {
3954
/// Version of DSC
@@ -57,6 +72,9 @@ pub struct MicrosoftDscMetadata {
5772
/// The security context of the configuration operation, can be specified to be required
5873
#[serde(rename = "securityContext", skip_serializing_if = "Option::is_none")]
5974
pub security_context: Option<SecurityContextKind>,
75+
/// Indicates what needs to be restarted after the configuration operation
76+
#[serde(rename = "restartRequired", skip_serializing_if = "Option::is_none")]
77+
pub restart_required: Option<Vec<RestartRequired>>,
6078
}
6179

6280
impl MicrosoftDscMetadata {
@@ -160,6 +178,8 @@ pub struct Resource {
160178
pub properties: Option<Map<String, Value>>,
161179
#[serde(skip_serializing_if = "Option::is_none")]
162180
pub metadata: Option<Metadata>,
181+
#[serde(skip_serializing_if = "Option::is_none")]
182+
pub condition: Option<String>,
163183
}
164184

165185
impl Default for Configuration {
@@ -217,6 +237,7 @@ impl Resource {
217237
kind: None,
218238
properties: None,
219239
metadata: None,
240+
condition: None,
220241
}
221242
}
222243
}

dsc_lib/src/configure/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use security_context_lib::{get_security_context, SecurityContext};
77
use serde_json::{Map, Value};
88
use std::{collections::HashMap, path::PathBuf};
99

10-
use super::config_doc::{DataType, SecurityContextKind};
10+
use super::config_doc::{DataType, RestartRequired, SecurityContextKind};
1111

1212
pub struct Context {
1313
pub execution_type: ExecutionKind,
@@ -18,6 +18,7 @@ pub struct Context {
1818
pub security_context: SecurityContextKind,
1919
pub variables: Map<String, Value>,
2020
pub start_datetime: DateTime<Local>,
21+
pub restart_required: Option<Vec<RestartRequired>>,
2122
}
2223

2324
impl Context {
@@ -35,6 +36,7 @@ impl Context {
3536
},
3637
variables: Map::new(),
3738
start_datetime: chrono::Local::now(),
39+
restart_required: None,
3840
}
3941
}
4042
}

0 commit comments

Comments
 (0)