ruby-pwsh 1.1.0 → 1.1.1
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ac282abeea132104fda1b3fc2f4743f4b99603cdd6b73a42b7063641c9e65d9
|
4
|
+
data.tar.gz: 410bc1d7a7b08366a89019324b172219102197f8aa6891bcfaa1729e3bd76925
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fd8c7af3f87ce61121a7404b66cfae5cf78fea8bdb885dc7715467bb5092bd974a9fd4d7f94824fe10675d56b4e4dc7b439826f95bc5d9672f14fcb74692501
|
7
|
+
data.tar.gz: 198328e45920aa2794cab2984e090c14c81ce56b4b038e4ae0b7f22ad66d327d0bbd34b5726709108c14609324dba1687a83a2f67026a2d8abf12d749067ca27
|
@@ -44,6 +44,7 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
44
44
|
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
45
45
|
# @param resources [Hash] the hash of the resource to canonicalize from either manifest or invocation
|
46
46
|
# @return [Hash] returns a hash representing the current state of the object, if it exists
|
47
|
+
# rubocop:disable Metrics/BlockLength, Metrics/MethodLength
|
47
48
|
def canonicalize(context, resources)
|
48
49
|
canonicalized_resources = []
|
49
50
|
resources.collect do |r|
|
@@ -83,9 +84,18 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
83
84
|
downcased_result.each do |key, value|
|
84
85
|
# Canonicalize to the manifest value unless the downcased strings match and the attribute is not an enum:
|
85
86
|
# - When the values don't match at all, the manifest value is desired;
|
86
|
-
# - When the values match case insensitively but the attribute is an enum,
|
87
|
-
#
|
88
|
-
|
87
|
+
# - When the values match case insensitively but the attribute is an enum, and the casing from invoke_get_method
|
88
|
+
# is not int the enum, prefer the casing of the manifest enum.
|
89
|
+
# - When the values match case insensitively and the attribute is not an enum, or is an enum and invoke_get_method casing
|
90
|
+
# is in the enum, prefer the casing from invoke_get_method
|
91
|
+
is_enum = enum_attributes(context).include?(key)
|
92
|
+
canonicalized_value_in_enum = if is_enum
|
93
|
+
enum_values(context, key).include?(canonicalized[key])
|
94
|
+
else
|
95
|
+
false
|
96
|
+
end
|
97
|
+
match_insensitively = same?(value, downcased_resource[key])
|
98
|
+
canonicalized[key] = r[key] unless match_insensitively && (canonicalized_value_in_enum || !is_enum)
|
89
99
|
canonicalized.delete(key) unless downcased_resource.key?(key)
|
90
100
|
end
|
91
101
|
# Cache the actually canonicalized resource separately
|
@@ -104,6 +114,7 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
104
114
|
context.debug("Canonicalized Resources: #{canonicalized_resources}")
|
105
115
|
canonicalized_resources
|
106
116
|
end
|
117
|
+
# rubocop:enable Metrics/BlockLength, Metrics/MethodLength
|
107
118
|
|
108
119
|
# Attempts to retrieve an instance of the DSC resource, invoking the `Get` method and passing any
|
109
120
|
# namevars as the Properties to Invoke-DscResource. The result object, if any, is compared to the
|
@@ -299,24 +310,16 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
299
310
|
# notify and retry
|
300
311
|
context.notice("Retrying: attempt #{try} of #{max_retry_count}.")
|
301
312
|
data = JSON.parse(yield)
|
302
|
-
# if no error, break
|
303
|
-
if data['errormessage'].nil?
|
304
|
-
|
305
|
-
#
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
end
|
313
|
-
# if not last attempt, notify, continue and retry
|
314
|
-
context.notice("Attempt #{try} of #{max_retry_count} failed.")
|
315
|
-
next
|
316
|
-
else
|
317
|
-
# if we get an unexpected error, return
|
318
|
-
return context.err(data['errormessage'])
|
319
|
-
end
|
313
|
+
# if no error, assume successful invocation and break
|
314
|
+
break if data['errormessage'].nil?
|
315
|
+
|
316
|
+
# notify of failed retry
|
317
|
+
context.notice("Attempt #{try} of #{max_retry_count} failed.")
|
318
|
+
# return if error does not match expceted error, or all retries exhausted
|
319
|
+
return context.err(data['errormessage']) unless data['errormessage'].match?(error_matcher) && try < max_retry_count
|
320
|
+
|
321
|
+
# else, retry
|
322
|
+
next
|
320
323
|
end
|
321
324
|
data
|
322
325
|
end
|
@@ -348,7 +351,7 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
348
351
|
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
349
352
|
# @param name_hash [Hash] the hash of namevars to be passed as properties to `Invoke-DscResource`
|
350
353
|
# @return [Hash] returns a hash representing the DSC resource munged to the representation the Puppet Type expects
|
351
|
-
def invoke_get_method(context, name_hash)
|
354
|
+
def invoke_get_method(context, name_hash) # rubocop:disable Metrics/AbcSize
|
352
355
|
context.debug("retrieving #{name_hash.inspect}")
|
353
356
|
|
354
357
|
query_props = name_hash.select { |k, v| mandatory_get_attributes(context).include?(k) || (k == :dsc_psdscrunascredential && !v.nil?) }
|
@@ -391,6 +394,8 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
391
394
|
# If a resource is found, it's present, so refill this Puppet-only key
|
392
395
|
data[:name] = name_hash[:name]
|
393
396
|
|
397
|
+
data = stringify_nil_attributes(context, data)
|
398
|
+
|
394
399
|
# Have to check for this to avoid a weird canonicalization warning
|
395
400
|
# The Resource API calls canonicalize against the current state which
|
396
401
|
# will lead to dsc_ensure being set to absent in the name_hash even if
|
@@ -660,6 +665,20 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
660
665
|
context.type.attributes.select { |_attribute, properties| properties[:mandatory_for_set] }.keys
|
661
666
|
end
|
662
667
|
|
668
|
+
# Parses the DSC resource type definition to retrieve the names of any attributes which are specifed as required strings
|
669
|
+
# This is used to ensure that any nil values are converted to empty strings to match puppets expecetd value
|
670
|
+
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
671
|
+
# @param data [Hash] the hash of properties returned from the DSC resource
|
672
|
+
# @return [Hash] returns a data hash with any nil values converted to empty strings
|
673
|
+
def stringify_nil_attributes(context, data)
|
674
|
+
nil_strings = data.select { |_name, value| value.nil? }.keys
|
675
|
+
string_attrs = context.type.attributes.select { |_name, properties| properties[:type] == 'String' }.keys
|
676
|
+
string_attrs.each do |attribute|
|
677
|
+
data[attribute] = '' if nil_strings.include?(attribute)
|
678
|
+
end
|
679
|
+
data
|
680
|
+
end
|
681
|
+
|
663
682
|
# Parses the DSC resource type definition to retrieve the names of any attributes which are specified as namevars
|
664
683
|
#
|
665
684
|
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
@@ -686,6 +705,28 @@ class Puppet::Provider::DscBaseProvider # rubocop:disable Metrics/ClassLength
|
|
686
705
|
context.type.attributes.select { |_name, properties| properties[:type].include?('Enum[') }.keys
|
687
706
|
end
|
688
707
|
|
708
|
+
# Parses the DSC resource type definition to retrieve the values of any attributes which are specified as enums
|
709
|
+
#
|
710
|
+
# @param context [Object] the Puppet runtime context to operate in and send feedback to
|
711
|
+
# @param attribute [String] the enum attribute to retrieve the allowed values from
|
712
|
+
# @return [Array] returns an array of attribute names as symbols which are enums
|
713
|
+
def enum_values(context, attribute)
|
714
|
+
# Get the attribute's type string for the given key
|
715
|
+
type_string = context.type.attributes[attribute][:type]
|
716
|
+
|
717
|
+
# Return an empty array if the key doesn't have an Enum type or doesn't exist
|
718
|
+
return [] unless type_string&.include?('Enum[')
|
719
|
+
|
720
|
+
# Extract the enum values from the type string
|
721
|
+
enum_content = type_string.match(/Enum\[(.*?)\]/)&.[](1)
|
722
|
+
|
723
|
+
# Return an empty array if we couldn't find the enum values
|
724
|
+
return [] if enum_content.nil?
|
725
|
+
|
726
|
+
# Return an array of the enum values, stripped of extra whitespace and quote marks
|
727
|
+
enum_content.split(',').map { |val| val.strip.delete('\'') }
|
728
|
+
end
|
729
|
+
|
689
730
|
# Look through a fully formatted string, replacing all instances where a value matches the formatted properties
|
690
731
|
# of an instantiated variable with references to the variable instead. This allows us to pass complex and nested
|
691
732
|
# CIM instances to the Invoke-DscResource parameter hash without constructing them *in* the hash.
|
data/lib/pwsh/version.rb
CHANGED
@@ -179,6 +179,8 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
179
179
|
end
|
180
180
|
|
181
181
|
it 'treats the manifest value as canonical' do
|
182
|
+
expect(context).to receive(:type).and_return(type)
|
183
|
+
expect(type).to receive(:attributes).and_return({ dsc_property: { type: "Enum['Dword']" } })
|
182
184
|
expect(canonicalized_resource.first[:dsc_property]).to eq('Dword')
|
183
185
|
end
|
184
186
|
end
|
@@ -812,9 +814,9 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
812
814
|
.exactly(5).times
|
813
815
|
expect(context).to receive(:notice).with(/Invoke-DscResource collision detected: Please stagger the timing of your Puppet runs as this can lead to unexpected behaviour./).once
|
814
816
|
expect(context).to receive(:notice).with('Sleeping for 60 seconds.').exactly(5).times
|
815
|
-
expect(context).to receive(:notice).with(/Retrying: attempt [1-
|
817
|
+
expect(context).to receive(:notice).with(/Retrying: attempt [1-5] of 5/).exactly(5).times
|
816
818
|
expect(ps_manager).to receive(:execute).and_return({ stdout: '{"errormessage": "The Invoke-DscResource cmdlet is in progress and must return before Invoke-DscResource can be invoked"}' })
|
817
|
-
expect(context).to receive(:notice).with(/Attempt [1-
|
819
|
+
expect(context).to receive(:notice).with(/Attempt [1-5] of 5 failed/).exactly(5).times
|
818
820
|
expect(context).to receive(:err).with(/The Invoke-DscResource cmdlet is in progress and must return before Invoke-DscResource can be invoked/)
|
819
821
|
allow(provider).to receive(:sleep)
|
820
822
|
expect(result).to be_nil
|
@@ -827,6 +829,7 @@ RSpec.describe Puppet::Provider::DscBaseProvider do
|
|
827
829
|
expect(context).to receive(:notice).with(/Retrying: attempt 1 of 5/).once
|
828
830
|
allow(provider).to receive(:sleep)
|
829
831
|
expect(ps_manager).to receive(:execute).and_return({ stdout: '{"errormessage": "Some unexpected error"}' }).once
|
832
|
+
expect(context).to receive(:notice).with(/Attempt 1 of 5 failed/).once
|
830
833
|
expect(context).to receive(:err).with(/Some unexpected error/)
|
831
834
|
expect(result).to be_nil
|
832
835
|
end
|
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: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: PowerShell code manager for ruby.
|
14
14
|
email:
|