puppet-resource_api 1.6.5 → 1.7.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: 160e4e687bacbb19cddb0b34398c6caa72ba308707a3718487c2fd4c86040804
4
- data.tar.gz: ece23bfd962d5f97f34690bcdb02dbbaeb64d8109b65e5044396bfebb13328fb
3
+ metadata.gz: c26bda3effbce092aa8b8defb8904fdb41a02231fba2830593bfc85413b66906
4
+ data.tar.gz: 89b49840bd21ea57227db05021e0b9ddb7ab7539b9b130a888e3fea99b7da87e
5
5
  SHA512:
6
- metadata.gz: '0888ca950e55d91f308274aab1d97ee46e6f5f924fad3b6abb150721012516f71afc740e6d4a297b188938f63416812d429e4e236908109d254ff9daf0a19a13'
7
- data.tar.gz: 94df73da789c0808562408becc35d38ee55d8a5447db00b91999475362819508531b3e59dca2d96d7928bfff61e40447c568168c859beb9b2fe7ccf79d93ac4d
6
+ metadata.gz: 971775219d3ae76f94a18ebef57b0a1be470a0c222b31a4a1cf0d1d4b8f4ecc71516fb6b004674a4878c619d97f4b6f3e644edcc43e3cba419070afd5ad53bd3
7
+ data.tar.gz: dfb2823ce573240977587f9a7431b1956a62a0367a740d4e0c9fc412436542d41065be88e7ed8348057fd42b1cf039c4ac69c8e4b7bad7f4771d73c2f6927454
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
- --order rand
3
+ --order rand
data/.travis.yml CHANGED
@@ -14,13 +14,13 @@ branches:
14
14
  matrix:
15
15
  include:
16
16
  - rvm: 2.4.3
17
- env: PUPPET_GEM_VERSION='~> 5' SIMPLECOV=yes # 5.5
18
- - env: RVM="jruby-1.7.26" PUPPET_GEM_VERSION='~> 5' JRUBY_OPTS="--debug" SIMPLECOV=yes
17
+ env: PUPPET_GEM_VERSION='~> 5' COVERAGE=yes # 5.5
18
+ - env: RVM="jruby-1.7.26" PUPPET_GEM_VERSION='~> 5' JRUBY_OPTS="--debug" COVERAGE=yes
19
19
  before_cache: pushd ~/.rvm && rm -rf archives rubies/ruby-2.2.7 rubies/ruby-2.3.4 && popd
20
20
  cache:
21
21
  bundler: true
22
22
  directories: ~/.rvm
23
- before_install: rvm use jruby-1.7.26 --install --binary --fuzzy && gem install bundler -v '~> 1.7.0'
23
+ before_install: rvm use jruby-1.7.26 --install --binary --fuzzy
24
24
  # disable coverage on jruby9k as this confuses codecov
25
25
  - env: RVM="jruby-9.1.9.0" PUPPET_GEM_VERSION='~> 5' JRUBY_OPTS="--debug"
26
26
  before_cache: pushd ~/.rvm && rm -rf archives rubies/ruby-2.2.7 rubies/ruby-2.3.4 && popd
@@ -28,9 +28,9 @@ matrix:
28
28
  bundler: true
29
29
  directories: ~/.rvm
30
30
  before_install: rvm use jruby-9.1.9.0 --install --binary --fuzzy
31
- - rvm: 2.5.1
31
+ - rvm: 2.4.3
32
32
  env: CHECK=rubocop
33
- - rvm: 2.5.1
33
+ - rvm: 2.4.3
34
34
  env: CHECK=license_finder
35
35
  bundler_args: ""
36
36
 
@@ -45,25 +45,25 @@ matrix:
45
45
  - rvm: 2.4.1
46
46
  env: PUPPET_GEM_VERSION='~> 5.0.0'
47
47
  - rvm: 2.1.9
48
- env: PUPPET_GEM_VERSION='~> 4' SIMPLECOV=yes # 4.10
48
+ env: PUPPET_GEM_VERSION='~> 4' COVERAGE=yes # 4.10
49
+ before_install:
50
+ - gem install bundler -v '< 2'
49
51
  - rvm: 2.1.9
50
52
  env: PUPPET_GEM_VERSION='~> 4.9.0'
53
+ before_install:
54
+ - gem install bundler -v '< 2'
51
55
  - rvm: 2.1.9
