puppet-resource_api 1.6.5 → 1.7.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 +4 -4
- data/.rspec +1 -1
- data/.travis.yml +14 -14
- data/Gemfile +6 -15
- data/README.md +6 -0
- data/Rakefile +2 -10
- data/lib/puppet/resource_api.rb +28 -85
- data/lib/puppet/resource_api/glue.rb +0 -26
- data/lib/puppet/resource_api/simple_provider.rb +3 -15
- data/lib/puppet/resource_api/type_definition.rb +57 -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: c26bda3effbce092aa8b8defb8904fdb41a02231fba2830593bfc85413b66906
|
4
|
+
data.tar.gz: 89b49840bd21ea57227db05021e0b9ddb7ab7539b9b130a888e3fea99b7da87e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 971775219d3ae76f94a18ebef57b0a1be470a0c222b31a4a1cf0d1d4b8f4ecc71516fb6b004674a4878c619d97f4b6f3e644edcc43e3cba419070afd5ad53bd3
|
7
|
+
data.tar.gz: dfb2823ce573240977587f9a7431b1956a62a0367a740d4e0c9fc412436542d41065be88e7ed8348057fd42b1cf039c4ac69c8e4b7bad7f4771d73c2f6927454
|
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' 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
|
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.
|
31
|
+
- rvm: 2.4.3
|
32
32
|
env: CHECK=rubocop
|
33
|
-
- rvm: 2.
|
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'
|
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
|
-
|
56
|
-
|
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
|
-
|
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
|
-
|
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['
|
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 ####
|
data/lib/puppet/resource_api.rb
CHANGED
@@ -19,43 +19,9 @@ module Puppet::ResourceApi
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def register_type(definition)
|
22
|
-
|
23
|
-
|
24
|
-
|
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[:
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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:
|
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
|
-
|
232
|
+
define_method(:refresh_current_state) do
|
286
233
|
@rsapi_current_state = if type_definition.feature?('simple_get_filter')
|
287
|
-
my_provider.get(context, [
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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, {
|
304
|
+
my_provider.set(context, { title => { is: @rsapi_current_state, should: target_state } }, noop: noop?)
|
362
305
|
else
|
363
|
-
my_provider.set(context,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#{
|
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
|
-
|
420
|
-
@title_patterns ||= if
|
421
|
-
parse_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 =
|
24
|
-
should =
|
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
|
-
|
7
|
-
|
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 =
|
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,
|
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.
|
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-
|
11
|
+
date: 2019-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hocon
|