puppet-resource_api 1.0.3 → 1.1.0

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: 3c0802c277632a57802c1b44466a56470474357dea596c39472c7e23a592aab9
4
- data.tar.gz: 66b3de030a9a2b91a2abac411d46e803152e973a10235eaf09c1b3381b41a184
3
+ metadata.gz: 1470bc0d22d986fc0eccd0580a072ea54f6482b3c830f994b2d83f230ba95b22
4
+ data.tar.gz: 1346ed773c82d9478dbbcd243f5fe4b1260c487b7b17f971268801bd772c7f83
5
5
  SHA512:
6
- metadata.gz: c16aea1e79a69f0c6112812c1f5e89884899064ffdcf31c7c2a9567e776435244646a3d0111c3c29acf64cfee8ce061f3684ef012edb7af574615aef910b2cb2
7
- data.tar.gz: 7e719c49452ddea14cabddaf3702eac1e15da5717138ce732be25c0f57b6c649df1f2702869adf3265b002fb83ca78f6df7b5671350119ea8b6fdc62f9eb2415
6
+ metadata.gz: 1f521be6aa211b933e12f712be3af9226af5d5d9df4a8bec2ca075e0faedd5898c7a9d1150024784c8e71c27bcbd996c34b010ecd656e15cf314e40014bb86ed
7
+ data.tar.gz: 6a473b6d9eb96158008dfc4622da547026f01c3fbe492689fb9478179f645338b8b264b693fdfd6451491fd432d025b05026a5c245db374078222e668241f0cc
@@ -3,6 +3,24 @@
3
3
  All significant changes to this repo will be summarized in this file.
4
4
 
5
5
 
