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 +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
|