puppet-resource_api 1.2.0 → 1.3.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/.rubocop.yml +1 -1
- data/.travis.yml +3 -0
- data/CHANGELOG.md +22 -0
- data/README.md +5 -5
- data/appveyor.yml +4 -0
- data/lib/puppet/resource_api.rb +125 -33
- data/lib/puppet/resource_api/glue.rb +21 -15
- data/lib/puppet/resource_api/type_definition.rb +6 -0
- data/lib/puppet/resource_api/version.rb +1 -1
- data/misc/ANNOUNCEMENT_TEMPLATE.md +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48ed58d882063171b3d9cd9b0711403cf6d8bc0c213aa98d0583d2b0bf8746a7
|
|
4
|
+
data.tar.gz: c6acb1edb2ee5b1cefe1cb0449090ee3072e380632952d82948b6eb2455a49b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fc8c73ce49206569836f00aa1c52380b1571055ccc3f6842577a6c890c657b19280ad9b6c09e376db8acc3b63daa700cebe6d64c47571d464df797ba1b0e482
|
|
7
|
+
data.tar.gz: 9e64c5cc2d4474014ed8f45d66b44ad0416874f29b6b2f6c5b0a0da01e93179525d3eee33029f3e28eaa29acb5f5ea2d537935265f608d23610e63d51e5b3ec3
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All significant changes to this repo will be summarized in this file.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
## [v1.3.0](https://github.com/puppetlabs/puppet-resource_api/tree/v1.3.0) (2018-05-24)
|
|
7
|
+
[Full Changelog](https://github.com/puppetlabs/puppet-resource_api/compare/v1.2.0...v1.3.0)
|
|
8
|
+
|
|
9
|
+
**Implemented enhancements:**
|
|
10
|
+
|
|
11
|
+
- Check for more attributes that puppet can't use [\#84](https://github.com/puppetlabs/puppet-resource_api/pull/84) ([DavidS](https://github.com/DavidS))
|
|
12
|
+
- \(PDK-531\) Support for composite namevars [\#82](https://github.com/puppetlabs/puppet-resource_api/pull/82) ([da-ar](https://github.com/da-ar))
|
|
13
|
+
- \(PDK-889\) Write support for multiple namevars [\#79](https://github.com/puppetlabs/puppet-resource_api/pull/79) ([da-ar](https://github.com/da-ar))
|
|
14
|
+
- \(PDK-889\) Read-only support for multiple namevars [\#76](https://github.com/puppetlabs/puppet-resource_api/pull/76) ([da-ar](https://github.com/da-ar))
|
|
15
|
+
|
|
16
|
+
**Fixed bugs:**
|
|
17
|
+
|
|
18
|
+
- Ignore `provider` attribute when calculating target state [\#83](https://github.com/puppetlabs/puppet-resource_api/pull/83) ([DavidS](https://github.com/DavidS))
|
|
19
|
+
- Add check to handle absent resources through puppet apply [\#81](https://github.com/puppetlabs/puppet-resource_api/pull/81) ([da-ar](https://github.com/da-ar))
|
|
20
|
+
- \(PDK-988\) restrain mungify from non-`puppet resource` workflows [\#80](https://github.com/puppetlabs/puppet-resource_api/pull/80) ([DavidS](https://github.com/DavidS))
|
|
21
|
+
|
|
22
|
+
**Merged pull requests:**
|
|
23
|
+
|
|
24
|
+
- Update fixtures module to PDK v1.5 [\#78](https://github.com/puppetlabs/puppet-resource_api/pull/78) ([DavidS](https://github.com/DavidS))
|
|
25
|
+
- Some glue fixes: announcement, to\_manifest, to\_hierayaml [\#77](https://github.com/puppetlabs/puppet-resource_api/pull/77) ([DavidS](https://github.com/DavidS))
|
|
26
|
+
- Release prep for v1.2.0 [\#75](https://github.com/puppetlabs/puppet-resource_api/pull/75) ([DavidS](https://github.com/DavidS))
|
|
27
|
+
|
|
6
28
|
## [v1.2.0](https://github.com/puppetlabs/puppet-resource_api/tree/v1.2.0) (2018-05-08)
|
|
7
29
|
[Full Changelog](https://github.com/puppetlabs/puppet-resource_api/compare/v1.1.0...v1.2.0)
|
|
8
30
|
|
data/README.md
CHANGED
|
@@ -209,8 +209,9 @@ There are still a few notable gaps between the implementation and the specificat
|
|
|
209
209
|
* Complex data types, like Hash, Tuple or Struct are not yet implemented.
|
|
210
210
|
* Only a single runtime environment (the Puppet commands) is currently implemented.
|
|
211
211
|
|
|
212
|
-
Restrictions of
|
|
213
|
-
* `supports_noop` is not effective, as puppet doesn't call into the type under noop.
|
|
212
|
+
Restrictions of puppet:
|
|
213
|
+
* `supports_noop` is not effective, as puppet doesn't call into the type under noop at all.
|
|
214
|
+
* Attributes cannot be called `title`, `provider`, or any of the [metaparameters](https://puppet.com/docs/puppet/5.5/metaparameter.html), as those are reserved by puppet itself.
|
|
214
215
|
|
|
215
216
|
Future possibilities:
|
|
216
217
|
* [Composite Namevars](https://tickets.puppetlabs.com/browse/PDK-531)
|
|
@@ -239,9 +240,8 @@ To cut a new release, from a current `master` checkout:
|
|
|
239
240
|
* double check the PRs to make sure they're all tagged correctly (using the new CHANGELOG for cross-checking)
|
|
240
241
|
* Check README and other materials for up-to-date-ness
|
|
241
242
|
* Commit changes with title "Release prep for v<VERSION>"
|
|
242
|
-
* Upload and PR the release
|
|
243
|
-
* make sure to use the name of your git remote pointing to main repo instead of "upstream"
|
|
243
|
+
* Upload and PR the release-prep branch to the puppetlabs GitHub repo
|
|
244
244
|
* Check that CI is green and merge the PR
|
|
245
245
|
* Run `rake release[upstream]` to release from your checkout
|
|
246
|
-
* make sure to use the name of your git remote pointing to
|
|
246
|
+
* make sure to use the name of your git remote pointing to the puppetlabs GitHub repo
|
|
247
247
|
* Remove the release-prep branch
|
data/appveyor.yml
CHANGED
data/lib/puppet/resource_api.rb
CHANGED
|
@@ -7,9 +7,17 @@ require 'puppet/type'
|
|
|
7
7
|
|
|
8
8
|
module Puppet::ResourceApi
|
|
9
9
|
def register_type(definition)
|
|
10
|
-
raise Puppet::DevError, 'requires a
|
|
11
|
-
raise Puppet::DevError, 'requires a name' unless definition.key? :name
|
|
12
|
-
raise Puppet::DevError, 'requires attributes' unless definition.key? :attributes
|
|
10
|
+
raise Puppet::DevError, 'requires a hash as definition, not `%{other_type}`' % { other_type: definition.class } unless definition.is_a? Hash
|
|
11
|
+
raise Puppet::DevError, 'requires a `:name`' unless definition.key? :name
|
|
12
|
+
raise Puppet::DevError, 'requires `:attributes`' unless definition.key? :attributes
|
|
13
|
+
raise Puppet::DevError, '`:attributes` must be a hash, not `%{other_type}`' % { other_type: definition[:attributes].class } unless definition[:attributes].is_a?(Hash)
|
|
14
|
+
[:title, :provider, :alias, :audit, :before, :consume, :export, :loglevel, :noop, :notify, :require, :schedule, :stage, :subscribe, :tag].each do |name|
|
|
15
|
+
raise Puppet::DevError, 'must not define an attribute called `%{name}`' % { name: name.inspect } if definition[:attributes].key? name
|
|
16
|
+
end
|
|
17
|
+
if definition.key?(:title_patterns) && !definition[:title_patterns].is_a?(Array)
|
|
18
|
+
raise Puppet::DevError, '`:title_patterns` must be an array, not `%{other_type}`' % { other_type: definition[:title_patterns].class }
|
|
19
|
+
end
|
|
20
|
+
|
|
13
21
|
validate_ensure(definition)
|
|
14
22
|
|
|
15
23
|
definition[:features] ||= []
|
|
@@ -37,8 +45,6 @@ module Puppet::ResourceApi
|
|
|
37
45
|
|
|
38
46
|
Puppet::Type.newtype(definition[:name].to_sym) do
|
|
39
47
|
@docs = definition[:docs]
|
|
40
|
-
has_namevar = false
|
|
41
|
-
namevar_name = nil
|
|
42
48
|
|
|
43
49
|
# Keeps a copy of the provider around. Weird naming to avoid clashes with puppet's own `provider` member
|
|
44
50
|
define_singleton_method(:my_provider) do
|
|
@@ -65,15 +71,26 @@ module Puppet::ResourceApi
|
|
|
65
71
|
define_method(:initialize) do |attributes|
|
|
66
72
|
# $stderr.puts "A: #{attributes.inspect}"
|
|
67
73
|
if attributes.is_a? Puppet::Resource
|
|
74
|
+
@title = attributes.title
|
|
68
75
|
attributes = attributes.to_hash
|
|
69
76
|
else
|
|
70
|
-
@
|
|
77
|
+
@ral_find_absent = true
|
|
71
78
|
end
|
|
72
79
|
# $stderr.puts "B: #{attributes.inspect}"
|
|
73
80
|
if type_definition.feature?('canonicalize')
|
|
74
81
|
attributes = my_provider.canonicalize(context, [attributes])[0]
|
|
75
82
|
end
|
|
76
|
-
|
|
83
|
+
|
|
84
|
+
# the `Puppet::Resource::Ral.find` method, when `instances` does not return a match, uses a Hash with a `:name` key to create
|
|
85
|
+
# an "absent" resource. This is often hit by `puppet resource`. This needs to work, even if the namevar is not called `name`.
|
|
86
|
+
# This bit here relies on the default `title_patterns` (see below) to match the title back to the first (and often only) namevar
|
|
87
|
+
if definition[:attributes][:name].nil? && attributes[:title].nil?
|
|
88
|
+
attributes[:title] = attributes.delete(:name)
|
|
89
|
+
if attributes[:title].nil? && !type_definition.namevars.empty?
|
|
90
|
+
attributes[:title] = @title
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
77
94
|
super(attributes)
|
|
78
95
|
end
|
|
79
96
|
|
|
@@ -81,6 +98,10 @@ module Puppet::ResourceApi
|
|
|
81
98
|
# enforce mandatory attributes
|
|
82
99
|
@missing_attrs = []
|
|
83
100
|
@missing_params = []
|
|
101
|
+
|
|
102
|
+
# do not validate on known-absent instances
|
|
103
|
+
return if @ral_find_absent
|
|
104
|
+
|
|
84
105
|
definition[:attributes].each do |name, options|
|
|
85
106
|
type = Puppet::Pops::Types::TypeParser.singleton.parse(options[:type])
|
|
86
107
|
|
|
@@ -98,7 +119,7 @@ module Puppet::ResourceApi
|
|
|
98
119
|
end
|
|
99
120
|
end
|
|
100
121
|
|
|
101
|
-
@missing_attrs -= [:ensure]
|
|
122
|
+
@missing_attrs -= [:ensure]
|
|
102
123
|
|
|
103
124
|
raise_missing_params if @missing_params.any?
|
|
104
125
|
end
|
|
@@ -115,7 +136,7 @@ module Puppet::ResourceApi
|
|
|
115
136
|
# TODO: using newparam everywhere would suppress change reporting
|
|
116
137
|
# that would allow more fine-grained reporting through context,
|
|
117
138
|
# but require more invest in hooking up the infrastructure to emulate existing data
|
|
118
|
-
param_or_property = if [:read_only, :parameter
|
|
139
|
+
param_or_property = if [:read_only, :parameter].include? options[:behaviour]
|
|
119
140
|
:newparam
|
|
120
141
|
else
|
|
121
142
|
:newproperty
|
|
@@ -133,11 +154,7 @@ module Puppet::ResourceApi
|
|
|
133
154
|
end
|
|
134
155
|
|
|
135
156
|
if options[:behaviour] == :namevar
|
|
136
|
-
# puts 'setting namevar'
|
|
137
|
-
# raise Puppet::DevError, "namevar must be called 'name', not '#{name}'" if name.to_s != 'name'
|
|
138
157
|
isnamevar
|
|
139
|
-
has_namevar = true
|
|
140
|
-
namevar_name = name
|
|
141
158
|
end
|
|
142
159
|
|
|
143
160
|
# read-only values do not need type checking, but can have default values
|
|
@@ -199,16 +216,16 @@ module Puppet::ResourceApi
|
|
|
199
216
|
end
|
|
200
217
|
end
|
|
201
218
|
|
|
202
|
-
if type.instance_of? Puppet::Pops::Types::POptionalType
|
|
203
|
-
type = type.type
|
|
204
|
-
end
|
|
205
|
-
|
|
206
219
|
# puppet symbolizes some values through puppet/parameter/value.rb (see .convert()), but (especially) Enums
|
|
207
220
|
# are strings. specifying a munge block here skips the value_collection fallback in puppet/parameter.rb's
|
|
208
221
|
# default .unsafe_munge() implementation.
|
|
209
222
|
munge { |v| v }
|
|
210
223
|
|
|
211
224
|
# provide hints to `puppet type generate` for better parsing
|
|
225
|
+
if type.instance_of? Puppet::Pops::Types::POptionalType
|
|
226
|
+
type = type.type
|
|
227
|
+
end
|
|
228
|
+
|
|
212
229
|
case type
|
|
213
230
|
when Puppet::Pops::Types::PStringType
|
|
214
231
|
# require any string value
|
|
@@ -250,10 +267,12 @@ module Puppet::ResourceApi
|
|
|
250
267
|
property = definition[:attributes][key.first]
|
|
251
268
|
attr_def[key.first] = property
|
|
252
269
|
end
|
|
253
|
-
|
|
254
|
-
|
|
270
|
+
context.type.namevars.each do |namevar|
|
|
271
|
+
if resource_hash[namevar].nil?
|
|
272
|
+
raise Puppet::ResourceError, "`#{name}.get` did not return a value for the `#{namevar}` namevar attribute"
|
|
273
|
+
end
|
|
255
274
|
end
|
|
256
|
-
Puppet::ResourceApi::TypeShim.new(resource_hash
|
|
275
|
+
Puppet::ResourceApi::TypeShim.new(resource_hash, name, context.type.namevars, attr_def)
|
|
257
276
|
end
|
|
258
277
|
end
|
|
259
278
|
|
|
@@ -264,7 +283,7 @@ module Puppet::ResourceApi
|
|
|
264
283
|
current_state = if type_definition.feature?('simple_get_filter')
|
|
265
284
|
my_provider.get(context, [title]).first
|
|
266
285
|
else
|
|
267
|
-
my_provider.get(context).find { |h| h
|
|
286
|
+
my_provider.get(context).find { |h| namevar_match?(h) }
|
|
268
287
|
end
|
|
269
288
|
|
|
270
289
|
strict_check(current_state) if current_state && type_definition.feature?('canonicalize')
|
|
@@ -274,7 +293,7 @@ module Puppet::ResourceApi
|
|
|
274
293
|
result[k] = v
|
|
275
294
|
end
|
|
276
295
|
else
|
|
277
|
-
result[
|
|
296
|
+
result[:title] = title
|
|
278
297
|
result[:ensure] = :absent if type_definition.ensurable?
|
|
279
298
|
end
|
|
280
299
|
|
|
@@ -288,12 +307,18 @@ module Puppet::ResourceApi
|
|
|
288
307
|
result
|
|
289
308
|
end
|
|
290
309
|
|
|
310
|
+
define_method(:namevar_match?) do |item|
|
|
311
|
+
context.type.namevars.all? do |namevar|
|
|
312
|
+
item[namevar] == @parameters[namevar].value if @parameters[namevar].respond_to? :value
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
291
316
|
define_method(:flush) do
|
|
292
317
|
raise_missing_attrs
|
|
293
318
|
|
|
294
319
|
# puts 'flush'
|
|
295
320
|
# skip puppet's injected metaparams
|
|
296
|
-
target_state = Hash[@parameters.reject { |k, _v| [:loglevel, :noop].include? k }.map { |k, v| [k, v.rs_value] }]
|
|
321
|
+
target_state = Hash[@parameters.reject { |k, _v| [:loglevel, :noop, :provider].include? k }.map { |k, v| [k, v.rs_value] }]
|
|
297
322
|
target_state = my_provider.canonicalize(context, [target_state]).first if type_definition.feature?('canonicalize')
|
|
298
323
|
|
|
299
324
|
retrieve unless @rapi_current_state
|
|
@@ -348,7 +373,7 @@ module Puppet::ResourceApi
|
|
|
348
373
|
#:nocov:
|
|
349
374
|
# codecov fails to register this multiline as covered, even though simplecov does.
|
|
350
375
|
message = <<MESSAGE.strip
|
|
351
|
-
#{definition[:name]}[#{
|
|
376
|
+
#{definition[:name]}[#{@title}]#get has not provided canonicalized values.
|
|
352
377
|
Returned values: #{current_state.inspect}
|
|
353
378
|
Canonicalized values: #{state_clone.inspect}
|
|
354
379
|
MESSAGE
|
|
@@ -372,6 +397,31 @@ MESSAGE
|
|
|
372
397
|
self.class.context
|
|
373
398
|
end
|
|
374
399
|
|
|
400
|
+
define_singleton_method(:title_patterns) do
|
|
401
|
+
@title_patterns ||= if definition.key? :title_patterns
|
|
402
|
+
parse_title_patterns(definition[:title_patterns])
|
|
403
|
+
else
|
|
404
|
+
[[%r{(.*)}m, [[type_definition.namevars.first]]]]
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Creates a `title_pattern` compatible data structure to pass to the underlying puppet runtime environment.
|
|
409
|
+
# It uses the named items in the regular expression to connect the dots
|
|
410
|
+
#
|
|
411
|
+
# @example `[ %r{^(?<package>.*[^-])-(?<manager>.*)$} ]` becomes
|
|
412
|
+
# [
|
|
413
|
+
# [
|
|
414
|
+
# %r{^(?<package>.*[^-])-(?<manager>.*)$},
|
|
415
|
+
# [ [:package], [:manager] ]
|
|
416
|
+
# ],
|
|
417
|
+
# ]
|
|
418
|
+
def self.parse_title_patterns(patterns)
|
|
419
|
+
patterns.map do |item|
|
|
420
|
+
regex = Regexp.new(item[:pattern])
|
|
421
|
+
[item[:pattern], regex.names.map { |x| [x.to_sym] }]
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
375
425
|
[:autorequire, :autobefore, :autosubscribe, :autonotify].each do |auto|
|
|
376
426
|
next unless definition[auto]
|
|
377
427
|
|
|
@@ -420,18 +470,32 @@ MESSAGE
|
|
|
420
470
|
end
|
|
421
471
|
end
|
|
422
472
|
|
|
423
|
-
|
|
424
|
-
|
|
473
|
+
def self.caller_is_resource_app?
|
|
474
|
+
caller.any? { |c| c.match(%r{application/resource.rb:}) }
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# This method handles translating values from the runtime environment to the expected types for the provider.
|
|
478
|
+
# When being called from `puppet resource`, it tries to transform the strings from the command line into their
|
|
479
|
+
# expected ruby representations, e.g. `"2"` (a string), will be transformed to `2` (the number) if (and only if)
|
|
480
|
+
# the target `type` is `Integer`.
|
|
481
|
+
# Additionally this function also validates that the passed in (and optionally transformed) value matches the
|
|
482
|
+
# specified type.
|
|
425
483
|
# @param type[Puppet::Pops::Types::TypedModelObject] the type to check/clean against
|
|
426
484
|
# @param value the value to clean
|
|
427
485
|
# @param error_msg_prefix[String] a prefix for the error messages
|
|
428
486
|
# @return [type] the cleaned value
|
|
429
487
|
# @raise [Puppet::ResourceError] if `value` could not be parsed into `type`
|
|
430
488
|
def self.mungify(type, value, error_msg_prefix)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
489
|
+
if caller_is_resource_app?
|
|
490
|
+
# When the provider is exercised from the `puppet resource` CLI, we need to unpack strings into
|
|
491
|
+
# the correct types, e.g. "1" (a string) to 1 (an integer)
|
|
492
|
+
cleaned_value, error_msg = try_mungify(type, value, error_msg_prefix)
|
|
493
|
+
raise Puppet::ResourceError, error_msg if error_msg
|
|
494
|
+
else
|
|
495
|
+
# Every other time, we can use the values as is
|
|
496
|
+
cleaned_value = value
|
|
497
|
+
end
|
|
498
|
+
Puppet::ResourceApi.validate(type, cleaned_value, error_msg_prefix)
|
|
435
499
|
cleaned_value
|
|
436
500
|
end
|
|
437
501
|
|
|
@@ -494,13 +558,41 @@ MESSAGE
|
|
|
494
558
|
# fall through to default handling
|
|
495
559
|
end
|
|
496
560
|
|
|
497
|
-
|
|
498
|
-
|
|
561
|
+
error_msg = try_validate(type, value, error_msg_prefix)
|
|
562
|
+
if error_msg
|
|
563
|
+
# an error :-(
|
|
564
|
+
[nil, error_msg]
|
|
565
|
+
else
|
|
566
|
+
# a match!
|
|
567
|
+
[value, nil]
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
# Validates the `value` against the specified `type`.
|
|
572
|
+
# @param type[Puppet::Pops::Types::TypedModelObject] the type to check against
|
|
573
|
+
# @param value the value to clean
|
|
574
|
+
# @param error_msg_prefix[String] a prefix for the error messages
|
|
575
|
+
# @raise [Puppet::ResourceError] if `value` is not of type `type`
|
|
576
|
+
# @private
|
|
577
|
+
def self.validate(type, value, error_msg_prefix)
|
|
578
|
+
error_msg = try_validate(type, value, error_msg_prefix)
|
|
579
|
+
|
|
580
|
+
raise Puppet::ResourceError, error_msg if error_msg
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# Tries to validate the `value` against the specified `type`.
|
|
584
|
+
# @param type[Puppet::Pops::Types::TypedModelObject] the type to check against
|
|
585
|
+
# @param value the value to clean
|
|
586
|
+
# @param error_msg_prefix[String] a prefix for the error messages
|
|
587
|
+
# @return [String, nil] a error message indicating the problem, or `nil` if the value was valid.
|
|
588
|
+
# @private
|
|
589
|
+
def self.try_validate(type, value, error_msg_prefix)
|
|
590
|
+
return nil if type.instance?(value)
|
|
499
591
|
|
|
500
592
|
# an error :-(
|
|
501
593
|
inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value)
|
|
502
594
|
error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch(error_msg_prefix, type, inferred_type)
|
|
503
|
-
|
|
595
|
+
error_msg
|
|
504
596
|
end
|
|
505
597
|
|
|
506
598
|
def self.validate_ensure(definition)
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
1
3
|
module Puppet; end # rubocop:disable Style/Documentation
|
|
2
4
|
module Puppet::ResourceApi
|
|
3
5
|
# A trivial class to provide the functionality required to push data through the existing type/provider parts of puppet
|
|
4
6
|
class TypeShim
|
|
5
|
-
attr_reader :values, :typename, :
|
|
7
|
+
attr_reader :values, :typename, :namevars, :attr_def
|
|
6
8
|
|
|
7
|
-
def initialize(
|
|
9
|
+
def initialize(resource_hash, typename, namevars, attr_def)
|
|
8
10
|
# internalize and protect - needs to go deeper
|
|
9
|
-
@values = resource_hash.dup
|
|
10
|
-
# "name" is a privileged key
|
|
11
|
-
@values[namevarname] = title
|
|
12
|
-
@values.freeze
|
|
11
|
+
@values = resource_hash.dup.freeze
|
|
13
12
|
|
|
14
13
|
@typename = typename
|
|
15
|
-
@
|
|
14
|
+
@namevars = namevars
|
|
16
15
|
@attr_def = attr_def
|
|
16
|
+
@resource = ResourceShim.new(@values, @typename, @namevars, @attr_def)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def to_resource
|
|
20
|
-
|
|
20
|
+
@resource
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def name
|
|
24
|
-
|
|
24
|
+
@resource.title
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# A trivial class to provide the functionality required to push data through the existing type/provider parts of puppet
|
|
29
29
|
class ResourceShim
|
|
30
|
-
attr_reader :values, :typename, :
|
|
30
|
+
attr_reader :values, :typename, :namevars, :attr_def
|
|
31
31
|
|
|
32
|
-
def initialize(resource_hash, typename,
|
|
32
|
+
def initialize(resource_hash, typename, namevars, attr_def)
|
|
33
33
|
@values = resource_hash.dup.freeze # whatevs
|
|
34
34
|
@typename = typename
|
|
35
|
-
@
|
|
35
|
+
@namevars = namevars
|
|
36
36
|
@attr_def = attr_def
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def title
|
|
40
|
-
values[@
|
|
40
|
+
values[@namevars.first]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def prune_parameters(*_args)
|
|
@@ -46,7 +46,7 @@ module Puppet::ResourceApi
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def to_manifest
|
|
49
|
-
(["#{@typename} { #{
|
|
49
|
+
(["#{@typename} { #{Puppet::Parameter.format_value_for_display(title)}: "] + filtered_keys.map do |k|
|
|
50
50
|
cs = ' '
|
|
51
51
|
ce = ''
|
|
52
52
|
if attr_def[k][:behaviour] && attr_def[k][:behaviour] == :read_only
|
|
@@ -59,7 +59,13 @@ module Puppet::ResourceApi
|
|
|
59
59
|
|
|
60
60
|
# Convert our resource to yaml for Hiera purposes.
|
|
61
61
|
def to_hierayaml
|
|
62
|
-
|
|
62
|
+
attributes = Hash[filtered_keys.map { |k| [k.to_s, values[k]] }]
|
|
63
|
+
YAML.dump('type' => { title => attributes }).split("\n").drop(2).join("\n") + "\n"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# attribute names that are not title or namevars
|
|
67
|
+
def filtered_keys
|
|
68
|
+
values.keys.reject { |k| k == :title || attr_def[k][:behaviour] == :namevar && @namevars.size == 1 }
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
71
|
end
|
|
@@ -15,6 +15,12 @@ class Puppet::ResourceApi::TypeDefinition
|
|
|
15
15
|
@definition[:attributes].key?(:ensure)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def namevars
|
|
19
|
+
@namevars ||= @definition[:attributes].select { |_name, options|
|
|
20
|
+
options.key?(:behaviour) && options[:behaviour] == :namevar
|
|
21
|
+
}.keys
|
|
22
|
+
end
|
|
23
|
+
|
|
18
24
|
# rubocop complains when this is named has_feature?
|
|
19
25
|
def feature?(feature)
|
|
20
26
|
supported = (definition[:features] && definition[:features].include?(feature))
|
|
@@ -16,7 +16,7 @@ Hi all,
|
|
|
16
16
|
|
|
17
17
|
We're pleased to announce that version X.Y.Z of the Resource API is being released today.
|
|
18
18
|
|
|
19
|
-
The Resource API provides a simple way to create new native resources in the form of types and providers for Puppet. It is provided as a Ruby gem to be referenced within modules. Support for it has been included as an experimental feature in version 1.4 of the Puppet Development Kit (`pdk new provider`). Use the [resource_api module](https://forge.puppet.com/puppetlabs/resource_api) to deploy it in your infrastructure.
|
|
19
|
+
The Resource API provides a simple way to create new native resources in the form of types and providers for Puppet. It is provided as a Ruby gem to be referenced within modules. Support for it has been included as an experimental feature in version 1.4 of the Puppet Development Kit (`pdk new provider`). Use the [resource_api module](https://forge.puppet.com/puppetlabs/resource_api) or the [puppet 6 nightly packages](https://groups.google.com/d/msg/puppet-users/N3LJGhsrqkU/TUEsq7VfDQAJ) to deploy it in your infrastructure.
|
|
20
20
|
|
|
21
21
|
The new release of the Resource API provides the following enhancements:
|
|
22
22
|
|
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.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Schmitt
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-05-
|
|
11
|
+
date: 2018-05-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: hocon
|
|
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
81
81
|
version: '0'
|
|
82
82
|
requirements: []
|
|
83
83
|
rubyforge_project:
|
|
84
|
-
rubygems_version: 2.7.
|
|
84
|
+
rubygems_version: 2.7.3
|
|
85
85
|
signing_key:
|
|
86
86
|
specification_version: 4
|
|
87
87
|
summary: This library provides a simple way to write new native resources for puppet.
|