Ask Your Question
0

how do I access class parameters in a custom fact?

asked 2015-03-23 21:52:35 -0500

Red Cricket gravatar image

Hi,

I have this simple situation:

    [root@my-pm-1 ~]# cd /etc/puppetlabs/puppet/modules/foo/
    [root@my-pm-1 foo]# tree
    .
    ├── lib
    │   └── facter
    │       └── ppp.rb
    ├── manifests
    │   └── init.pp
    └── templates
        └── foo.txt.erb

    4 directories, 3 files
    [root@my-pm-1 foo]# cat lib/facter/ppp.rb 
    Facter.add('ppp') do
           setcode do
                    ppp = Facter::Util::Resolution.exec("/bin/echo p1={#p1} p2={#p2} p3={#p3}")
                    if ppp
                            ppp
                    else
                            nil
                    end
           end
    end

    [root@my-pm-1 foo]# cat manifests/init.pp 
    class foo (
            $p1     = 'one',
            $p2     = 'two',
            $p3     = 'three',
    ) {

            file { '/tmp/foo.txt':
                    content => template('foo/foo.txt.erb'), 
            }
    }
    [root@my-pm-1 foo]# cat templates/foo.txt.erb 
    p1 = <%= @p1 %>
    p2 = <%= @p2 %>
    p3 = <%= @p3 %>

On a node that has been assigned class foo I have this ...

    [root@my-rabbit-3 ~]# puppet agent -t
    Info: Retrieving plugin
    .
    .
    .
    Info: Caching catalog for my-rabbit-3
    Info: Applying configuration version '1427164794'
    Notice: /Stage[main]/Foo/File[/tmp/foo.txt]/ensure: defined content as '{md5}5ee610659b9379a497c5f59c93aa7a9d'
    Notice: Finished catalog run in 4.35 seconds
    [root@my-rabbit-3 ~]# cat /tmp/foo.txt
    p1 = one
    p2 = two
    p3 = three
    [root@my-rabbit-3 ~]# facter -p | grep ppp
    ppp => p1={#p1} p2={#p2} p3={#p3}

... I was hoping that the output of facter -p | grep ppp would be ...

    ppp => p1=one p2=two p3=three

... what am I doing wrong here?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
-1

answered 2015-03-24 13:32:32 -0500

Red Cricket gravatar image

updated 2015-03-24 14:29:51 -0500

What I had to do was create a shell script on the node via an erb template, (foo/templates/foo.sh.erb) , something like:

#!/bin/sh
export p1=<%= @p1 %>
export p2=<%= @p2 %>
export p3=<%= @p3 %>
echo "p1=$p1 p2=$p2 p3=$p3"

Then in my foo/manifests/init.pp I added:

        file { '/root/foo.sh':
                content => template('foo/foo.sh.erb'),
                owner => root,
                mode => '0500', 
        }

Then I changed my lib/facter/ppp.rb to ...

Facter.add('ppp') do
           setcode do
                    ppp = Facter::Util::Resolution.exec("/root/foo.sh")
                    if ppp
                            ppp
                    else
                            nil
                    end
           end
    end

This seems to work, although I will continue to find a better solution.

edit flag offensive delete link more

Comments

This seems round about. You have variables when you declare the class. You write a shell script with those variables in it, send it to the agent. The agent then reports these same variables back to the master as facts. If you've initially assigned these variables on the master already...

WhatsARanjit gravatar imageWhatsARanjit ( 2015-03-25 05:20:49 -0500 )edit

...why not just use them as they are? You can have global and node-level variables assigned in site.pp. You can have class-level variables which are your params. No need to shell out to the agent.

WhatsARanjit gravatar imageWhatsARanjit ( 2015-03-25 05:21:47 -0500 )edit

My example is a contrived one. In my real world application I am executing `/usr/bin/keystone --os-tenant-name=admn --os-username=admn --os-password=somepassword --os-auth-url=https://my-vip.example.com:35357/v2.0 tenant-list | grep service | sed -e's/ //g' | cut -d'|' -f2` ...

Red Cricket gravatar imageRed Cricket ( 2015-03-25 10:04:58 -0500 )edit

where the values for os-tenant-name, os-username, os-password and os-auth-url are passed to my class as parameters. It is the output of the above keystone command that needs to be used in a config. file on the node.

Red Cricket gravatar imageRed Cricket ( 2015-03-25 10:06:39 -0500 )edit

Red Cricket, can you mark WhatsARanjit's answer as correct? This answer is not technically correct even though it can be made to work.

rnelson0 gravatar imagernelson0 ( 2015-03-25 20:16:31 -0500 )edit
2

answered 2015-03-24 07:42:40 -0500

WhatsARanjit gravatar image

Facts are delivered from agent to master at the beginning of the Puppet run. At this time, the node knows nothing about what classes and/or parameters it will receive. Because of this, you cannot use class parameters or any other values from your modules in your facts.

edit flag offensive delete link more

Comments

I wonder why templates do not have this restriction.

Red Cricket gravatar imageRed Cricket ( 2015-03-24 11:09:13 -0500 )edit

Templates are evaluated on the master during compilation. So all the info is there- facts, classes, params.

WhatsARanjit gravatar imageWhatsARanjit ( 2015-03-24 11:49:22 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2015-03-23 21:52:35 -0500

Seen: 1,462 times

Last updated: Mar 24 '15