Remove key&value from hash

361 views
Skip to first unread message

Albert Shih

unread,
Sep 19, 2018, 9:24:36 AM9/19/18
to puppet...@googlegroups.com
Hi,

I'm would like to have a profile for example for apache.

profile::apache

who can pass some hash to apache. For example let's say I've

profile::apache::vhosts:
vhost1:
....
vhost2:
....

and I want to do

class profile::apache (
Hash $vhosts
)
{

create_resources('apache::vhost', $vhosts)

}

But now I want to add some parameter who's not in the apache::vhost, for
example :

profile::apache::vhosts:
vhost1:
- monitored : true
....
vhost2:
- monitored : false
....

so before I can do the

create_resources('apache::vhost', $something)

i need to exclude « monitored » from that hash table. And...I don't know
how to do that. I try map, reduce etc.. and was unable to exclude some
nested key/value from a hash.

Regards



--
Albert SHIH
DIO bâtiment 15
Observatoire de Paris
xmpp: j...@obspm.fr
Heure local/Local time:
Wed Sep 19 14:50:21 CEST 2018

Henrik Lindberg

unread,
Sep 19, 2018, 10:00:40 AM9/19/18
to puppet...@googlegroups.com
Puppet has a function named tree_each() that can be used to flatten and
filter a tree structure of data. Once filtered it is possible to again
create a Hash out of the result.

Documentation here:
https://puppet.com/docs/puppet/5.5/function.html#treeeach

Here are two examples (both from the documentation; the first from
tree_each(), and the second from Hash.new().

The first example shows the flattened filtered value.
To get the pruned hash in that example, do what is done in
Example 2 at the end - i.e. Hash($flattened_pruned_value, 'hash_tree').

It is really difficult to achieve the same with just reduce() and
filter() functions - you would have to more or less implement
the tree_each() function - but you don't have to since puppet has it :-)

Hope this helps you with what you were trying to do.

Also - note that it may be better for you (instead of filtering your
values and then give the resulting structure to create_reources()), to
iterate over the structure and the simply have conditional logic
around the declaration of resources. That is much less magic to read.

Best
- henrik

Encourage you to play with these examples:

#### EXAMPLE 1
# A tree of some complexity (here very simple for readability)
$tree = [
{ name => 'user1', status => 'inactive', id => '10'},
{ name => 'user2', status => 'active', id => '20'}
]
notice $tree.tree_each.filter |$v| {
$value = $v[1]
$value =~ Hash and $value[status] == active
}


#### EXAMPLE 2
####
# A hash tree with 'water' at different locations
$h = { a => { b => { x => 'water'}}, b => { y => 'water'} }

# a helper function that turns water into wine
function make_wine($x) { if $x == 'water' { 'wine' } else { $x } }

# create a flattened tree with water turned into wine
$flat_tree = $h.tree_each.map |$entry| { [$entry[0], make_wine($entry[1])] }

# create a new Hash and log it
notice Hash($flat_tree, 'hash_tree')


>
>
>
> --
> Albert SHIH
> DIO bâtiment 15
> Observatoire de Paris
> xmpp: j...@obspm.fr
> Heure local/Local time:
> Wed Sep 19 14:50:21 CEST 2018
>


--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Albert Shih

unread,
Sep 20, 2018, 4:17:17 AM9/20/18
to puppet...@googlegroups.com
Le 19/09/2018 à 16:00:20+0200, Henrik Lindberg a écrit
THANKS.....I would check on that.

>
> The first example shows the flattened filtered value.
> To get the pruned hash in that example, do what is done in
> Example 2 at the end - i.e. Hash($flattened_pruned_value, 'hash_tree').
>
> It is really difficult to achieve the same with just reduce() and
> filter() functions - you would have to more or less implement

I concur ;-)

> the tree_each() function - but you don't have to since puppet has it :-)
>
> Hope this helps you with what you were trying to do.
>
> Also - note that it may be better for you (instead of filtering your values
> and then give the resulting structure to create_reources()), to
> iterate over the structure and the simply have conditional logic
> around the declaration of resources. That is much less magic to read.

