diff --git a/lib/dsc-lib/src/configure/config_doc.rs b/lib/dsc-lib/src/configure/config_doc.rs index 6489114b6..367d01456 100644 --- a/lib/dsc-lib/src/configure/config_doc.rs +++ b/lib/dsc-lib/src/configure/config_doc.rs @@ -3,28 +3,30 @@ use chrono::{DateTime, Local}; use rust_i18n::t; -use schemars::{JsonSchema, json_schema}; +use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::{Map, Value}; use std::{collections::HashMap, fmt::Display}; use crate::schemas::{ - dsc_repo::{DscRepoSchema, UnrecognizedSchemaUri}, + dsc_repo::DscRepoSchema, transforms::{idiomaticize_externally_tagged_enum, idiomaticize_string_enum} }; -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "securityContext", folder_path = "metadata/Microsoft.DSC")] pub enum SecurityContextKind { Current, Elevated, Restricted, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "operation", folder_path = "metadata/Microsoft.DSC")] pub enum Operation { Get, Set, @@ -32,9 +34,10 @@ pub enum Operation { Export, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "executionType", folder_path = "metadata/Microsoft.DSC")] pub enum ExecutionKind { Actual, WhatIf, @@ -47,9 +50,10 @@ pub struct Process { pub id: u32, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_externally_tagged_enum)] +#[dsc_repo_schema(base_name = "restartRequired", folder_path = "metadata/Microsoft.DSC")] pub enum RestartRequired { System(String), Service(String), @@ -104,7 +108,8 @@ impl MicrosoftDscMetadata { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "document.metadata", folder_path = "config")] pub struct Metadata { #[serde(rename = "Microsoft.DSC", skip_serializing_if = "Option::is_none")] pub microsoft: Option, @@ -112,25 +117,29 @@ pub struct Metadata { pub other: Map, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "document.function", folder_path = "config")] pub struct UserFunction { pub namespace: String, pub members: HashMap, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "definition", folder_path = "definitions/functions/user")] pub struct UserFunctionDefinition { pub parameters: Option>, pub output: UserFunctionOutput, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "parameter", folder_path = "definitions/functions/user")] pub struct UserFunctionParameter { pub name: String, pub r#type: DataType, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "output", folder_path = "definitions/functions/user")] pub struct UserFunctionOutput { pub r#type: DataType, pub value: String, @@ -143,8 +152,9 @@ pub enum ValueOrCopy { Copy(Copy), } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "document.output", folder_path = "config")] pub struct Output { pub condition: Option, pub r#type: DataType, @@ -152,8 +162,18 @@ pub struct Output { pub value_or_copy: ValueOrCopy, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema( + base_name = "document", + folder_path = "config", + should_bundle = true, + schema_field( + name = schema, + title = t!("configure.config_doc.configurationDocumentSchemaTitle"), + description = t!("configure.config_doc.configurationDocumentSchemaDescription"), + ) +)] pub struct Configuration { #[serde(rename = "$schema")] #[schemars(schema_with = "Configuration::recognized_schema_uris_subschema")] @@ -222,8 +242,9 @@ where } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "document.parameter", folder_path = "config")] pub struct Parameter { #[serde(rename = "type")] pub parameter_type: DataType, @@ -245,8 +266,9 @@ pub struct Parameter { pub metadata: Option>, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "dataTypes", folder_path = "definitions/parameters")] pub enum DataType { #[serde(rename = "string")] String, @@ -353,8 +375,9 @@ pub struct Sku { pub capacity: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "document.resource", folder_path = "config")] pub struct Resource { #[serde(skip_serializing_if = "Option::is_none")] pub condition: Option, @@ -406,30 +429,6 @@ impl Default for Configuration { } } -impl DscRepoSchema for Configuration { - const SCHEMA_FILE_BASE_NAME: &'static str = "document"; - const SCHEMA_FOLDER_PATH: &'static str = "config"; - const SCHEMA_SHOULD_BUNDLE: bool = true; - - fn schema_property_metadata() -> schemars::Schema { - json_schema!({ - "title": t!("configure.config_doc.configurationDocumentSchemaTitle").to_string(), - "description": t!("configure.config_doc.configurationDocumentSchemaDescription").to_string(), - }) - } - - fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUri> { - if Self::is_recognized_schema_uri(&self.schema) { - Ok(()) - } else { - Err(UnrecognizedSchemaUri( - self.schema.clone(), - Self::recognized_schema_uris(), - )) - } - } -} - impl Configuration { #[must_use] pub fn new() -> Self { diff --git a/lib/dsc-lib/src/configure/config_result.rs b/lib/dsc-lib/src/configure/config_result.rs index 3bce3860d..31b7c2a84 100644 --- a/lib/dsc-lib/src/configure/config_result.rs +++ b/lib/dsc-lib/src/configure/config_result.rs @@ -7,7 +7,7 @@ use serde_json::{Map, Value}; use crate::dscresources::invoke_result::{GetResult, SetResult, TestResult}; use crate::configure::config_doc::{Configuration, Metadata}; -use crate::schemas::transforms::idiomaticize_string_enum; +use crate::schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "camelCase")] @@ -18,8 +18,9 @@ pub enum MessageLevel { Information, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "message", folder_path = "definitions")] pub struct ResourceMessage { pub name: String, #[serde(rename="type")] @@ -28,8 +29,9 @@ pub struct ResourceMessage { pub level: MessageLevel, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "get.full", folder_path = "outputs/resource")] pub struct ResourceGetResult { #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, @@ -50,8 +52,9 @@ impl From for ResourceGetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "get", folder_path = "outputs/config")] pub struct ConfigurationGetResult { pub metadata: Option, pub results: Vec, @@ -97,8 +100,9 @@ impl From for ConfigurationGetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "set.full", folder_path = "outputs/resource")] pub struct ResourceSetResult { #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, @@ -140,8 +144,9 @@ impl Default for GroupResourceSetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "set", folder_path = "outputs/config")] pub struct ConfigurationSetResult { pub metadata: Option, pub results: Vec, @@ -171,8 +176,9 @@ impl Default for ConfigurationSetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "test.full", folder_path = "outputs/resource")] pub struct ResourceTestResult { #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option, @@ -203,8 +209,9 @@ impl Default for GroupResourceTestResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "test", folder_path = "outputs/config")] pub struct ConfigurationTestResult { pub metadata: Option, pub results: Vec, @@ -234,8 +241,9 @@ impl Default for ConfigurationTestResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "export", folder_path = "outputs/config")] pub struct ConfigurationExportResult { pub metadata: Option, pub result: Option, diff --git a/lib/dsc-lib/src/dscresources/dscresource.rs b/lib/dsc-lib/src/dscresources/dscresource.rs index cf230c231..afb2612a8 100644 --- a/lib/dsc-lib/src/dscresources/dscresource.rs +++ b/lib/dsc-lib/src/dscresources/dscresource.rs @@ -14,6 +14,8 @@ use std::collections::HashMap; use std::path::PathBuf; use tracing::{debug, info, trace}; +use crate::schemas::dsc_repo::DscRepoSchema; + use super::{ command_resource, dscerror, @@ -25,8 +27,9 @@ use super::{ } }; -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "list", folder_path = "outputs/resource")] pub struct DscResource { /// The namespaced name of the resource. #[serde(rename="type")] @@ -59,9 +62,10 @@ pub struct DscResource { pub manifest: Option, } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "resourceCapabilities", folder_path = "definitions")] pub enum Capability { /// The resource supports retrieving configuration. Get, diff --git a/lib/dsc-lib/src/dscresources/invoke_result.rs b/lib/dsc-lib/src/dscresources/invoke_result.rs index 9d7404a12..c1170c781 100644 --- a/lib/dsc-lib/src/dscresources/invoke_result.rs +++ b/lib/dsc-lib/src/dscresources/invoke_result.rs @@ -6,9 +6,11 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::HashMap; use crate::configure::config_result::{ResourceGetResult, ResourceSetResult, ResourceTestResult}; +use crate::schemas::dsc_repo::DscRepoSchema; -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(untagged)] +#[dsc_repo_schema(base_name = "get", folder_path = "outputs/resource")] pub enum GetResult { Resource(ResourceGetResponse), Group(Vec), @@ -33,16 +35,18 @@ impl From for GetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "get.simple", folder_path = "outputs/resource")] pub struct ResourceGetResponse { /// The state of the resource as it was returned by the Get method. #[serde(rename = "actualState")] pub actual_state: Value, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(untagged)] +#[dsc_repo_schema(base_name = "set", folder_path = "outputs/resource")] pub enum SetResult { Resource(ResourceSetResponse), Group(Vec), @@ -69,8 +73,9 @@ impl From for SetResult { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "set.simple", folder_path = "outputs/resource")] pub struct ResourceSetResponse { /// The state of the resource as it was before the Set method was called. #[serde(rename = "beforeState")] @@ -83,8 +88,9 @@ pub struct ResourceSetResponse { pub changed_properties: Option>, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(untagged)] +#[dsc_repo_schema(base_name = "test", folder_path = "outputs/resource")] pub enum TestResult { Resource(ResourceTestResponse), Group(Vec), @@ -107,8 +113,9 @@ pub fn get_in_desired_state(test_result: &TestResult) -> bool { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "test.simple", folder_path = "outputs/resource")] pub struct ResourceTestResponse { /// The state of the resource as it was expected to be. #[serde(rename = "desiredState")] @@ -124,8 +131,9 @@ pub struct ResourceTestResponse { pub diff_properties: Vec, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "validate", folder_path = "outputs/resource")] pub struct ValidateResult { /// Whether the supplied configuration is valid. pub valid: bool, @@ -133,16 +141,18 @@ pub struct ValidateResult { pub reason: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "export", folder_path = "outputs/resource")] pub struct ExportResult { /// The state of the resource as it was returned by the Export method. #[serde(rename = "actualState")] pub actual_state: Vec, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "resolve", folder_path = "outputs/resource")] pub struct ResolveResult { /// The resolved configuration. pub configuration: Value, diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 513d9b2b2..4e9a19925 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use rust_i18n::t; -use schemars::{Schema, JsonSchema, json_schema}; +use schemars::JsonSchema; use semver::Version; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; @@ -10,12 +10,13 @@ use std::collections::HashMap; use crate::{ dscerror::DscError, - schemas::{dsc_repo::{DscRepoSchema, UnrecognizedSchemaUri}, transforms::idiomaticize_string_enum}, + schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}, }; -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "resourceKind", folder_path = "definitions")] pub enum Kind { Adapter, Exporter, @@ -24,8 +25,18 @@ pub enum Kind { Resource, } -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema( + base_name = "manifest", + folder_path = "resource", + should_bundle = true, + schema_field( + name = schema_version, + title = t!("dscresources.resource_manifest.resourceManifestSchemaTitle"), + description = t!("dscresources.resource_manifest.resourceManifestSchemaDescription"), + ) +)] pub struct ResourceManifest { /// The version of the resource manifest schema. #[serde(rename = "$schema")] @@ -82,8 +93,9 @@ pub struct ResourceManifest { pub metadata: Option>, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(untagged)] +#[dsc_repo_schema(base_name = "commandArgs", folder_path = "definitions")] pub enum ArgKind { /// The argument is a string. String(String), @@ -102,8 +114,9 @@ pub enum ArgKind { } } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "inputKind", folder_path = "definitions")] pub enum InputKind { /// The input is accepted as environmental variables. #[serde(rename = "env")] @@ -113,7 +126,8 @@ pub enum InputKind { Stdin, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.schema", folder_path = "resource")] pub enum SchemaKind { /// The schema is returned by running a command. #[serde(rename = "command")] @@ -131,8 +145,9 @@ pub struct SchemaCommand { pub args: Option>, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "returnKind", folder_path = "definitions")] pub enum ReturnKind { /// The return JSON is the state of the resource. #[serde(rename = "state")] @@ -142,7 +157,8 @@ pub enum ReturnKind { StateAndDiff, } -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.get", folder_path = "resource")] pub struct GetMethod { /// The command to run to get the state of the resource. pub executable: String, @@ -153,7 +169,8 @@ pub struct GetMethod { pub input: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.set", folder_path = "resource")] pub struct SetMethod { /// The command to run to set the state of the resource. pub executable: String, @@ -172,7 +189,8 @@ pub struct SetMethod { pub returns: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.test", folder_path = "resource")] pub struct TestMethod { /// The command to run to test the state of the resource. pub executable: String, @@ -185,7 +203,8 @@ pub struct TestMethod { pub returns: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.delete", folder_path = "resource")] pub struct DeleteMethod { /// The command to run to delete the state of the resource. pub executable: String, @@ -195,7 +214,8 @@ pub struct DeleteMethod { pub input: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.validate", folder_path = "resource")] pub struct ValidateMethod { // TODO: enable validation via schema or command /// The command to run to validate the state of the resource. pub executable: String, @@ -205,7 +225,8 @@ pub struct ValidateMethod { // TODO: enable validation via schema or command pub input: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.export", folder_path = "resource")] pub struct ExportMethod { /// The command to run to enumerate instances of the resource. pub executable: String, @@ -215,7 +236,8 @@ pub struct ExportMethod { pub input: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.resolve", folder_path = "resource")] pub struct ResolveMethod { /// The command to run to enumerate instances of the resource. pub executable: String, @@ -225,7 +247,8 @@ pub struct ResolveMethod { pub input: Option, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.adapter", folder_path = "resource")] pub struct Adapter { /// The way to list adapter supported resources. pub list: ListMethod, @@ -256,30 +279,6 @@ pub struct ListMethod { pub args: Option>, } -impl DscRepoSchema for ResourceManifest { - const SCHEMA_FILE_BASE_NAME: &'static str = "manifest"; - const SCHEMA_FOLDER_PATH: &'static str = "resource"; - const SCHEMA_SHOULD_BUNDLE: bool = true; - - fn schema_property_metadata() -> Schema { - json_schema!({ - "title": t!("dscresources.resource_manifest.resourceManifestSchemaTitle").to_string(), - "description": t!("dscresources.resource_manifest.resourceManifestSchemaDescription").to_string(), - }) - } - - fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUri> { - if Self::is_recognized_schema_uri(&self.schema_version) { - Ok(()) - } else { - Err(UnrecognizedSchemaUri( - self.schema_version.clone(), - Self::recognized_schema_uris(), - )) - } - } -} - /// Import a resource manifest from a JSON value. /// /// # Arguments diff --git a/lib/dsc-lib/src/extensions/discover.rs b/lib/dsc-lib/src/extensions/discover.rs index 6efb91abb..11128669c 100644 --- a/lib/dsc-lib/src/extensions/discover.rs +++ b/lib/dsc-lib/src/extensions/discover.rs @@ -20,6 +20,7 @@ use crate::{ }, extension_manifest::ExtensionManifest, }, + schemas::dsc_repo::DscRepoSchema }; use rust_i18n::t; use schemars::JsonSchema; @@ -27,7 +28,8 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; use tracing::{info, trace}; -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.discover", folder_path = "extension")] pub struct DiscoverMethod { /// The command to run to get the state of the resource. pub executable: String, @@ -35,7 +37,8 @@ pub struct DiscoverMethod { pub args: Option>, } -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "discover", folder_path = "extension/stdout")] pub struct DiscoverResult { /// The path to the resource manifest, must be absolute. #[serde(rename = "manifestPath")] diff --git a/lib/dsc-lib/src/extensions/dscextension.rs b/lib/dsc-lib/src/extensions/dscextension.rs index cc21002a9..379dedcb6 100644 --- a/lib/dsc-lib/src/extensions/dscextension.rs +++ b/lib/dsc-lib/src/extensions/dscextension.rs @@ -2,15 +2,16 @@ // Licensed under the MIT License. use crate::extensions::import::ImportMethod; -use crate::schemas::transforms::idiomaticize_string_enum; +use crate::schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}; use serde::{Deserialize, Serialize}; use serde_json::Value; use schemars::JsonSchema; use std::fmt::Display; use std::path::PathBuf; -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "list", folder_path = "outputs/extension")] pub struct DscExtension { /// The namespaced name of the resource. #[serde(rename="type")] @@ -33,9 +34,10 @@ pub struct DscExtension { pub manifest: Value, } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(rename_all = "camelCase")] #[schemars(transform = idiomaticize_string_enum)] +#[dsc_repo_schema(base_name = "extensionCapabilities", folder_path = "definitions")] pub enum Capability { /// The extension aids in discovering resources. Discover, diff --git a/lib/dsc-lib/src/extensions/extension_manifest.rs b/lib/dsc-lib/src/extensions/extension_manifest.rs index 1337d48b6..59c95e979 100644 --- a/lib/dsc-lib/src/extensions/extension_manifest.rs +++ b/lib/dsc-lib/src/extensions/extension_manifest.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use rust_i18n::t; -use schemars::{Schema, JsonSchema, json_schema}; +use schemars::JsonSchema; use semver::Version; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; @@ -10,10 +10,20 @@ use std::collections::HashMap; use crate::dscerror::DscError; use crate::extensions::{discover::DiscoverMethod, import::ImportMethod, secret::SecretMethod}; -use crate::schemas::dsc_repo::{DscRepoSchema, UnrecognizedSchemaUri}; +use crate::schemas::dsc_repo::DscRepoSchema; -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema( + base_name = "manifest", + folder_path = "extension", + should_bundle = true, + schema_field( + name = schema_version, + title = t!("extensions.extension_manifest.extensionManifestSchemaTitle"), + description = t!("extensions.extension_manifest.extensionManifestSchemaDescription"), + ) +)] pub struct ExtensionManifest { /// The version of the extension manifest schema. #[serde(rename = "$schema")] @@ -47,30 +57,6 @@ pub struct ExtensionManifest { pub metadata: Option>, } -impl DscRepoSchema for ExtensionManifest { - const SCHEMA_FILE_BASE_NAME: &'static str = "manifest"; - const SCHEMA_FOLDER_PATH: &'static str = "extension"; - const SCHEMA_SHOULD_BUNDLE: bool = true; - - fn schema_property_metadata() -> Schema { - json_schema!({ - "title": t!("extensions.extension_manifest.extensionManifestSchemaTitle").to_string(), - "description": t!("extensions.extension_manifest.extensionManifestSchemaDescription").to_string(), - }) - } - - fn validate_schema_uri(&self) -> Result<(), UnrecognizedSchemaUri> { - if Self::is_recognized_schema_uri(&self.schema_version) { - Ok(()) - } else { - Err(UnrecognizedSchemaUri( - self.schema_version.clone(), - Self::recognized_schema_uris(), - )) - } - } -} - /// Import a resource manifest from a JSON value. /// /// # Arguments diff --git a/lib/dsc-lib/src/extensions/import.rs b/lib/dsc-lib/src/extensions/import.rs index d164eda69..d456c235a 100644 --- a/lib/dsc-lib/src/extensions/import.rs +++ b/lib/dsc-lib/src/extensions/import.rs @@ -8,8 +8,11 @@ use crate::{ DscExtension, }, extension_manifest::ExtensionManifest, - }, parser::Statement + }, + parser::Statement, + schemas::dsc_repo::DscRepoSchema }; + use path_absolutize::Absolutize; use rust_i18n::t; use schemars::JsonSchema; @@ -17,7 +20,8 @@ use serde::{Deserialize, Serialize}; use std::path::Path; use tracing::{debug, info}; -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.import", folder_path = "extension")] pub struct ImportMethod { /// The extensions to import. #[serde(rename = "fileExtensions")] diff --git a/lib/dsc-lib/src/extensions/secret.rs b/lib/dsc-lib/src/extensions/secret.rs index 5af7caa48..819620b07 100644 --- a/lib/dsc-lib/src/extensions/secret.rs +++ b/lib/dsc-lib/src/extensions/secret.rs @@ -13,7 +13,9 @@ use crate::{ }, extension_manifest::ExtensionManifest, }, + schemas::dsc_repo::DscRepoSchema }; + use rust_i18n::t; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -38,7 +40,8 @@ pub enum SecretArgKind { }, } -#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] +#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "manifest.secret", folder_path = "extension")] pub struct SecretMethod { /// The command to run to get the state of the resource. pub executable: String, diff --git a/lib/dsc-lib/src/functions/mod.rs b/lib/dsc-lib/src/functions/mod.rs index 0ab82e7f1..da75c6ec1 100644 --- a/lib/dsc-lib/src/functions/mod.rs +++ b/lib/dsc-lib/src/functions/mod.rs @@ -6,6 +6,7 @@ use std::collections::HashMap; use crate::DscError; use crate::configure::context::Context; use crate::functions::user_function::invoke_user_function; +use crate::schemas::dsc_repo::DscRepoSchema; use rust_i18n::t; use schemars::JsonSchema; use serde::Serialize; @@ -89,7 +90,8 @@ pub mod variables; pub mod try_which; /// The kind of argument that a function accepts. -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema, DscRepoSchema)] +#[dsc_repo_schema(base_name = "argKind", folder_path = "definitions/functions/builtin")] pub enum FunctionArgKind { Array, Boolean, @@ -330,8 +332,9 @@ impl Default for FunctionDispatcher { } } -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "list", folder_path = "outputs/function")] pub struct FunctionDefinition { pub category: Vec, pub name: String, @@ -348,8 +351,9 @@ pub struct FunctionDefinition { pub return_types: Vec, } -#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, JsonSchema, DscRepoSchema)] #[serde(deny_unknown_fields)] +#[dsc_repo_schema(base_name = "category", folder_path = "definitions/functions/builtin")] pub enum FunctionCategory { Array, Cidr,