52
56
  env: PUPPET_GEM_VERSION='~> 4.8.0'
57
+ before_install:
58
+ - gem install bundler -v '< 2'
53
59
  - rvm: 2.1.9
54
60
  env: PUPPET_GEM_VERSION='~> 4.7.0'
55
- - rvm: 2.5.1
56
- env: PUPPET_GEM_VERSION='~> 6' # 6.0, soon 6.1
57
- - rvm: 2.5.1
58
- env: PUPPET_GEM_VERSION='~> 6.0'
61
+ before_install:
62
+ - gem install bundler -v '< 2'
59
63
  - rvm: 2.5.1
60
64
  env: PUPPET_GEM_VERSION='https://github.com/puppetlabs/puppet.git#master'
61
65
  - rvm: 2.5.1
62
66
  env: PUPPET_GEM_VERSION='https://github.com/puppetlabs/puppet.git#6.0.x'
63
- - rvm: 2.4.3
64
- env: PUPPET_GEM_VERSION='https://github.com/puppetlabs/puppet.git#5.5.x'
65
- - rvm: 2.1.9
66
- env: PUPPET_GEM_VERSION='https://github.com/puppetlabs/puppet.git#4.10.x'
67
67
  notifications:
68
68
  hipchat:
69
69
  rooms:
data/Gemfile CHANGED
@@ -7,27 +7,18 @@ gemspec
7
7
 
8
8
  group :tests do
9
9
  gem 'codecov'
10
+ # license_finder does not install on windows using older versions of rubygems.
11
+ # ruby 2.4 is confirmed working on appveyor.
12
+ gem 'license_finder' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
10
13
  gem 'rake', '~> 10.0'
11
14
  gem 'rspec', '~> 3.0'
15
+ gem 'rubocop-rspec'
12
16
  # rubocop 0.58 throws when testing against ruby 2.1, so pin to the latest,
13
17
  # unless we're dealing with jruby...
14
18
  if RUBY_PLATFORM == 'java'
15
- # load a rubocop version that works on java for the Rakefile
16
- gem 'parser', '2.3.3.1'
17
- gem 'rubocop', '0.41.2'
18
- elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.0')
19
- gem 'rubocop', '0.57.2'
20
- # the last version of parallel to support ruby 2.1
21
- gem 'parallel', '1.13.0'
22
- gem 'rubocop-rspec'
19
+ gem 'rubocop'
23
20
  else
24
- # 2.1-compatible analysis was dropped after version 0.58
25
- # This needs to be removed once we drop puppet4 support.
26
- gem 'rubocop', '~> 0.57.0'
27
- gem 'rubocop-rspec'
28
- # license_finder does not install on windows using older versions of rubygems.
29
- # ruby 2.4 is confirmed working on appveyor.
30
- gem 'license_finder' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
21
+ gem 'rubocop', '0.57.2'
31
22
  end
32
23
  gem 'simplecov-console'
33
24
  # the test gems required for module testing
