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
1 change: 1 addition & 0 deletions dsc/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ pub enum SchemaType {
TestResult,
ResolveResult,
DscResource,
Resource,
ResourceManifest,
Include,
Configuration,
Expand Down
4 changes: 4 additions & 0 deletions dsc/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use dsc_lib::{
configure::{
config_doc::{
Configuration,
Resource,
RestartRequired,
},
config_result::{
Expand Down Expand Up @@ -164,6 +165,9 @@ pub fn get_schema(schema: SchemaType) -> Schema {
SchemaType::DscResource => {
schema_for!(DscResource)
},
SchemaType::Resource => {
schema_for!(Resource)
},
SchemaType::ResourceManifest => {
schema_for!(ResourceManifest)
},
Expand Down
30 changes: 30 additions & 0 deletions dsc/tests/dsc_resource_schema.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

Describe 'tests for the Resource schema within a configuration' {
It 'Unknown properties are an error' {
$yaml = @'
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: test
type: Microsft.Dsc.Debug/Echo
unknownProperty: true
properties:
output: "Hello World"
'@
dsc config get -i $yaml 2>$TestDrive/error.log
$LASTEXITCODE | Should -Be 2
(Get-Content $TestDrive/error.log -Raw) | Should -Match 'Error: JSON: unknown field `unknownProperty`'

}

It 'dsc schema returns a valid schema' {
$schema = dsc schema -t resource
$LASTEXITCODE | Should -Be 0
$schema | Should -Not -BeNullOrEmpty
$schema = $schema | ConvertFrom-Json
$schema.'$schema' | Should -BeExactly 'https://json-schema.org/draft/2020-12/schema'
$schema.title | Should -BeExactly 'Resource'
$schema.additionalProperties | Should -Be $false
}
}
92 changes: 90 additions & 2 deletions dsc_lib/src/configure/config_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,23 +163,101 @@ pub enum DataType {
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
pub enum CopyMode {
#[serde(rename = "serial")]
Serial,
#[serde(rename = "parallel")]
Parallel,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Copy {
pub name: String,
pub count: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<CopyMode>,
#[serde(skip_serializing_if = "Option::is_none", rename = "batchSize")]
pub batch_size: Option<i32>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Plan {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "promotionCode")]
pub promotion_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub publisher: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub product: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Identity {
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "userAssignedIdentities")]
pub user_assigned_identities: Option<Map<String, Value>>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Sku {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tier: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub family: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub capacity: Option<i32>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Resource {
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
/// The fully qualified name of the resource type
#[serde(rename = "type")]
pub resource_type: String,
#[serde(skip_serializing_if = "Option::is_none", rename = "apiVersion")]
pub api_version: Option<String>,
/// A friendly name for the resource instance
pub name: String, // friendly unique instance name
#[serde(skip_serializing_if = "Option::is_none")]
pub comments: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<String>,
#[serde(rename = "dependsOn", skip_serializing_if = "Option::is_none")]
#[schemars(regex(pattern = r"^\[resourceId\(\s*'[a-zA-Z0-9\.]+/[a-zA-Z0-9]+'\s*,\s*'[a-zA-Z0-9 ]+'\s*\)]$"))]
pub depends_on: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Map<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub identity: Option<Identity>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sku: Option<Sku>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub copy: Option<Copy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub plan: Option<Plan>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<Map<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Metadata>,
pub resources: Option<Vec<Resource>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
pub metadata: Option<Metadata>,
}

impl Default for Configuration {
Expand Down Expand Up @@ -237,6 +315,16 @@ impl Resource {
properties: None,
metadata: None,
condition: None,
identity: None,
sku: None,
scope: None,
copy: None,
plan: None,
resources: None,
comments: None,
location: None,
tags: None,
api_version: None,
}
}
}
Expand Down
Loading