On Wednesday, November 5, 2014 8:37:08 PM UTC-6, henrik lindberg wrote:
>
> 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. 
>
>

Purging unmanaged resources is what Resources can do now, but I've always 
thought the original idea was much grander.  The type's own documentation 
is couched partially in terms of generating resource instances, which  fits 
with "managing [otherwise] unmanaged resources", but it also described as 
"managing other resource types", which sounds like something different.  I 
suspect that some of the features that might otherwise have been 
implemented via the Resources type went other places instead (especially 
into collectors).
 

> 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). 
>


Yes, I think this essential problem stunted the development of the 
Resources type.


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.



Most everyone here should be deeply familiar with this pattern, though they 
may not know it by name.  Puppet has relied on it forever in the form of 
resource providers.

I'm not sure it quite fits the situation, though, because fundamental to 
the Strategy pattern is a common view of the inputs directing the work to 
be performed.  For strategies to be applicable to a very general problem, 
such as "managing unmanaged resources", the form of the inputs must be very 
general.  If you went down this path you would soon have to consider what 
you are gaining by using the Resources type as a front end.

 

> 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). 
>
>

I'm not buying that.  The adapter pattern works fine for resources in 
general, including specifying non-default strategies (providers) for 
particular resources.  This is a problem that could be solved for Resources 
--  for instance, by using the existing provider system, as Felix suggested.

 

> 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. 
>
>

So the idea here is what?  Resource instances for unmanaged physical 
resources of the specified type(s) are created, with the specified 
parameters, to manage those physical resources?

Or are the options supposed to effectively be resource-type-specific 
parameters to some sort of "things_Resources_can_do_with_this_type()" 
function that all resources will provide?  If the latter, then what are the 
implications for providers?

 

> 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). 
>


Are you supposing that this would be limited to purging unmanaged 
resources, or is that just an example?  I know there are issues with 
purging resources of types that don't prefetch or that aren't Ensurable, 
but if that's all you're going after then this sounds a bit out of 
proportion.
 
 

>
> 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. 
>
>

I know that the type system is a shiny new toy, and it has lots of promise, 
but it seems a lot lower level than the Resources metatype.  I am not 
enthusiastic about putting low-level hooks into the type system intended 
narrowly for the Resources type to manipulate.  I could, however, get 
behind something more generic, such as a mechanism in the type system by 
which information about the parameters supported by a resource type can be 
exposed.

Having said all that, I can completely get behind Luke's idea to provide 
for client-side queries.  I am confused, however, as to why the ideas for 
that seem to be running in directions such as overloading resource titles 
and introducing new collector-like forms, when the entire purpose of the 
Resources type is to serve this kind of function.  Why not just add a 
parameter to Resources to specify the a query predicate (the default being 
something like "!managed", and another to specify a hash of resource 
properties to set, e.g. { ensure => absent }.  Deprecate the existing 
'purge' and 'unless_system_user' parameters.  This would look similar to 
some of the forms being proposed, but it would rely mostly on existing 
facilities for everything other than actually performing queries.  Example:

resources { 'remove-unmanaged-users':
  name  => 'user',
  match => "uid > 100 && !managed",
  set   => { ensure => 'absent' }
}

I admit that I'm a bit leery of the "!managed" bit of the predicate, as its 
presence suggests that maybe it can be omitted to allow whatever is 
implemented for this to modify the properties of *managed* resources, too.  
This could be especially nasty if it were possible to stack these things so 
that more than one applies to the same resource.  *I urge that that 
possibility be foreclosed*, at least in the initial implementation.  It can 
be added later if there turns out to be sufficient justification, but it 
cannot easily be taken away once granted.


John


-- 
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/f0897a62-e231-4313-9b9b-7e24fa0be577%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to