Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add capabilities to DscResource schema #357

Merged
merged 1 commit into from
Mar 8, 2024
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
16 changes: 8 additions & 8 deletions dsc/src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use dsc_lib::dscresources::invoke_result::{
use dsc_lib::{
DscManager,
dscresources::invoke_result::ValidateResult,
dscresources::dscresource::{ImplementedAs, Invoke},
dscresources::dscresource::{Capability, ImplementedAs, Invoke},
dscresources::resource_manifest::{import_manifest, ResourceManifest},
};
use serde_yaml::Value;
Expand Down Expand Up @@ -400,13 +400,17 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option<String>) {
ResourceSubCommand::List { resource_name, description, tags, format } => {

let mut write_table = false;
let mut table = Table::new(&["Type", "Kind", "Version", "Methods", "Requires", "Description"]);
let mut table = Table::new(&["Type", "Kind", "Version", "Caps", "Requires", "Description"]);
if format.is_none() && atty::is(Stream::Stdout) {
// write as table if format is not specified and interactive
write_table = true;
}
for resource in dsc.list_available_resources(&resource_name.clone().unwrap_or_default()) {
let mut methods = "g---".to_string();
let mut capabilities = "g---".to_string();
if resource.capabilities.contains(&Capability::Set) { capabilities.replace_range(1..2, "s"); }
if resource.capabilities.contains(&Capability::Test) { capabilities.replace_range(2..3, "t"); }
if resource.capabilities.contains(&Capability::Export) { capabilities.replace_range(3..4, "e"); }

// if description, tags, or write_table is specified, pull resource manifest if it exists
if let Some(ref resource_manifest) = resource.manifest {
let manifest = match import_manifest(resource_manifest.clone()) {
Expand Down Expand Up @@ -438,10 +442,6 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option<String>) {
}
if !found { continue; }
}

if manifest.set.is_some() { methods.replace_range(1..2, "s"); }
if manifest.test.is_some() { methods.replace_range(2..3, "t"); }
if manifest.export.is_some() { methods.replace_range(3..4, "e"); }
} else {
// resource does not have a manifest but filtering on description or tags was requested - skip such resource
if description.is_some() || tags.is_some() {
Expand All @@ -454,7 +454,7 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option<String>) {
resource.type_name,
format!("{:?}", resource.kind),
resource.version,
methods,
capabilities,
resource.requires.unwrap_or_default(),
resource.description.unwrap_or_default()
]);
Expand Down
8 changes: 8 additions & 0 deletions dsc/tests/dsc_resource_list.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ Describe 'Tests for listing resources' {
$resources.type | Should -BeExactly $expectedType
}
}

It 'Capabilities are returned' {
$resource = dsc resource list Microsoft/OSInfo | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$resource.capabilities.Count | Should -Be 2
$resource.capabilities | Should -Contain 'Get'
$resource.capabilities | Should -Contain 'Export'
}
}
15 changes: 14 additions & 1 deletion dsc_lib/src/discovery/command_discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

use crate::discovery::discovery_trait::ResourceDiscovery;
use crate::dscresources::dscresource::{DscResource, ImplementedAs};
use crate::dscresources::dscresource::{Capability, DscResource, ImplementedAs};
use crate::dscresources::resource_manifest::{import_manifest, Kind, ResourceManifest};
use crate::dscresources::command_resource::invoke_command;
use crate::dscerror::DscError;
Expand Down Expand Up @@ -281,12 +281,25 @@ fn load_manifest(path: &Path) -> Result<DscResource, DscError> {
Kind::Resource
};

// all command based resources are required to support `get`
let mut capabilities = vec![Capability::Get];
if manifest.set.is_some() {
capabilities.push(Capability::Set);
}
if manifest.test.is_some() {
capabilities.push(Capability::Test);
}
if manifest.export.is_some() {
capabilities.push(Capability::Export);
}

let resource = DscResource {
type_name: manifest.resource_type.clone(),
kind,
implemented_as: ImplementedAs::Command,
description: manifest.description.clone(),
version: manifest.version.clone(),
capabilities,
path: path.to_str().unwrap().to_string(),
directory: path.parent().unwrap().to_str().unwrap().to_string(),
manifest: Some(serde_json::to_value(manifest)?),
Expand Down
11 changes: 11 additions & 0 deletions dsc_lib/src/dscresources/dscresource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct DscResource {
pub kind: Kind,
/// The version of the resource.
pub version: String,
/// The capabilities of the resource.
pub capabilities: Vec<Capability>,
/// The file path to the resource.
pub path: String,
/// The description of the resource.
Expand All @@ -40,6 +42,14 @@ pub struct DscResource {
pub manifest: Option<Value>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
pub enum Capability {
Get,
Set,
Test,
Export,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
#[serde(untagged)]
pub enum ImplementedAs {
Expand All @@ -56,6 +66,7 @@ impl DscResource {
type_name: String::new(),
kind: Kind::Resource,
version: String::new(),
capabilities: Vec::new(),
description: None,
path: String::new(),
directory: String::new(),
Expand Down
11 changes: 10 additions & 1 deletion powershell-adapter/powershell.resource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,21 @@ if ($Operation -eq 'List')

$fullResourceTypeName = "$moduleName/$($r.ResourceType)"
$script:ResourceCache[$fullResourceTypeName] = $r
if ($WinPS) {$requiresString = "Microsoft.Windows/WindowsPowerShell"} else {$requiresString = "Microsoft.DSC/PowerShell"}
if ($WinPS) {$requiresString = "Microsoft.Windows/WindowsPowerShell"} else {$requiresString = "Microsoft.DSC/PowerShell"}

$t = [Type]$r.ResourceType
$exportMethod = $t.GetMethod('Export')

$capabilities = @('Get', 'Set', 'Test')
if ($null -ne $exportMethod) {
$capabilities += 'Export'
}

$z = [pscustomobject]@{
type = $fullResourceTypeName;
kind = 'Resource';
version = $version_string;
capabilities = $capabilities;
path = $r.Path;
directory = $r.ParentPath;
implementedAs = $r.ImplementationDetail;
Expand Down
5 changes: 4 additions & 1 deletion tools/test_group_resource/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod args;
use args::{Args, SubCommand};
use clap::Parser;
use dsc_lib::dscresources::resource_manifest::{ResourceManifest, GetMethod, Kind};
use dsc_lib::dscresources::dscresource::{DscResource, ImplementedAs};
use dsc_lib::dscresources::dscresource::{Capability, DscResource, ImplementedAs};

fn main() {
let args = Args::parse();
Expand All @@ -16,6 +16,7 @@ fn main() {
type_name: "Test/TestResource1".to_string(),
kind: Kind::Resource,
version: "1.0.0".to_string(),
capabilities: vec![Capability::Get, Capability::Set],
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource1".to_string(),
Expand Down Expand Up @@ -48,6 +49,7 @@ fn main() {
type_name: "Test/TestResource2".to_string(),
kind: Kind::Resource,
version: "1.0.1".to_string(),
capabilities: vec![Capability::Get, Capability::Set],
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource2".to_string(),
Expand Down Expand Up @@ -84,6 +86,7 @@ fn main() {
type_name: "InvalidResource".to_string(),
kind: Kind::Resource,
version: "1.0.0".to_string(),
capabilities: vec![Capability::Get],
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource1".to_string(),
Expand Down
1 change: 1 addition & 0 deletions wmi-adapter/wmi.resource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ if ($Operation -eq 'List')
type = $fullResourceTypeName;
kind = 'Resource';
version = $version_string;
capabilities = @('Get');
path = "";
directory = "";
implementedAs = "";
Expand Down
Loading