Foreman Template writing - Iterate over Facts Hash/Structured Facts

I am trying to find a way to iterate over facts hash with 'each' function.
But i get this error:

' There was an error rendering the CentOS_test1 template: undefined method
`each' for nil:NilClass'

Safe mode rendering is off.

How do i iterate over nested structured facts/facts hash in provision
templates in foreman?

For example - the following does not work.

<% @host.facts_hash['kickstart_repos::base'].each do |k| %>
<%= k %>: <%= @host.facts_hash[k] %>
<% end %>

Is there a restriction on what ruby methods i can use inside templates? The
same template works fine in puppet/with ruby.

I tried searching for examples but could not find any.
The documentation mentions that :

@host.facts: Contains a hash of facts from Facter/Ohai etc. (1.7.2+)
@host.facts_hash : Contains a hash of facts from Facter/Ohai etc. (only
works if safemode_render=false)

I assume the above means, that both those variables are hashes and can be
iterated?

Does foreman store facts as hash?

Because when i queried the node using api to gather facts, i see that the
facts hash that i uploaded is now null:

        &quot;kickstart_repos&quot;: null,
        &quot;kickstart_repos::base&quot;: null, 

I see that it has created the child variables out of the hash.

"kickstart_repos::base::baseurl":
"http://10.230.1.106:8090/centos/7/os/x86_64/",

This makes the template writing really difficult, because i will have to
statically mention each key of the facts hash that i have uploaded, in the
templates.

One of the advantages of hash is that it could be dynamic, and we should be
able to iterate over whichever keys it contains.

How do i make foreman store the facts as a hash and not function as above?

··· On Tuesday, August 29, 2017 at 4:31:25 PM UTC-4, lohit....@gmail.com wrote: > > I am trying to find a way to iterate over facts hash with 'each' function. > But i get this error: > > ' There was an error rendering the CentOS_test1 template: undefined method > `each' for nil:NilClass' > > Safe mode rendering is off. > > How do i iterate over nested structured facts/facts hash in provision > templates in foreman? > > For example - the following does not work. > > <% @host.facts_hash['kickstart_repos::base'].each do |k| %> > <%= k %>: <%= @host.facts_hash[k] %> > <% end %> > > Is there a restriction on what ruby methods i can use inside templates? > The same template works fine in puppet/with ruby. > > I tried searching for examples but could not find any. > The documentation mentions that : > > @host.facts: Contains a hash of facts from Facter/Ohai etc. (1.7.2+) > @host.facts_hash : Contains a hash of facts from Facter/Ohai etc. (only > works if safemode_render=false) > > I assume the above means, that both those variables are hashes and can be > iterated? > >

> Does foreman store facts as hash?

No, but they are presented as a hash when calling @host.facts. I saw
it poking around with foreman-rake console:

irb(main):003:0> Host.first.facts.class
=> Hash

> Because when i queried the node using api to gather facts, i see that the
> facts hash that i uploaded is now null:

Can you share the facts hash that you have uploaded? If it had multiple
levels, they are stored as strings like you posted.

If you want to iterate through the actual FactValue object, it might
make it simple for you:

fact_values = FactValue.search_for("host = #{Host.first.fqdn}")

Or if you want to get ONLY the values with an actual value (so the ones
that are 'leaves' of the tree):

FactValue.search_for("host = #{Host.first.fqdn}").where.not(:value =>
nil)

··· On 08/29, lohit.valleru@gmail.com wrote:
        "kickstart_repos": null,
        "kickstart_repos::base": null,

I see that it has created the child variables out of the hash.

“kickstart_repos::base::baseurl”:
http://10.230.1.106:8090/centos/7/os/x86_64/”,

This makes the template writing really difficult, because i will have to
statically mention each key of the facts hash that i have uploaded, in the
templates.

One of the advantages of hash is that it could be dynamic, and we should be
able to iterate over whichever keys it contains.

How do i make foreman store the facts as a hash and not function as above?

