Ask Your Question

Filter hash by arrays value

asked 2018-09-19 13:12:32 -0500

Ivan Arjune gravatar image

updated 2018-09-19 13:25:33 -0500

Using puppet version 4.8.2

I have 2 lists of host roles in different categories, stage1 and stage2. This data is laid out as a hash of arrays in hiera.

    - role1
    - role2
    - role3
    - role4

I'm using this data to create a custom fact on the hosts that will give me what stage the host belongs to. I'm going to use this for controlled releases.

#facter stage

In the manifest i'm grabbing the entire 'stages' hash and then filtering out the stage that contains the hosts role and then using the keys value as the variable to create the custom fact on the host.

Well this is the idea at least.

I can't figure out how to filter out the array which contains the hosts role without using the array position for the value I'm matching.

How do i select from a range of values in an array?

In this WORKING example I'm specifically looking at index[0] for value "role3". This is NOT what i want to do, but it's a working POC.

How can do this without knowing the index position of what i'm looking for?

$data = lookup( { name => stages })
$stagedata = filter($data) |$key,  $value| { $value[0] =~ "role3" }
$stage =   flatten($|$key,$value| {$key})
notify {"STAGE: $stage":}

Notice: STAGE: [stage2]

If i leave of the index position i get an error

Error: Evaluation Error: Left match operand must result in a String value. Got an Array.
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2018-09-19 13:43:34 -0500

Ivan Arjune gravatar image

updated 2018-09-19 14:55:04 -0500

I thought I answered my own question, but didn't. I thought i didn't need to use an array for the data, and just make the whole thing a hash.


and then for the filter use

$stagedata = filter($data) |$key,  $value| { $value == "role2" }

But this won't match because the string looks like this

stage1 => role1 role2, stage2 => role3 role4

So for this i need to use partial match, =~, but this is not acceptable because matches need to be exact.

So back to the drawing board... anyone have a idea here??

This is either the answer or a workaround to the problem. I dropped all that filtering business and used this guys solution:

$data.each |$key,$value| { 
   if ( "$role" in $value ) {
    file { "/opt/puppetlabs/facter/facts.d/stage.yaml":
      content => "stage: $key"
edit flag offensive delete link more


Your lower example is a reasonable solution.

DarylW gravatar imageDarylW ( 2018-09-20 08:09:25 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2018-09-19 13:12:32 -0500

Seen: 125 times

Last updated: Sep 19