I know that, and generaly that's would be my solution, but the point is
apache::vhost got a *lot* of attributes......and it's very boring to add
all attributes or change my module each time I need a new attributes from
apache::vhost.

>
> Best
> - henrik
>
> Encourage you to play with these examples:
>
> #### EXAMPLE 1
> # A tree of some complexity (here very simple for readability)
> $tree = [
> { name => 'user1', status => 'inactive', id => '10'},
> { name => 'user2', status => 'active', id => '20'}
> ]
> notice $tree.tree_each.filter |$v| {
> $value = $v[1]
> $value =~ Hash and $value[status] == active
> }
>
>
> #### EXAMPLE 2
> ####
> # A hash tree with 'water' at different locations
> $h = { a => { b => { x => 'water'}}, b => { y => 'water'} }
>
> # a helper function that turns water into wine
> function make_wine($x) { if $x == 'water' { 'wine' } else { $x } }
>
> # create a flattened tree with water turned into wine
> $flat_tree = $h.tree_each.map |$entry| { [$entry[0], make_wine($entry[1])] }
>
> # create a new Hash and log it
> notice Hash($flat_tree, 'hash_tree')

Nice !!!.

Regards.

--
Albert SHIH
DIO bâtiment 15
Observatoire de Paris
xmpp: j...@obspm.fr
Heure local/Local time:
Thu Sep 20 10:12:55 CEST 2018

Henrik Lindberg

unread,
Sep 21, 2018, 7:55:21 AM9/21/18
to puppet...@googlegroups.com
Do you know that you can apply a hash of attribute-name to value at
once? Here is a simple example with a notify setting the message in a
hash (just to show you how). You can have as many attributes to value
mappings you like.

$hash = { 'message' => 'set via a wildcard' }
notify { example:
* => $hash
}

This way, you can look things up from hiera and apply all of the
attributes at once.

Best,
- henrik

Albert Shih

unread,
Sep 21, 2018, 8:21:16 AM9/21/18
to puppet...@googlegroups.com
Le 21/09/2018 à 13:54:59+0200, Henrik Lindberg a écrit
> On 2018-09-20 10:17, Albert Shih wrote:
> > Le 19/09/2018 à 16:00:20+0200, Henrik Lindberg a écrit
> >
> > I know that, and generaly that's would be my solution, but the point is
> > apache::vhost got a *lot* of attributes......and it's very boring to add
> > all attributes or change my module each time I need a new attributes from
> > apache::vhost.
> >
>
> Do you know that you can apply a hash of attribute-name to value at once?
> Here is a simple example with a notify setting the message in a hash (just
> to show you how). You can have as many attributes to value mappings you
> like.
>
> $hash = { 'message' => 'set via a wildcard' }
> notify { example:
> * => $hash
> }
>
> This way, you can look things up from hiera and apply all of the attributes
> at once.

Thanks, but yes I know that. The point is if you pass inside the $hash, a
parameter who not manage by the ressource like apache, puppet complaint
about that

So I cannot do something like

fqdn.yaml

profile::apache::vhosts:
'vhost1':
attribute_from_apache_vhost_class
attribute_from_apache_vhost_class
attribute_from_apache_vhost_class
my_attribute_not_in_apache_vhost_class


class 'profile::apache' (
Hash $vhosts
)
{
apache::vhosts::vhosts {'all'
* => $vhosts
}
}

so that's why I need to « cleanup »  the hash and remove

my_attribute_not_in_apache_vhost_class

Currently I do something no very clean IMHO : I got a another parameter in
the hiera :

profile::apache::vhosts_my_thing:
'vhost1':
my_attribute_not_in_apache_vhost_class


But in my point of view it's not a good solution because the information
vhost1 should be unique. And not in two place.

Regards



--
Albert SHIH
DIO bâtiment 15
Observatoire de Paris
xmpp: j...@obspm.fr
Heure local/Local time:
Fri Sep 21 14:13:43 CEST 2018
Reply all
Reply to author
Forward
0 new messages