puppet-resource_api 1.6.4 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -1
- data/.travis.yml +4 -4
- data/Gemfile +6 -5
- data/Rakefile +10 -2
- data/lib/puppet/resource_api.rb +51 -23
- data/lib/puppet/resource_api/glue.rb +26 -0
- data/lib/puppet/resource_api/simple_provider.rb +15 -3
- data/lib/puppet/resource_api/type_definition.rb +1 -7
- data/lib/puppet/resource_api/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 160e4e687bacbb19cddb0b34398c6caa72ba308707a3718487c2fd4c86040804
|
4
|
+
data.tar.gz: ece23bfd962d5f97f34690bcdb02dbbaeb64d8109b65e5044396bfebb13328fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0888ca950e55d91f308274aab1d97ee46e6f5f924fad3b6abb150721012516f71afc740e6d4a297b188938f63416812d429e4e236908109d254ff9daf0a19a13'
|
7
|
+
data.tar.gz: 94df73da789c0808562408becc35d38ee55d8a5447db00b91999475362819508531b3e59dca2d96d7928bfff61e40447c568168c859beb9b2fe7ccf79d93ac4d
|
data/.rspec
CHANGED
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'
|
18
|
-
- env: RVM="jruby-1.7.26" PUPPET_GEM_VERSION='~> 5' JRUBY_OPTS="--debug"
|
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
|
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
|
23
|
+
before_install: rvm use jruby-1.7.26 --install --binary --fuzzy && gem install bundler -v '~> 1.7.0'
|
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
|
@@ -45,7 +45,7 @@ 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'
|
48
|
+
env: PUPPET_GEM_VERSION='~> 4' SIMPLECOV=yes # 4.10
|
49
49
|
- rvm: 2.1.9
|
50
50
|
env: PUPPET_GEM_VERSION='~> 4.9.0'
|
51
51
|
- rvm: 2.1.9
|
data/Gemfile
CHANGED
@@ -7,16 +7,14 @@ 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')
|
13
10
|
gem 'rake', '~> 10.0'
|
14
11
|
gem 'rspec', '~> 3.0'
|
15
12
|
# rubocop 0.58 throws when testing against ruby 2.1, so pin to the latest,
|
16
13
|
# unless we're dealing with jruby...
|
17
14
|
if RUBY_PLATFORM == 'java'
|
18
|
-
# load
|
19
|
-
gem '
|
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'
|
20
18
|
elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.0')
|
21
19
|
gem 'rubocop', '0.57.2'
|
22
20
|
# the last version of parallel to support ruby 2.1
|
@@ -27,6 +25,9 @@ group :tests do
|
|
27
25
|
# This needs to be removed once we drop puppet4 support.
|
28
26
|
gem 'rubocop', '~> 0.57.0'
|
29
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')
|
30
31
|
end
|
31
32
|
gem 'simplecov-console'
|
32
33
|
# the test gems required for module testing
|
data/Rakefile
CHANGED
@@ -14,22 +14,30 @@ 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
|
18
17
|
# thanks to the fixtures/modules/ symlinks this needs to exclude fixture modules explicitely
|
19
18
|
excludes = ['fixtures/**/*.rb,fixtures/modules/*/**/*.rb']
|
20
19
|
if RUBY_PLATFORM == 'java'
|
21
20
|
excludes += ['acceptance/**/*.rb', 'integration/**/*.rb', 'puppet/resource_api/*_context_spec.rb', 'puppet/util/network_device/simple/device_spec.rb']
|
22
21
|
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
|
+
|
27
29
|
namespace :spec do
|
28
30
|
desc 'Run RSpec code examples with coverage collection'
|
29
31
|
task :coverage do
|
30
|
-
ENV['
|
32
|
+
ENV['SIMPLECOV'] = 'yes'
|
31
33
|
Rake::Task['spec'].execute
|
32
34
|
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
|
33
41
|
end
|
34
42
|
|
35
43
|
#### LICENSE_FINDER ####
|
data/lib/puppet/resource_api.rb
CHANGED
@@ -37,6 +37,16 @@ module Puppet::ResourceApi
|
|
37
37
|
unknown_features = definition[:features] - supported_features
|
38
38
|
Puppet.warning("Unknown feature detected: #{unknown_features.inspect}") unless unknown_features.empty?
|
39
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
|
+
|
40
50
|
# fixup any weird behavior ;-)
|
41
51
|
definition[:attributes].each do |name, attr|
|
42
52
|
next unless attr[:behavior]
|
@@ -56,7 +66,7 @@ module Puppet::ResourceApi
|
|
56
66
|
end
|
57
67
|
|
58
68
|
Puppet::Type.newtype(definition[:name].to_sym) do
|
59
|
-
@docs = definition[:
|
69
|
+
@docs = definition[:desc]
|
60
70
|
|
61
71
|
# Keeps a copy of the provider around. Weird naming to avoid clashes with puppet's own `provider` member
|
62
72
|
define_singleton_method(:my_provider) do
|
@@ -81,7 +91,7 @@ module Puppet::ResourceApi
|
|
81
91
|
apply_to_device
|
82
92
|
end
|
83
93
|
|
84
|
-
|
94
|
+
def initialize(attributes)
|
85
95
|
# $stderr.puts "A: #{attributes.inspect}"
|
86
96
|
if attributes.is_a? Puppet::Resource
|
87
97
|
@title = attributes.title
|
@@ -109,7 +119,7 @@ module Puppet::ResourceApi
|
|
109
119
|
# the `Puppet::Resource::Ral.find` method, when `instances` does not return a match, uses a Hash with a `:name` key to create
|
110
120
|
# an "absent" resource. This is often hit by `puppet resource`. This needs to work, even if the namevar is not called `name`.
|
111
121
|
# This bit here relies on the default `title_patterns` (see below) to match the title back to the first (and often only) namevar
|
112
|
-
if
|
122
|
+
if type_definition.attributes[:name].nil? && attributes[:title].nil?
|
113
123
|
attributes[:title] = attributes.delete(:name)
|
114
124
|
if attributes[:title].nil? && !type_definition.namevars.empty?
|
115
125
|
attributes[:title] = @title
|
@@ -123,11 +133,25 @@ module Puppet::ResourceApi
|
|
123
133
|
title
|
124
134
|
end
|
125
135
|
|
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
|
+
|
126
150
|
def to_resource
|
127
151
|
to_resource_shim(super)
|
128
152
|
end
|
129
153
|
|
130
|
-
|
154
|
+
def to_resource_shim(resource)
|
131
155
|
resource_hash = Hash[resource.keys.map { |k| [k, resource[k]] }]
|
132
156
|
resource_hash[:title] = resource.title
|
133
157
|
ResourceShim.new(resource_hash, type_definition.name, type_definition.namevars, type_definition.attributes, catalog)
|
@@ -234,7 +258,7 @@ module Puppet::ResourceApi
|
|
234
258
|
end
|
235
259
|
end
|
236
260
|
|
237
|
-
|
261
|
+
def self.instances
|
238
262
|
# puts 'instances'
|
239
263
|
# force autoloading of the provider
|
240
264
|
provider(type_definition.name)
|
@@ -251,16 +275,16 @@ module Puppet::ResourceApi
|
|
251
275
|
result = if resource_hash.key? :title
|
252
276
|
new(title: resource_hash[:title])
|
253
277
|
else
|
254
|
-
new(title: resource_hash
|
278
|
+
new(title: build_title(type_definition, resource_hash))
|
255
279
|
end
|
256
280
|
result.cache_current_state(resource_hash)
|
257
281
|
result
|
258
282
|
end
|
259
283
|
end
|
260
284
|
|
261
|
-
|
285
|
+
def refresh_current_state
|
262
286
|
@rsapi_current_state = if type_definition.feature?('simple_get_filter')
|
263
|
-
my_provider.get(context, [
|
287
|
+
my_provider.get(context, [rsapi_title]).find { |h| namevar_match?(h) }
|
264
288
|
else
|
265
289
|
my_provider.get(context).find { |h| namevar_match?(h) }
|
266
290
|
end
|
@@ -269,7 +293,11 @@ module Puppet::ResourceApi
|
|
269
293
|
type_definition.check_schema(@rsapi_current_state)
|
270
294
|
strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
|
271
295
|
else
|
272
|
-
@rsapi_current_state =
|
296
|
+
@rsapi_current_state = if rsapi_title.is_a? Hash
|
297
|
+
rsapi_title.dup
|
298
|
+
else
|
299
|
+
{ title: rsapi_title }
|
300
|
+
end
|
273
301
|
@rsapi_current_state[:ensure] = :absent if type_definition.ensurable?
|
274
302
|
end
|
275
303
|
end
|
@@ -280,7 +308,7 @@ module Puppet::ResourceApi
|
|
280
308
|
strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
|
281
309
|
end
|
282
310
|
|
283
|
-
|
311
|
+
def retrieve
|
284
312
|
refresh_current_state unless @rsapi_current_state
|
285
313
|
|
286
314
|
Puppet.debug("Current State: #{@rsapi_current_state.inspect}")
|
@@ -294,13 +322,13 @@ module Puppet::ResourceApi
|
|
294
322
|
result
|
295
323
|
end
|
296
324
|
|
297
|
-
|
325
|
+
def namevar_match?(item)
|
298
326
|
context.type.namevars.all? do |namevar|
|
299
327
|
item[namevar] == @parameters[namevar].value if @parameters[namevar].respond_to? :value
|
300
328
|
end
|
301
329
|
end
|
302
330
|
|
303
|
-
|
331
|
+
def flush
|
304
332
|
raise_missing_attrs
|
305
333
|
|
306
334
|
# puts 'flush'
|
@@ -318,7 +346,7 @@ module Puppet::ResourceApi
|
|
318
346
|
# enforce init_only attributes
|
319
347
|
if Puppet.settings[:strict] != :off && @rsapi_current_state && (@rsapi_current_state[:ensure] == 'present' && target_state[:ensure] == 'present')
|
320
348
|
target_state.each do |name, value|
|
321
|
-
next unless
|
349
|
+
next unless type_definition.attributes[name][:behaviour] == :init_only && value != @rsapi_current_state[name]
|
322
350
|
message = "Attempting to change `#{name}` init_only attribute value from `#{@rsapi_current_state[name]}` to `#{value}`"
|
323
351
|
case Puppet.settings[:strict]
|
324
352
|
when :warning
|
@@ -330,9 +358,9 @@ module Puppet::ResourceApi
|
|
330
358
|
end
|
331
359
|
|
332
360
|
if type_definition.feature?('supports_noop')
|
333
|
-
my_provider.set(context, {
|
361
|
+
my_provider.set(context, { rsapi_title => { is: @rsapi_current_state, should: target_state } }, noop: noop?)
|
334
362
|
else
|
335
|
-
my_provider.set(context,
|
363
|
+
my_provider.set(context, rsapi_title => { is: @rsapi_current_state, should: target_state }) unless noop?
|
336
364
|
end
|
337
365
|
raise 'Execution encountered an error' if context.failed?
|
338
366
|
|
@@ -340,17 +368,17 @@ module Puppet::ResourceApi
|
|
340
368
|
@rsapi_current_state = target_state
|
341
369
|
end
|
342
370
|
|
343
|
-
|
371
|
+
def raise_missing_attrs
|
344
372
|
error_msg = "The following mandatory attributes were not provided:\n * " + @missing_attrs.join(", \n * ")
|
345
373
|
raise Puppet::ResourceError, error_msg if @missing_attrs.any? && (value(:ensure) != :absent && !value(:ensure).nil?)
|
346
374
|
end
|
347
375
|
|
348
|
-
|
376
|
+
def raise_missing_params
|
349
377
|
error_msg = "The following mandatory parameters were not provided:\n * " + @missing_params.join(", \n * ")
|
350
378
|
raise Puppet::ResourceError, error_msg
|
351
379
|
end
|
352
380
|
|
353
|
-
|
381
|
+
def strict_check(current_state)
|
354
382
|
return if Puppet.settings[:strict] == :off
|
355
383
|
|
356
384
|
# if strict checking is on we must notify if the values are changed by canonicalize
|
@@ -364,7 +392,7 @@ module Puppet::ResourceApi
|
|
364
392
|
#:nocov:
|
365
393
|
# codecov fails to register this multiline as covered, even though simplecov does.
|
366
394
|
message = <<MESSAGE.strip
|
367
|
-
#{
|
395
|
+
#{type_definition.name}[#{@title}]#get has not provided canonicalized values.
|
368
396
|
Returned values: #{current_state.inspect}
|
369
397
|
Canonicalized values: #{state_clone.inspect}
|
370
398
|
MESSAGE
|
@@ -377,7 +405,7 @@ MESSAGE
|
|
377
405
|
raise Puppet::DevError, message
|
378
406
|
end
|
379
407
|
|
380
|
-
|
408
|
+
nil
|
381
409
|
end
|
382
410
|
|
383
411
|
define_singleton_method(:context) do
|
@@ -388,9 +416,9 @@ MESSAGE
|
|
388
416
|
self.class.context
|
389
417
|
end
|
390
418
|
|
391
|
-
|
392
|
-
@title_patterns ||= if definition.key? :title_patterns
|
393
|
-
parse_title_patterns(definition[:title_patterns])
|
419
|
+
def self.title_patterns
|
420
|
+
@title_patterns ||= if type_definition.definition.key? :title_patterns
|
421
|
+
parse_title_patterns(type_definition.definition[:title_patterns])
|
394
422
|
else
|
395
423
|
[[%r{(.*)}m, [[type_definition.namevars.first]]]]
|
396
424
|
end
|
@@ -41,9 +41,35 @@ 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
|
+
|
44
55
|
# attribute names that are not title or namevars
|
45
56
|
def filtered_keys
|
46
57
|
values.keys.reject { |k| k == :title || !attr_def[k] || (attr_def[k][:behaviour] == :namevar && @namevars.size == 1) }
|
47
58
|
end
|
48
59
|
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
|
49
75
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Puppet; end # rubocop:disable Style/Documentation
|
2
|
+
|
2
3
|
module Puppet::ResourceApi
|
3
4
|
# This class provides a default implementation for set(), when your resource does not benefit from batching.
|
4
5
|
# Instead of processing changes yourself, the `create`, `update`, and `delete` functions, are called for you,
|
@@ -19,12 +20,12 @@ module Puppet::ResourceApi
|
|
19
20
|
|
20
21
|
raise 'SimpleProvider cannot be used with a Type that is not ensurable' unless context.type.ensurable?
|
21
22
|
|
22
|
-
is =
|
23
|
-
should =
|
23
|
+
is = SimpleProvider.create_absent(:name, name) if is.nil?
|
24
|
+
should = SimpleProvider.create_absent(:name, name) if should.nil?
|
24
25
|
|
25
26
|
name_hash = if context.type.namevars.length > 1
|
26
27
|
# pass a name_hash containing the values of all namevars
|
27
|
-
name_hash = {
|
28
|
+
name_hash = {}
|
28
29
|
context.type.namevars.each do |namevar|
|
29
30
|
name_hash[namevar] = change[:should][namevar]
|
30
31
|
end
|
@@ -60,5 +61,16 @@ module Puppet::ResourceApi
|
|
60
61
|
def delete(_context, _name)
|
61
62
|
raise "#{self.class} has not implemented `delete`"
|
62
63
|
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
|
63
75
|
end
|
64
76
|
end
|
@@ -27,13 +27,7 @@ class Puppet::ResourceApi::TypeDefinition
|
|
27
27
|
|
28
28
|
# rubocop complains when this is named has_feature?
|
29
29
|
def feature?(feature)
|
30
|
-
|
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
|
30
|
+
(definition[:features] && definition[:features].include?(feature))
|
37
31
|
end
|
38
32
|
|
39
33
|
# validates a resource hash against its type schema
|
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.
|
4
|
+
version: 1.6.5
|
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-
|
11
|
+
date: 2019-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hocon
|