On Tuesday, August 29, 2017 at 4:31:25 PM UTC-4, lohit....@gmail.com wrote:

I am trying to find a way to iterate over facts hash with ‘each’ function.
But i get this error:

’ There was an error rendering the CentOS_test1 template: undefined method
`each’ for nil:NilClass’

Safe mode rendering is off.

How do i iterate over nested structured facts/facts hash in provision
templates in foreman?

For example - the following does not work.

<% @host.facts_hash[‘kickstart_repos::base’].each do |k| %>
<%= k %>: <%= @host.facts_hash[k] %>
<% end %>

Is there a restriction on what ruby methods i can use inside templates?
The same template works fine in puppet/with ruby.

I tried searching for examples but could not find any.
The documentation mentions that :

@host.facts: Contains a hash of facts from Facter/Ohai etc. (1.7.2+)
@host.facts_hash : Contains a hash of facts from Facter/Ohai etc. (only
works if safemode_render=false)

I assume the above means, that both those variables are hashes and can be
iterated?


You received this message because you are subscribed to the Google Groups “Foreman users” group.
To unsubscribe from this group and stop receiving emails from it, send an email to foreman-users+unsubscribe@googlegroups.com.
To post to this group, send email to foreman-users@googlegroups.com.
Visit this group at https://groups.google.com/group/foreman-users.
For more options, visit https://groups.google.com/d/optout.


Daniel Lobato Garcia

@dLobatog
blog.daniellobato.me
daniellobato.me

GPG: http://keys.gnupg.net/pks/lookup?op=get&search=0x7A92D6DD38D6DE30
Keybase: https://keybase.io/elobato

Thanks Daniel. Please see my comments as below.

> > Does foreman store facts as hash?
>
> No, but they are presented as a hash when calling @host.facts. I saw
> it poking around with foreman-rake console:
>
> irb(main):003:0> Host.first.facts.class
> => Hash
>

Yes, i do understand that @host.facts is hash, however i would need the
facts mentioned in @host.facts to be in hash format. That is they have
multiple levels, and i see that foreman breaks it down with '::' in between.

>
> > Because when i queried the node using api to gather facts, i see that the
> > facts hash that i uploaded is now null:
>
> Can you share the facts hash that you have uploaded? If it had multiple
> levels, they are stored as strings like you posted.

This is the simplest of hashes that i have.

{"epel"=>{"baseurl"=>"http://10.230.1.106:8090/epel/7/x86_64/"},
"gpfs4"=>{"baseurl"=>"http://10.230.1.106:8090/gpfs/4.2.3.2"},
"base"=>{"baseurl"=>"http://10.230.1.106:8090/centos/7/os/x86_64/"},
"puppetlabs"=>{"baseurl"=>"http://10.230.1.106:8090/puppetlabs/7/x86_64/"},
"updates"=>{"baseurl"=>"http://10.230.1.106:8090/centos/7/updates/x86_64/"}}

I see that foreman breaks up the above hash into multiple facts, like
kickstart_repos::epel::baseurl.
I do not want to be mentioning kickstart::repos::epel::baseurl as a search
condition in the template. I would instead want to iterate over the above
hash, and get whatever exists in it, since the hash can change its keys
names and values with respect to different hosts.

>
> If you want to iterate through the actual FactValue object, it might
> make it simple for you:
>
> fact_values = FactValue.search_for("host = #{Host.first.fqdn}")
>
> Or if you want to get ONLY the values with an actual value (so the ones
> that are 'leaves' of the tree):
>
> FactValue.search_for("host = #{Host.first.fqdn}").where.not(:value =>
> nil)
>
>
I am trying to understand the above syntax. When i do search_for, i still
have to mention the key?. How do i search for the above hash which is
broken down by foreman into multiple facts? When i do an api query for
facts : i get

"kickstart_repos": null

While instead what i expect is :

"kickstart_repos": {"epel"=>{"baseurl"=>"
http://10.230.1.106:8090/epel/7/x86_64/"}, "gpfs4"=>{"baseurl"=>"
http://10.230.1.106:8090/gpfs/4.2.3.2"}, "base"=>{"baseurl"=>"
http://10.230.1.106:8090/centos/7/os/x86_64/"}, "puppetlabs"=>{"baseurl"=>"
http://10.230.1.106:8090/puppetlabs/7/x86_64/"}, "updates"=>{"baseurl"=>"
http://10.230.1.106:8090/centos/7/updates/x86_64/"}}

So that i can iterate in erb, with .each on "kickstart_repos" fact as a
hash, and print each url as below, in kickstart template

Kickstart repos

repo --name epel --baseurl http://xxxxx/epel/7/x86_64/ --install

repo --name gpfs4 --baseurl http://xxxx/gpfs/4.2.3.2 --install

repo --name base --baseurl http://xxxxx/centos/7/os/x86_64/ --install

repo --name puppetlabs --baseurl http://xxxxxx/puppetlabs/7/x86_64/
–install

repo --name updates --baseurl http://xxxx/centos/7/updates/x86_64/ --install

The above could change for different hosts, Some hosts might have
"puppetlabs repo" but some might not.

··· On Wed, Aug 30, 2017 at 10:38 AM, Daniel Lobato Garcia wrote: > On 08/29, lohit.valleru@gmail.com wrote:
        "kickstart_repos": null,
        "kickstart_repos::base": null,

I see that it has created the child variables out of the hash.

“kickstart_repos::base::baseurl”:
http://10.230.1.106:8090/centos/7/os/x86_64/”,

This makes the template writing really difficult, because i will have to
statically mention each key of the facts hash that i have uploaded, in
the
templates.

One of the advantages of hash is that it could be dynamic, and we should
be
able to iterate over whichever keys it contains.

How do i make foreman store the facts as a hash and not function as
above?

On Tuesday, August 29, 2017 at 4:31:25 PM UTC-4, lohit....@gmail.com > wrote:

I am trying to find a way to iterate over facts hash with 'each’
function.

But i get this error:

’ There was an error rendering the CentOS_test1 template: undefined
method

`each’ for nil:NilClass’

