How to use chef LWRP to modify one file

Hi all, I have a question on the use of chef LWRP when various
resources have to be configured in one file.

An example is fail2ban. Fail2ban is a perfect service to implement a
LWRP for, except that all jails have to be configured in jail.local.
Most programs (like logrotate) allow you to specify each instance of
your service in a “service.d” folder, so as to not clobber the
configuration of other services of the same program. Unfortunately,
fail2ban does this for actons and filters, but requires all jails to
be configured in jail.local.

Now the format for each jail is very simple, so it’s easy to do a
template that loops over each jail definition like so:

<% @local_jail.each do |jail| -%>
[<%= jail[“name”] %>]
logpath = <%= jail[“logpath”] %>
enabled = true
filter = <%= jail[“filter”] %>
action = <%= jail[“action”] %>
maxretry = <%= jail[“maxretry”] %>
bantime = <%= jail[“bantime”] %>

<% end -%>

Idealy you could call this as a LWRP, so you could have something like:

fail2ban_app “myapp” do
logpath "log/path/here/"
filter "filter.name.here"
action "action.name.here"
end

However, as far as I have been able to see in the documentation, each
time the LWRP is called, it has to generate a template. Is it possible
to just have the LWRP just accumulate the variables each time it is
called and then generate the template at the end? Or is there another
way of doing this that I am not seeing? I am still somewhat of a chef
newbie so I might have missed something.

Im not sure if its possible this way, but I must say that your use case is
very common,

we should be able to accumulate these information in a data structure as
part of the lwrp, and use the data in another resource that creates the file

action :create do
ruby_block "update_data" do
block do
node.set[:fail2ban][:jail_name]={:filter=>new_resource.filter,:maxretry=>new_resource.maxretry,:bantime=>new_resource.bantime}
end
notifies :create ,"template[/etc/fail2ban.conf]"
end
end

and then in the default recipe ,
template "/etc/fail2ban.conf" do
variables(:data=>node[:faile2ban])
end

...
also we can have a hacky implementation where the template resource logic
is pushed as a report handler.

I'll try the first approach and let you know
regards
ranjib

On Tue, Apr 10, 2012 at 4:04 PM, Alejandro Recarey alexrecarey@gmail.comwrote:

Hi all, I have a question on the use of chef LWRP when various
resources have to be configured in one file.

An example is fail2ban. Fail2ban is a perfect service to implement a
LWRP for, except that all jails have to be configured in jail.local.
Most programs (like logrotate) allow you to specify each instance of
your service in a "service.d" folder, so as to not clobber the
configuration of other services of the same program. Unfortunately,
fail2ban does this for actons and filters, but requires all jails to
be configured in jail.local.

Now the format for each jail is very simple, so it's easy to do a
template that loops over each jail definition like so:

<% @local_jail.each do |jail| -%>
[<%= jail["name"] %>]
logpath = <%= jail["logpath"] %>
enabled = true
filter = <%= jail["filter"] %>
action = <%= jail["action"] %>
maxretry = <%= jail["maxretry"] %>
bantime = <%= jail["bantime"] %>

<% end -%>

Idealy you could call this as a LWRP, so you could have something like:

fail2ban_app "myapp" do
logpath "log/path/here/"
filter "filter.name.here"
action "action.name.here"
end

However, as far as I have been able to see in the documentation, each
time the LWRP is called, it has to generate a template. Is it possible
to just have the LWRP just accumulate the variables each time it is
called and then generate the template at the end? Or is there another
way of doing this that I am not seeing? I am still somewhat of a chef
newbie so I might have missed something.

also i think we have to check for the existing node[:fail2ban].attribute?('
new_resource.name) and nested values appropriately and make a call to
@new_resource.updated_by_last_action(true)
accordingly

On Tue, Apr 10, 2012 at 4:47 PM, Ranjib Dey ranjibd@thoughtworks.comwrote:

Im not sure if its possible this way, but I must say that your use case is
very common,

we should be able to accumulate these information in a data structure as
part of the lwrp, and use the data in another resource that creates the file

action :create do
ruby_block "update_data" do
block do
node.set[:fail2ban][:new_resource.name
]={:filter=>new_resource.filter,:maxretry=>new_resource.maxretry,:bantime=>new_resource.bantime}
end
notifies :create ,"template[/etc/fail2ban.conf]"
end
end

and then in the default recipe ,
template "/etc/fail2ban.conf" do
variables(:data=>node[:faile2ban])
end

...
also we can have a hacky implementation where the template resource logic
is pushed as a report handler.

I'll try the first approach and let you know
regards
ranjib

On Tue, Apr 10, 2012 at 4:04 PM, Alejandro Recarey alexrecarey@gmail.comwrote:

Hi all, I have a question on the use of chef LWRP when various
resources have to be configured in one file.

An example is fail2ban. Fail2ban is a perfect service to implement a
LWRP for, except that all jails have to be configured in jail.local.
Most programs (like logrotate) allow you to specify each instance of
your service in a "service.d" folder, so as to not clobber the
configuration of other services of the same program. Unfortunately,
fail2ban does this for actons and filters, but requires all jails to
be configured in jail.local.

Now the format for each jail is very simple, so it's easy to do a
template that loops over each jail definition like so:

<% @local_jail.each do |jail| -%>
[<%= jail["name"] %>]
logpath = <%= jail["logpath"] %>
enabled = true
filter = <%= jail["filter"] %>
action = <%= jail["action"] %>
maxretry = <%= jail["maxretry"] %>
bantime = <%= jail["bantime"] %>

<% end -%>

Idealy you could call this as a LWRP, so you could have something like:

fail2ban_app "myapp" do
logpath "log/path/here/"
filter "filter.name.here"
action "action.name.here"
end

However, as far as I have been able to see in the documentation, each
time the LWRP is called, it has to generate a template. Is it possible
to just have the LWRP just accumulate the variables each time it is
called and then generate the template at the end? Or is there another
way of doing this that I am not seeing? I am still somewhat of a chef
newbie so I might have missed something.

On Tue, Apr 10, 2012 at 11:34, Alejandro Recarey alexrecarey@gmail.com wrote:

Hi all, I have a question on the use of chef LWRP when various
resources have to be configured in one file.

However, as far as I have been able to see in the documentation, each
time the LWRP is called, it has to generate a template. Is it possible
to just have the LWRP just accumulate the variables each time it is
called and then generate the template at the end? Or is there another
way of doing this that I am not seeing? I am still somewhat of a chef
newbie so I might have missed something.

See the bottom of http://wiki.opscode.com/display/chef/Definitions ;
while that's for definitions, the same code ought to be easily
transferred to an LWRP.
-t

Thank you Ranjib and Thom for your answers, I am looking into the
problem with your help. With some luck I will find an answer.