custom function to read inifile

292 views
Skip to first unread message

Ritesh Nanda

unread,
Jul 22, 2014, 5:36:45 PM7/22/14
to puppet...@googlegroups.com
Hello ,

I was trying to write a custom function which would run on puppet master take input a ini file , parse a section of that ini file and assign 
its value to a variable .
Something like 

$test = iniread('example.ini', 'Program', 'path')

This would assign the value to test variable when the functions runs on the puppet master.

iniread.rb file looks like 

require 'rubygems'
require 'inifile'
module Puppet::Parser::Functions
      newfunction(:iniread, :type => :rvalue) do |args|
raise(Puppet::ParseError, 'inifile read(): Wrong number of arguments ' +
      "given (#{args.size} for 3)") if args.size != 3
       
        filename = args[0]
        section = args[1]
        key = args[2]

        file = IniFile.load(filename)
        data = file[section]
        value = data[key]
        return value

      end
    end

It gives an error while running 

Error 400 on SERVER: undefined method `[]' for nil:NilClass at /etc/puppetlabs/puppet/modules/example/manifests/init.pp:45

init.pp has 

$test =iniread("example.ini", "Program", "path") 


Doing that in ruby works 

require 'inifile'
filename = ARGV[0]
section = ARGV[1]
key = ARGV[2]
file = IniFile.load(filename)
data = file[section]
InstPath = data[key]
puts InstPath

Help to this would be really appreciated. 

Regards,
Ritesh 



Henrik Lindberg

unread,
Jul 23, 2014, 10:04:57 AM7/23/14
to puppet...@googlegroups.com
On 2014-22-07 23:36, Ritesh Nanda wrote:
> Hello ,
>
> I was trying to write a custom function which would run on puppet master
> take input a ini file , parse a section of that ini file and assign
> its value to a variable ..
> Something like
>
> $test = iniread('example.ini', 'Program', 'path')
>
> This would assign the value to test variable when the functions runs on
> the puppet master.
>
> iniread.rb file looks like
>
> require 'rubygems'

Should typically not be used, since it may force user to use rubygems.
You don't need it since all you want is for the runtime to find the
IniFile class. The gem/or class should simply be present in a location
that puppet loads from (it uses gempath if rubygems is available, but
can also load from other places; such as modules which are not installed
as gems).

> require 'inifile'
> module Puppet::Parser::Functions
> newfunction(:iniread, :type => :rvalue) do |args|

You do not need to open the module to call newfunction, do this instead:

Puppet::Parser::Functions.newfunction(
:iniread, :type => :rvalue,
:arity => 3,
:doc => "Reads an .ini file and...") do |args|

# body here
end

> raise(Puppet::ParseError, 'inifile read(): Wrong number of arguments ' +
> "given (#{args.size} for 3)") if args.size != 3

You get this automatically by specifying :arity=>3 as an option.
(Unless you are on a very old puppet that does not support this).

> filename = args[0]
> section = args[1]
> key = args[2]
>
> file = IniFile.load(filename)
> data = file[section]
> value = data[key]
> return value
>
> end
> end
>
> It gives an error while running
>
> Error 400 on SERVER: undefined method `[]' for nil:NilClass at
> /etc/puppetlabs/puppet/modules/example/manifests/init.pp:45
>
Run with --trace to see where the exception is raised.
My guess is that IniFile.load returns nil for the filename you gave it.
You want to protect the user and raise a specific error about not being
able to load the given file.

Regards
- henrik

> init.pp has
>
> $test =iniread("example.ini", "Program", "path")
>
>
> Doing that in ruby works
>
> require 'inifile'
> filename = ARGV[0]
> section = ARGV[1]
> key = ARGV[2]
> file = IniFile.load(filename)
> data = file[section]
> InstPath = data[key]
> puts InstPath
>
> Help to this would be really appreciated.
>
> Regards,
> Ritesh
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to puppet-users...@googlegroups.com
> <mailto:puppet-users...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-users/460bb860-e8cb-4022-a1a3-47fb4b0015e5%40googlegroups.com
> <https://groups.google.com/d/msgid/puppet-users/460bb860-e8cb-4022-a1a3-47fb4b0015e5%40googlegroups..com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


--

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

Craig Barr

unread,
Jul 23, 2014, 4:31:13 PM7/23/14
to puppet...@googlegroups.com
Does this meet your use case? 

Ritesh Nanda

unread,
Jul 23, 2014, 6:12:05 PM7/23/14
to puppet...@googlegroups.com
Craig , i looked at that module puppetlabs-inifile, it  allows to change the settings in  ini file , i want to read/parse a ini file , assign a value to a variable.

@henrik you were correct problem was with iniFile.load class . Now the functions looks like 

require_relative 'inifile'

