From d8eaca88038fa0ef15fda0c4a11a7f08daebc8ef Mon Sep 17 00:00:00 2001 From: Ohad Levy Date: Thu, 9 Apr 2009 20:58:47 +0800 Subject: mini daemon to trigger puppetrun on clients without puppet listen mode --- ext/puppetlisten/puppetlisten.rb | 76 ++++++++++++++++++++++++++++++++++++++++ ext/puppetlisten/puppetrun.rb | 39 +++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100755 ext/puppetlisten/puppetlisten.rb create mode 100755 ext/puppetlisten/puppetrun.rb (limited to 'ext/puppetlisten') 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 -- cgit