Skip to content
Open
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 adapters/powershell/PowerShell_adapter.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"tags": [
"PowerShell"
],
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
"adapter": {
"list": {
"executable": "pwsh",
Expand Down
1 change: 1 addition & 0 deletions adapters/powershell/powershell.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"tags": [
"PowerShell"
],
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
"adapter": {
"list": {
"executable": "pwsh",
Expand Down
6 changes: 6 additions & 0 deletions data.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"runcommandonset",
"sshdconfig",
"sshd_config.dsc.resource.json",
"sshd-subsystem.dsc.resource.json",
"sshd-subsystemList.dsc.resource.json",
"y2j"
],
"macOS": [
Expand Down Expand Up @@ -56,6 +58,8 @@
"runcommandonset",
"sshdconfig",
"sshd_config.dsc.resource.json",
"sshd-subsystem.dsc.resource.json",
"sshd-subsystemList.dsc.resource.json",
"y2j"
],
"Windows": [
Expand Down Expand Up @@ -92,6 +96,8 @@
"sshdconfig.exe",
"sshd-windows.dsc.resource.json",
"sshd_config.dsc.resource.json",
"sshd-subsystem.dsc.resource.json",
"sshd-subsystemList.dsc.resource.json",
"windowspowershell.dsc.resource.json",
"windowsupdate.dsc.resource.json",
"wu_dsc.exe",
Expand Down
7 changes: 3 additions & 4 deletions dsc/src/mcp/list_dsc_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rmcp::{ErrorData as McpError, Json, tool, tool_router, handler::server::wrap
use rust_i18n::t;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use tokio::task;

#[derive(Serialize, JsonSchema)]
Expand Down Expand Up @@ -63,7 +62,7 @@ impl McpServer {
},
None => None,
};
let mut resources = BTreeMap::<FullyQualifiedTypeName, ResourceSummary>::new();
let mut resources = Vec::<ResourceSummary>::new();
for resource in dsc.list_available(&DiscoveryKind::Resource, &TypeNameFilter::default(), adapter_filter, ProgressFormat::None) {
if let Resource(resource) = resource {
let summary = ResourceSummary {
Expand All @@ -72,10 +71,10 @@ impl McpServer {
description: resource.description.clone(),
require_adapter: resource.require_adapter,
};
resources.insert(resource.type_name.clone(), summary);
resources.push(summary);
}
}
Ok(ResourceListResult { resources: resources.into_values().collect() })
Ok(ResourceListResult { resources })
}).await.map_err(|e| McpError::internal_error(e.to_string(), None))??;

Ok(Json(result))
Expand Down
4 changes: 2 additions & 2 deletions dsc/tests/dsc_mcp.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ Describe 'Tests for MCP server' {

$response = Send-McpRequest -request $mcpRequest
$response.id | Should -BeGreaterOrEqual 3
$resources = dsc resource list | ConvertFrom-Json -Depth 20 | Select-Object type, kind, description -Unique
$response.result.structuredContent.resources.Count | Should -Be $resources.Count
$resources = dsc resource list | ConvertFrom-Json -Depth 20 | Select-Object type, kind, description
$response.result.structuredContent.resources.Count | Should -Be $resources.Count -Because "MCP:`n$($response.result.structuredContent.resources | Format-Table | Out-String)`nDSC:`n$($resources | Format-Table | Out-String)"
for ($i = 0; $i -lt $resources.Count; $i++) {
($response.result.structuredContent.resources[$i].psobject.properties | Measure-Object).Count | Should -BeGreaterOrEqual 3
$response.result.structuredContent.resources[$i].type | Should -BeExactly $resources[$i].type -Because ($response.result.structuredContent | ConvertTo-Json -Depth 20 | Out-String)
Expand Down
75 changes: 62 additions & 13 deletions dsc/tests/dsc_resource_list.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,28 @@ Describe 'Tests for listing resources' {
) {
param($tags, $description, $expectedCount, $expectedType)

if ($tags -and $description) {
$resources = dsc resource list --tags $tags --description $description | ConvertFrom-Json
}
elseif ($tags) {
$resources = dsc resource list --tags $tags | ConvertFrom-Json
}
else {
$resources = dsc resource list --description $description | ConvertFrom-Json
}
$oldPath = $env:DSC_RESOURCE_PATH
try {
# Need to restrict the search as more resources are being added like from PS7
$env:DSC_RESOURCE_PATH = Split-Path (Get-Command dsc).Source -Parent

$LASTEXITCODE | Should -Be 0
$resources.Count | Should -Be $expectedCount
if ($expectedCount -gt 0) {
$resources.type | Should -BeExactly $expectedType
if ($tags -and $description) {
$resources = dsc resource list --tags $tags --description $description | ConvertFrom-Json
}
elseif ($tags) {
$resources = dsc resource list --tags $tags | ConvertFrom-Json
}
else {
$resources = dsc resource list --description $description | ConvertFrom-Json
}

$LASTEXITCODE | Should -Be 0
$resources.Count | Should -Be $expectedCount
if ($expectedCount -gt 0) {
$resources.type | Should -BeExactly $expectedType
}
} finally {
$env:DSC_RESOURCE_PATH = $oldPath
}
}

Expand Down Expand Up @@ -111,4 +119,45 @@ Describe 'Tests for listing resources' {
}
$foundWideLine | Should -BeTrue
}

It 'No duplicates based on type name and version are returned' {
$resource_manifest = @'
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
"type": "Microsoft.DSC.Debug/EchoDupe",
"version": "1.2.3",
"description": "A duplicate resource for testing",
"get": {
"executable": "dscecho",
"args": [
{
"jsonInputArg": "--input",
"mandatory": true
}
]
},
"schema": {
"command": {
"executable": "dscecho"
}
}
}
'@
$manifestPath = Join-Path $TestDrive "echoDupeManifest.dsc.resource.json"
$manifestDupePath = Join-Path $TestDrive "echoDupeManifestDuplicate.dsc.resource.json"
Set-Content -Path $manifestPath -Value $resource_manifest
Set-Content -Path $manifestDupePath -Value $resource_manifest

try {
$env:DSC_RESOURCE_PATH = $TestDrive + [System.IO.Path]::PathSeparator + $env:PATH
$resources = dsc resource list | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$resourceGroups = $resources | Group-Object -Property type, version
foreach ($group in $resourceGroups) {
$group.Count | Should -Be 1 -Because ($resources | ConvertTo-Json -Depth 20)
}
} finally {
$env:DSC_RESOURCE_PATH = $null
}
}
}
1 change: 1 addition & 0 deletions extensions/powershell/powershell.dsc.extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"type": "Microsoft.PowerShell/Discover",
"version": "0.1.0",
"description": "Discovers DSC resources packaged in PowerShell 7 modules.",
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
"discover": {
"executable": "pwsh",
"args": [
Expand Down
16 changes: 12 additions & 4 deletions lib/dsc-lib/src/discovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Discovery {
Box::new(command_discovery::CommandDiscovery::new(progress_format)),
];

let mut resources: Vec<ImportedManifest> = Vec::new();
let mut resources: BTreeMap<String, ImportedManifest> = BTreeMap::new();

for mut discovery_type in discovery_types {

Expand All @@ -81,8 +81,16 @@ impl Discovery {
};

for (_resource_name, found_resources) in discovered_resources {
for resource in found_resources {
resources.push(resource.clone());
for manifest in found_resources {
let key = match &manifest {
ImportedManifest::Resource(resource) => {
format!("{}@{}", resource.type_name.to_lowercase(), resource.version)
},
ImportedManifest::Extension(extension) => {
format!("{}@{}", extension.type_name.to_lowercase(), extension.version)
}
};
resources.insert(key, manifest);
}
};

Expand All @@ -91,7 +99,7 @@ impl Discovery {
}
}

resources
resources.into_values().collect::<Vec<ImportedManifest>>()
}

pub fn get_extensions(&mut self, capability: &Capability) -> Vec<DscExtension> {
Expand Down
1 change: 1 addition & 0 deletions resources/PSScript/psscript.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"type": "Microsoft.DSC.Transitional/PowerShellScript",
"description": "Enable running PowerShell 7 scripts inline",
"version": "0.1.0",
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
"get": {
"executable": "pwsh",
"args": [
Expand Down
1 change: 1 addition & 0 deletions resources/sshdconfig/sshd-subsystem.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"type": "Microsoft.OpenSSH.SSHD/Subsystem",
"description": "Manage SSH Server Subsystem keyword (single entry)",
"version": "0.1.0",
"condition": "[not(equals(tryWhich('sshd'), null()))]",
"get": {
"executable": "sshdconfig",
"args": [
Expand Down
1 change: 1 addition & 0 deletions resources/sshdconfig/sshd-subsystemList.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"type": "Microsoft.OpenSSH.SSHD/SubsystemList",
"description": "Manage SSH Server Subsystem keyword (accepts multiple entries)",
"version": "0.1.0",
"condition": "[not(equals(tryWhich('sshd'), null()))]",
"get": {
"executable": "sshdconfig",
"args": [
Expand Down
1 change: 1 addition & 0 deletions resources/sshdconfig/sshd-windows.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"tags": [
"Windows"
],
"condition": "[not(equals(tryWhich('sshd'), null()))]",
"version": "0.1.0",
"get": {
"executable": "sshdconfig",
Expand Down
1 change: 1 addition & 0 deletions resources/sshdconfig/sshd_config.dsc.resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
"type": "Microsoft.OpenSSH.SSHD/sshd_config",
"description": "Manage SSH Server Configuration",
"condition": "[not(equals(tryWhich('sshd'), null()))]",
"version": "0.1.0",
"get": {
"executable": "sshdconfig",
Expand Down
Loading