Safe mode rendering is off.

How do i iterate over nested structured facts/facts hash in provision
templates in foreman?

For example - the following does not work.

<% @host.facts_hash[‘kickstart_repos::base’].each do |k| %>
<%= k %>: <%= @host.facts_hash[k] %>
<% end %>

Is there a restriction on what ruby methods i can use inside templates?
The same template works fine in puppet/with ruby.

I tried searching for examples but could not find any.
The documentation mentions that :

@host.facts: Contains a hash of facts from Facter/Ohai etc. (1.7.2+)
@host.facts_hash : Contains a hash of facts from Facter/Ohai etc. (only
works if safemode_render=false)

I assume the above means, that both those variables are hashes and can
be

iterated?


You received this message because you are subscribed to the Google
Groups “Foreman users” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to foreman-users+unsubscribe@googlegroups.com.
To post to this group, send email to foreman-users@googlegroups.com.
Visit this group at https://groups.google.com/group/foreman-users.
For more options, visit https://groups.google.com/d/optout.


Daniel Lobato Garcia

@dLobatog
blog.daniellobato.me
daniellobato.me

GPG: http://keys.gnupg.net/pks/lookup?op=get&search=0x7A92D6DD38D6DE30
Keybase: https://keybase.io/elobato


You received this message because you are subscribed to a topic in the
Google Groups “Foreman users” group.
To unsubscribe from this topic, visit https://groups.google.com/d/
topic/foreman-users/3N9wZJXtvxA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
foreman-users+unsubscribe@googlegroups.com.
To post to this group, send email to foreman-users@googlegroups.com.
Visit this group at https://groups.google.com/group/foreman-users.
For more options, visit https://groups.google.com/d/optout.