Hi,
I am bringing up this topic because of a recent discussion and PR for
the ticket https://tickets.puppetlabs.com/browse/PUP-1486
Here is a recap.
The Resources resource is used to "manage unmanaged" resources of a
particular given type - e.g. to purge users, groups etc. that are not
otherwise managed.
The issues are that "managing the unmanaged" may require additional
attributes that are specific to the type that is referenced. The base
type only has the attributes "unless_system_user" and "unless_uid" (se
https://docs.puppetlabs.com/references/latest/type.html#resources for
the documentation).
At times it is suggested that the Resources type should have additional
attributes that are specific only to one type. This solution has the
obvious problem that over time, the Resource type would then have a very
large number of attributes for different types and the temptation will
be great to borrow attributes and apply similar semantics. Over time
this solution will become unmanageable.
Another solution was proposed in PR-3269
(https://github.com/puppetlabs/puppet/pull/3269) which we closed for
various reasons.
The approach in the PR was to add a "newresourcesparam" to Puppet::Type
allowing this to define additional parameters to the Resources type.
An obvious problem with this approach is the need to load all types in
order to check the validity of attributes of a Resources instance.
Instead, I would like to see something where the concerns are separated
(to avoid the problem of "the base class knows about all the things").
One good pattern is "the strategy pattern" / "adapter pattern" which is
used internally in the future parser. (You can read about this here:
http://puppet-on-the-edge.blogspot.se/2014/02/puppet-internals-adapter-pattern.html).
TL;DR - an adapter is responsible for "sticking a label" on someone else
without that someone having to be concerned about its existence,
protocol etc.
How can we achieve something similar in a simple way in Puppet?
One very simple approach is to add the basic ability to handle such
"adapters", or "extra data" if you like, in the Resources type. We
cannot use the actual adapter pattern since when it comes to resources,
they are serialized and processed in ways that would drop such adapters
(since those are really a runtime concept).
Proposal:
* Add the attribute options (with the type Array[Resource])
* Add the ability in a resource type to specify a list of type names
that it allows instances of as options (typically one)
* Add the ability in type to get the options.
Here is a simulation of the above using just user defined types - a type
"base" specifies that it takes an "option" that must be a reference to a
"Base_option":
define base_options($p1, $p2) {
}
define base(Resource[base_option] $option = undef) {
}
base { 'the_base':
extraref => Base_options[the_options]
}
base_options { the_options:
p1 => 'extra 1',
p2 => 'extra 2'
}
This way, everything ends up in the catalog. The same using Resources
would look like this:
resources { base:
options => [Base_options[the_options]]
}
How the rest of the protocol between Resources and the types that
support options should work is left to be designed, but basically; the
Resources implementation should present the options to the type either
for just asking if a particular resource should be purged or not (as it
does now but done as a delegation to the particular type).
I think this design is:
* type safe - it is possible to statically check the combination of the
managed type, the options it supports, and the type of the entries in
options.
* The optional type can be a user defined type - all that is needed are
the parameter values specified by the user.
* A user defined type can be name-spaced
Alternative - using the type system in Puppet 4.0
Another alternative is to simply use the new type system in Puppet 4.0.
A type that supports options to Resources returns a Struct type that
describes the options. (A Struct is a detailed type specification of a
hash). (Read more about the Struct type here:
http://puppet-on-the-edge.blogspot.se/2014/02/adding-struct-and-tuple-to-puppet-type.html)
In the catalog a Struct type is simply encoded as a String, and it is
easily converted back to an instance of the type which can be used for
type checking the options received from the Resources type.
Thoughts?
- henrik
--
Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/
--
You received this message because you are subscribed to the Google Groups "Puppet
Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/puppet-dev/m3ems4%24qu3%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.