data/README.md CHANGED
@@ -231,6 +231,12 @@ Future possibilities:
231
231
  * [Multiple Providers](https://tickets.puppetlabs.com/browse/PDK-530)
232
232
  * [Commands API](https://tickets.puppetlabs.com/browse/PDK-847)
233
233
 
234
+ ## Development
235
+
236
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
237
+
238
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
239
+
234
240
  ## Contributing
235
241
 
236
242
  Bug reports and pull requests are welcome on GitHub at https://github.com/puppetlabs/puppet-resource_api.
data/Rakefile CHANGED
@@ -14,30 +14,22 @@ end
14
14
  require 'rspec/core/rake_task'
15
15
 
16
16
  RSpec::Core::RakeTask.new(:spec) do |t|
17
+ Rake::Task[:spec_prep].invoke
17
18
  # thanks to the fixtures/modules/ symlinks this needs to exclude fixture modules explicitely
18
19
  excludes = ['fixtures/**/*.rb,fixtures/modules/*/**/*.rb']
19
20
  if RUBY_PLATFORM == 'java'
20
21
  excludes += ['acceptance/**/*.rb', 'integration/**/*.rb', 'puppet/resource_api/*_context_spec.rb', 'puppet/util/network_device/simple/device_spec.rb']
21
22
  t.rspec_opts = '--tag ~agent_test'
22
- t.rspec_opts << ' --tag ~j17_exclude' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0')
23
23
  end
24
24
  t.exclude_pattern = "spec/{#{excludes.join ','}}"
25
25
  end
26
26
 
27
- task :spec => :spec_prep
28
-
29
27
  namespace :spec do
30
28
  desc 'Run RSpec code examples with coverage collection'
31
29
  task :coverage do
32
- ENV['SIMPLECOV'] = 'yes'
30
+ ENV['COVERAGE'] = 'yes'
33
31
  Rake::Task['spec'].execute
34
32
  end
35
-
36
- RSpec::Core::RakeTask.new(:unit) do |t|
37
- t.pattern = "spec/puppet/**/*_spec.rb,spec/integration/**/*_spec.rb"
38
- end
39
-
40
- task :unit => :spec_prep
41
33
  end
42
34
 
43
35
  #### LICENSE_FINDER ####
@@ -19,43 +19,9 @@ module Puppet::ResourceApi
19
19
  end
20
20
 
21
21
  def register_type(definition)
22
- raise Puppet::DevError, 'requires a hash as definition, not `%{other_type}`' % { other_type: definition.class } unless definition.is_a? Hash
23
- raise Puppet::DevError, 'requires a `:name`' unless definition.key? :name
24
- raise Puppet::DevError, 'requires `:attributes`' unless definition.key? :attributes
25
- raise Puppet::DevError, '`:attributes` must be a hash, not `%{other_type}`' % { other_type: definition[:attributes].class } unless definition[:attributes].is_a?(Hash)
26
- [:title, :provider, :alias, :audit, :before, :consume, :export, :loglevel, :noop, :notify, :require, :schedule, :stage, :subscribe, :tag].each do |name|
27
- raise Puppet::DevError, 'must not define an attribute called `%{name}`' % { name: name.inspect } if definition[:attributes].key? name
28
- end
29
- if definition.key?(:title_patterns) && !definition[:title_patterns].is_a?(Array)
30
- raise Puppet::DevError, '`:title_patterns` must be an array, not `%{other_type}`' % { other_type: definition[:title_patterns].class }
31
- end
32
-
33
- Puppet::ResourceApi::DataTypeHandling.validate_ensure(definition)
34
-
35
- definition[:features] ||= []
36
- supported_features = %w[supports_noop canonicalize remote_resource simple_get_filter].freeze
37
- unknown_features = definition[:features] - supported_features
38
- Puppet.warning("Unknown feature detected: #{unknown_features.inspect}") unless unknown_features.empty?
39
-
40
- # fixup desc/docs backwards compatibility
41
- if definition.key? :docs
42
- if definition[:desc]
43
- raise Puppet::DevError, '`%{name}` has both `desc` and `docs`, prefer using `desc`' % { name: definition[:name] }
44
- end
45
- definition[:desc] = definition[:docs]
46
- definition.delete(:docs)
47
- end
48
- Puppet.warning('`%{name}` has no documentation, add it using a `desc` key' % { name: definition[:name] }) unless definition.key? :desc
49
-
50
- # fixup any weird behavior ;-)
51
- definition[:attributes].each do |name, attr|
52
- next unless attr[:behavior]
53
- if attr[:behaviour]
54
- raise Puppet::DevError, "the '#{name}' attribute has both a `behavior` and a `behaviour`, only use one"
55
- end
56
- attr[:behaviour] = attr[:behavior]
57
- attr.delete(:behavior)
58
- end
22
+ # Attempt to create a TypeDefinition from the input hash
23
+ # This will validate and throw if its not right
24
+ type_def = TypeDefinition.new(definition)
59
25
 
60
26
  # prepare the ruby module for the provider
61
27
  # this has to happen before Puppet::Type.newtype starts autoloading providers
@@ -66,7 +32,8 @@ module Puppet::ResourceApi
66
32
  end
67
33
 
68
34
  Puppet::Type.newtype(definition[:name].to_sym) do
69
- @docs = definition[:desc]
35
+ @docs = definition[:docs]
36
+ @type_definition = type_def
70
37
 
71
38
  # Keeps a copy of the provider around. Weird naming to avoid clashes with puppet's own `provider` member
72
39
  define_singleton_method(:my_provider) do
@@ -80,7 +47,7 @@ module Puppet::ResourceApi
80
47
  end
81
48
 
82
49
  define_singleton_method(:type_definition) do
83
- @type_definition ||= TypeDefinition.new(definition)
50
+ @type_definition
84
51
  end
85
52
 
86
53
  def type_definition
@@ -91,7 +58,7 @@ module Puppet::ResourceApi
91
58
  apply_to_device
92
59
  end
93
60
 
94
- def initialize(attributes)
61
+ define_method(:initialize) do |attributes|
95
62
  # $stderr.puts "A: #{attributes.inspect}"
96
63
  if attributes.is_a? Puppet::Resource
97
64
  @title = attributes.title
@@ -119,7 +86,7 @@ module Puppet::ResourceApi
119
86
  # the `Puppet::Resource::Ral.find` method, when `instances` does not return a match, uses a Hash with a `:name` key to create
120
87
  # an "absent" resource. This is often hit by `puppet resource`. This needs to work, even if the namevar is not called `name`.
121
88
  # This bit here relies on the default `title_patterns` (see below) to match the title back to the first (and often only) namevar
122
- if type_definition.attributes[:name].nil? && attributes[:title].nil?
89
+ if definition[:attributes][:name].nil? && attributes[:title].nil?
123
90
  attributes[:title] = attributes.delete(:name)
124
91
  if attributes[:title].nil? && !type_definition.namevars.empty?
125
92
  attributes[:title] = @title
@@ -133,25 +100,11 @@ module Puppet::ResourceApi
133
100
  title
134
101
  end
135
102
 
136
- def self.build_title(type_definition, resource_hash)
137
- if type_definition.namevars.size > 1
138
- # use a MonkeyHash to allow searching in Puppet's RAL
139
- Puppet::ResourceApi::MonkeyHash[type_definition.namevars.map { |attr| [attr, resource_hash[attr]] }]
140
- else
141
- resource_hash[type_definition.namevars[0]]
142
- end
143
- end
144
-
145
- def rsapi_title
146
- @rsapi_title ||= self.class.build_title(type_definition, self)
147
- @rsapi_title
148
- end
149
-
150
103
  def to_resource
151
104
  to_resource_shim(super)
152
105
  end
153
106
 
154
- def to_resource_shim(resource)
107
+ define_method(:to_resource_shim) do |resource|
155
108
  resource_hash = Hash[resource.keys.map { |k| [k, resource[k]] }]
156
109
  resource_hash[:title] = resource.title
157
110
  ResourceShim.new(resource_hash, type_definition.name, type_definition.namevars, type_definition.attributes, catalog)
@@ -219,14 +172,8 @@ module Puppet::ResourceApi
219
172
  # https://puppet.com/docs/puppet/6.0/custom_types.html#reference-5883
220
173
  # for details.
221
174
  send(param_or_property, name.to_sym, parent: parent) do
222
- unless options[:type]
223
- raise Puppet::DevError, "#{definition[:name]}.#{name} has no type"
224
- end
225
-
226
175
  if options[:desc]
227
176
  desc "#{options[:desc]} (a #{options[:type]})"
228
- else
229
- warn("#{definition[:name]}.#{name} has no docs")
230
177
  end
231
178
 
232
179
  # The initialize method is called when puppet core starts building up
@@ -258,7 +205,7 @@ module Puppet::ResourceApi
258
205
  end
259
206
  end
260
207
 
261
- def self.instances
208
+ define_singleton_method(:instances) do
262
209
  # puts 'instances'
263
210
  # force autoloading of the provider
264
211
  provider(type_definition.name)
@@ -275,16 +222,16 @@ module Puppet::ResourceApi
275
222
  result = if resource_hash.key? :title
276
223
  new(title: resource_hash[:title])
277
224
  else
278
- new(title: build_title(type_definition, resource_hash))
225
+ new(title: resource_hash[type_definition.namevars.first])
279
226
  end
280
227
  result.cache_current_state(resource_hash)
281
228
  result
282
229
  end
283
230
  end
284
231
 
285
- def refresh_current_state
232
+ define_method(:refresh_current_state) do
286
233
  @rsapi_current_state = if type_definition.feature?('simple_get_filter')
287
- my_provider.get(context, [rsapi_title]).find { |h| namevar_match?(h) }
234
+ my_provider.get(context, [title]).find { |h| namevar_match?(h) }
288
235
  else
289
236
  my_provider.get(context).find { |h| namevar_match?(h) }
290
237
  end
@@ -293,11 +240,7 @@ module Puppet::ResourceApi
293
240
  type_definition.check_schema(@rsapi_current_state)
294
241
  strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
295
242
  else
296
- @rsapi_current_state = if rsapi_title.is_a? Hash
297
- rsapi_title.dup
298
- else
299
- { title: rsapi_title }
300
- end
243
+ @rsapi_current_state = { title: title }
301
244
  @rsapi_current_state[:ensure] = :absent if type_definition.ensurable?
302
245
  end
303
246
  end
@@ -308,7 +251,7 @@ module Puppet::ResourceApi
308
251
  strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
309
252
  end
310
253
 
311
- def retrieve
254
+ define_method(:retrieve) do
312
255
  refresh_current_state unless @rsapi_current_state
313
256
 
314
257
  Puppet.debug("Current State: #{@rsapi_current_state.inspect}")
@@ -322,13 +265,13 @@ module Puppet::ResourceApi
322
265
  result
323
266
  end
324
267
 
325
- def namevar_match?(item)
268
+ define_method(:namevar_match?) do |item|
326
269
  context.type.namevars.all? do |namevar|
327
270
  item[namevar] == @parameters[namevar].value if @parameters[namevar].respond_to? :value
328
271
  end
329
272
  end
330
273
 
331
- def flush
274
+ define_method(:flush) do
332
275
  raise_missing_attrs
333
276
 
334
277
  # puts 'flush'
@@ -346,7 +289,7 @@ module Puppet::ResourceApi
346
289
  # enforce init_only attributes
347
290
  if Puppet.settings[:strict] != :off && @rsapi_current_state && (@rsapi_current_state[:ensure] == 'present' && target_state[:ensure] == 'present')
348
291
  target_state.each do |name, value|
349
- next unless type_definition.attributes[name][:behaviour] == :init_only && value != @rsapi_current_state[name]
292
+ next unless definition[:attributes][name][:behaviour] == :init_only && value != @rsapi_current_state[name]
350
293
  message = "Attempting to change `#{name}` init_only attribute value from `#{@rsapi_current_state[name]}` to `#{value}`"
351
294
  case Puppet.settings[:strict]
352
295
  when :warning
@@ -358,9 +301,9 @@ module Puppet::ResourceApi
358
301
  end
359
302
 
360
303
  if type_definition.feature?('supports_noop')
361
- my_provider.set(context, { rsapi_title => { is: @rsapi_current_state, should: target_state } }, noop: noop?)
304
+ my_provider.set(context, { title => { is: @rsapi_current_state, should: target_state } }, noop: noop?)
362
305
  else
363
- my_provider.set(context, rsapi_title => { is: @rsapi_current_state, should: target_state }) unless noop?
306
+ my_provider.set(context, title => { is: @rsapi_current_state, should: target_state }) unless noop?
364
307
  end
365
308
  raise 'Execution encountered an error' if context.failed?
366
309
 
@@ -368,17 +311,17 @@ module Puppet::ResourceApi
368
311
  @rsapi_current_state = target_state
369
312
  end
370
313
 
371
- def raise_missing_attrs
314
+ define_method(:raise_missing_attrs) do
372
315
  error_msg = "The following mandatory attributes were not provided:\n * " + @missing_attrs.join(", \n * ")
373
316
  raise Puppet::ResourceError, error_msg if @missing_attrs.any? && (value(:ensure) != :absent && !value(:ensure).nil?)
374
317
  end
375
318
 
376
- def raise_missing_params
319
+ define_method(:raise_missing_params) do
377
320
  error_msg = "The following mandatory parameters were not provided:\n * " + @missing_params.join(", \n * ")
378
321
  raise Puppet::ResourceError, error_msg
379
322
  end
380
323
 
381
- def strict_check(current_state)
324
+ define_method(:strict_check) do |current_state|
382
325
  return if Puppet.settings[:strict] == :off
383
326
 
384
327
  # if strict checking is on we must notify if the values are changed by canonicalize
@@ -392,7 +335,7 @@ module Puppet::ResourceApi
392
335
  #:nocov:
393
336
  # codecov fails to register this multiline as covered, even though simplecov does.
394
337
  message = <<MESSAGE.strip
395
- #{type_definition.name}[#{@title}]#get has not provided canonicalized values.
338
+ #{definition[:name]}[#{@title}]#get has not provided canonicalized values.
396
339
  Returned values: #{current_state.inspect}
397
340
  Canonicalized values: #{state_clone.inspect}
398
341
  MESSAGE
@@ -405,7 +348,7 @@ MESSAGE
405
348
  raise Puppet::DevError, message
406
349
  end
407
350
 
408
- nil
351
+ return nil
409
352
  end
410
353
 
411
354
  define_singleton_method(:context) do
@@ -416,9 +359,9 @@ MESSAGE
416
359
  self.class.context
417
360
  end
418
361
 
419
- def self.title_patterns
420
- @title_patterns ||= if type_definition.definition.key? :title_patterns
421
- parse_title_patterns(type_definition.definition[:title_patterns])
362
+ define_singleton_method(:title_patterns) do
363
+ @title_patterns ||= if definition.key? :title_patterns
364
+ parse_title_patterns(definition[:title_patterns])
422
365
  else
423
366
  [[%r{(.*)}m, [[type_definition.namevars.first]]]]
424
367
  end
@@ -41,35 +41,9 @@ module Puppet::ResourceApi
41
41
  YAML.dump('type' => { title => attributes }).split("\n").drop(2).join("\n") + "\n"
42
42
  end
43
43
 
44
- def to_hash
45
- values
46
- end
47
-
48
- def to_json(*)
49
- attrs = filtered_keys.map { |k| [k.to_s, values[k]] unless values[k].nil? }
50
- attributes = Hash[*attrs.compact.flatten]
51
- resource = { title => attributes }
52
- resource.to_json
53
- end
54
-
55
44
  # attribute names that are not title or namevars
56
45
  def filtered_keys
57
46
  values.keys.reject { |k| k == :title || !attr_def[k] || (attr_def[k][:behaviour] == :namevar && @namevars.size == 1) }
58
47
  end
59
48
  end
60
-
61
- # this hash allows key-value based ordering comparisons between instances of this and instances of this and other classes
62
- # this is required for `lib/puppet/indirector/resource/ral.rb`'s `search` method which expects all titles to be comparable
63
- class MonkeyHash < Hash
64
- def <=>(other)
65
- result = self.class.name <=> other.class.name
66
- if result.zero?
67
- result = keys.sort <=> other.keys.sort
68
- end
69
- if result.zero?
70
- result = keys.sort.map { |k| self[k] } <=> other.keys.sort.map { |k| other[k] }
71
- end
72
- result
73
- end
74
- end
75
49
  end
@@ -1,5 +1,4 @@
1
1
  module Puppet; end # rubocop:disable Style/Documentation
2
-
3
2
  module Puppet::ResourceApi
4
3
  # This class provides a default implementation for set(), when your resource does not benefit from batching.
5
4
  # Instead of processing changes yourself, the `create`, `update`, and `delete` functions, are called for you,
@@ -20,12 +19,12 @@ module Puppet::ResourceApi
20
19
 
21
20
  raise 'SimpleProvider cannot be used with a Type that is not ensurable' unless context.type.ensurable?
22
21
 
23
- is = SimpleProvider.create_absent(:name, name) if is.nil?
24
- should = SimpleProvider.create_absent(:name, name) if should.nil?
22
+ is = { name: name, ensure: 'absent' } if is.nil?
23
+ should = { name: name, ensure: 'absent' } if should.nil?
25
24
 
26
25
  name_hash = if context.type.namevars.length > 1
27
26
  # pass a name_hash containing the values of all namevars
28
- name_hash = {}
27
+ name_hash = { title: name }
29
28
  context.type.namevars.each do |namevar|
30
29
  name_hash[namevar] = change[:should][namevar]
31
30
  end
@@ -61,16 +60,5 @@ module Puppet::ResourceApi
61
60
  def delete(_context, _name)
62
61
  raise "#{self.class} has not implemented `delete`"
63
62
  end
64
-
65
- # @api private
66
- def self.create_absent(namevar, title)
67
- result = if title.is_a? Hash
68
- title.dup
69
- else
70
- { namevar => title }
71
- end
72
- result[:ensure] = 'absent'
73
- result
74
- end
75
63
  end
76
64
  end
@@ -3,8 +3,8 @@ class Puppet::ResourceApi::TypeDefinition
3
3
  attr_reader :definition
4
4
 
5
5
  def initialize(definition)
6
- raise Puppet::DevError, 'TypeDefinition requires definition to be a Hash' unless definition.is_a?(Hash)
7
- @definition = definition
6
+ @data_type_cache = {}
7
+ validate_schema(definition)
8
8
  end
9
9
 
10
10
  def name
@@ -27,7 +27,60 @@ class Puppet::ResourceApi::TypeDefinition
27
27
 
28
28
  # rubocop complains when this is named has_feature?
29
29
  def feature?(feature)
30
- (definition[:features] && definition[:features].include?(feature))
30
+ supported = (definition[:features] && definition[:features].include?(feature))
31
+ if supported
32
+ Puppet.debug("#{definition[:name]} supports `#{feature}`")
33
+ else
34
+ Puppet.debug("#{definition[:name]} does not support `#{feature}`")
35
+ end
36
+ supported
37
+ end
38
+
39
+ def validate_schema(definition)
40
+ raise Puppet::DevError, 'Type definition must be a Hash, not `%{other_type}`' % { other_type: definition.class } unless definition.is_a?(Hash)
41
+ raise Puppet::DevError, 'Type definition must have a name' unless definition.key? :name
42
+ raise Puppet::DevError, 'Type definition must have `:attributes`' unless definition.key? :attributes
43
+ unless definition[:attributes].is_a?(Hash)
44
+ raise Puppet::DevError, '`%{name}.attributes` must be a hash, not `%{other_type}`' % {
45
+ name: definition[:name], other_type: definition[:attributes].class
46
+ }
47
+ end
48
+ [:title, :provider, :alias, :audit, :before, :consume, :export, :loglevel, :noop, :notify, :require, :schedule, :stage, :subscribe, :tag].each do |name|
49
+ raise Puppet::DevError, 'must not define an attribute called `%{name}`' % { name: name.inspect } if definition[:attributes].key? name
50
+ end
51
+ if definition.key?(:title_patterns) && !definition[:title_patterns].is_a?(Array)
52
+ raise Puppet::DevError, '`:title_patterns` must be an array, not `%{other_type}`' % { other_type: definition[:title_patterns].class }
53
+ end
54
+
55
+ Puppet::ResourceApi::DataTypeHandling.validate_ensure(definition)
56
+
57
+ definition[:features] ||= []
58
+ supported_features = %w[supports_noop canonicalize remote_resource simple_get_filter].freeze
59
+ unknown_features = definition[:features] - supported_features
60
+ Puppet.warning("Unknown feature detected: #{unknown_features.inspect}") unless unknown_features.empty?
61
+
62
+ definition[:attributes].each do |key, attr|
63
+ raise Puppet::DevError, "`#{definition[:name]}.#{key}` must be a Hash, not a #{attr.class}" unless attr.is_a? Hash
64
+ raise Puppet::DevError, "`#{definition[:name]}.#{key}` has no type" unless attr.key? :type
65
+ Puppet.warning("`#{definition[:name]}.#{key}` has no docs") unless attr.key? :desc
66
+
67
+ # validate the type by attempting to parse into a puppet type
68
+ @data_type_cache[definition[:attributes][key][:type]] ||=
69
+ Puppet::ResourceApi::DataTypeHandling.parse_puppet_type(
70
+ key,
71
+ definition[:attributes][key][:type],
72
+ )
73
+
74
+ # fixup any weird behavior ;-)
75
+ next unless attr[:behavior]
76
+ if attr[:behaviour]
77
+ raise Puppet::DevError, "the '#{key}' attribute has both a `behavior` and a `behaviour`, only use one"
78
+ end
79
+ attr[:behaviour] = attr[:behavior]
80
+ attr.delete(:behavior)
81
+ end
82
+ # store the validated definition
83
+ @definition = definition
31
84
  end
32
85
 
33
86
  # validates a resource hash against its type schema
@@ -78,10 +131,7 @@ class Puppet::ResourceApi::TypeDefinition
78
131
  bad_vals = {}
79
132
  resource.each do |key, value|
80
133
  next unless attributes[key]
81
- type = Puppet::ResourceApi::DataTypeHandling.parse_puppet_type(
82
- key,
83
- attributes[key][:type],
84
- )
134
+ type = @data_type_cache[attributes[key][:type]]
85
135
  error_message = Puppet::ResourceApi::DataTypeHandling.try_validate(
86
136
  type,
87
137
  value,
@@ -1,5 +1,5 @@
1
1
  module Puppet
2
2
  module ResourceApi
3
- VERSION = '1.6.5'.freeze
3
+ VERSION = '1.7.0'.freeze
4
4
  end
5
5
  end
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.6.5
4
+ version: 1.7.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: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hocon