11require 'pathname'
22require 'puppet/resource_api/data_type_handling'
33require 'puppet/resource_api/glue'
4+ require 'puppet/resource_api/parameter'
5+ require 'puppet/resource_api/property'
46require 'puppet/resource_api/puppet_context' unless RUBY_PLATFORM == 'java'
7+ require 'puppet/resource_api/read_only_parameter'
58require 'puppet/resource_api/type_definition'
9+ require 'puppet/resource_api/value_creator'
610require 'puppet/resource_api/version'
711require 'puppet/type'
812require 'puppet/util/network_device'
@@ -174,13 +178,23 @@ def to_resource
174178 # TODO: using newparam everywhere would suppress change reporting
175179 # that would allow more fine-grained reporting through context,
176180 # but require more invest in hooking up the infrastructure to emulate existing data
177- param_or_property = if [ :read_only , :parameter , :namevar ] . include? options [ :behaviour ]
178- :newparam
179- else
180- :newproperty
181- end
181+ if [ :parameter , :namevar ] . include? options [ :behaviour ]
182+ param_or_property = :newparam
183+ parent = Puppet ::ResourceApi ::Parameter
184+ elsif options [ :behaviour ] == :read_only
185+ param_or_property = :newparam
186+ parent = Puppet ::ResourceApi ::ReadOnlyParameter
187+ else
188+ param_or_property = :newproperty
189+ parent = Puppet ::ResourceApi ::Property
190+ end
182191
183- send ( param_or_property , name . to_sym ) do
192+ # This call creates a new parameter or property with all work-arounds or
193+ # customizations required by the Resource API applied. Under the hood,
194+ # this maps to the relevant DSL methods in Puppet::Type. See
195+ # https://puppet.com/docs/puppet/6.0/custom_types.html#reference-5883
196+ # for details.
197+ send ( param_or_property , name . to_sym , parent : parent ) do
184198 unless options [ :type ]
185199 raise Puppet ::DevError , "#{ definition [ :name ] } .#{ name } has no type"
186200 end
@@ -191,144 +205,32 @@ def to_resource
191205 warn ( "#{ definition [ :name ] } .#{ name } has no docs" )
192206 end
193207
194- if options [ :behaviour ] == :namevar
195- isnamevar
196- end
197-
198- # read-only values do not need type checking, but can have default values
199- if options [ :behaviour ] != :read_only && options . key? ( :default )
200- if options . key? :default
201- if options [ :default ] == false
202- # work around https://tickets.puppetlabs.com/browse/PUP-2368
203- defaultto :false # rubocop:disable Lint/BooleanSymbol
204- elsif options [ :default ] == true
205- # work around https://tickets.puppetlabs.com/browse/PUP-2368
206- defaultto :true # rubocop:disable Lint/BooleanSymbol
207- else
208- # marshal the default option to decouple that from the actual value.
209- # we cache the dumped value in `marshalled`, but use a block to unmarshal
210- # everytime the value is requested. Objects that can't be marshalled
211- # See https://stackoverflow.com/a/8206537/4918
212- marshalled = Marshal . dump ( options [ :default ] )
213- defaultto { Marshal . load ( marshalled ) } # rubocop:disable Security/MarshalLoad
214- end
215- end
208+ # The initialize method is called when puppet core starts building up
209+ # type objects. The core passes in a hash of shape { resource:
210+ # #<Puppet::Type::TypeName> }. We use this to pass through the
211+ # required configuration data to the parent (see
212+ # Puppet::ResourceApi::Property, Puppet::ResourceApi::Parameter and
213+ # Puppet::ResourceApi::ReadOnlyParameter).
214+ define_method ( :initialize ) do |resource_hash |
215+ super ( definition [ :name ] , self . class . data_type , name , resource_hash )
216216 end
217217
218- if name == :ensure
219- def insync? ( is )
220- rs_value . to_s == is . to_s
221- end
218+ # get pops data type object for this parameter or property
219+ define_singleton_method ( :data_type ) do
220+ @rsapi_data_type ||= Puppet ::ResourceApi ::DataTypeHandling . parse_puppet_type (
221+ name ,
222+ options [ :type ] ,
223+ )
222224 end
223225
224- type = Puppet ::ResourceApi ::DataTypeHandling . parse_puppet_type (
225- name ,
226- options [ :type ] ,
226+ # from ValueCreator call create_values which makes alias values and
227+ # default values for properties and params
228+ Puppet ::ResourceApi ::ValueCreator . create_values (
229+ self ,
230+ data_type ,
231+ param_or_property ,
232+ options ,
227233 )
228-
229- if param_or_property == :newproperty
230- define_method ( :should ) do
231- if name == :ensure && rs_value . is_a? ( String )
232- rs_value . to_sym
233- elsif rs_value == false
234- # work around https://tickets.puppetlabs.com/browse/PUP-2368
235- :false # rubocop:disable Lint/BooleanSymbol
236- elsif rs_value == true
237- # work around https://tickets.puppetlabs.com/browse/PUP-2368
238- :true # rubocop:disable Lint/BooleanSymbol
239- else
240- rs_value
241- end
242- end
243-
244- define_method ( :should= ) do |value |
245- @shouldorig = value
246-
247- if name == :ensure
248- value = value . to_s
249- end
250-
251- # Puppet requires the @should value to always be stored as an array. We do not use this
252- # for anything else
253- # @see Puppet::Property.should=(value)
254- @should = [
255- Puppet ::ResourceApi ::DataTypeHandling . mungify (
256- type ,
257- value ,
258- "#{ definition [ :name ] } .#{ name } " ,
259- Puppet ::ResourceApi . caller_is_resource_app? ,
260- ) ,
261- ]
262- end
263-
264- # used internally
265- # @returns the final mungified value of this property
266- define_method ( :rs_value ) do
267- @should ? @should . first : @should
268- end
269- else
270- define_method ( :value ) do
271- @value
272- end
273-
274- define_method ( :value= ) do |value |
275- if options [ :behaviour ] == :read_only
276- raise Puppet ::ResourceError , "Attempting to set `#{ name } ` read_only attribute value to `#{ value } `"
277- end
278-
279- @value = Puppet ::ResourceApi ::DataTypeHandling . mungify (
280- type ,
281- value ,
282- "#{ definition [ :name ] } .#{ name } " ,
283- Puppet ::ResourceApi . caller_is_resource_app? ,
284- )
285- end
286-
287- # used internally
288- # @returns the final mungified value of this parameter
289- define_method ( :rs_value ) do
290- @value
291- end
292- end
293-
294- # puppet symbolizes some values through puppet/parameter/value.rb (see .convert()), but (especially) Enums
295- # are strings. specifying a munge block here skips the value_collection fallback in puppet/parameter.rb's
296- # default .unsafe_munge() implementation.
297- munge { |v | v }
298-
299- # provide hints to `puppet type generate` for better parsing
300- if type . instance_of? Puppet ::Pops ::Types ::POptionalType
301- type = type . type
302- end
303-
304- case type
305- when Puppet ::Pops ::Types ::PStringType
306- # require any string value
307- Puppet ::ResourceApi . def_newvalues ( self , param_or_property , %r{} )
308- when Puppet ::Pops ::Types ::PBooleanType
309- Puppet ::ResourceApi . def_newvalues ( self , param_or_property , 'true' , 'false' )
310- aliasvalue true , 'true'
311- aliasvalue false , 'false'
312- aliasvalue :true , 'true' # rubocop:disable Lint/BooleanSymbol
313- aliasvalue :false , 'false' # rubocop:disable Lint/BooleanSymbol
314-
315- when Puppet ::Pops ::Types ::PIntegerType
316- Puppet ::ResourceApi . def_newvalues ( self , param_or_property , %r{^-?\d +$} )
317- when Puppet ::Pops ::Types ::PFloatType , Puppet ::Pops ::Types ::PNumericType
318- Puppet ::ResourceApi . def_newvalues ( self , param_or_property , Puppet ::Pops ::Patterns ::NUMERIC )
319- end
320-
321- if param_or_property == :newproperty
322- # stop puppet from trying to call into the provider when
323- # no pre-defined values have been specified
324- # "This is not the provider you are looking for." -- Obi-Wan Kaniesobi.
325- def call_provider ( value ) ; end
326- end
327-
328- case options [ :type ]
329- when 'Enum[present, absent]'
330- Puppet ::ResourceApi . def_newvalues ( self , param_or_property , 'absent' , 'present' )
331- end
332234 end
333235 end
334236
@@ -582,17 +484,6 @@ def self.class_name_from_type_name(type_name)
582484 type_name . to_s . split ( '_' ) . map ( &:capitalize ) . join
583485 end
584486
585- # Add the value to `this` property or param, depending on whether param_or_property is `:newparam`, or `:newproperty`
586- def self . def_newvalues ( this , param_or_property , *values )
587- if param_or_property == :newparam
588- this . newvalues ( *values )
589- else
590- values . each do |v |
591- this . newvalue ( v ) { }
592- end
593- end
594- end
595-
596487 def self . caller_is_resource_app?
597488 caller . any? { |c | c . match ( %r{application/resource.rb:} ) }
598489 end
0 commit comments