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

Making PowerShell adapter and class-based resources cross-platform #439

Merged
merged 5 commits into from
May 30, 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
11 changes: 7 additions & 4 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,13 @@ if (!$Clippy -and !$SkipBuild) {
if ($Test) {
$failed = $false

$FullyQualifiedName = @{ModuleName="PSDesiredStateConfiguration";ModuleVersion="2.0.7"}
if (-not(Get-Module -ListAvailable -FullyQualifiedName $FullyQualifiedName))
{ "Installing module PSDesiredStateConfiguration 2.0.7"
Install-PSResource -Name PSDesiredStateConfiguration -Version 2.0.7 -Repository PSGallery -TrustRepository
if ($IsWindows) {
# PSDesiredStateConfiguration module is needed for Microsoft.Windows/WindowsPowerShell adapter
$FullyQualifiedName = @{ModuleName="PSDesiredStateConfiguration";ModuleVersion="2.0.7"}
if (-not(Get-Module -ListAvailable -FullyQualifiedName $FullyQualifiedName))
{ "Installing module PSDesiredStateConfiguration 2.0.7"
Install-PSResource -Name PSDesiredStateConfiguration -Version 2.0.7 -Repository PSGallery -TrustRepository
}
}

if (-not(Get-Module -ListAvailable -Name Pester))
Expand Down
17 changes: 9 additions & 8 deletions powershell-adapter/Tests/powershellgroup.config.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Describe 'PowerShell adapter resource tests' {
Remove-Item -Force -ea SilentlyContinue -Path $cacheFilePath
}

It 'Get works on config with class-based resources' -Skip:(!$IsWindows){
It 'Get works on config with class-based resources' {

$r = Get-Content -Raw $pwshConfigPath | dsc config get
$LASTEXITCODE | Should -Be 0
Expand All @@ -33,23 +33,23 @@ Describe 'PowerShell adapter resource tests' {
$res.results[0].result.actualState.result[0].properties.EnumProp | Should -BeExactly 'Expected'
}

It 'Test works on config with class-based resources' -Skip:(!$IsWindows){
It 'Test works on config with class-based resources' {

$r = Get-Content -Raw $pwshConfigPath | dsc config test
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.results[0].result.actualState.result[0] | Should -Not -BeNull
}

It 'Set works on config with class-based resources' -Skip:(!$IsWindows){
It 'Set works on config with class-based resources' {

$r = Get-Content -Raw $pwshConfigPath | dsc config set
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.results.result.afterState.result[0].type | Should -Be "TestClassResource/TestClassResource"
}

It 'Export works on config with class-based resources' -Skip:(!$IsWindows){
It 'Export works on config with class-based resources' {

$yaml = @'
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
Expand All @@ -71,20 +71,21 @@ Describe 'PowerShell adapter resource tests' {
$res.resources[0].properties.result[0].Prop1 | Should -Be "Property of object1"
}

It 'Custom psmodulepath in config works' -Skip:(!$IsWindows){
It 'Custom psmodulepath in config works' {

$OldPSModulePath = $env:PSModulePath
Copy-Item -Recurse -Force -Path "$PSScriptRoot/TestClassResource" -Destination $TestDrive
Rename-Item -Path "$PSScriptRoot/TestClassResource" -NewName "_TestClassResource"

try {
$psmp = "`$env:PSModulePath"+[System.IO.Path]::PathSeparator+$TestDrive
$yaml = @"
`$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
resources:
- name: Working with class-based resources
type: Microsoft.DSC/PowerShell
properties:
psmodulepath: `$env:PSModulePath;$TestDrive
psmodulepath: $psmp
resources:
- name: Class-resource Info
type: TestClassResource/TestClassResource
Expand All @@ -104,7 +105,7 @@ Describe 'PowerShell adapter resource tests' {
}
}

It 'DSCConfigRoot macro is working when config is from a file' -Skip:(!$IsWindows){
It 'DSCConfigRoot macro is working when config is from a file' {

$yaml = @"
`$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
Expand All @@ -129,7 +130,7 @@ Describe 'PowerShell adapter resource tests' {
$res.results.result.actualState.result.properties.Prop1 | Should -Be $TestDrive
}

It 'DSC_CONFIG_ROOT env var is cwd when config is piped from stdin' -Skip:(!$IsWindows){
It 'DSC_CONFIG_ROOT env var is cwd when config is piped from stdin' {

$yaml = @"
`$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
Expand Down
17 changes: 8 additions & 9 deletions powershell-adapter/Tests/powershellgroup.resource.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,48 +23,47 @@ Describe 'PowerShell adapter resource tests' {
Remove-Item -Force -ea SilentlyContinue -Path $cacheFilePath
}

It 'Discovery includes class-based and script-based resources ' -Skip:(!$IsWindows){
It 'Discovery includes class-based resources' {

$r = dsc resource list * -a Microsoft.DSC/PowerShell
$r = dsc resource list '*' -a Microsoft.DSC/PowerShell
$LASTEXITCODE | Should -Be 0
$resources = $r | ConvertFrom-Json
($resources | ? {$_.Type -eq 'TestClassResource/TestClassResource'}).Count | Should -Be 1
($resources | ? {$_.Type -eq 'PSTestModule/TestPSRepository'}).Count | Should -Be 1
}

It 'Get works on class-based resource' -Skip:(!$IsWindows){
It 'Get works on class-based resource' {

$r = "{'Name':'TestClassResource1'}" | dsc resource get -r 'TestClassResource/TestClassResource'
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.actualState.result.properties.Prop1 | Should -BeExactly 'ValueForProp1'
}

It 'Get uses enum names on class-based resource' -Skip:(!$IsWindows){
It 'Get uses enum names on class-based resource' {

$r = "{'Name':'TestClassResource1'}" | dsc resource get -r 'TestClassResource/TestClassResource'
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.actualState.result.properties.EnumProp | Should -BeExactly 'Expected'
}

It 'Test works on class-based resource' -Skip:(!$IsWindows){
It 'Test works on class-based resource' {

$r = "{'Name':'TestClassResource1','Prop1':'ValueForProp1'}" | dsc resource test -r 'TestClassResource/TestClassResource'
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.actualState.result.properties.InDesiredState | Should -Be $True
}

It 'Set works on class-based resource' -Skip:(!$IsWindows){
It 'Set works on class-based resource' {

$r = "{'Name':'TestClassResource1','Prop1':'ValueForProp1'}" | dsc resource set -r 'TestClassResource/TestClassResource'
$LASTEXITCODE | Should -Be 0
$res = $r | ConvertFrom-Json
$res.afterState.result | Should -Not -BeNull
}

It 'Export works on PS class-based resource' -Skip:(!$IsWindows){
It 'Export works on PS class-based resource' {

$r = dsc resource export -r TestClassResource/TestClassResource
$LASTEXITCODE | Should -Be 0
Expand All @@ -74,7 +73,7 @@ Describe 'PowerShell adapter resource tests' {
$res.resources[0].properties.result[0].Prop1 | Should -Be "Property of object1"
}

It 'Get --all works on PS class-based resource' -Skip:(!$IsWindows){
It 'Get --all works on PS class-based resource' {

$r = dsc resource get --all -r TestClassResource/TestClassResource
$LASTEXITCODE | Should -Be 0
Expand Down
37 changes: 23 additions & 14 deletions powershell-adapter/psDscAdapter/powershell.resource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ param(
[string]$jsonInput = '@{}'
)

function Write-DscTrace {
param(
[Parameter(Mandatory = $false)]
[ValidateSet('Error', 'Warn', 'Info', 'Debug', 'Trace')]
[string]$Operation = 'Debug',
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string]$Message
)

$trace = @{$Operation = $Message } | ConvertTo-Json -Compress
$host.ui.WriteErrorLine($trace)
}

# Adding some debug info to STDERR
'PSVersion=' + $PSVersionTable.PSVersion.ToString() | Write-DscTrace
'PSPath=' + $PSHome | Write-DscTrace
'PSModulePath=' + $env:PSModulePath | Write-DscTrace

if ('Validate' -ne $Operation) {
# write $jsonInput to STDERR for debugging
$trace = @{'Debug' = 'jsonInput=' + $jsonInput } | ConvertTo-Json -Compress
Expand All @@ -21,14 +39,15 @@ if ('Validate' -ne $Operation) {
else {
$psDscAdapter = Import-Module "$PSScriptRoot/psDscAdapter.psd1" -Force -PassThru
}


# initialize OUTPUT as array
$result = [System.Collections.Generic.List[Object]]::new()
}

if ($jsonInput) {
$inputobj_pscustomobj = $jsonInput | ConvertFrom-Json
if ($jsonInput -ne '@{}') {
$inputobj_pscustomobj = $jsonInput | ConvertFrom-Json
}
$new_psmodulepath = $inputobj_pscustomobj.psmodulepath
if ($new_psmodulepath)
{
Expand All @@ -48,6 +67,7 @@ switch ($Operation) {
$DscResourceInfo = $dscResource.DscResourceInfo

# Provide a way for existing resources to specify their capabilities, or default to Get, Set, Test
# TODO: for perf, it is better to take capabilities from psd1 in Invoke-DscCacheRefresh, not by extra call to Get-Module
if ($DscResourceInfo.ModuleName) {
$module = Get-Module -Name $DscResourceInfo.ModuleName -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
if ($module.PrivateData.PSData.DscCapabilities) {
Expand Down Expand Up @@ -82,7 +102,7 @@ switch ($Operation) {
[resourceOutput]@{
type = $dscResource.Type
kind = 'Resource'
version = $DscResourceInfo.version.ToString()
version = [string]$DscResourceInfo.version
capabilities = $capabilities
path = $DscResourceInfo.Path
directory = $DscResourceInfo.ParentPath
Expand Down Expand Up @@ -159,14 +179,3 @@ class resourceOutput {
[string] $requireAdapter
[string] $description
}

# Adding some debug info to STDERR
$trace = @{'Debug' = 'PSVersion=' + $PSVersionTable.PSVersion.ToString() } | ConvertTo-Json -Compress
$host.ui.WriteErrorLine($trace)
$trace = @{'Debug' = 'PSPath=' + $PSHome } | ConvertTo-Json -Compress
$host.ui.WriteErrorLine($trace)
$m = Get-Command 'Get-DscResource'
$trace = @{'Debug' = 'Module=' + $m.Source.ToString() } | ConvertTo-Json -Compress
$host.ui.WriteErrorLine($trace)
$trace = @{'Debug' = 'PSModulePath=' + $env:PSModulePath } | ConvertTo-Json -Compress
$host.ui.WriteErrorLine($trace)
Loading
Loading