Simon Kuhn
2009-May-18 18:31 UTC
[Puppet Users] File contents into a variable (once it exists)
I''m trying to approach ssh authorized_keys distribution from another angle. It seems like the standard method is to either put the ssh public key into a variable in a puppet manifest or to place the file within the puppet file hierarchy. I''m not happy with either of these options, because I would like to create a user from start to finish as hands-off as possible (including ssh key generation and propagation). So I want the following to happen: - Define a user in a puppet class - Have puppet create that user''s home directory and ssh public/private keys on the main server - Export public keys into that user''s authorized_keys file on every server I have a method that does this (or so it seems), but the main problem is that without some tomfoolery I can''t figure out how to read a file''s contents into a variable only AFTER that file is created by an exec command. I have the following (after ''user'' has been called): if $hostname == puppet { exec { "create-ssh-key-$name@$domain": command => "ssh-keygen -t rsa -C ''$name@ $domain'' -N '''' -q -f /home/$name/.ssh/id_rsa", path => "/usr/bin:/bin", creates => ["/home/$name/.ssh/id_rsa","/home/ $name/.ssh/id_rsa.pub"], require => [ User["$name"], File["/home/ $name/.ssh/"] ], before => Ssh_authorized_key["$name@$domain"], user => $name, } @@ssh_authorized_key { "$name@$domain": ensure => present, key => generate("/usr/bin/cut","-f2","-d ","/ home/$name/.ssh/id_rsa.pub"), target => "/home/$name/.ssh/authorized_keys", type => ssh-rsa, user => $name, name => "$name@$domain", require => User["$name"], } } Ssh_authorized_key <<| name == "$name@$domain" |>> However, unless I completely remove the ssh_authorized_key call until the user exists, I wind up with this error: May 16 00:44:12 puppet puppetmasterd[22843]: Failed to execute generator /usr/bin/cut: Execution of ''/usr/bin/cut -f2 -d /home/ user/.ssh/id_rsa.pub'' returned 1: /usr/bin/cut: /home/user/.ssh/ id_rsa.pub: No such file or directory at /etc/puppet/modules/users/ manifests/init.pp:34 on node puppetmaster I''ve tried a number of different requires, befores, and splitting things into multiple files/classes/defines to try to force the execution order that I want but to no avail. It seems like ''generate'' is always run early, and so the user and id_rsa.pub file haven''t been made yet. I finally used the following tactic: key => file("/home/$name/.ssh/id_rsa.pub","/etc/ssh/ssh_host_key.pub") so that the first execution puts the host''s public key into authorized_keys (which serves no purpose, but it''s the same format and that file will always exist) and the second execution does the right thing. But it''s pretty gross, and it means users will take a longer time than necessary to fully propagate. Is there some method that I''m overlooking to force puppet to schedule ''ssh_authorized_key'' after ''exec'' in this case? -- Simon Kuhn --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---
Paul Lathrop
2009-May-18 22:30 UTC
[Puppet Users] Re: File contents into a variable (once it exists)
Simon, It seems like you are trying to work with puppet as though it were a procedural language, not a declarative one. You should try to think of a way of expressing your user abstraction in terms of declarative statements instead of as a series of steps. If you must do a series of steps, you might consider writing a custom resource type for your needs. --Paul On Mon, May 18, 2009 at 11:31 AM, Simon Kuhn <simon.kuhn@gmail.com> wrote:> > I''m trying to approach ssh authorized_keys distribution from another > angle. It seems like the standard method is to either put the ssh > public key into a variable in a puppet manifest or to place the file > within the puppet file hierarchy. I''m not happy with either of these > options, because I would like to create a user from start to finish as > hands-off as possible (including ssh key generation and propagation). > > So I want the following to happen: > > - Define a user in a puppet class > - Have puppet create that user''s home directory and ssh public/private > keys on the main server > - Export public keys into that user''s authorized_keys file on every > server > > I have a method that does this (or so it seems), but the main problem > is that without some tomfoolery I can''t figure out how to read a > file''s contents into a variable only AFTER that file is created by an > exec command. > > I have the following (after ''user'' has been called): > > if $hostname == puppet { > exec { "create-ssh-key-$name@$domain": > command => "ssh-keygen -t rsa -C ''$name@ > $domain'' -N '''' -q -f /home/$name/.ssh/id_rsa", > path => "/usr/bin:/bin", > creates => ["/home/$name/.ssh/id_rsa","/home/ > $name/.ssh/id_rsa.pub"], > require => [ User["$name"], File["/home/ > $name/.ssh/"] ], > before => Ssh_authorized_key["$name@$domain"], > user => $name, > } > > @@ssh_authorized_key { "$name@$domain": > ensure => present, > key => generate("/usr/bin/cut","-f2","-d ","/ > home/$name/.ssh/id_rsa.pub"), > target => "/home/$name/.ssh/authorized_keys", > type => ssh-rsa, > user => $name, > name => "$name@$domain", > require => User["$name"], > } > } > > Ssh_authorized_key <<| name == "$name@$domain" |>> > > However, unless I completely remove the ssh_authorized_key call until > the user exists, I wind up with this error: > > May 16 00:44:12 puppet puppetmasterd[22843]: Failed to execute > generator /usr/bin/cut: Execution of ''/usr/bin/cut -f2 -d /home/ > user/.ssh/id_rsa.pub'' returned 1: /usr/bin/cut: /home/user/.ssh/ > id_rsa.pub: No such file or directory at /etc/puppet/modules/users/ > manifests/init.pp:34 on node puppetmaster > > I''ve tried a number of different requires, befores, and splitting > things into multiple files/classes/defines to try to force the > execution order that I want but to no avail. It seems like ''generate'' > is always run early, and so the user and id_rsa.pub file haven''t been > made yet. > > I finally used the following tactic: > > key => file("/home/$name/.ssh/id_rsa.pub","/etc/ssh/ssh_host_key.pub") > > so that the first execution puts the host''s public key into > authorized_keys (which serves no purpose, but it''s the same format and > that file will always exist) and the second execution does the right > thing. But it''s pretty gross, and it means users will take a longer > time than necessary to fully propagate. > > Is there some method that I''m overlooking to force puppet to schedule > ''ssh_authorized_key'' after ''exec'' in this case? > > -- > Simon Kuhn > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---
Simon Kuhn
2009-May-19 04:21 UTC
[Puppet Users] File contents into a variable (once it exists)
Paul, Thanks for the tip regarding approaching the problem from a more puppet-like declarative stance. I''m not really sure that it''s possible here, besides making a custom resource type as you mention. The main hurdle that I see with any solution is that fundamentally generate() / file() don''t behave according to the normal dependence rules that the rest of Puppet uses. For instance, this would work perfectly fine: @@ssh_authorized_key { "$name@$domain": source => "puppet://puppet/ssh/id_rsa.pub", requires => User["$name"], } but attempting to jerry-rig the same behavior by reading in an arbitrary file on the puppetmaster system will not work (without my kluge approach). So, I guess barring a change in puppet to only fetch function results when that resource is actually to be created (versus when it is to be parsed), there''s no alternative. -- Simon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---
Peter Meier
2009-May-19 08:18 UTC
[Puppet Users] Re: File contents into a variable (once it exists)
Hi> but attempting to jerry-rig the same behavior by reading in an > arbitrary file on the puppetmaster system will not work (without my > kluge approach). So, I guess barring a change in puppet to only fetch > function results when that resource is actually to be created (versus > when it is to be parsed), there''s no alternative.if you''re fine with creating the keys on the master you could write a function which provides you the content. Functions are always evaluated on the master only. The function could even create the ssh keys if they''re not yet on the master. cheers pete --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---
Luke Kanies
2009-May-20 16:14 UTC
[Puppet Users] Re: File contents into a variable (once it exists)
On May 19, 2009, at 3:18 AM, Peter Meier wrote:> > Hi > >> but attempting to jerry-rig the same behavior by reading in an >> arbitrary file on the puppetmaster system will not work (without my >> kluge approach). So, I guess barring a change in puppet to only fetch >> function results when that resource is actually to be created (versus >> when it is to be parsed), there''s no alternative. > > if you''re fine with creating the keys on the master you could write a > function which provides you the content. > > Functions are always evaluated on the master only. The function could > even create the ssh keys if they''re not yet on the master.As Peter indicates, you need to see the separation between client and server - you want to create the keys on the server and then read them in, both of which should use functions, not resources. Then you feed the keys to a resource, which knows how to deploy them on the client. -- To be positive: To be mistaken at the top of one''s voice. -- Ambrose Bierce --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---