ruby-pwsh 0.9.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/CHANGELOG.md +25 -0
- data/Rakefile +68 -10
- data/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb +29 -3
- data/lib/puppet/provider/dsc_base_provider/invoke_dsc_resource_functions.ps1 +1 -1
- data/lib/puppet/provider/dsc_base_provider/invoke_dsc_resource_postscript.ps1 +6 -0
- data/lib/pwsh/version.rb +1 -1
- data/lib/pwsh.rb +1 -1
- data/lib/templates/init.ps1 +11 -1
- data/metadata.json +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0192c9fd1e6f719c01cfbc185c847943ec0878c1fbfda56749a52dfd5d7fca7
|
4
|
+
data.tar.gz: 5d40c16d7f2efe2585a0c65d0e6050aaa72e4083510cbac376038a85ec725264
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e1356eb57e96fa78906861bdd6bf887c5f9eb14175f5408e4db779a3b66ac1bc9bf92d1436f36d019da8b3e18f0bfbc175170d8e3058eff6c3e51235b433ac0
|
7
|
+
data.tar.gz: de4bdce317e05453eb9179df50f065c09c16da4529b304ed0adb7e4becc3c8378ea0f67d69444209ac72d6a5f19881b594f624c311412e8fa32fdcb4bdb9b34d
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org).
|
4
4
|
|
5
|
+
## [v0.10.2](https://github.com/puppetlabs/ruby-pwsh/tree/v0.10.2) - 2022-06-24
|
6
|
+
|
7
|
+
[Full Changelog](https://github.com/puppetlabs/ruby-pwsh/compare/0.10.1...v0.10.2)
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
- (GH-188) Filter current environment variables [#189](https://github.com/puppetlabs/ruby-pwsh/pull/189) ([chelnak](https://github.com/chelnak))
|
12
|
+
|
13
|
+
## [0.10.1](https://github.com/puppetlabs/ruby-pwsh/tree/0.10.1) (2021-08-23)
|
14
|
+
|
15
|
+
[Full Changelog](https://github.com/puppetlabs/ruby-pwsh/compare/0.10.0...0.10.1)
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- \(GH-180\) Ensure instance\_key respects full uniqueness of options [\#181](https://github.com/puppetlabs/ruby-pwsh/pull/181) ([michaeltlombardi](https://github.com/michaeltlombardi))
|
20
|
+
- \(GH-165\) Ensure null-value nested cim instance arrays are appropriately munged [\#177](https://github.com/puppetlabs/ruby-pwsh/pull/177) ([michaeltlombardi](https://github.com/michaeltlombardi))
|
21
|
+
|
22
|
+
## [0.10.0](https://github.com/puppetlabs/ruby-pwsh/tree/0.10.0) (2021-07-02)
|
23
|
+
|
24
|
+
[Full Changelog](https://github.com/puppetlabs/ruby-pwsh/compare/0.9.0...0.10.0)
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- \(GH-172\) Enable use of class-based DSC Resources by munging PSModulePath [\#173](https://github.com/puppetlabs/ruby-pwsh/pull/173) ([michaeltlombardi](https://github.com/michaeltlombardi))
|
29
|
+
|
5
30
|
## [0.9.0](https://github.com/puppetlabs/ruby-pwsh/tree/0.9.0) (2021-06-28)
|
6
31
|
|
7
32
|
[Full Changelog](https://github.com/puppetlabs/ruby-pwsh/compare/0.8.0...0.9.0)
|
data/Rakefile
CHANGED
@@ -99,6 +99,63 @@ task :build_module do
|
|
99
99
|
File.open('README.md', 'wb') { |file| file.write(actual_readme_content) }
|
100
100
|
end
|
101
101
|
|
102
|
+
# Used in vendor_dsc_module
|
103
|
+
TAR_LONGLINK = '././@LongLink'
|
104
|
+
|
105
|
+
# Vendor a Puppetized DSC Module to spec/fixtures/modules.
|
106
|
+
#
|
107
|
+
# This is necessary because `puppet module install` fails on modules with
|
108
|
+
# long file paths, like xpsdesiredstateconfiguration
|
109
|
+
#
|
110
|
+
# @param command [String] command to execute.
|
111
|
+
# @return [Object] the standard out stream.
|
112
|
+
def vendor_dsc_module(name, version, destination)
|
113
|
+
require 'open-uri'
|
114
|
+
require 'rubygems/package'
|
115
|
+
require 'zlib'
|
116
|
+
|
117
|
+
module_uri = "https://forge.puppet.com/v3/files/dsc-#{name}-#{version}.tar.gz"
|
118
|
+
tar_gz_archive = File.expand_path("#{name}.tar.gz", ENV['TEMP'])
|
119
|
+
|
120
|
+
# Download the archive from the forge
|
121
|
+
File.open(tar_gz_archive, 'wb') do |file|
|
122
|
+
file.write(URI.open(module_uri).read) # rubocop:disable Security/Open
|
123
|
+
end
|
124
|
+
|
125
|
+
# Unzip to destination
|
126
|
+
# Taken directly from StackOverflow:
|
127
|
+
# - https://stackoverflow.com/a/19139114
|
128
|
+
Gem::Package::TarReader.new(Zlib::GzipReader.open(tar_gz_archive)) do |tar|
|
129
|
+
dest = nil
|
130
|
+
tar.each do |entry|
|
131
|
+
if entry.full_name == TAR_LONGLINK
|
132
|
+
dest = File.join(destination, entry.read.strip)
|
133
|
+
next
|
134
|
+
end
|
135
|
+
dest ||= File.join(destination, entry.full_name)
|
136
|
+
if entry.directory?
|
137
|
+
File.delete(dest) if File.file?(dest)
|
138
|
+
FileUtils.mkdir_p(dest, mode: entry.header.mode, verbose: false)
|
139
|
+
elsif entry.file?
|
140
|
+
FileUtils.rm_rf(dest) if File.directory?(dest)
|
141
|
+
File.open(dest, 'wb') do |f|
|
142
|
+
f.print(entry.read)
|
143
|
+
end
|
144
|
+
FileUtils.chmod(entry.header.mode, dest, verbose: false)
|
145
|
+
elsif entry.header.typeflag == '2' # Symlink!
|
146
|
+
File.symlink(entry.header.linkname, dest)
|
147
|
+
end
|
148
|
+
dest = nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Rename folder to just the module name, as needed by Puppet
|
153
|
+
Dir.glob("#{destination}/*#{name}*").each do |existing_folder|
|
154
|
+
new_folder = File.expand_path(name, destination)
|
155
|
+
FileUtils.mv(existing_folder, new_folder)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
102
159
|
namespace :dsc do
|
103
160
|
namespace :acceptance do
|
104
161
|
desc 'Prep for running DSC acceptance tests'
|
@@ -107,20 +164,21 @@ namespace :dsc do
|
|
107
164
|
modules_folder = File.expand_path('spec/fixtures/modules', File.dirname(__FILE__))
|
108
165
|
FileUtils.mkdir_p(modules_folder) unless Dir.exist?(modules_folder)
|
109
166
|
# symlink the parent folder to the modules folder for puppet
|
110
|
-
|
167
|
+
symlink_path = File.expand_path('pwshlib', modules_folder)
|
168
|
+
File.symlink(File.dirname(__FILE__), symlink_path) unless Dir.exist?(symlink_path)
|
111
169
|
# Install each of the required modules for acceptance testing
|
112
170
|
# Note: This only works for modules in the dsc namespace on the forge.
|
113
|
-
|
171
|
+
puppetized_dsc_modules = [
|
172
|
+
{ name: 'powershellget', version: '2.2.5-0-1' },
|
173
|
+
{ name: 'jeadsc', version: '0.7.2-0-3' },
|
174
|
+
{ name: 'xpsdesiredstateconfiguration', version: '9.1.0-0-1' },
|
175
|
+
{ name: 'xwebadministration', version: '3.2.0-0-2' },
|
176
|
+
{ name: 'accesscontroldsc', version: '1.4.1-0-3' }
|
177
|
+
]
|
178
|
+
puppetized_dsc_modules.each do |puppet_module|
|
114
179
|
next if Dir.exist?(File.expand_path(puppet_module[:name], modules_folder))
|
115
180
|
|
116
|
-
|
117
|
-
'bundle exec puppet module install',
|
118
|
-
"dsc-#{puppet_module[:name]}",
|
119
|
-
"--version #{puppet_module[:version]}",
|
120
|
-
'--ignore-dependencies',
|
121
|
-
"--target-dir #{modules_folder}"
|
122
|
-
].join(' ')
|
123
|
-
run_local_command(install_command)
|
181
|
+
vendor_dsc_module(puppet_module[:name], puppet_module[:version], modules_folder)
|
124
182
|
end
|
125
183
|
end
|
126
184
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
@@ -416,7 +416,7 @@ class Puppet::Provider::DscBaseProvider
|
|
416
416
|
def invocable_resource(should, context, dsc_invoke_method)
|
417
417
|
resource = {}
|
418
418
|
resource[:parameters] = {}
|
419
|
-
%i[name dscmeta_resource_friendly_name dscmeta_resource_name dscmeta_module_name dscmeta_module_version].each do |k|
|
419
|
+
%i[name dscmeta_resource_friendly_name dscmeta_resource_name dscmeta_resource_implementation dscmeta_module_name dscmeta_module_version].each do |k|
|
420
420
|
resource[k] = context.type.definition[k]
|
421
421
|
end
|
422
422
|
should.each do |k, v|
|
@@ -655,6 +655,27 @@ class Puppet::Provider::DscBaseProvider
|
|
655
655
|
modified_string
|
656
656
|
end
|
657
657
|
|
658
|
+
# Parses a resource definition (as from `invocable_resource`) and, if the resource is implemented
|
659
|
+
# as a PowerShell class, ensures the System environment variable for PSModulePath is munged to
|
660
|
+
# include the vendored PowerShell modules. Due to a bug in PSDesiredStateConfiguration, class-based
|
661
|
+
# DSC Resources cannot be called via Invoke-DscResource by path, only by module name, *and* the
|
662
|
+
# module must be discoverable in the system-level PSModulePath. The postscript for invocation has
|
663
|
+
# logic to reset the system PSModulePath as stored in the script lines returned by this method.
|
664
|
+
#
|
665
|
+
# @param resource [Hash] a hash with the information needed to run `Invoke-DscResource`
|
666
|
+
# @return [String] A multi-line string which sets the PSModulePath at the system level
|
667
|
+
def munge_psmodulepath(resource)
|
668
|
+
return unless resource[:dscmeta_resource_implementation] == 'Class'
|
669
|
+
|
670
|
+
vendor_path = resource[:vendored_modules_path].gsub('/', '\\')
|
671
|
+
<<~MUNGE_PSMODULEPATH.strip
|
672
|
+
$UnmungedPSModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath','machine')
|
673
|
+
$MungedPSModulePath = $env:PSModulePath + ';#{vendor_path}'
|
674
|
+
[System.Environment]::SetEnvironmentVariable('PSModulePath', $MungedPSModulePath, [System.EnvironmentVariableTarget]::Machine)
|
675
|
+
$env:PSModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath','machine')
|
676
|
+
MUNGE_PSMODULEPATH
|
677
|
+
end
|
678
|
+
|
658
679
|
# Parses a resource definition (as from `invocable_resource`) for any properties which are PowerShell
|
659
680
|
# Credentials. As these values need to be serialized into PSCredential objects, return an array of
|
660
681
|
# PowerShell lines, each of which instantiates a variable which holds the value as a PSCredential.
|
@@ -784,7 +805,11 @@ class Puppet::Provider::DscBaseProvider
|
|
784
805
|
}
|
785
806
|
if resource.key?(:dscmeta_module_version)
|
786
807
|
params[:ModuleName] = {}
|
787
|
-
params[:ModuleName][:ModuleName] =
|
808
|
+
params[:ModuleName][:ModuleName] = if resource[:dscmeta_resource_implementation] == 'Class'
|
809
|
+
resource[:dscmeta_module_name]
|
810
|
+
else
|
811
|
+
"#{resource[:vendored_modules_path]}/#{resource[:dscmeta_module_name]}/#{resource[:dscmeta_module_name]}.psd1"
|
812
|
+
end
|
788
813
|
params[:ModuleName][:RequiredVersion] = resource[:dscmeta_module_version]
|
789
814
|
else
|
790
815
|
params[:ModuleName] = resource[:dscmeta_module_name]
|
@@ -841,13 +866,14 @@ class Puppet::Provider::DscBaseProvider
|
|
841
866
|
# The postscript defines the invocation error and result handling; expects `$InvokeParams` to be defined
|
842
867
|
postscript = File.new("#{template_path}/invoke_dsc_resource_postscript.ps1").read
|
843
868
|
# The blocks define the variables to define for the postscript.
|
869
|
+
module_path_block = munge_psmodulepath(resource)
|
844
870
|
credential_block = prepare_credentials(resource)
|
845
871
|
cim_instances_block = prepare_cim_instances(resource)
|
846
872
|
parameters_block = invoke_params(resource)
|
847
873
|
# clean them out of the temporary cache now that they're not needed; failure to do so can goof up future executions in this run
|
848
874
|
clear_instantiated_variables!
|
849
875
|
|
850
|
-
[functions, preamble, credential_block, cim_instances_block, parameters_block, postscript].join("\n")
|
876
|
+
[functions, preamble, module_path_block, credential_block, cim_instances_block, parameters_block, postscript].join("\n")
|
851
877
|
end
|
852
878
|
|
853
879
|
# Convert a Puppet/Ruby value into a PowerShell representation. Requires some slight additional
|
@@ -115,7 +115,7 @@ Function ConvertTo-CanonicalResult {
|
|
115
115
|
}
|
116
116
|
|
117
117
|
if ($Property.Definition -match 'InstanceArray') {
|
118
|
-
If ($Value.GetType().Name -notmatch '\[\]') { $Value = @($Value) }
|
118
|
+
If ($null -eq $Value -or $Value.GetType().Name -notmatch '\[\]') { $Value = @($Value) }
|
119
119
|
}
|
120
120
|
|
121
121
|
$ResultObject.$PropertyName = $Value
|
@@ -3,6 +3,12 @@ Try {
|
|
3
3
|
} catch {
|
4
4
|
$Response.errormessage = $_.Exception.Message
|
5
5
|
return ($Response | ConvertTo-Json -Compress)
|
6
|
+
} Finally {
|
7
|
+
If (![string]::IsNullOrEmpty($UnmungedPSModulePath)) {
|
8
|
+
# Reset the PSModulePath
|
9
|
+
[System.Environment]::SetEnvironmentVariable('PSModulePath', $UnmungedPSModulePath, [System.EnvironmentVariableTarget]::Machine)
|
10
|
+
$env:PSModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath', 'machine')
|
11
|
+
}
|
6
12
|
}
|
7
13
|
|
8
14
|
# keep the switch for when Test passes back changed properties
|
data/lib/pwsh/version.rb
CHANGED
data/lib/pwsh.rb
CHANGED
@@ -406,7 +406,7 @@ Invoke-PowerShellUserCode @params
|
|
406
406
|
#
|
407
407
|
# @return[String] Unique string representing the manager instance.
|
408
408
|
def self.instance_key(cmd, args, options)
|
409
|
-
cmd + args.join(' ') + options
|
409
|
+
cmd + args.join(' ') + options.to_s
|
410
410
|
end
|
411
411
|
|
412
412
|
# Return whether or not a particular stream is valid and readable
|
data/lib/templates/init.ps1
CHANGED
@@ -35,8 +35,18 @@ $global:ourFunctions = @'
|
|
35
35
|
function Reset-ProcessEnvironmentVariables {
|
36
36
|
param($CachedEnvironmentVariables)
|
37
37
|
|
38
|
+
# When Protected Event Logging and PowerShell Script Block logging are enabled together
|
39
|
+
# the SystemRoot environment variable is a requirement. If it is removed as part of this purge
|
40
|
+
# it causes the PowerShell process to crash, therefore breaking the pipe between Ruby and the
|
41
|
+
# remote PowerShell session.
|
42
|
+
# The least descructive way to avoid this is to filter out SystemRoot when pulling our current list
|
43
|
+
# of environment variables. Then we can continue safely with the removal.
|
44
|
+
$CurrentEnvironmentVariables = Get-ChildItem -Path Env:\* |
|
45
|
+
Where-Object {$_.Name -ne "SystemRoot"}
|
46
|
+
|
38
47
|
# Delete existing environment variables
|
39
|
-
|
48
|
+
$CurrentEnvironmentVariables |
|
49
|
+
ForEach-Object -Process { Remove-Item -Path "ENV:\$($_.Name)" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Recurse }
|
40
50
|
|
41
51
|
# Re-add the cached environment variables
|
42
52
|
$CachedEnvironmentVariables |
|
data/metadata.json
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-pwsh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: PowerShell code manager for ruby.
|
14
14
|
email:
|
@@ -54,7 +54,7 @@ metadata:
|
|
54
54
|
homepage_uri: https://github.com/puppetlabs/ruby-pwsh
|
55
55
|
source_code_uri: https://github.com/puppetlabs/ruby-pwsh
|
56
56
|
changelog_uri: https://github.com/puppetlabs/ruby-pwsh
|
57
|
-
post_install_message:
|
57
|
+
post_install_message:
|
58
58
|
rdoc_options: []
|
59
59
|
require_paths:
|
60
60
|
- lib
|
@@ -69,8 +69,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0'
|
71
71
|
requirements: []
|
72
|
-
rubygems_version: 3.
|
73
|
-
signing_key:
|
72
|
+
rubygems_version: 3.0.3.1
|
73
|
+
signing_key:
|
74
74
|
specification_version: 4
|
75
75
|
summary: PowerShell code manager for ruby.
|
76
76
|
test_files: []
|