Skip to content

Commit 498eb6a

Browse files
(GH-642) Add schemas module, update for schema handling in v3
This commit only touches the `dsc` and `dsc_lib` crates. A future commit will update the examples, manifests, and tests throughout the repository for the updated schema URIs. Tests against this commit specifically will not pass, but the changes to the library are broken out here for easier review. This change defines a new module in the library for interacting with and managing JSON Schemas for DSC. The code in this module is made public for use in other repository crates, but shouldn't be used by crates outside of this repository. It defines new enumerations: - `SchemaUriPrefix` for handling URIs pointing to either the GitHub repository or friendly `aka.ms` locations. - `SchemaForm` for the different forms the DSC schemas are published to (canonical, bundled, and enhanced for VS Code) - `RecognizedSchemaVersion` for managing the version folders schemas are publsihed to for and after GA. It defines a few helper functions for constructing the various URIs for a schema. These helper functions may be useful for testing, but should primarily be used through the new `DscRepoSchema` trait, which requires a type to define the base name and folder path for its schema and whether the schema should be published in its bundled form (only applies to top-level schemas, not subschemas). The trait provides default implementations for retrieving the schema URIs and a function to return a generated JSON Schema for the `$schema` keyword, used by both configuration documents and resource manifests. As we canonicalize and improve the schemas, this trait should make it simpler to manage the schemas across new versions and should be the container for JSON Schema enhancements specific to the DSC schemas. This change updates the configuration document and resource manifest definitions to implement the `DscRepoSchema` trait and replaces the per-type enumerations for schema version URIs by passing the `recognized_schema_uris_subschema` to the schemars `schema_with` attribute.
1 parent 91a8a67 commit 498eb6a

File tree

6 files changed

+653
-61
lines changed

6 files changed

+653
-61
lines changed

dsc_lib/locales/en-us.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
_version = 1
22

3+
[configure.config_doc]
4+
configurationDocumentSchemaTitle = "Configuration document schema URI"
5+
configurationDocumentSchemaDescription = "Defines the JSON Schema the configuration document adheres to."
6+
37
[configure.constraints]
48
minLengthIsNull = "Parameter '%{name}' has minimum length constraint but is null"
59
notMinLength = "Parameter '%{name}' has minimum length constraint of %{min_length} but is %{length}"
@@ -144,6 +148,10 @@ diffKeyNotObject = "diff: key '%{key}' is not an object"
144148
diffArraySize = "diff: arrays have different lengths"
145149
diffMissingItem = "diff: actual array missing expected item"
146150

151+
[dscresources.resource_manifest]
152+
resourceManifestSchemaTitle = "Resource manifest schema URI"
153+
resourceManifestSchemaDescription = "Defines the JSON Schema the resource manifest adheres to."
154+
147155
[functions]
148156
invalidArgType = "Invalid argument type"
149157
invalidArguments = "Invalid argument(s)"

dsc_lib/src/configure/config_doc.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
use rust_i18n::t;
45
use schemars::JsonSchema;
56
use serde::{Deserialize, Serialize};
67
use serde_json::{Map, Value};
7-
use std::{collections::HashMap, hash::Hash};
8+
use std::collections::HashMap;
9+
10+
use crate::schemas::DscRepoSchema;
811

