Skip to content

Commit c2a24c4

Browse files
authored
Merge pull request #679 from SteveL-MSFT/export-metadata
Preserve custom metadata when exporting config
2 parents 3703da2 + 3d10df0 commit c2a24c4

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

dsc/tests/dsc_export.tests.ps1

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,22 @@ Describe 'resource export tests' {
105105
$config_with_process_list.'resources' | Should -Not -BeNullOrEmpty
106106
$config_with_process_list.resources.count | Should -BeGreaterThan 1
107107
}
108+
109+
It 'Export for config preserves metadata' {
110+
$yaml = @'
111+
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
112+
metadata:
113+
winget:
114+
processor: dscv3
115+
hello: world
116+
resources:
117+
- name: OS
118+
type: Microsoft/OSInfo
119+
'@
120+
$out = $yaml | dsc config export -f - | ConvertFrom-Json
121+
$LASTEXITCODE | Should -Be 0
122+
$out.metadata.winget.processor | Should -BeExactly 'dscv3'
123+
$out.metadata.hello | Should -BeExactly 'world'
124+
$out.metadata.'Microsoft.DSC'.operation | Should -BeExactly 'export'
125+
}
108126
}

dsc_lib/src/configure/config_doc.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pub struct MicrosoftDscMetadata {
7272
pub struct Metadata {
7373
#[serde(rename = "Microsoft.DSC", skip_serializing_if = "Option::is_none")]
7474
pub microsoft: Option<MicrosoftDscMetadata>,
75+
#[serde(flatten)]
76+
pub other: Map<String, Value>,
7577
}
7678

7779
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
@@ -85,7 +87,7 @@ pub struct Configuration {
8587
#[serde(skip_serializing_if = "Option::is_none")]
8688
pub parameters: Option<HashMap<String, Parameter>>,
8789
#[serde(skip_serializing_if = "Option::is_none")]
88-
pub variables: Option<HashMap<String, Value>>,
90+
pub variables: Option<Map<String, Value>>,
8991
pub resources: Vec<Resource>,
9092
#[serde(skip_serializing_if = "Option::is_none")]
9193
pub metadata: Option<Metadata>,
@@ -110,7 +112,7 @@ pub struct Parameter {
110112
#[serde(skip_serializing_if = "Option::is_none")]
111113
pub description: Option<String>,
112114
#[serde(skip_serializing_if = "Option::is_none")]
113-
pub metadata: Option<HashMap<String, Value>>,
115+
pub metadata: Option<Map<String, Value>>,
114116
}
115117

116118
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
@@ -144,7 +146,7 @@ pub struct Resource {
144146
#[serde(skip_serializing_if = "Option::is_none")]
145147
pub properties: Option<Map<String, Value>>,
146148
#[serde(skip_serializing_if = "Option::is_none")]
147-
pub metadata: Option<HashMap<String, Value>>,
149+
pub metadata: Option<Map<String, Value>>,
148150
}
149151

150152
impl Default for Configuration {

dsc_lib/src/configure/context.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
use chrono::{DateTime, Local};
55
use crate::configure::config_doc::ExecutionKind;
66
use security_context_lib::{get_security_context, SecurityContext};
7-
use serde_json::Value;
7+
use serde_json::{Map, Value};
88
use std::{collections::HashMap, path::PathBuf};
99

1010
use super::config_doc::{DataType, SecurityContextKind};
1111

1212
pub struct Context {
1313
pub execution_type: ExecutionKind,
14-
pub references: HashMap<String, Value>,
14+
pub references: Map<String, Value>,
1515
pub system_root: PathBuf,
1616
pub parameters: HashMap<String, (Value, DataType)>,
1717
pub security_context: SecurityContextKind,
18-
pub variables: HashMap<String, Value>,
18+
pub variables: Map<String, Value>,
1919
pub start_datetime: DateTime<Local>,
2020
}
2121

@@ -24,14 +24,14 @@ impl Context {
2424
pub fn new() -> Self {
2525
Self {
2626
execution_type: ExecutionKind::Actual,
27-
references: HashMap::new(),
27+
references: Map::new(),
2828
system_root: get_default_os_system_root(),
2929
parameters: HashMap::new(),
3030
security_context: match get_security_context() {
3131
SecurityContext::Admin => SecurityContextKind::Elevated,
3232
SecurityContext::User => SecurityContextKind::Restricted,
3333
},
34-
variables: HashMap::new(),
34+
variables: Map::new(),
3535
start_datetime: chrono::Local::now(),
3636
}
3737
}

dsc_lib/src/configure/mod.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ impl Configurator {
278278
duration: Some(end_datetime.signed_duration_since(start_datetime).to_string()),
279279
..Default::default()
280280
}
281-
)
281+
),
282+
other: Map::new(),
282283
}
283284
),
284285
name: resource.name.clone(),
@@ -426,7 +427,8 @@ impl Configurator {
426427
duration: Some(end_datetime.signed_duration_since(start_datetime).to_string()),
427428
..Default::default()
428429
}
429-
)
430+
),
431+
other: Map::new(),
430432
}
431433
),
432434
name: resource.name.clone(),
@@ -497,7 +499,8 @@ impl Configurator {
497499
duration: Some(end_datetime.signed_duration_since(start_datetime).to_string()),
498500
..Default::default()
499501
}
500-
)
502+
),
503+
other: Map::new(),
501504
}
502505
),
503506
name: resource.name.clone(),
@@ -527,6 +530,7 @@ impl Configurator {
527530
pub fn invoke_export(&mut self) -> Result<ConfigurationExportResult, DscError> {
528531
let mut result = ConfigurationExportResult::new();
529532
let mut conf = config_doc::Configuration::new();
533+
conf.metadata.clone_from(&self.config.metadata);
530534

531535
let mut progress = ProgressBar::new(self.config.resources.len() as u64, self.progress_format)?;
532536
let resources = self.config.resources.clone();
@@ -552,7 +556,17 @@ impl Configurator {
552556
progress.write_increment(1);
553557
}
554558

555-
conf.metadata = Some(self.get_result_metadata(Operation::Export));
559+
let export_metadata = self.get_result_metadata(Operation::Export);
560+
match conf.metadata {
561+
Some(mut metadata) => {
562+
metadata.microsoft = export_metadata.microsoft;
563+
conf.metadata = Some(metadata);
564+
},
565+
_ => {
566+
conf.metadata = Some(export_metadata);
567+
},
568+
}
569+
556570
result.result = Some(conf);
557571
Ok(result)
558572
}
@@ -685,7 +699,8 @@ impl Configurator {
685699
duration: Some(end_datetime.signed_duration_since(self.context.start_datetime).to_string()),
686700
security_context: Some(self.context.security_context.clone()),
687701
}
688-
)
702+
),
703+
other: Map::new(),
689704
}
690705
}
691706

0 commit comments

Comments
 (0)