Possible to call data_bag_item w/in erb template?


#1

I am trying to call the data_bag_item method within an erb template. My
sudo users may have multiple sudo cmds so i have embedded them directly into
the user’s databag like so

file: users/oper.json
{
“id”: “oper”,
“groups”: “oper”,
“uid”: 977,
“shell”: “/bin/bash”,
“password”: “$1$WV1cZLkt$FmFEuRFCGKWaabud6.Gld1”,
“sudo_cmds”: [ “ALL=(ALL) NOPASSWD:/sbin/reboot”,
“ALL=(ALL) NOPASSWD:/sbin/poweroff” ]
}

file: recipes/default.rb
sudoers = []
data_bag(‘users’).each do |user_name|
u = data_bag_item(‘users’, user_name)

    if u['sudo_cmds']
            sudoers << u['id']
    end

end

template “/etc/sudoers” do
source "sudoers.erb"
mode 0440
owner "root"
group "root"
variables(
:sudoers => sudoers
)
end

file: sudoers.erb

User privilege specification

root ALL=(ALL) ALL

<% @sudoers.each do |user|
cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)

    cmds.each do |cmd|  -%>

<%= user %> <%= cmd %>
<% end
end -%>

Here is the error i get when I try to do this

Generated at Sat Oct 08 16:38:16 +0200 2011
Chef::Mixin::Template::TemplateError:

