puppet-resource_api 1.8.9 → 1.8.14
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|