912
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
1013
#[serde(rename_all = "camelCase")]
@@ -75,7 +78,8 @@ pub struct Metadata {
7578
#[serde(deny_unknown_fields)]
7679
pub struct Configuration {
7780
#[serde(rename = "$schema")]
78-
pub schema: DocumentSchemaUri,
81+
#[schemars(schema_with = "Configuration::recognized_schema_uris_subschema")]
82+
pub schema: String,
7983
#[serde(rename = "contentVersion")]
8084
pub content_version: Option<String>,
8185
#[serde(skip_serializing_if = "Option::is_none")]
@@ -143,41 +147,31 @@ pub struct Resource {
143147
pub metadata: Option<HashMap<String, Value>>,
144148
}
145149

146-
// Defines the valid and recognized canonical URIs for the configuration schema
147-
#[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq, Deserialize, Serialize, JsonSchema)]
148-
pub enum DocumentSchemaUri {
149-
#[default]
150-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json")]
151-
Version2024_04,
152-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/config/document.json")]
153-
Bundled2024_04,
154-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/config/document.vscode.json")]
155-
VSCode2024_04,
156-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/config/document.json")]
157-
Version2023_10,
158-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/bundled/config/document.json")]
159-
Bundled2023_10,
160-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/bundled/config/document.vscode.json")]
161-
VSCode2023_10,
162-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json")]
163-
Version2023_08,
164-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/config/document.json")]
165-
Bundled2023_08,
166-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/config/document.vscode.json")]
167-
VSCode2023_08,
168-
}
169-
170150
impl Default for Configuration {
171151
fn default() -> Self {
172152
Self::new()
173153
}
174154
}
175155

156+
impl DscRepoSchema for Configuration {
157+
const SCHEMA_FILE_BASE_NAME: &'static str = "document";
158+
const SCHEMA_FOLDER_PATH: &'static str = "config";
159+
const SCHEMA_SHOULD_BUNDLE: bool = true;
160+
161+
fn schema_metadata() -> schemars::schema::Metadata {
162+
schemars::schema::Metadata {
163+
title: Some(t!("configure.config_doc.configurationDocumentSchemaTitle").into()),
164+
description: Some(t!("configure.config_doc.configurationDocumentSchemaDescription").into()),
165+
..Default::default()
166+
}
167+
}
168+
}
169+
176170
impl Configuration {
177171
#[must_use]
178172
pub fn new() -> Self {
179173
Self {
180-
schema: DocumentSchemaUri::Version2024_04,
174+
schema: Self::default_schema_id_uri(),
181175
content_version: Some("1.0.0".to_string()),
182176
parameters: None,
183177
variables: None,

dsc_lib/src/configure/depends_on.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ mod tests {
108108
#[test]
109109
fn test_simple_order() {
110110
let config_yaml: &str = r#"
111-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
111+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
112112
resources:
113113
- name: Second
114114
type: Test/Null
@@ -128,7 +128,7 @@ mod tests {
128128
#[test]
129129
fn test_duplicate_name() {
130130
let config_yaml: &str = r#"
131-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
131+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
132132
resources:
133133
- name: First
134134
type: Test/Null
@@ -149,7 +149,7 @@ mod tests {
149149
#[test]
150150
fn test_missing_dependency() {
151151
let config_yaml: &str = r#"
152-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
152+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
153153
resources:
154154
- name: Second
155155
type: Test/Null
@@ -166,7 +166,7 @@ mod tests {
166166
#[test]
167167
fn test_multiple_same_dependency() {
168168
let config_yaml: &str = r#"
169-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
169+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
170170
resources:
171171
- name: Second
172172
type: Test/Null
@@ -191,7 +191,7 @@ mod tests {
191191
#[test]
192192
fn test_circular_dependency() {
193193
let config_yaml: &str = r#"
194-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
194+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
195195
resources:
196196
- name: Second
197197
type: Test/Null
@@ -212,7 +212,7 @@ mod tests {
212212
#[test]
213213
fn test_multiple_dependencies() {
214214
let config_yaml: &str = r#"
215-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
215+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
216216
resources:
217217
- name: Third
218218
type: Test/Null
@@ -236,7 +236,7 @@ mod tests {
236236
#[test]
237237
fn test_complex_circular_dependency() {
238238
let config_yaml: &str = r#"
239-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
239+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
240240
resources:
241241
- name: Third
242242
type: Test/Null
@@ -262,7 +262,7 @@ mod tests {
262262
#[test]
263263
fn test_complex_dependency() {
264264
let config_yaml: &str = r#"
265-
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
265+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
266266
resources:
267267
- name: Third
268268
type: Test/Null

dsc_lib/src/dscresources/resource_manifest.rs

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
use rust_i18n::t;
45
use schemars::JsonSchema;
56
use semver::Version;
67
use serde::{Deserialize, Serialize};
78
use serde_json::Value;
89
use std::collections::HashMap;
910

10-
use crate::dscerror::DscError;
11+
use crate::{dscerror::DscError, schemas::DscRepoSchema};
1112

1213
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
1314
#[serde(rename_all = "camelCase")]
@@ -23,7 +24,8 @@ pub enum Kind {
2324
pub struct ResourceManifest {
2425
/// The version of the resource manifest schema.
2526
#[serde(rename = "$schema")]
26-
pub schema_version: ManifestSchemaUri,
27+
#[schemars(schema_with = "ResourceManifest::recognized_schema_uris_subschema")]
28+
pub schema_version: String,
2729
/// The namespaced name of the resource.
2830
#[serde(rename = "type")]
2931
pub resource_type: String,
@@ -70,30 +72,6 @@ pub struct ResourceManifest {
7072
pub schema: Option<SchemaKind>,
7173
}
7274

73-
// Defines the valid and recognized canonical URIs for the manifest schema
74-
#[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq, Deserialize, Serialize, JsonSchema)]
75-
pub enum ManifestSchemaUri {
76-
#[default]
77-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/resource/manifest.json")]
78-
Version2024_04,
79-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json")]
80-
Bundled2024_04,
81-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.vscode.json")]
82-
VSCode2024_04,
83-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/resource/manifest.json")]
84-
Version2023_10,
85-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/bundled/resource/manifest.json")]
86-
Bundled2023_10,
87-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/10/bundled/resource/manifest.vscode.json")]
88-
VSCode2023_10,
89-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/resource/manifest.json")]
90-
Version2023_08,
91-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.json")]
92-
Bundled2023_08,
93-
#[serde(rename = "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/bundled/resource/manifest.vscode.json")]
94-
VSCode2023_08,
95-
}
96-
9775
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
9876
#[serde(untagged)]
9977
pub enum ArgKind {
@@ -256,6 +234,20 @@ pub struct ListMethod {
256234
pub args: Option<Vec<String>>,
257235
}
258236

237+
impl DscRepoSchema for ResourceManifest {
238+
const SCHEMA_FILE_BASE_NAME: &'static str = "manifest";
239+
const SCHEMA_FOLDER_PATH: &'static str = "resource";
240+
const SCHEMA_SHOULD_BUNDLE: bool = true;
241+
242+
fn schema_metadata() -> schemars::schema::Metadata {
243+
schemars::schema::Metadata {
244+
title: Some(t!("dscresources.resource_manifest.resourceManifestSchemaTitle").into()),
245+
description: Some(t!("dscresources.resource_manifest.resourceManifestSchemaDescription").into()),
246+
..Default::default()
247+
}
248+
}
249+
}
250+
259251
/// Import a resource manifest from a JSON value.
260252
///
261253
/// # Arguments

dsc_lib/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod functions;
1616
pub mod parser;
1717
pub mod progress;
1818
pub mod util;
19+
pub mod schemas;
1920

2021
i18n!("locales", fallback = "en-us");
2122

0 commit comments

Comments
 (0)