puppet-resource_api 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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