6
+ ## [v1.1.0](https://github.com/puppetlabs/puppet-resource_api/tree/v1.1.0) (2018-04-12)
7
+ [Full Changelog](https://github.com/puppetlabs/puppet-resource_api/compare/v1.0.3...v1.1.0)
8
+
9
+ **Implemented enhancements:**
10
+
11
+ - \(PDK-895\) basic array support [\#59](https://github.com/puppetlabs/puppet-resource_api/pull/59) ([DavidS](https://github.com/DavidS))
12
+
13
+ **Fixed bugs:**
14
+
15
+ - \(PDK-919\) Workaround PUP-2368 "using booleans result in unmanaged pro… [\#62](https://github.com/puppetlabs/puppet-resource_api/pull/62) ([DavidS](https://github.com/DavidS))
16
+
17
+ **Merged pull requests:**
18
+
19
+ - \(PDK-526\) do not rely on git when building the gem on jenkins [\#61](https://github.com/puppetlabs/puppet-resource_api/pull/61) ([DavidS](https://github.com/DavidS))
20
+ - \(PDK-896\) Advanced Array tests [\#60](https://github.com/puppetlabs/puppet-resource_api/pull/60) ([DavidS](https://github.com/DavidS))
21
+ - Update puppetlabs\_spec\_helper to fixed master version [\#58](https://github.com/puppetlabs/puppet-resource_api/pull/58) ([DavidS](https://github.com/DavidS))
22
+ - Release prep for v1.0.3 [\#57](https://github.com/puppetlabs/puppet-resource_api/pull/57) ([DavidS](https://github.com/DavidS))
23
+
6
24
  ## [v1.0.3](https://github.com/puppetlabs/puppet-resource_api/tree/v1.0.3) (2018-04-06)
7
25
  [Full Changelog](https://github.com/puppetlabs/puppet-resource_api/compare/v1.0.2...v1.0.3)
8
26
 
data/Gemfile CHANGED
@@ -16,7 +16,7 @@ group :tests do
16
16
  gem 'rubocop'
17
17
  gem 'simplecov-console'
18
18
  # the test gems required for module testing
19
- gem 'puppetlabs_spec_helper', github: 'DavidS/puppetlabs_spec_helper', ref: 'refactor'
19
+ gem 'puppetlabs_spec_helper', '~> 2.7'
20
20
  gem 'rspec-puppet'
21
21
  end
22
22
 
data/README.md CHANGED
@@ -191,11 +191,12 @@ This gem is still under heavy development. This section is a living document of
191
191
  Currently working:
192
192
  * Basic type and provider definition, using `name`, `desc`, and `attributes`.
193
193
  * Scalar puppet 4 [data types](https://puppet.com/docs/puppet/5.3/lang_data_type.html#core-data-types):
194
- * String
194
+ * String, Enum, Pattern
195
195
  * Integer, Float, Numeric
196
196
  * Boolean
197
- * Enum[absent, present]
198
- * simple Optionals
197
+ * Array
198
+ * Optional
199
+ * Variant
199
200
  * The `canonicalize`, `simple_get_filter`, and `remote_resource` features.
200
201
  * All the logging facilities.
201
202
  * Executing the new provider under the following commands:
@@ -205,7 +206,7 @@ Currently working:
205
206
  * `puppet device` (if applicable)
206
207
 
207
208
  There are still a few notable gaps between the implementation and the specification:
208
- * Complex data types, like Array, Hash, Tuple or Struct are not yet implemented.
209
+ * Complex data types, like Hash, Tuple or Struct are not yet implemented.
209
210
  * Only a single runtime environment (the Puppet commands) is currently implemented.
210
211
 
211
212
  Restrictions of running under puppet:
@@ -9,17 +9,6 @@ install:
9
9
  - set PATH=C:\Ruby%RUBY_VERSION%\bin;C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
10
10
  - SET LOG_SPEC_ORDER=true
11
11
  - SET COVERAGE=yes
12
- # Due to a bug in the version of OpenSSL shipped with Ruby 2.4.1 on Windows
13
- # (https://bugs.ruby-lang.org/issues/11033). Errors are ignored because the
14
- # mingw gem calls out to pacman to install OpenSSL which is already
15
- # installed, causing gem to raise a warning that powershell determines to be
16
- # a fatal error.
17
- - ps: |
18
- $ErrorActionPreference = "SilentlyContinue"
19
- if($env:RUBY_VERSION -eq "24-x64") {
20
- gem install openssl "~> 2.0.4" --no-rdoc --no-ri -- --with-openssl-dir=C:\msys64\mingw64
21
- }
22
- $host.SetShouldExit(0)
23
12
  - bundle install --jobs 4 --retry 2 --without development
24
13
 
25
14
  build: off
@@ -145,26 +145,46 @@ module Puppet::ResourceApi
145
145
  end
146
146
 
147
147
  type = Puppet::Pops::Types::TypeParser.singleton.parse(options[:type])
148
- validate do |value|
149
- if options[:behaviour] == :read_only
150
- raise Puppet::ResourceError, "Attempting to set `#{name}` read_only attribute value to `#{value}`"
148
+ if param_or_property == :newproperty
149
+ define_method(:should) do
150
+ if type.is_a? Puppet::Pops::Types::PBooleanType
151
+ # work around https://tickets.puppetlabs.com/browse/PUP-2368
152
+ rs_value ? :true : :false # rubocop:disable Lint/BooleanSymbol
153
+ else
154
+ rs_value
155
+ end
156
+ end
157
+
158
+ define_method(:should=) do |value|
159
+ @shouldorig = value
160
+ # Puppet requires the @should value to always be stored as an array. We do not use this
161
+ # for anything else
162
+ # @see Puppet::Property.should=(value)
163
+ @should = [Puppet::ResourceApi.mungify(type, value, "#{definition[:name]}.#{name}")]
151
164
  end
152
165
 
153
- return true if type.instance?(value)
166
+ # used internally
167
+ # @returns the final mungified value of this property
168
+ define_method(:rs_value) do
169
+ @should ? @should.first : @should
170
+ end
171
+ else
172
+ define_method(:value) do
173
+ @value
174
+ end
154
175
 
155
- if value.is_a? String
156
- # when running under `puppet resource`, we need to try to coerce from strings to the real type
157
- case value
158
- when %r{^-?\d+$}, Puppet::Pops::Patterns::NUMERIC
159
- value = Puppet::Pops::Utils.to_n(value)
160
- when %r{\Atrue|false\Z}
161
- value = value == 'true'
176
+ define_method(:value=) do |value|
177
+ if options[:behaviour] == :read_only
178
+ raise Puppet::ResourceError, "Attempting to set `#{name}` read_only attribute value to `#{value}`"
162
179
  end
163
- return true if type.instance?(value)
164
180
 
165
- inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
166
- error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("#{definition[:name]}.#{name}", type, inferred_type)
167
- raise Puppet::ResourceError, error_msg
181
+ @value = Puppet::ResourceApi.mungify(type, value, "#{definition[:name]}.#{name}")
182
+ end
183
+
184
+ # used internally
185
+ # @returns the final mungified value of this parameter
186
+ define_method(:rs_value) do
187
+ @value
168
188
  end
169
189
  end
170
190
 
@@ -172,49 +192,40 @@ module Puppet::ResourceApi
172
192
  type = type.type
173
193
  end
174
194
 
175
- # provide better handling of the standard types
195
+ # puppet symbolizes some values through puppet/parameter/value.rb (see .convert()), but (especially) Enums
196
+ # are strings. specifying a munge block here skips the value_collection fallback in puppet/parameter.rb's
197
+ # default .unsafe_munge() implementation.
198
+ munge { |v| v }
199
+
200
+ # provide hints to `puppet type generate` for better parsing
176
201
  case type
177
202
  when Puppet::Pops::Types::PStringType
178
203
  # require any string value
179
204
  Puppet::ResourceApi.def_newvalues(self, param_or_property, %r{})
180
- # rubocop:disable Lint/BooleanSymbol
181
205
  when Puppet::Pops::Types::PBooleanType
182
206
  Puppet::ResourceApi.def_newvalues(self, param_or_property, 'true', 'false')
207
+ # rubocop:disable Lint/BooleanSymbol
183
208
  aliasvalue true, 'true'
184
209
  aliasvalue false, 'false'
185
210
  aliasvalue :true, 'true'
186
211
  aliasvalue :false, 'false'
187
-
188
- munge do |v|
189
- case v
190
- when 'true', :true
191
- true
192
- when 'false', :false
193
- false
194
- else
195
- v
196
- end
197
- end
198
- # rubocop:enable Lint/BooleanSymbol
212
+ # rubocop:enable Lint/BooleanSymbol
199
213
  when Puppet::Pops::Types::PIntegerType
200
214
  Puppet::ResourceApi.def_newvalues(self, param_or_property, %r{^-?\d+$})
201
- munge do |v|
202
- Puppet::Pops::Utils.to_n(v)
203
- end
204
215
  when Puppet::Pops::Types::PFloatType, Puppet::Pops::Types::PNumericType
205
216
  Puppet::ResourceApi.def_newvalues(self, param_or_property, Puppet::Pops::Patterns::NUMERIC)
206
- munge do |v|
207
- Puppet::Pops::Utils.to_n(v)
208
- end
217
+ end
218
+
219
+ if param_or_property == :newproperty
220
+ # stop puppet from trying to call into the provider when
221
+ # no pre-defined values have been specified
222
+ # "This is not the provider you are looking for." -- Obi-Wan Kaniesobi.
223
+ def call_provider(value); end
209
224
  end
210
225
 
211
226
  case options[:type]
212
227
  when 'Enum[present, absent]'
213
228
  Puppet::ResourceApi.def_newvalues(self, param_or_property, 'absent', 'present')
214
- # puppet symbolizes these values through puppet/paramter/value.rb (see .convert()), but Enums are strings
215
- # specifying a munge block here skips the value_collection fallback in puppet/parameter.rb's
216
- # default .unsafe_munge() implementation
217
- munge { |v| v }
218
229
  end
219
230
  end
220
231
  end
@@ -266,9 +277,8 @@ module Puppet::ResourceApi
266
277
 
267
278
  define_method(:flush) do
268
279
  # puts 'flush'
269
- target_state = Hash[@parameters.map { |k, v| [k, v.value] }]
270
- # remove puppet's injected metaparams
271
- target_state.delete(:loglevel)
280
+ # skip puppet's injected metaparams
281
+ target_state = Hash[@parameters.reject { |k, _v| [:loglevel, :noop].include? k }.map { |k, v| [k, v.rs_value] }]
272
282
  target_state = my_provider.canonicalize(context, [target_state]).first if feature_support?('canonicalize')
273
283
 
274
284
  retrieve unless @rapi_current_state
@@ -385,4 +395,87 @@ MESSAGE
385
395
  end
386
396
  end
387
397
  end
398
+
399
+ # Validates and munges values coming from puppet into a shape palatable to the provider.
400
+ # This includes parsing values from strings, e.g. when running in `puppet resource`.
401
+ # @param type[Puppet::Pops::Types::TypedModelObject] the type to check/clean against
402
+ # @param value the value to clean
403
+ # @param error_msg_prefix[String] a prefix for the error messages
404
+ # @return [type] the cleaned value
405
+ # @raise [Puppet::ResourceError] if `value` could not be parsed into `type`
406
+ def self.mungify(type, value, error_msg_prefix)
407
+ cleaned_value, error = try_mungify(type, value, error_msg_prefix)
408
+
409
+ raise Puppet::ResourceError, error if error
410
+
411
+ cleaned_value
412
+ end
413
+
414
+ # Recursive implementation part of #mungify. Uses a multi-valued return value to avoid excessive
415
+ # exception throwing for regular usage
416
+ # @return [Array] if the mungify worked, the first element is the cleaned value, and the second
417
+ # element is nil. If the mungify failed, the first element is nil, and the second element is an error
418
+ # message
419
+ # @private
420
+ def self.try_mungify(type, value, error_msg_prefix)
421
+ case type
422
+ when Puppet::Pops::Types::PArrayType
423
+ if value.is_a? Array
424
+ conversions = value.map do |v|
425
+ try_mungify(type.element_type, v, error_msg_prefix)
426
+ end
427
+ # only convert the values if none failed. otherwise fall through and rely on puppet to render a proper error
428
+ if conversions.all? { |c| c[1].nil? }
429
+ value = conversions.map { |c| c[0] }
430
+ end
431
+ end
432
+ when Puppet::Pops::Types::PBooleanType
433
+ value = case value
434
+ when 'true', :true # rubocop:disable Lint/BooleanSymbol
435
+ true
436
+ when 'false', :false # rubocop:disable Lint/BooleanSymbol
437
+ false
438
+ else
439
+ value
440
+ end
441
+ when Puppet::Pops::Types::PIntegerType, Puppet::Pops::Types::PFloatType, Puppet::Pops::Types::PNumericType
442
+ if value =~ %r{^-?\d+$} || value =~ Puppet::Pops::Patterns::NUMERIC
443
+ value = Puppet::Pops::Utils.to_n(value)
444
+ end
445
+ when Puppet::Pops::Types::PEnumType, Puppet::Pops::Types::PStringType, Puppet::Pops::Types::PPatternType
446
+ if value.is_a? Symbol
447
+ value = value.to_s
448
+ end
449
+ when Puppet::Pops::Types::POptionalType
450
+ return value.nil? ? [nil, nil] : try_mungify(type.type, value, error_msg_prefix)
451
+ when Puppet::Pops::Types::PVariantType
452
+ # try converting to anything except string first
453
+ string_type = type.types.find { |t| t.is_a? Puppet::Pops::Types::PStringType }
454
+ conversion_results = (type.types - [string_type]).map do |t|
455
+ try_mungify(t, value, error_msg_prefix)
456
+ end
457
+
458
+ # only consider valid results
459
+ conversion_results = conversion_results.select { |r| r[1].nil? }.to_a
460
+
461
+ # use the conversion result if unambiguous
462
+ return conversion_results[0] if conversion_results.length == 1
463
+
464
+ # return an error if ambiguous
465
+ return [nil, "#{error_msg_prefix} #{value.inspect} is not unabiguously convertable to #{type}"] if conversion_results.length > 1
466
+
467
+ # try to interpret as string
468
+ return try_mungify(string_type, value, error_msg_prefix) if string_type
469
+
470
+ # fall through to default handling
471
+ end
472
+
473
+ # a match!
474
+ return [value, nil] if type.instance?(value)
475
+
476
+ # an error :-(
477
+ inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
478
+ error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(error_msg_prefix, type, inferred_type)
479
+ return [nil, error_msg] # the entire function is using returns for clarity # rubocop:disable Style/RedundantReturn
480
+ end
388
481
  end
@@ -1,5 +1,5 @@
1
1
  module Puppet
2
2
  module ResourceApi
3
- VERSION = '1.0.3'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
5
5
  end
@@ -11,9 +11,15 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = 'This library provides a simple way to write new native resources for puppet.'
12
12
  spec.homepage = 'https://github.com/puppetlabs/puppet-resource_api'
13
13
 
14
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
- f.match(%r{^(test|spec|features)/})
16
- end
14
+ # on out internal jenkins, there is no `.git` directory, but since it is a clean machine, we don't need to worry about anything else
15
+ spec.files = if Dir.exist?('.git')
16
+ `git ls-files -z`.split("\x0")
17
+ else
18
+ Dir.glob('**/*')
19
+ end.reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+
17
23
  spec.bindir = 'exe'
18
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
25
  spec.require_paths = ['lib']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-resource_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Schmitt
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-06 00:00:00.000000000 Z
11
+ date: 2018-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hocon