summaryrefslogtreecommitdiffstats
path: root/ext/puppetlisten
diff options
context:
space:
mode:
authorOhad Levy <ohad.levy@infineon.com>2009-04-09 20:58:47 +0800
committerJames Turnbull <james@lovedthanlost.net>2009-04-12 13:28:43 +1000
commitd8eaca88038fa0ef15fda0c4a11a7f08daebc8ef (patch)
tree920050be9bfa9b5cf91cef9e385c23df8e50f3d8 /ext/puppetlisten
parent7bb8c35f6c70cf32feba9a3ce224155b9d446289 (diff)
downloadpuppet-d8eaca88038fa0ef15fda0c4a11a7f08daebc8ef.tar.gz
puppet-d8eaca88038fa0ef15fda0c4a11a7f08daebc8ef.tar.xz
puppet-d8eaca88038fa0ef15fda0c4a11a7f08daebc8ef.zip
mini daemon to trigger puppetrun on clients without puppet listen mode
Diffstat (limited to 'ext/puppetlisten')
-rwxr-xr-xext/puppetlisten/puppetlisten.rb76
-rwxr-xr-xext/puppetlisten/puppetrun.rb39
2 files changed, 115 insertions, 0 deletions
diff --git a/ext/puppetlisten/puppetlisten.rb b/ext/puppetlisten/puppetlisten.rb
new file mode 100755
index 000000000..00923ed48
--- /dev/null
+++ b/ext/puppetlisten/puppetlisten.rb
@@ -0,0 +1,76 @@
+#! /usr/bin/env ruby
+# this is a daemon which accepts non standard (within puppet normal intervals) puppet configruation run request
+# uses SSL for communication based on the puppet infrastructure
+# ohadlevy@gmail.com
+
+port = 8139
+cmd = "puppetd -o -v --no-daemonize"
+
+require 'puppet/sslcertificates/support'
+require 'socket'
+require 'facter'
+
+# load puppet configuration, needed to find SSL certificates
+Puppet[:config] = "/etc/puppet/puppet.conf"
+Puppet.parse_config
+
+# set the SSL environment
+ctx = OpenSSL::SSL::SSLContext.new()
+ctx.key = OpenSSL::PKey::RSA.new(File::read(Puppet[:hostprivkey]))
+ctx.cert = OpenSSL::X509::Certificate.new(File::read(Puppet[:hostcert]))
+ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
+ctx.ca_file = Puppet[:localcacert]
+
+# find which hosts are allowed to trigger us
+allowed_servers = Array.new
+runner = false;
+File.open(Puppet[:authconfig]).each do |line|
+ case line
+ when /^\s*#/: next # skip comments
+ when /^\s*$/: next # skip blank lines
+ when /\[puppetrunner\]/: # puppetrunner section
+ runner=true
+ when /^\s*(\w+)\s+(.+)$/:
+ var = $1
+ value = $2
+ case var
+ when "allow":
+ value.split(/\s*,\s*/).each { |val|
+ allowed_servers << val
+ puts "allowing %s access" % val
+ } if runner==true
+ end
+ else
+ runner=false
+ end
+end
+
+# be a daemon
+sock = TCPServer.new(port)
+ssls = OpenSSL::SSL::SSLServer.new(sock, ctx)
+
+loop do
+ begin
+ ns = ssls.accept # start SSL session
+ af, port, host, ip = ns.peeraddr
+ print "connection from #{host+"("+ip+")"} "
+ if allowed_servers.include?(host)
+ #TODO add support for tags and other command line arguments
+ puts "accepted"
+ ns.puts "Executing #{cmd} on #{Facter.fqdn}.\n*******OUTPUT********\n\n"
+ IO.popen(cmd) do |f|
+ while line = f.gets do
+ ns.puts line
+ end
+ end
+ ns.puts "\n*********DONE**********"
+ else
+ ns.puts "denied\n"
+ puts "denied"
+ end
+ ns.close
+ rescue
+ ns.close
+ next
+ end
+end
diff --git a/ext/puppetlisten/puppetrun.rb b/ext/puppetlisten/puppetrun.rb
new file mode 100755
index 000000000..937152058
--- /dev/null
+++ b/ext/puppetlisten/puppetrun.rb
@@ -0,0 +1,39 @@
+#! /usr/bin/env ruby
+# this scripts calls a client and ask him to trigger a puppetd run
+# uses SSL for communication based on the puppet infrastructure
+# the client allows access based on the namespaceauth
+# ohadlevy@gmail.com
+
+port = 8139
+if ARGV[0].nil?
+ warn "Usage: hostname to run against"
+ exit 1
+else
+ host = ARGV[0]
+end
+
+require 'puppet/sslcertificates/support'
+require 'socket'
+
+# load puppet configuration, needed to find ssl certificates
+Puppet[:config] = "/etc/puppet/puppet.conf"
+Puppet.parse_config
+
+# establish the certificate
+ctx = OpenSSL::SSL::SSLContext.new()
+ctx.key = OpenSSL::PKey::RSA.new(File::read(Puppet[:hostprivkey]))
+ctx.cert = OpenSSL::X509::Certificate.new(File::read(Puppet[:hostcert]))
+ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ctx.ca_file = Puppet[:localcacert]
+
+# establish the connection
+s = TCPSocket.new(host, port)
+ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
+ssl.connect # start SSL session
+ssl.sync_close = true # if true the underlying socket will be
+ # closed in SSLSocket#close. (default: false)
+while (line = ssl.gets)
+ puts line
+end
+
+ssl.close