puppet-resource_api 1.8.9 → 1.8.14
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/.dependency_decisions.yml +9 -9
- data/.github/dependabot.yml +12 -0
- data/.rubocop.yml +1 -1
- data/.travis.yml +12 -48
- data/CHANGELOG.md +138 -24
- data/Gemfile +39 -17
- data/HISTORY.md +0 -5
- data/README.md +6 -6
- data/appveyor.yml +3 -3
- data/contrib/pre-commit +2 -0
- data/docs/README.md +7 -0
- data/docs/hands-on-lab/01-installing-prereqs.md +16 -0
- data/docs/hands-on-lab/02-connecting-to-the-lightbulbs-emulator.png +0 -0
- data/docs/hands-on-lab/02-connecting-to-the-lightbulbs.md +26 -0
- data/docs/hands-on-lab/03-creating-a-new-module.md +47 -0
- data/docs/hands-on-lab/03-creating-a-new-module_vscode.png +0 -0
- data/docs/hands-on-lab/04-adding-a-new-transport.md +123 -0
- data/docs/hands-on-lab/05-implementing-the-transport-hints.md +19 -0
- data/docs/hands-on-lab/05-implementing-the-transport.md +126 -0
- data/docs/hands-on-lab/06-implementing-the-provider.md +227 -0
- data/docs/hands-on-lab/07-implementing-a-task.md +181 -0
- data/lib/puppet/resource_api.rb +95 -55
- data/lib/puppet/resource_api/base_context.rb +6 -0
- data/lib/puppet/resource_api/data_type_handling.rb +2 -0
- data/lib/puppet/resource_api/glue.rb +9 -2
- data/lib/puppet/resource_api/io_context.rb +2 -0
- data/lib/puppet/resource_api/parameter.rb +4 -2
- data/lib/puppet/resource_api/property.rb +65 -5
- data/lib/puppet/resource_api/puppet_context.rb +2 -0
- data/lib/puppet/resource_api/read_only_parameter.rb +2 -0
- data/lib/puppet/resource_api/simple_provider.rb +2 -0
- data/lib/puppet/resource_api/transport.rb +2 -0
- data/lib/puppet/resource_api/transport/wrapper.rb +2 -0
- data/lib/puppet/resource_api/type_definition.rb +63 -3
- data/lib/puppet/resource_api/value_creator.rb +2 -0
- data/lib/puppet/resource_api/version.rb +3 -1
- data/lib/puppet/util/network_device/simple/device.rb +2 -0
- metadata +15 -4
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puppet/util'
|
2
4
|
require 'puppet/parameter'
|
3
5
|
|
@@ -13,11 +15,11 @@ class Puppet::ResourceApi::Parameter < Puppet::Parameter
|
|
13
15
|
# @param attribute_name the name of attribue of the parameter
|
14
16
|
# @param resource_hash the resource hash instance which is passed to the
|
15
17
|
# parent class.
|
16
|
-
def initialize(type_name, data_type, attribute_name, resource_hash)
|
18
|
+
def initialize(type_name, data_type, attribute_name, resource_hash, _referrable_type = nil)
|
17
19
|
@type_name = type_name
|
18
20
|
@data_type = data_type
|
19
21
|
@attribute_name = attribute_name
|
20
|
-
super(resource_hash) # Pass resource to parent Puppet class.
|
22
|
+
super(**resource_hash) # Pass resource to parent Puppet class.
|
21
23
|
end
|
22
24
|
|
23
25
|
# This method assigns value to the parameter and cleans value.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puppet/util'
|
2
4
|
require 'puppet/property'
|
3
5
|
|
@@ -11,14 +13,31 @@ class Puppet::ResourceApi::Property < Puppet::Property
|
|
11
13
|
# @param attribute_name the name of attribue of the property
|
12
14
|
# @param resource_hash the resource hash instance which is passed to the
|
13
15
|
# parent class.
|
14
|
-
def initialize(type_name, data_type, attribute_name, resource_hash)
|
16
|
+
def initialize(type_name, data_type, attribute_name, resource_hash, referrable_type = nil)
|
15
17
|
@type_name = type_name
|
16
18
|
@data_type = data_type
|
17
19
|
@attribute_name = attribute_name
|
18
|
-
|
19
|
-
|
20
|
+
@resource = resource_hash[:resource]
|
21
|
+
@referrable_type = referrable_type
|
22
|
+
|
23
|
+
# Do not want to define insync on the base class because
|
24
|
+
# this overrides for everything instead of only for the
|
25
|
+
# appropriate instance/class of the property.
|
26
|
+
if self.class != Puppet::ResourceApi::Property
|
27
|
+
# Define class method insync?(is) if the custom_insync feature flag is set
|
28
|
+
if referrable_type&.type_definition&.feature?('custom_insync')
|
29
|
+
def_custom_insync?
|
30
|
+
if @attribute_name == :rsapi_custom_insync_trigger
|
31
|
+
@change_to_s_value = 'Custom insync logic determined that this resource is out of sync'
|
32
|
+
end
|
33
|
+
# Define class method insync?(is) if the name is :ensure and custom_insync feature flag is not set
|
34
|
+
elsif @attribute_name == :ensure
|
35
|
+
def_ensure_insync?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
20
39
|
# Pass resource to parent Puppet class.
|
21
|
-
super(resource_hash)
|
40
|
+
super(**resource_hash)
|
22
41
|
end
|
23
42
|
|
24
43
|
# This method returns value of the property.
|
@@ -69,10 +88,51 @@ class Puppet::ResourceApi::Property < Puppet::Property
|
|
69
88
|
# method overloaded only for the :ensure property, add option to check if the
|
70
89
|
# rs_value matches is. Only if the class is child of
|
71
90
|
# Puppet::ResourceApi::Property.
|
72
|
-
def
|
91
|
+
def def_ensure_insync?
|
73
92
|
define_singleton_method(:insync?) { |is| rs_value.to_s == is.to_s }
|
74
93
|
end
|
75
94
|
|
95
|
+
def def_custom_insync?
|
96
|
+
define_singleton_method(:insync?) do |is|
|
97
|
+
provider = @referrable_type.my_provider
|
98
|
+
context = @referrable_type.context
|
99
|
+
should_hash = @resource.rsapi_canonicalized_target_state
|
100
|
+
is_hash = @resource.rsapi_current_state
|
101
|
+
title = @resource.rsapi_title
|
102
|
+
|
103
|
+
raise(Puppet::DevError, 'No insync? method defined in the provider; an insync? method must be defined if the custom_insync feature is defined for the type') unless provider.respond_to?(:insync?)
|
104
|
+
|
105
|
+
provider_insync_result, change_message = provider.insync?(context, title, @attribute_name, is_hash, should_hash)
|
106
|
+
|
107
|
+
unless provider_insync_result.nil? || change_message.nil? || change_message.empty?
|
108
|
+
@change_to_s_value = change_message
|
109
|
+
end
|
110
|
+
|
111
|
+
case provider_insync_result
|
112
|
+
when nil
|
113
|
+
# If validating ensure and no custom insync was used, check if rs_value matches is.
|
114
|
+
return rs_value.to_s == is.to_s if @attribute_name == :ensure
|
115
|
+
# Otherwise, super and rely on Puppet::Property.insync?
|
116
|
+
super(is)
|
117
|
+
when TrueClass, FalseClass
|
118
|
+
return provider_insync_result
|
119
|
+
else
|
120
|
+
# When returning anything else, raise a DevError for a non-idiomatic return
|
121
|
+
raise(Puppet::DevError, "Custom insync for #{@attribute_name} returned a #{provider_insync_result.class} with a value of #{provider_insync_result.inspect} instead of true/false; insync? MUST return nil or the boolean true or false") # rubocop:disable Metrics/LineLength
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
define_singleton_method(:change_to_s) do |current_value, newvalue|
|
126
|
+
# As defined in the custom insync? method, it is sometimes useful to overwrite the default change messaging;
|
127
|
+
# The enables a user to return a more useful change report than a strict "is to should" report.
|
128
|
+
# If @change_to_s_value is not set, Puppet writes a generic change notification, like:
|
129
|
+
# Notice: /Stage[main]/Main/<type_name>[<name_hash>]/<property name>: <property name> changed <is value> to <should value>
|
130
|
+
# If #change_to_s_value is *nil* Puppet writes a weird empty message like:
|
131
|
+
# Notice: /Stage[main]/Main/<type_name>[<name_hash>]/<property name>:
|
132
|
+
@change_to_s_value || super(current_value, newvalue)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
76
136
|
# puppet symbolizes some values through puppet/parameter/value.rb
|
77
137
|
# (see .convert()), but (especially) Enums are strings. specifying a
|
78
138
|
# munge block here skips the value_collection fallback in
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Provides accessor methods for the type being provided
|
2
4
|
module Puppet::ResourceApi
|
3
5
|
# pre-declare class
|
@@ -15,7 +17,11 @@ module Puppet::ResourceApi
|
|
15
17
|
|
16
18
|
# rubocop complains when this is named has_feature?
|
17
19
|
def feature?(feature)
|
18
|
-
|
20
|
+
definition[:features]&.include?(feature)
|
21
|
+
end
|
22
|
+
|
23
|
+
def title_patterns
|
24
|
+
definition[:title_patterns] ||= []
|
19
25
|
end
|
20
26
|
|
21
27
|
def validate_schema(definition, attr_key)
|
@@ -30,10 +36,56 @@ module Puppet::ResourceApi
|
|
30
36
|
Puppet::ResourceApi::DataTypeHandling.validate_ensure(definition)
|
31
37
|
|
32
38
|
definition[:features] ||= []
|
33
|
-
supported_features = %w[supports_noop canonicalize remote_resource simple_get_filter].freeze
|
39
|
+
supported_features = %w[supports_noop canonicalize custom_insync remote_resource simple_get_filter].freeze
|
34
40
|
unknown_features = definition[:features] - supported_features
|
35
41
|
Puppet.warning("Unknown feature detected: #{unknown_features.inspect}") unless unknown_features.empty?
|
36
42
|
end
|
43
|
+
|
44
|
+
# This call creates a new parameter or property with all work-arounds or
|
45
|
+
# customizations required by the Resource API applied. Under the hood,
|
46
|
+
# this maps to the relevant DSL methods in Puppet::Type. See
|
47
|
+
# https://puppet.com/docs/puppet/6.0/custom_types.html#reference-5883
|
48
|
+
# for details.
|
49
|
+
#
|
50
|
+
# type: the Resource API Type the attribute is being created in
|
51
|
+
# attribute_name: the name of the attribute being created
|
52
|
+
# param_or_property: Whether to call the :newparam or :newproperty method
|
53
|
+
# parent: The type of attribute to create: Property, ReadOnly, or Parameter
|
54
|
+
# options: The hash of attribute options, including type, desc, default, and behaviour
|
55
|
+
def create_attribute_in(type, attribute_name, param_or_property, parent, options)
|
56
|
+
type.send(param_or_property, attribute_name.to_sym, parent: parent) do
|
57
|
+
if options[:desc]
|
58
|
+
desc "#{options[:desc]} (a #{options[:type]})"
|
59
|
+
end
|
60
|
+
|
61
|
+
# The initialize method is called when puppet core starts building up
|
62
|
+
# type objects. The core passes in a hash of shape { resource:
|
63
|
+
# #<Puppet::Type::TypeName> }. We use this to pass through the
|
64
|
+
# required configuration data to the parent (see
|
65
|
+
# Puppet::ResourceApi::Property, Puppet::ResourceApi::Parameter and
|
66
|
+
# Puppet::ResourceApi::ReadOnlyParameter).
|
67
|
+
define_method(:initialize) do |resource_hash|
|
68
|
+
super(type.name, self.class.data_type, attribute_name, resource_hash, type)
|
69
|
+
end
|
70
|
+
|
71
|
+
# get pops data type object for this parameter or property
|
72
|
+
define_singleton_method(:data_type) do
|
73
|
+
@rsapi_data_type ||= Puppet::ResourceApi::DataTypeHandling.parse_puppet_type(
|
74
|
+
attribute_name,
|
75
|
+
options[:type],
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
# from ValueCreator call create_values which makes alias values and
|
80
|
+
# default values for properties and params
|
81
|
+
Puppet::ResourceApi::ValueCreator.create_values(
|
82
|
+
self,
|
83
|
+
data_type,
|
84
|
+
param_or_property,
|
85
|
+
options,
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
37
89
|
end
|
38
90
|
|
39
91
|
# RSAPI Transport schema
|
@@ -84,6 +136,13 @@ module Puppet::ResourceApi
|
|
84
136
|
}.keys
|
85
137
|
end
|
86
138
|
|
139
|
+
def insyncable_attributes
|
140
|
+
@insyncable_attributes ||= attributes.reject { |_name, options|
|
141
|
+
# Only attributes without any behavior are normal Puppet Properties and get insynced
|
142
|
+
options.key?(:behaviour)
|
143
|
+
}.keys
|
144
|
+
end
|
145
|
+
|
87
146
|
def validate_schema(definition, attr_key)
|
88
147
|
raise Puppet::DevError, '%{type_class} must be a Hash, not `%{other_type}`' % { type_class: self.class.name, other_type: definition.class } unless definition.is_a?(Hash)
|
89
148
|
@attributes = definition[attr_key]
|
@@ -106,6 +165,7 @@ module Puppet::ResourceApi
|
|
106
165
|
Puppet.warning('`%{name}` has no documentation, add it using a `desc` key' % { name: definition[:name] }) unless definition.key? :desc
|
107
166
|
|
108
167
|
attributes.each do |key, attr|
|
168
|
+
raise Puppet::DevError, '`rsapi_custom_insync_trigger` cannot be specified as an attribute; it is reserved for propertyless types with the custom_insync feature' if key == :rsapi_custom_insync_trigger # rubocop:disable Metrics/LineLength
|
109
169
|
raise Puppet::DevError, "`#{definition[:name]}.#{key}` must be a Hash, not a #{attr.class}" unless attr.is_a? Hash
|
110
170
|
raise Puppet::DevError, "`#{definition[:name]}.#{key}` has no type" unless attr.key? :type
|
111
171
|
Puppet.warning('`%{name}.%{key}` has no documentation, add it using a `desc` key' % { name: definition[:name], key: key }) unless attr.key? :desc
|
@@ -190,7 +250,7 @@ module Puppet::ResourceApi
|
|
190
250
|
if is_sensitive
|
191
251
|
bad_vals[key] = '<< redacted value >> ' + error_message unless error_message.nil?
|
192
252
|
else
|
193
|
-
bad_vals[key] = value unless error_message.nil?
|
253
|
+
bad_vals[key] = "#{value} (#{error_message})" unless error_message.nil?
|
194
254
|
end
|
195
255
|
end
|
196
256
|
bad_vals
|
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.8.
|
4
|
+
version: 1.8.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Schmitt
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hocon
|
@@ -33,6 +33,7 @@ extra_rdoc_files: []
|
|
33
33
|
files:
|
34
34
|
- ".dependency_decisions.yml"
|
35
35
|
- ".fixtures.yml"
|
36
|
+
- ".github/dependabot.yml"
|
36
37
|
- ".gitignore"
|
37
38
|
- ".rspec"
|
38
39
|
- ".rubocop.yml"
|
@@ -52,6 +53,17 @@ files:
|
|
52
53
|
- codecov.yml
|
53
54
|
- contrib/README.md
|
54
55
|
- contrib/pre-commit
|
56
|
+
- docs/README.md
|
57
|
+
- docs/hands-on-lab/01-installing-prereqs.md
|
58
|
+
- docs/hands-on-lab/02-connecting-to-the-lightbulbs-emulator.png
|
59
|
+
- docs/hands-on-lab/02-connecting-to-the-lightbulbs.md
|
60
|
+
- docs/hands-on-lab/03-creating-a-new-module.md
|
61
|
+
- docs/hands-on-lab/03-creating-a-new-module_vscode.png
|
62
|
+
- docs/hands-on-lab/04-adding-a-new-transport.md
|
63
|
+
- docs/hands-on-lab/05-implementing-the-transport-hints.md
|
64
|
+
- docs/hands-on-lab/05-implementing-the-transport.md
|
65
|
+
- docs/hands-on-lab/06-implementing-the-provider.md
|
66
|
+
- docs/hands-on-lab/07-implementing-a-task.md
|
55
67
|
- lib/puppet/resource_api.rb
|
56
68
|
- lib/puppet/resource_api/base_context.rb
|
57
69
|
- lib/puppet/resource_api/data_type_handling.rb
|
@@ -88,8 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
100
|
- !ruby/object:Gem::Version
|
89
101
|
version: '0'
|
90
102
|
requirements: []
|
91
|
-
|
92
|
-
rubygems_version: 2.7.6.2
|
103
|
+
rubygems_version: 3.2.5
|
93
104
|
signing_key:
|
94
105
|
specification_version: 4
|
95
106
|
summary: This library provides a simple way to write new native resources for puppet.
|