Revision 8c974670
Added by Ohad Levy over 12 years ago
files/external_node.rb | ||
---|---|---|
#! /usr/bin/env ruby
|
||
|
||
SETTINGS = {
|
||
:url => "http://foreman",
|
||
:puppetdir => "/var/lib/puppet",
|
||
:timeout => 3,
|
||
}
|
||
|
||
### Do not edit below this line
|
||
|
||
def url
|
||
SETTINGS[:url] || raise("Must provide URL - please edit file")
|
||
end
|
||
|
||
def certname
|
||
ARGV[0] || raise("Must provide certname as an argument")
|
||
end
|
||
|
||
def puppetdir
|
||
SETTINGS[:puppetdir] || raise("Must provide puppet base directory - please edit file")
|
||
end
|
||
|
||
def stat_file
|
||
FileUtils.mkdir_p "#{puppetdir}/yaml/foreman/"
|
||
"#{puppetdir}/yaml/foreman/#{certname}.yaml"
|
||
end
|
||
|
||
def tsecs
|
||
SETTINGS[:timeout] || 3
|
||
end
|
||
|
||
require 'net/http'
|
||
require 'net/https' if url =~ /^https/
|
||
require 'fileutils'
|
||
require 'timeout'
|
||
|
||
def upload_facts
|
||
# Temp file keeping the last run time
|
||
last_run = File.exists?(stat_file) ? File.stat(stat_file).mtime.utc : Time.now - 365*24*60*60
|
||
filename = "#{puppetdir}/yaml/facts/#{certname}.yaml"
|
||
last_fact = File.stat(filename).mtime.utc
|
||
if last_fact > last_run
|
||
fact = File.read(filename)
|
||
begin
|
||
Net::HTTP.post_form(URI.parse("#{url}/fact_values/create?format=yml"), {'facts'=> fact})
|
||
rescue => e
|
||
raise "Could not send facts to Foreman: #{e}"
|
||
end
|
||
end
|
||
end
|
||
|
||
def cache result
|
||
File.open(stat_file, 'w') {|f| f.write(result) }
|
||
end
|
||
|
||
def read_cache
|
||
File.read(stat_file)
|
||
rescue => e
|
||
raise "Unable to read from Cache file: #{e}"
|
||
end
|
||
|
||
def enc
|
||
foreman_url = "#{url}/node/#{certname}?format=yml"
|
||
uri = URI.parse(foreman_url)
|
||
req = Net::HTTP::Get.new(foreman_url)
|
||
res = Net::HTTP.start(uri.host, uri.port) { |http| http.request(req) }
|
||
|
||
raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"
|
||
res.body
|
||
end
|
||
|
||
# Actual code starts here
|
||
begin
|
||
# send facts to Foreman - optional uncomment 'upload_facts' to activate.
|
||
# if you use this option below, make sure that you don't send facts to foreman via the rake task or push facts alternatives.
|
||
#
|
||
# upload_facts
|
||
#
|
||
# query External node
|
||
begin
|
||
result = ""
|
||
timeout(tsecs) do
|
||
result = enc
|
||
cache result
|
||
end
|
||
rescue TimeoutError, SocketError, Errno::EHOSTUNREACH
|
||
# Read from cache, we got some sort of an error.
|
||
result = read_cache
|
||
ensure
|
||
puts result
|
||
end
|
||
rescue => e
|
||
warn e
|
||
exit 1
|
||
end
|
files/foreman-report.rb | ||
---|---|---|
# copy this file to your report dir - e.g. /usr/lib/ruby/1.8/puppet/reports/
|
||
# add this report in your puppetmaster reports - e.g, in your puppet.conf add:
|
||
# reports=log, foreman # (or any other reports you want)
|
||
|
||
# URL of your Foreman installation
|
||
$foreman_url="http://foreman:3000"
|
||
|
||
require 'puppet'
|
||
require 'net/http'
|
||
require 'uri'
|
||
|
||
Puppet::Reports.register_report(:foreman) do
|
||
Puppet.settings.use(:reporting)
|
||
desc "Sends reports directly to Foreman"
|
||
|
||
def process
|
||
begin
|
||
uri = URI.parse($foreman_url)
|
||
http = Net::HTTP.new(uri.host, uri.port)
|
||
if uri.scheme == 'https' then
|
||
http.use_ssl = true
|
||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||
end
|
||
req = Net::HTTP::Post.new("/reports/create?format=yml")
|
||
req.set_form_data({'report' => to_yaml})
|
||
response = http.request(req)
|
||
rescue Exception => e
|
||
raise Puppet::Error, "Could not send report to Foreman at #{$foreman_url}/reports/create?format=yml: #{e}"
|
||
end
|
||
end
|
||
end
|
files/push_facts.rb | ||
---|---|---|
#! /usr/bin/env ruby
|
||
#
|
||
# This scripts runs on remote puppetmasters that you wish to import their nodes facts into Foreman
|
||
# it uploads all of the new facts its encounter based on a control file which is stored in /tmp directory.
|
||
# This script can run in cron, e.g. once every minute
|
||
# if you run it on many puppetmasters at the same time, you might consider adding something like:
|
||
# sleep rand(10) # that not all PM hammers the DB at once.
|
||
# ohadlevy@gmail.com
|
||
|
||
# puppet config dir
|
||
puppetdir="/var/lib/puppet"
|
||
|
||
# URL where Foreman lives
|
||
url="http://foreman"
|
||
|
||
# Temp file keeping the last run time
|
||
stat_file = "/tmp/foreman_fact_importer"
|
||
|
||
require 'fileutils'
|
||
require 'net/http'
|
||
require 'net/https'
|
||
require 'uri'
|
||
|
||
last_run = File.exists?(stat_file) ? File.stat(stat_file).mtime.utc : Time.now - 365*60*60
|
||
|
||
Dir["#{puppetdir}/yaml/facts/*.yaml"].each do |filename|
|
||
last_fact = File.stat(filename).mtime.utc
|
||
if last_fact > last_run
|
||
fact = File.read(filename)
|
||
puts "Importing #{filename}"
|
||
begin
|
||
uri = URI.parse(url)
|
||
http = Net::HTTP.new(uri.host, uri.port)
|
||
if uri.scheme == 'https' then
|
||
http.use_ssl = true
|
||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||
end
|
||
req = Net::HTTP::Post.new("/fact_values/create?format=yml")
|
||
req.set_form_data({'facts' => fact})
|
||
response = http.request(req)
|
||
rescue Exception => e
|
||
raise "Could not send facts to Foreman: #{e}"
|
||
end
|
||
end
|
||
end
|
||
FileUtils.touch stat_file
|
manifests/config.pp | ||
---|---|---|
class foreman::config {
|
||
Cron {
|
||
require => User["$foreman::params::user"],
|
||
user => $foreman::params::user,
|
||
environment => "RAILS_ENV=${foreman::params::environment}",
|
||
}
|
||
|
||
file {"/etc/foreman/settings.yaml":
|
||
content => template("foreman/settings.yaml.erb"),
|
||
notify => Class["foreman::service"],
|
||
owner => $foreman::params::user,
|
||
require => User["$foreman::params::user"],
|
||
}
|
||
|
||
file { $foreman::params::app_root:
|
||
ensure => directory,
|
||
}
|
||
|
||
user { $foreman::params::user:
|
||
shell => "/sbin/nologin",
|
||
comment => "Foreman",
|
||
ensure => "present",
|
||
home => $foreman::params::app_root,
|
||
require => Class["foreman::install"],
|
||
}
|
||
|
||
# cleans up the session entries in the database
|
||
# if you are using fact or report importers, this creates a session per request
|
||
# which can easily result with a lot of old and unrequired in your database
|
||
# eventually slowing it down.
|
||
cron{"clear_session_table":
|
||
command => "(cd $foreman::params::app_root && rake db:sessions:clear)",
|
||
minute => "15",
|
||
hour => "23",
|
||
}
|
||
|
||
if $foreman::params::reports { include foreman::config::reports }
|
||
if $foreman::params::enc { include foreman::config::enc }
|
||
if $foreman::params::passenger { include foreman::config::passenger }
|
||
}
|
manifests/config/enc.pp | ||
---|---|---|
class foreman::config::enc {
|
||
file{
|
||
"/etc/puppet/node.rb":
|
||
content => template("foreman/external_node.rb.erb"),
|
||
mode => 550,
|
||
owner => "puppet",
|
||
group => "puppet";
|
||
"${foreman::params::puppet_home}/yaml/foreman":
|
||
ensure => directory,
|
||
mode => 640,
|
||
owner => "puppet",
|
||
group => "puppet";
|
||
}
|
||
}
|
manifests/config/passenger.pp | ||
---|---|---|
class foreman::config::passenger {
|
||
include apache::ssl
|
||
include ::passenger
|
||
|
||
file {"foreman_vhost":
|
||
path => "${foreman::params::apache_conf_dir}/foreman.conf",
|
||
content => template("foreman/foreman-vhost.conf.erb"),
|
||
mode => 644,
|
||
notify => Exec["reload-apache"],
|
||
}
|
||
|
||
exec {"restart_foreman":
|
||
command => "/bin/touch ${foreman::params::app_root}/tmp/restart.txt",
|
||
refreshonly => true,
|
||
cwd => $foreman::params::app_root,
|
||
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||
require => Class["foreman::install"]
|
||
}
|
||
|
||
# passenger ~2.10 will not load the app if a config.ru doesn't exist in the app
|
||
# root. Also, passenger will run as suid to the owner of the config.ru file.
|
||
file {
|
||
"$foreman::params::app_root/config.ru":
|
||
ensure => link,
|
||
owner => $foreman::params::user,
|
||
target => "${foreman::params::app_root}/vendor/rails/railties/dispatches/config.ru";
|
||
"$foreman::params::app_root/config/environment.rb":
|
||
owner => $foreman::params::user,
|
||
require => Class["foreman::install"];
|
||
}
|
||
|
||
}
|
manifests/config/reports.pp | ||
---|---|---|
class foreman::config::reports {
|
||
|
||
# foreman reporter
|
||
file {"${foreman::params::puppet_basedir}/reports/foreman.rb":
|
||
mode => 444,
|
||
owner => puppet,
|
||
group => puppet,
|
||
content => template("foreman/foreman-report.rb.erb"),
|
||
# notify => Service["puppetmaster"],
|
||
}
|
||
|
||
cron {
|
||
"expire_old_reports":
|
||
command => "(cd $foreman::params::app_root && rake reports:expire)",
|
||
minute => "30",
|
||
hour => "7",
|
||
}
|
||
|
||
cron{"daily summary":
|
||
command => "(cd $foreman::params::app_root && rake reports:summarize)",
|
||
minute => "31",
|
||
hour => "7",
|
||
}
|
||
|
||
|
||
|
||
}
|
manifests/defines.pp | ||
---|---|---|
# common/manifests/defines/line.pp -- a trivial mechanism to ensure a line exists in a file
|
||
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||
# See LICENSE for the full license granted to you.
|
||
|
||
# Usage:
|
||
# line { description:
|
||
# file => "filename",
|
||
# line => "content",
|
||
# ensure => {absent,*present*}
|
||
# }
|
||
#
|
||
|
||
define myline($file, $line, $ensure = 'present') {
|
||
case $ensure {
|
||
default : { err ( "unknown ensure value '${ensure}'" ) }
|
||
present: {
|
||
exec { "echo '${line}' >> '${file}'":
|
||
path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"],
|
||
unless => "grep -qFx '${line}' '${file}'",
|
||
user => root,
|
||
}
|
||
}
|
||
absent: {
|
||
exec { "perl -ni -e 'print unless /^\\Q${line}\\E\$/' '${file}'":
|
||
path => ["/bin", "/sbin", "/usr/bin", "/usr/sbin"],
|
||
onlyif => "grep -qFx '${line}' '${file}'",
|
||
user => root,
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
define link_file($source_path, $target_path) {
|
||
file{"$target_path/$name":
|
||
ensure => link,
|
||
target => "$source_path/$name"
|
||
}
|
||
}
|
manifests/externalnodes.pp | ||
---|---|---|
class foreman::externalnodes {
|
||
file{"/etc/puppet/node.rb":
|
||
source => "puppet:///modules/foreman/external_node.rb",
|
||
mode => 555,
|
||
owner => "puppet", group => "puppet",
|
||
}
|
||
|
||
}
|
manifests/import_facts.pp | ||
---|---|---|
class foreman::import_facts {
|
||
|
||
file {"/etc/puppet/push_facts.rb":
|
||
mode => 555,
|
||
owner => puppet, group => puppet,
|
||
source => "puppet:///modules/foreman/push_facts.rb",
|
||
ensure => $using_store_configs ? {
|
||
true => "absent",
|
||
false => "present"
|
||
},
|
||
}
|
||
|
||
cron{"send_facts_to_foreman":
|
||
command => "/etc/puppet/push_facts.rb",
|
||
user => "puppet",
|
||
minute => "*/2",
|
||
ensure => $using_store_configs ? {
|
||
true => "absent",
|
||
false => "present"
|
||
},
|
||
}
|
||
|
||
}
|
manifests/init.pp | ||
---|---|---|
class foreman {
|
||
|
||
# default variables
|
||
$using_store_configs = false # true or false
|
||
$using_passenger = false # true or false
|
||
$use_development = false # used for initial download
|
||
|
||
$railspath = "/usr/share"
|
||
$foreman_dir = "${railspath}/foreman"
|
||
$foreman_user = "foreman"
|
||
|
||
import "defines.pp"
|
||
|
||
Exec {
|
||
cwd => $foreman_dir,
|
||
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||
require => User[$foreman_user],
|
||
user => $foreman_user,
|
||
}
|
||
|
||
Cron {
|
||
require => User["$foreman_user"],
|
||
user => $foreman_user,
|
||
environment => "RAILS_ENV=production",
|
||
}
|
||
|
||
include foreman::import_facts
|
||
include foreman::reports
|
||
include foreman::externalnodes
|
||
|
||
# Current package is available for Red Hat 5
|
||
if $lsbmajdistrelease == "5" and $lsbdistid != "Debian" {
|
||
include foreman::package
|
||
# passenger setup for Red Hat 5
|
||
include foreman::passenger
|
||
} else {
|
||
include foreman::install_from_source
|
||
}
|
||
|
||
file{$foreman_dir:
|
||
ensure => directory,
|
||
require => User[$foreman_user],
|
||
owner => $foreman_user,
|
||
}
|
||
|
||
user { $foreman_user:
|
||
shell => "/sbin/nologin",
|
||
comment => "Foreman",
|
||
ensure => "present",
|
||
home => $foreman_dir,
|
||
}
|
||
|
||
|
||
# cleans up the session entries in the database
|
||
# if you are using fact or report importers, this creates a session per request
|
||
# which can easily result with a lot of old and unrequired in your database
|
||
# eventually slowing it down.
|
||
cron{"clear_session_table":
|
||
command => "(cd $foreman_dir && rake db:sessions:clear)",
|
||
minute => "15",
|
||
hour => "23",
|
||
}
|
||
|
||
cron{"daily summary":
|
||
command => "(cd $foreman_dir && rake reports:summarize)",
|
||
minute => "30",
|
||
hour => "07",
|
||
}
|
||
include foreman::params
|
||
include foreman::install
|
||
include foreman::config
|
||
include foreman::service
|
||
}
|
manifests/install.pp | ||
---|---|---|
class foreman::install {
|
||
include foreman::install::repos
|
||
|
||
case $operatingsystem {
|
||
redhat,centos,fedora: { include foreman::install::redhat }
|
||
default: { fail("${hostname}: This module does not support operatingsystem $operatingsystem") }
|
||
}
|
||
}
|
manifests/install/redhat.pp | ||
---|---|---|
class foreman::install::redhat {
|
||
|
||
package{"foreman":
|
||
ensure => latest,
|
||
require => Class["foreman::install::repos::redhat"],
|
||
notify => Class["foreman::service"],
|
||
}
|
||
}
|
manifests/install/repos.pp | ||
---|---|---|
class foreman::install::repos {
|
||
case $operatingsystem {
|
||
redhat,centos,fedora: { include foreman::install::repos::redhat }
|
||
default: { fail("${hostname}: This module does not support operatingsystem $operatingsystem") }
|
||
}
|
||
}
|
manifests/install/repos/redhat.pp | ||
---|---|---|
class foreman::install::repos::redhat {
|
||
yumrepo {
|
||
"foreman":
|
||
descr => "Foreman stable repository",
|
||
baseurl => "http://yum.theforeman.org/stable",
|
||
gpgcheck => "0",
|
||
enabled => "1";
|
||
"foreman-testing":
|
||
descr => "Foreman testing repository",
|
||
baseurl => "http://yum.theforeman.org/test",
|
||
enabled => $foreman::params::use_testing ? {
|
||
true => "1",
|
||
default => "0",
|
||
},
|
||
gpgcheck => "0",
|
||
}
|
||
}
|
manifests/install_from_source.pp | ||
---|---|---|
class foreman::install_from_source {
|
||
|
||
$version = $use_development ? {
|
||
true => "nightly",
|
||
false => "latest"
|
||
}
|
||
|
||
Package { ensure => installed, before => Exec["db_migrate"], }
|
||
|
||
file{$railspath: ensure => directory}
|
||
|
||
package{"rake":
|
||
name => $operatingsystem ? {
|
||
default => "rake",
|
||
"CentOs" => "rubygem-rake",
|
||
"RedHat" => "rubygem-rake",
|
||
},
|
||
}
|
||
|
||
package{"sqlite3-ruby":
|
||
name => $operatingsystem ? {
|
||
default => "libsqlite3-ruby",
|
||
"CentOs" => "rubygem-sqlite3-ruby",
|
||
"RedHat" => "rubygem-sqlite3-ruby",
|
||
},
|
||
}
|
||
|
||
package{"rack": ensure => "1.0.1", provider => gem}
|
||
|
||
# Initial Foreman Install
|
||
exec{"install_foreman":
|
||
command => "wget -q http://theforeman.org/foreman-$version.tar.bz2 -O - | tar xjf -",
|
||
cwd => $railspath,
|
||
creates => "$foreman_dir/public",
|
||
notify => Exec["db_migrate"],
|
||
require => File[$foreman_dir],
|
||
}
|
||
|
||
exec{"db_migrate":
|
||
command => "rake db:migrate",
|
||
environment => "RAILS_ENV=production",
|
||
refreshonly => true
|
||
}
|
||
|
||
}
|
manifests/package.pp | ||
---|---|---|
class foreman::package {
|
||
|
||
yumrepo { "foreman":
|
||
descr => "Foreman stable repository",
|
||
baseurl => "http://yum.theforeman.org/stable",
|
||
gpgcheck => "0",
|
||
enabled => "1"
|
||
}
|
||
|
||
yumrepo { 'foreman-testing':
|
||
enabled => '0',
|
||
gpgcheck => '0',
|
||
descr => 'Foreman testing repository',
|
||
baseurl => 'http://yum.theforeman.org/test'
|
||
}
|
||
|
||
package{"foreman":
|
||
ensure => installed,
|
||
require => Yumrepo["foreman"],
|
||
notify => Service["foreman"],
|
||
}
|
||
|
||
service {"foreman":
|
||
ensure => $using_passenger ? {
|
||
true => "stopped",
|
||
false => "running"
|
||
},
|
||
enable => $using_passenger ? {
|
||
true => "false",
|
||
false => "true",
|
||
},
|
||
hasstatus => true,
|
||
}
|
||
}
|
manifests/params.pp | ||
---|---|---|
class foreman::params {
|
||
|
||
# Basic configurations
|
||
$foreman_url = "http://${fqdn}:3000"
|
||
# Should foreman act as an external node classifier (manage puppet class assignments)
|
||
$enc = true
|
||
# Should foreman receive reports from puppet
|
||
$reports = true
|
||
# Should foreman recive facts from puppet
|
||
$facts = true
|
||
# Do you use storeconfig (and run foreman on the same database) ? (note: not required)
|
||
$storeconfigs = false
|
||
# should foreman manage host provisioning as well
|
||
$unattended = true
|
||
# Enable users authentication (default user:admin pw:changeme)
|
||
$authentication = false
|
||
# configure foreman via apache and passenger
|
||
$passenger = true
|
||
# force SSL (note: requires passenger)
|
||
$ssl = true
|
||
|
||
# Advance configurations - no need to change anything here by default
|
||
# allow usage of test / RC rpms as well
|
||
$use_testing = true
|
||
$railspath = "/usr/share"
|
||
$app_root = "${railspath}/foreman"
|
||
$user = "foreman"
|
||
$environment = "production"
|
||
|
||
# OS specific paths
|
||
case $operatingsystem {
|
||
redhat,centos,fedora: {
|
||
$puppet_basedir = "/usr/lib/ruby/site_ruby/1.8/puppet"
|
||
$apache_conf_dir = "/etc/httpd/conf.d"
|
||
}
|
||
default: {
|
||
$puppet_basedir = "/usr/lib/ruby/1.8/puppet"
|
||
$apache_conf_dir = "/etc/apache2/conf.d/foreman.conf"
|
||
}
|
||
}
|
||
$puppet_home = "/var/lib/puppet"
|
||
}
|
manifests/passenger.pp | ||
---|---|---|
class foreman::passenger {
|
||
if $using_passenger {
|
||
include apache2::passenger
|
||
include apache2::ssl
|
||
}
|
||
|
||
file{"foreman_vhost":
|
||
path => $lsbdistid ? {
|
||
default => "/etc/httpd/conf.d/foreman.conf",
|
||
"Ubuntu" => "/etc/apache2/conf.d/foreman.conf",
|
||
"Debian" => "/etc/apache2/conf.d/foreman.conf"
|
||
},
|
||
content => template("foreman/foreman-vhost.conf.erb"),
|
||
mode => 644,
|
||
notify => $using_passenger ? {
|
||
true => Exec["reload-apache2"],
|
||
default => undef,
|
||
},
|
||
ensure => $using_passenger ? {
|
||
true => "present",
|
||
default => "absent",
|
||
},
|
||
}
|
||
|
||
exec{"restart_foreman":
|
||
command => "/bin/touch $foreman_dir/tmp/restart.txt",
|
||
refreshonly => true
|
||
}
|
||
|
||
#passenger ~2.10 will not load the app if a config.ru doesn't exist in the app
|
||
#root. Also, passenger will run as suid to the owner of the config.ru file.
|
||
case $lsbdistid {
|
||
'Ubuntu','Debian': {
|
||
file{"${foreman_dir}/config.ru":
|
||
ensure => file,
|
||
owner => $foreman_user,
|
||
source => "file:///${foreman_dir}/vendor/rails/railties/dispatches/config.ru",
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
manifests/reports.pp | ||
---|---|---|
# please follow the instructions at: http://theforeman.org/wiki/foreman/Puppet_Reports
|
||
|
||
class foreman::reports {
|
||
# directory where your puppet is installed
|
||
$puppet_basedir = $operatingsystem ? {
|
||
default => "/usr/lib/ruby/1.8/puppet",
|
||
"CentOs" => "/usr/lib/ruby/site_ruby/1.8/puppet",
|
||
"RedHat" => "/usr/lib/ruby/site_ruby/1.8/puppet",
|
||
}
|
||
|
||
# foreman reporter
|
||
file {"${puppet_basedir}/reports/foreman.rb":
|
||
mode => 444,
|
||
owner => puppet, group => puppet,
|
||
source => "puppet:///modules/foreman/foreman-report.rb",
|
||
}
|
||
|
||
cron{"expire_old_reports":
|
||
command => "(cd $foreman_dir && rake reports:expire)",
|
||
environment => "RAILS_ENV=production",
|
||
user => $foreman_user,
|
||
minute => "30",
|
||
hour => "7",
|
||
}
|
||
|
||
}
|
manifests/service.pp | ||
---|---|---|
class foreman::service {
|
||
service {"foreman":
|
||
ensure => $foreman::params::passenger ? {
|
||
true => "stopped",
|
||
false => "running"
|
||
},
|
||
enable => $foreman::params::passenger ? {
|
||
true => "false",
|
||
false => "true",
|
||
},
|
||
hasstatus => true,
|
||
}
|
||
}
|
templates/external_node.rb.erb | ||
---|---|---|
#! /usr/bin/env ruby
|
||
|
||
SETTINGS = {
|
||
:url => "<%= scope.lookupvar('foreman::params::foreman_url')%>",
|
||
:puppetdir => "<%= scope.lookupvar('foreman::params::puppet_home')%>",
|
||
:timeout => 3,
|
||
}
|
||
|
||
### Do not edit below this line
|
||
|
||
def url
|
||
SETTINGS[:url] || raise("Must provide URL - please edit file")
|
||
end
|
||
|
||
def certname
|
||
ARGV[0] || raise("Must provide certname as an argument")
|
||
end
|
||
|
||
def puppetdir
|
||
SETTINGS[:puppetdir] || raise("Must provide puppet base directory - please edit file")
|
||
end
|
||
|
||
def stat_file
|
||
FileUtils.mkdir_p "#{puppetdir}/yaml/foreman/"
|
||
"#{puppetdir}/yaml/foreman/#{certname}.yaml"
|
||
end
|
||
|
||
def tsecs
|
||
SETTINGS[:timeout] || 3
|
||
end
|
||
|
||
require 'net/http'
|
||
require 'net/https' if url =~ /^https/
|
||
require 'fileutils'
|
||
require 'timeout'
|
||
|
||
def upload_facts
|
||
# Temp file keeping the last run time
|
||
last_run = File.exists?(stat_file) ? File.stat(stat_file).mtime.utc : Time.now - 365*24*60*60
|
||
filename = "#{puppetdir}/yaml/facts/#{certname}.yaml"
|
||
last_fact = File.stat(filename).mtime.utc
|
||
if last_fact > last_run
|
||
fact = File.read(filename)
|
||
begin
|
||
Net::HTTP.post_form(URI.parse("#{url}/fact_values/create?format=yml"), {'facts'=> fact})
|
||
rescue => e
|
||
raise "Could not send facts to Foreman: #{e}"
|
||
end
|
||
end
|
||
end
|
||
|
||
def cache result
|
||
File.open(stat_file, 'w') {|f| f.write(result) }
|
||
end
|
||
|
||
def read_cache
|
||
File.read(stat_file)
|
||
rescue => e
|
||
raise "Unable to read from Cache file: #{e}"
|
||
end
|
||
|
||
def enc
|
||
foreman_url = "#{url}/node/#{certname}?format=yml"
|
||
uri = URI.parse(foreman_url)
|
||
req = Net::HTTP::Get.new(foreman_url)
|
||
res = Net::HTTP.start(uri.host, uri.port) { |http| http.request(req) }
|
||
|
||
raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"
|
||
res.body
|
||
end
|
||
|
||
# Actual code starts here
|
||
begin
|
||
# send facts to Foreman - optional uncomment 'upload_facts' to activate.
|
||
# if you use this option below, make sure that you don't send facts to foreman via the rake task or push facts alternatives.
|
||
#
|
||
<% if scope.lookupvar('foreman::params::facts') and not scope.lookupvar('foreman::params::storeconfigs') -%>
|
||
upload_facts
|
||
<% end -%>
|
||
#
|
||
# query External node
|
||
begin
|
||
result = ""
|
||
timeout(tsecs) do
|
||
result = enc
|
||
cache result
|
||
end
|
||
rescue TimeoutError, SocketError, Errno::EHOSTUNREACH
|
||
# Read from cache, we got some sort of an error.
|
||
result = read_cache
|
||
ensure
|
||
puts result
|
||
end
|
||
rescue => e
|
||
warn e
|
||
exit 1
|
||
end
|
templates/foreman-report.rb.erb | ||
---|---|---|
# copy this file to your report dir - e.g. /usr/lib/ruby/1.8/puppet/reports/
|
||
# add this report in your puppetmaster reports - e.g, in your puppet.conf add:
|
||
# reports=log, foreman # (or any other reports you want)
|
||
|
||
# URL of your Foreman installation
|
||
$foreman_url=<%= scope.lookupvar("http://foreman:3000") %>
|
||
|
||
require 'puppet'
|
||
require 'net/http'
|
||
require 'uri'
|
||
|
||
Puppet::Reports.register_report(:foreman) do
|
||
Puppet.settings.use(:reporting)
|
||
desc "Sends reports directly to Foreman"
|
||
|
||
def process
|
||
begin
|
||
uri = URI.parse($foreman_url)
|
||
http = Net::HTTP.new(uri.host, uri.port)
|
||
if uri.scheme == 'https' then
|
||
http.use_ssl = true
|
||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||
end
|
||
req = Net::HTTP::Post.new("/reports/create?format=yml")
|
||
req.set_form_data({'report' => to_yaml})
|
||
response = http.request(req)
|
||
rescue Exception => e
|
||
raise Puppet::Error, "Could not send report to Foreman at #{$foreman_url}/reports/create?format=yml: #{e}"
|
||
end
|
||
end
|
||
end
|
templates/foreman-vhost.conf.erb | ||
---|---|---|
<VirtualHost <%= ipaddress %>:80>
|
||
ServerName <%= fqdn %>
|
||
ServerAlias foreman
|
||
DocumentRoot <%= scope.lookupvar 'foreman::foreman_dir' %>/public
|
||
<% if has_variable?("lsbdistid") and lsbdistid == 'Ubuntu' || lsbdistid == 'Debian' %> PassengerAppRoot <%= scope.lookupvar 'foreman::foreman_dir' %><% end %>
|
||
DocumentRoot <%= scope.lookupvar 'foreman::params::app_root' %>/public
|
||
PassengerAppRoot <%= scope.lookupvar 'foreman::params::app_root' %>
|
||
|
||
RailsAutoDetect On
|
||
AddDefaultCharset UTF-8
|
||
... | ... | |
ServerAlias foreman
|
||
|
||
RailsAutoDetect On
|
||
DocumentRoot <%= scope.lookupvar 'foreman::foreman_dir' %>/public
|
||
PassengerAppRoot <%= scope.lookupvar 'foreman::foreman_dir' %>
|
||
DocumentRoot <%= scope.lookupvar 'foreman::params::app_root' %>/public
|
||
PassengerAppRoot <%= scope.lookupvar 'foreman::params::app_root' %>
|
||
|
||
# Use puppet certificates for SSL
|
||
|
templates/settings.yaml.erb | ||
---|---|---|
---
|
||
#your default puppet server - can be overridden in the host level
|
||
#if none specified, plain "puppet" will be used.
|
||
#:puppet_server: puppet
|
||
:unattended: <%= scope.lookupvar("foreman::params::unattended") %>
|
||
:puppetconfdir: /etc/puppet/puppet.conf
|
||
:login: <%= scope.lookupvar("foreman::params::authentication") %>
|
||
:require_ssl: <%= scope.lookupvar("foreman::params::ssl") %>
|
Also available in: Unified diff
restructure foreman module