This allows me to keep inifile.rb file inside the function directory. Is this correct ?

Puppet::Parser::Functions.newfunction(
  :inireadvalue, :type => :rvalue,
  :arity => 3,
  :doc => "Reads an .ini file and...") do |args|
        filename   = args[0]
        section    = args[1]
        key         = args[2]

     if !File.exist?(filename)

raise(Puppet::ParseError, 'inireadvalue(): Path and file provided does not  exists ' +
      'Provide the correct path')
end

fileload = IniFile.load(filename)
        data = fileload[section]
        value = data[key]
        return value


      end

      
Thanks for your help.

Regards,
Ritesh Nanda


--
You received this message because you are subscribed to a topic in the Google Groups "Puppet Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/puppet-users/mNzxsAqTZ7I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/705ed63d-1ae5-4fb5-afbc-6dfa7b579154%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

 With Regards 

 Ritesh Nanda

Jason Antman

unread,
Jul 30, 2014, 8:37:45 AM7/30/14
to puppet...@googlegroups.com
Before you get any further, you do understand that the inifile has to be on the *master*, right? Just checking, because I've seen a lot of people trying to write functions, and only later realizing that the data they want is on the node, not the master.

When I've come up with issues like this (mainly JSON not ini, but whatever, same difference for our purposes) I put the data somewhere that Puppet can access natively (like in my ENC) and have puppet *write* files not read them.


--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/CAO5CbpBOAynKgnZFOr_QVe80Dxo5ccRwrYOsy6GhGg4_rvrbjA%40mail.gmail.com.

Ritesh Nanda

unread,
Jul 30, 2014, 10:04:30 AM7/30/14
to puppet...@googlegroups.com
Thanks Jason , i had that thing in mind , i made it part of the function itself to download the file and then read it .

Thanks for the concern.

Regards,
Ritesh 



For more options, visit https://groups.google.com/d/optout.

Ritesh Nanda

unread,
Aug 4, 2014, 2:15:43 PM8/4/14
to puppet...@googlegroups.com
Hello ,

In this custom function i am trying to download a file and then parse it , that works correctly , now i want the url value to be in a variable or hiera and this custom function fetches that value from variable.
Using lookupvar doesn't works . Below is the code and error.

require_relative 'inifile'
require 'open-uri'

Puppet::Parser::Functions.newfunction(
  :inireadvalue, :type => :rvalue,
  :arity => 4,
  :doc => "Reads an .ini file and...") do |args|
        package = args[0]
        filename = args[1]
        section = args[2]
        key = args[3]

remote_base_url = lookupvar('$::windows_l2_agent::l2_agent_list::url')
remote_page_name = "#{package}" + "/" + "#{filename}"
remote_full_url = remote_base_url + "/" + remote_page_name
remote_data = open(remote_full_url).read
my_local_file = open("/tmp/#{filename}", "w")
my_local_file.write(remote_data)
my_local_file.close

if !File.exist?("/tmp/#{filename}")

raise(Puppet::ParseError, 'inireadvalue(): Path and file provided does not  exists ' +
      'Provide the correct path')
end

fileload = IniFile.load("/tmp/#{filename}")
        data = fileload[section]
        value = data[key]
        return value


      end


Error it gives is 

Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: (Scope(Windows_l2_agent::Install_agent[ADSECGRP])) Could not look up qualified variable '$::windows_l2_agent::l2_agent_list::url'; class $::windows_l2_agent::l2_agent_list could not be found
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: undefined method `+' for nil:NilClass at /etc/puppetlabs/puppet/environments/development/modules/windows_l2_agent/manifests/install_agent.pp:3 on node cnpdcccvd0434.cdbt.pldc.kp.org
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: Wrapped exception:
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: undefined method `+' for nil:NilClass
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: undefined method `+' for nil:NilClass at /etc/puppetlabs/puppet/environments/development/modules/windows_l2_agent/manifests/install_agent.pp:3 on node cnpdcccvd0434.cdbt.pldc.kp.org
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: undefined method `+' for nil:NilClass at /etc/puppetlabs/puppet/environments/development/modules/windows_l2_agent/manifests/install_agent.pp:3 on node cnpdcccvd0434.cdbt.pldc.kp.org
Aug  4 11:04:04 pzxdcc0002 puppet-master[10376]: Report processor failed: Report from  contained no metrics, which is often caused by a failed catalog compilation. Unable to process.

Regards,
Ritesh

Ritesh Nanda

unread,
Aug 4, 2014, 2:23:09 PM8/4/14
to puppet...@googlegroups.com
Sorry for the question it worked , it was a typo .


--
You received this message because you are subscribed to a topic in the Google Groups "Puppet Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/puppet-users/mNzxsAqTZ7I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to puppet-users...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages