Arrays and case statements

407 views
Skip to first unread message

Kim Scarborough

unread,
Feb 21, 2014, 4:47:19 PM2/21/14
to puppet...@googlegroups.com
So I have a bunch of linux servers in different groups. Each server's group is defined as a custom fact. I want to set an array variable based on the server's group membership, so I have code like this:

case $servergroup {
    MAMMAL:  { $foo = ['horse', 'cow', 'dog'] }
    REPTILE: { $foo = ['gator', 'frog'] }
    BIRD:    { $foo = ['finch', 'chicken'] }
}


This works fine. The problem is that now I have a server that needs to be in two groups. I know I can convert a custom fact into an array like this:

$slist = split($servergroup, ',')

But I don't know how to have each value in the array be processed through the case statement. I tried this (using the future parser):

each($slist) |$val| { case $val {
    MAMMAL:  { $foo = ['horse', 'cow', 'dog'] }
    REPTILE: { $foo = ['gator', 'frog'] }
    BIRD:    { $foo = ['finch', 'chicken'] }
    }
}


But I just get an error.

(There's another issue, which is that I'll want the $foo array to append to the previous value rather than overwrite, but I'll deal with that after getting over this hurdle).

Is what I'm trying possible? Am I going about this totally the wrong way?

Eugene Vilensky

unread,
Feb 21, 2014, 8:09:43 PM2/21/14
to puppet...@googlegroups.com
On Fri, Feb 21, 2014 at 3:47 PM, Kim Scarborough <cho...@gmail.com> wrote:
> Is what I'm trying possible? Am I going about this totally the wrong way?

Check out how classifying your data using Hiera can resolve and simplify this:
http://docs.puppetlabs.com/hiera/1/index.html#why-hiera

Kim Scarborough

unread,
Feb 21, 2014, 9:11:30 PM2/21/14
to puppet...@googlegroups.com
On Friday, February 21, 2014 7:09:43 PM UTC-6, Trammael wrote:
Check out how classifying your data using Hiera can resolve and simplify this:
http://docs.puppetlabs.com/hiera/1/index.html#why-hiera

Wow, that's hard to understand (at least for me). Will that still work with an array in a fact? Like, if in <http://docs.puppetlabs.com/hiera/1/hierarchy.html#example>, $environment is an array?

jcbollinger

unread,
Feb 24, 2014, 9:40:46 AM2/24/14
to puppet...@googlegroups.com


Your approach will not work.  One of the core characteristics of Puppet variables is that once assigned, their values never change.

I haven't played much with the future parser, but since you're looking that direction, I think it can do the job for you.  Start by replacing your 'case' statement with a hash declaration:

$group_attributes = {
  'MAMMAL'  => ['horse', 'cow', 'dog'],
  'REPTILE' => ['gator', 'frog'],
  'BIRD'    => ['finch', 'chicken']
}


The task you want to perform is essentially to transform / map server groups to attibutes, so the future parser's map() function seems a good candidate.  The only extra trick is that you want to combine the results of each mapping, but that should be straightforward if none of the elements 'horse', 'cow', etc. are themselves arrays IRL.  Something along these lines ought to do the job:

$foo = flatten(
    split($servergroup, ',').map |$group_name| {
        $group_attributes[$group_name]
    }
  )

Note in particular that there is only one assignment to variable $foo.  Note also that it will work equally well for servers belonging to one group and those belonging to many.

If you are comfortable with using the future parser, then I think that's a pretty good and effective application, much easier to apply to the merging problem than hiera would be.  There is still a role in this for hiera, however: it would be better to store the $group_attributes data in an external file, and getting the data from there into Puppet is Hiera's bread & butter.


John

Reply all
Reply to author
Forward
0 new messages