My first post. I am just getting started with puppet and have made
good progress with some basics using templates and files.
I would like to perform and an action based on whether or not a
particular system binary executes successfully, but I don't see an
obvious way to set puppet conditionals based on an exit value of an
arbitrary command. Is there a well known recipe that does something
like this shell snippet?:
if [ "/usr/bin/my_harmless_binary 2>&1 >/dev/null" ]; then
echo "my_harmless_binary succeeded"
cp /tmp/file1 /data/
else
echo "my_harmless_binary FAILED"
fi
--
-ashley
Did you try poking at it with a stick?
thank you both. my current task will use a file action. I'm trying
to make puppet chose between alturnative versions of a file based on
the result of a binary.
I will work on the custom fact idea. if such an issue is coming at
me so early in the game, then I may as well get started learning
how to build facts.
>
> John
>
> --
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
[...]
> thank you both. my current task will use a file action. I'm trying
> to make puppet chose between alturnative versions of a file based on
> the result of a binary.
>
> I will work on the custom fact idea. if such an issue is coming at
> me so early in the game, then I may as well get started learning
> how to build facts.
For what it is worth, I would say that the reason you are running into
this so early in the process is that you are not yet using puppet the
way it expects to be used – and, so, you run into these complications.
In the puppet model you would not ask the system about that binary,
then do something: you would say "machine A should have the binary,
and the something, while machine B should not have either".
The idea is that you declare, as far as possible, the state your
system should be – not what calculations you make to get from the
current to the desired state. Fact should, ideally, be things about
the system that don't vary (memory size, disk space) with state
changes, not questions about the current state.
So, I would strongly encourage you to "answer" the question about that
binary by deciding if the machine should have it installed, and if it
should work, and then implementing *that* in puppet. The file install
bit should just fall into line after that.
Regards,
Daniel
--
⎋ Puppet Labs Developer – http://puppetlabs.com
✉ Daniel Pittman <dan...@puppetlabs.com>
✆ Contact me via gtalk, email, or phone: +1 (877) 575-9775
♲ Made with 100 percent post-consumer electrons
You caught me. I'm a recoveing cfengine junky. It will take a while
to stop thinking in terms of making actions dependent on client's
membership in a (cf) class.
So here are the specifics of what I'm trying to do in this particular
task. I welcome any ideas on following the puppet way:
We run a 3rd party tool called centrifyDC to integrate our linux
servers with AD. a client can either be "joined" to a centrify (AD)
zone or not. I'm writing a puppet module to manage site
customizations to various files in /etc/pam.d. Trouble is centrify,
when joining to AD, will prepend it's own pam configs to my existing
pam files. so before I can push my custom pam configs, I need to
know if the client is joined to AD or not. the command to check the
centify status is /usr/bin/adinfo. it is installed on all nodes via
puppet.
My first fact (I am so proud):
# adinfo.rb
# Mon Jan 31 15:54:02 PST 2011
# ago...@ucop.edu
#
# a custom fact returning the centrify zone
if FileTest.exists?("/usr/bin/adinfo")
Facter.add(:adinfo) do
setcode do
%x{/usr/bin/adinfo --zone}.chomp
end
end
end
modules/pam/manifests/init.pp:
# module pam
# pmlab01-vhost.ucop.edu
# Fri Jan 28 17:34:53 PST 2011
# ago...@ucop.edu
# Pam configs
class pam {
file { "/etc/pam.d":
owner => root, group => root, mode => 644,
if $adinfo {
source => "puppet:///pam/centrify",
} else {
source => "puppet:///pam/no_centrify",
}
recurse => true,
}
}
On Mon, Jan 31, 2011 at 03:46:32PM -0800, Daniel Pittman wrote:
> On Mon, Jan 31, 2011 at 15:31, Ashley Gould <ago...@ucop.edu> wrote:
> > On Mon, Jan 31, 2011 at 02:14:29PM -0800, jcbollinger wrote:
> >> On Jan 31, 3:12 pm, Ashley Gould <ago...@ucop.edu> wrote:
> >>
> >> > if [ "/usr/bin/my_harmless_binary 2>&1 >/dev/null" ]; then
> >> > echo "my_harmless_binary succeeded"
> >> > cp /tmp/file1 /data/
> >> > else
> >> > echo "my_harmless_binary FAILED"
> >> > fi
>
> [...]
> Regards,
> Daniel
> --
> ⎋ Puppet Labs Developer – http://puppetlabs.com
> ✉ Daniel Pittman <dan...@puppetlabs.com>
> ✆ Contact me via gtalk, email, or phone: +1 (877) 575-9775
> ♲ Made with 100 percent post-consumer electrons
--
[...]
> You caught me. I'm a recoveing cfengine junky. It will take a while
> to stop thinking in terms of making actions dependent on client's
> membership in a (cf) class.
>
> So here are the specifics of what I'm trying to do in this particular
> task. I welcome any ideas on following the puppet way:
OK. So, in the circumstances, where membership of the domain with
centrifyDC is *not* managed by puppet, your use of a fact is the right
thing to do. For better or worse, "am I joined to a domain" is a fact
about the machine that comes from outside of puppet.
In the longer term I would hope to have that information pushed out
from the puppet system, so that if a node *should* be joined with
centrifyDC puppet will make it so, but until then what you have is
great.
[...]
> My first fact (I am so proud):
>
> # adinfo.rb
> # Mon Jan 31 15:54:02 PST 2011
> # ago...@ucop.edu
> #
> # a custom fact returning the centrify zone
>
> if FileTest.exists?("/usr/bin/adinfo")
> Facter.add(:adinfo) do
> setcode do
> %x{/usr/bin/adinfo --zone}.chomp
> end
> end
> end
Perfect. You even handled the case where centrify isn't installed
correctly, so this will not blow up random other systems. :)
Probably the one thing to watch out for is that *only* the empty
string is reliably false in puppet, in context, so you can't just
return the (Ruby) false value or something. That gets turned into a
string, and the string "false" is actually true in puppet. Just for
the future. :)
> class pam {
> file { "/etc/pam.d":
> owner => root, group => root, mode => 644,
> if $adinfo {
> source => "puppet:///pam/centrify",
> } else {
> source => "puppet:///pam/no_centrify",
> }
You actually want:
mode => 0644,
$adinfo ? {
'' => '.../no_centrify',
default => '.../centrify' # Assuming that "any value" means "in a domain"
},
whatever => else
The if statement is not used in that context, only a case statement.
I have considered that option, but I'll need to learn to walk first.
What makes it difficult for puppet to manage this task is that the
centrifyDC tools require authorization as AD admin user to join a
node to AD. This can be scripted, but I don't want to hardcode AD
admin passwords into puppet manifests. Again, suggestions are very
welcome.
Are you ok with keeping these credentials on disk at all? If so, you
could feed the relevant join exec the data from local disk.
Another alternative would be to set up an out-of-band process where
the clients reuse their SSL certificates to make client-authenticated
requests to a host that returns the relevant credentials only during
the times when the node needs them.
>
>
> --
>
> -ashley
>
> Did you try poking at it with a stick?
>
For what it is worth, I "solved" a similar problem that we had by
doing it by hand. We had sufficiently few rollouts where this
mattered that it was just easier to document that step required hand
action than to automate it and solve these security issues.
(Also, I went looking and found zero attempts to solve this in a
reusable, FOSS way, let alone working solutions.)
I've done this a few times too. Have a single class that the relevant
chunks of your manifests depend upon, and then have a cluster of Execs
that just check for the existence of this data on the local client.
I kept wanting to be able to notify a notify resource so you could get
a nice human oriented error, but I don't think I worked out a good
solution for that.
> (Also, I went looking and found zero attempts to solve this in a
> reusable, FOSS way, let alone working solutions.)
Yep. I've been dreaming of a Puppet-integrated Password Safe for a while :)
>
> Regards,
> Daniel
> --
> ⎋ Puppet Labs Developer – http://puppetlabs.com
> ✉ Daniel Pittman <dan...@puppetlabs.com>
> ✆ Contact me via gtalk, email, or phone: +1 (877) 575-9775
> ♲ Made with 100 percent post-consumer electrons
>
Alas! I'm currently enjoying a powerful need for such a thing. My one
need is that someone who compromises a puppet client host shouldn't have
access to the safe except in specific circumstances specified by
external conditions.
I'd also like a pony. Have it on my desk by Monday.
--
"N'aimez pas votre voiture?
Alor, l'heure est arrive pour la brul�!"
-- Mark Jaroski
In my previous life, we created a special account in AD with only the
permission to create a computer account in the directory. The special
account didn't have login rights or anything. It should be well
documented in your centrifyDC tools how to create such a limited
account.
Once you have this account in place, you can lock it.
You can then unlock the account when you need to build a machine and
have it automatically lock again after 15 minutes or so, if you want.
Hope this helps,
--
Jeff McCune
http://www.puppetlabs.com/
I actually did some work on this on the plane recently, re-using the
certificates that nodes already have to do arbitrary encryption and
decryption.
It's not as seamless as I'd like, I've essentially subclassed the file
type, but it's giving me some ideas about how we might want to come up
with something more integrated.
I'll polish it up and put it up on github next week when I get back from FOSDEM.
Hi Nigel,
I found this via a google search today. I've come up with a few
possible solutions, but I don't like them. I was thinking of using
the existing cert as well.
Have you posted the code you came up with?
Kyle