Chef::Mixin::Template::TemplateError (undefined method `data_bag_item’ for
#Erubis::Context:0xb6ffcb64) on line #12:

10:
11: <% @sudoers.each do |user|
12: cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
13:
14: cmds.each do |cmd| -%>


#2

Hi Bryan - in the data structure you have there, you can just use it directly.

<% @sudoers.each do |user| %>
<% user[“sudo_cmds”].each do |cmd| %>
<%= cmd %>
<% end %>
<% end %>

Adam

On Sat, Oct 8, 2011 at 7:38 AM, Bryan Berry bryan.berry@gmail.com wrote:

I am trying to call the data_bag_item method within an erb template. My
sudo users may have multiple sudo cmds so i have embedded them directly into
the user’s databag like so
file: users/oper.json
{
“id”: “oper”,
“groups”: “oper”,
“uid”: 977,
“shell”: “/bin/bash”,
“password”: “$1$WV1cZLkt$FmFEuRFCGKWaabud6.Gld1”,
“sudo_cmds”: [ “ALL=(ALL) NOPASSWD:/sbin/reboot”,
“ALL=(ALL) NOPASSWD:/sbin/poweroff” ]
}
file: recipes/default.rb
sudoers = []
data_bag(‘users’).each do |user_name|
u = data_bag_item(‘users’, user_name)
if u[‘sudo_cmds’]
sudoers << u[‘id’]
end
end
template “/etc/sudoers” do
source "sudoers.erb"
mode 0440
owner "root"
group "root"
variables(
:sudoers => sudoers
)
end

file: sudoers.erb

User privilege specification

root ALL=(ALL) ALL
<% @sudoers.each do |user|
cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
cmds.each do |cmd| -%>
<%= user %> <%= cmd %>
<% end
end -%>

Here is the error i get when I try to do this
Generated at Sat Oct 08 16:38:16 +0200 2011
Chef::Mixin::Template::TemplateError:
Chef::Mixin::Template::TemplateError (undefined method `data_bag_item’ for
#Erubis::Context:0xb6ffcb64) on line #12:
10:
11: <% @sudoers.each do |user|
12: cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
13:
14: cmds.each do |cmd| -%>


Opscode, Inc.
Adam Jacob, Chief Product Officer
T: (206) 619-7151 E: adam@opscode.com


#3

alright I figured out what I was doing wrong

in my ruby code

sudoers[username] = u[‘sudo_cmds’]

<% @sudoers.each do |user,cmds|
cmds.each do |cmd| -%>
<%= user %> <%= cmd %>
<% end
end -%>

thanks for your help Adam!

it is taking me some time to figure out all the tricks in ruby

On Sat, Oct 8, 2011 at 10:04 PM, Adam Jacob adam@opscode.com wrote:

Hi Bryan - in the data structure you have there, you can just use it
directly.

<% @sudoers.each do |user| %>
<% user[“sudo_cmds”].each do |cmd| %>
<%= cmd %>
<% end %>
<% end %>

Adam

On Sat, Oct 8, 2011 at 7:38 AM, Bryan Berry bryan.berry@gmail.com wrote:

I am trying to call the data_bag_item method within an erb template. My
sudo users may have multiple sudo cmds so i have embedded them directly
into
the user’s databag like so
file: users/oper.json
{
“id”: “oper”,
“groups”: “oper”,
“uid”: 977,
“shell”: “/bin/bash”,
“password”: “$1$WV1cZLkt$FmFEuRFCGKWaabud6.Gld1”,
“sudo_cmds”: [ “ALL=(ALL) NOPASSWD:/sbin/reboot”,
“ALL=(ALL) NOPASSWD:/sbin/poweroff” ]
}
file: recipes/default.rb
sudoers = []
data_bag(‘users’).each do |user_name|
u = data_bag_item(‘users’, user_name)
if u[‘sudo_cmds’]
sudoers << u[‘id’]
end
end
template “/etc/sudoers” do
source "sudoers.erb"
mode 0440
owner "root"
group "root"
variables(
:sudoers => sudoers
)
end

file: sudoers.erb

User privilege specification

root ALL=(ALL) ALL
<% @sudoers.each do |user|
cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
cmds.each do |cmd| -%>
<%= user %> <%= cmd %>
<% end
end -%>

Here is the error i get when I try to do this
Generated at Sat Oct 08 16:38:16 +0200 2011
Chef::Mixin::Template::TemplateError:
Chef::Mixin::Template::TemplateError (undefined method `data_bag_item’
for
#Erubis::Context:0xb6ffcb64) on line #12:
10:
11: <% @sudoers.each do |user|
12: cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
13:
14: cmds.each do |cmd| -%>


Opscode, Inc.
Adam Jacob, Chief Product Officer
T: (206) 619-7151 E: adam@opscode.com


#4

As Adam said, you don’t need to do that in this case, but it’s in general a
bad idea to have templates that know too much about where their data values
come from; it makes your configuration brittle. If you change your data bag
layout, or move the information out of data bags and into attributes, then
you have to redo the template (and probably the recipe, too); if you keep
the template dumb, only the recipe has to change.

My rule of thumb for templates is: no code other than conditionals and
loops, no data lookups other than the passed-in instance variables. These
are more what yout’d call guidelines than strict rules, but I need a really
good reason to break them.

On Sat, Oct 8, 2011 at 10:38 AM, Bryan Berry bryan.berry@gmail.com wrote:

I am trying to call the data_bag_item method within an erb template. My
sudo users may have multiple sudo cmds so i have embedded them directly into
the user’s databag like so

file: users/oper.json
{
“id”: “oper”,
“groups”: “oper”,
“uid”: 977,
“shell”: “/bin/bash”,
“password”: “$1$WV1cZLkt$FmFEuRFCGKWaabud6.Gld1”,
“sudo_cmds”: [ “ALL=(ALL) NOPASSWD:/sbin/reboot”,
“ALL=(ALL) NOPASSWD:/sbin/poweroff” ]
}

file: recipes/default.rb
sudoers = []
data_bag(‘users’).each do |user_name|
u = data_bag_item(‘users’, user_name)

    if u['sudo_cmds']
            sudoers << u['id']
    end

end

template “/etc/sudoers” do
source "sudoers.erb"
mode 0440
owner "root"
group "root"
variables(
:sudoers => sudoers
)
end

file: sudoers.erb

User privilege specification

root ALL=(ALL) ALL

<% @sudoers.each do |user|
cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)

    cmds.each do |cmd|  -%>

<%= user %> <%= cmd %>
<% end
end -%>

Here is the error i get when I try to do this

Generated at Sat Oct 08 16:38:16 +0200 2011
Chef::Mixin::Template::TemplateError:

Chef::Mixin::Template::TemplateError (undefined method `data_bag_item’ for
#Erubis::Context:0xb6ffcb64) on line #12:

10:
11: <% @sudoers.each do |user|
12: cmds = data_bag_item(‘users/#{user}’, ‘sudo_cmds’)
13:
14: cmds.each do |cmd| -%>


Mark J. Reed markjreed@gmail.com