On Monday, May 13, 2013 11:26:21 AM UTC-5, Eugene Brodsky wrote:
>
> Hi all,
> With the goal of making my code a little more DRY, I am trying to define 
> resource parameters in an array of hashes, and then create defined 
> resources from these array items. I am having trouble figuring out the 
> syntax for accessing the hash values for the hash currently being worked on 
> ("self?").
>
> Here's the code to make it clear:
>
> ##### Configuration arguments
>
> $sites = [{
>     sitedomain => 'site1.domain.dev',
>     repo => 'git@repo.address/Repo',
>     branch => 'develop',
>     serveralias => "",
>     priority => '010'
>   },{
>     sitedomain => 'site2.domain.dev',
>     repo => 'git@repo.address/Repo',
>     branch => 'develop',
>     serveralias => "",
>     priority => '020'
>   },]
>
> #### Deploy configuration
>
> apache::vhost { $sites :
>   priority => ${????}[priority],
>   sitedomain => ${????}[sitedomain],
>   serveralias => ${????}[serveralias],
> }
> git::clone { $sites :
>   repo          => ${????}[repo],
>   branch        => ${????}[branch],
> }
>
> How do I access the hash values for the current hash? (trouble spots 
> marked with "????").
>
> I've experimented a lot while reading documentation and these forums, but 
> didn't get anywhere. I tried assigning each hash to a variable, but I still 
> can't get at that variable's name from within resource definition.
>
> Is what i'm trying to do even possible? Or am I stuck copying and pasting 
> the roughly identical block of code for every site that needs to be present 
> on the server?
>
> Thank you in advance for any insight.
>


The specific approach you are attempting will not work, but there are 
variations that will.

First off, the title of a resource is always a string.  Not a hash, not an 
array, but a string.  Puppet DSL provides a shortcut for declaring multiple 
resources (native or defined-type) having the same parameters, by writing a 
single resource declaration where the (string) titles are given as an array 
literal or an array-valued variable.  The result is exactly equivalent to 
multiple resource declarations, one for each given title, each with the 
specified parameters.  That shortcut does not generalize.  It never makes 
sense to specify a hash as a resource title, nor an array containing any 
non-string values.

Moreover, all elements of a resource declaration itself are evaluated in 
the context in which the declaration appears.  That applies here in that 
inside your resource *declarations*, there cannot be a sense of a 'current' 
element of a composite title.  That sort of thing has to go into the *
implementation* of the resource type (where the 'current' element is just 
the plain resource title of one of several similar resources).  Again: 
titles are always strings.

Back to the question of how you achieve what you're after.  There are at 
least two relatively straightforward ways, both requiring a slightly 
different form for your data.  Instead of an array of hashes, you need a 
hash of hashes, with the keys of the outer hash being identifying strings 
suitable for use as resource titles or parts of them.  The inner hashes can 
be similar or perhaps the same as the parameter hashes you have now.  For 
example:

$sites = {
  'site1' => {
    sitedomain => 'site1.domain.dev',
    repo => 'git@repo.address/Repo',
    branch => 'develop',
    serveralias => "",
    priority => '010'
  }, 
  ...
}


Having your data in that general form, you have two basic alternatives:

   1. Use the built-in create_resources() function
   2. Create a defined type that performs a similar function

If, as in your case, your inner hashes combine parameters for resources of 
different types, option (1) would require a defined-type wrapper to use as 
the resource type passed to create_resources(), so that doesn't end up 
being any simpler.  You should read docs for that function, but there isn't 
really much more to say.  I will illustrate the alternative, however.

The defined type you need for option (2) is a bit different from the one 
you would need for option (1).  In this case, the defined type needs only 
one parameter, that being the hash of hashes:

define mymodule::site($sites) {
  include 'apache'  # if necessary
  include 'git'         # if necessary

  # Select the inner hash for this site from
  # the hash of hashes, using this resource's
  # title as the key:
  $site_data = $sites[$title]

  # Declare resources

  apache::vhost { "${title}-vhost" :
    priority => $site_data['priority'],
    sitedomain => $site_data['sitedomain'],
    serveralias => $site_data['serveralias'],
  }

  git::clone { "${title}-git" :
    repo          => $site_data['repo'],
    branch        => $site_data['branch'],
  }
}

You use then that defined type like so:

class somemodule::someclass {
  $site_names = <see below>
  mymodule::sites { $keys: sites => $sites }
}

The last bit is how to get the site names.  It may be the case that which 
sites to declare is a separate question from which sites' parameters are 
recorded in the $sites hash, in which case you'll have to determine for 
yourself how to get a suitable array of site names (each being one of the 
keys of the $sites hash).

If you just want to declare them all, however, then PuppetLabs's add-in 
'stdlib' module provides a keys() function that will return an array of the 
keys of a hash, which is just what you want for this purpose.  Or you can 
roll your own; by itself, a keys() function is not very hard.

$site_names = keys(sites)


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-users+unsubscr...@googlegroups.com.
To post to this group, send email to puppet-users@googlegroups.com.
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to