ruby-pwsh 0.9.0 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|