foreman/lib/tasks/puppet.rake @ f516c137
d135ae69 | Telmo | # Author: Roberto Moral Denche (Telmo : telmox@gmail.com)
|
|
# Description: The tasks defined in this Rakefile will help you populate some of the
|
|||
a67b0923 | Paul Kelly | # fields in Foreman with what is already present in your database from
|
|
# StoragedConfig.
|
|||
require 'rake/clean'
|
|||
41d40698 | Paul Kelly | require 'yaml'
|
|
d135ae69 | Telmo | ||
namespace :puppet do
|
|||
a67b0923 | Paul Kelly | root = "/"
|
|
# Author: Paul Kelly (paul.ian.kelly@gogglemail.com)
|
|||
# Description: The tasks defined in this namespace populate a directory structure with rdocs for the
|
|||
# clases defined in puppet.
|
|||
namespace :rdoc do
|
|||
desc "
|
|||
Populates the rdoc tree with information about all the classes in your modules."
|
|||
task :generate => [:environment, :prepare] do
|
|||
Puppetclass.rdoc root
|
|||
end
|
|||
desc "
|
|||
Optionally creates a copy of the current puppet modules and sanitizes it.
|
|||
It should return the directory into which it has copied the cleaned modules"
|
|||
task :prepare => :environment do
|
|||
root = Puppetclass.prepare_rdoc root
|
|||
end
|
|||
end
|
|||
326575f8 | Ohad Levy | namespace :migrate do
|
|
1fe671cf | Ohad Levy | desc "Populates the host fields in Foreman based on your StoredConfig DB"
|
|
326575f8 | Ohad Levy | task :populate_hosts => :environment do
|
|
e22af92d | Ohad Levy | counter = 0
|
|
Host.find_each do |host|
|
|||
d6de9136 | Ohad Levy | if host.fact_values.size == 0
|
|
cf2f7656 | Ohad Levy | $stdout.puts "#{host.hostname} has no facts, skipping"
|
|
d6de9136 | Ohad Levy | next
|
|
end
|
|||
e88536b2 | Daniel Lobato | if host.populate_fields_from_facts
|
|
e22af92d | Ohad Levy | counter += 1
|
|
else
|
|||
cf2f7656 | Ohad Levy | $stdout.puts "#{host.hostname}: #{host.errors.full_messages.join(", ")}"
|
|
326575f8 | Ohad Levy | end
|
|
end
|
|||
e22af92d | Ohad Levy | puts "Imported #{counter} hosts out of #{Host.count} Hosts" unless counter == 0
|
|
end
|
|||
end
|
|||
namespace :import do
|
|||
desc "Imports hosts and facts from existings YAML files, use dir= to override default directory"
|
|||
task :hosts_and_facts => :environment do
|
|||
2bf4a47a | Andy Taylor | dir = ENV['dir'] || "#{SETTINGS[:puppetvardir]}/yaml/facts"
|
|
e22af92d | Ohad Levy | puts "Importing from #{dir}"
|
|
Dir["#{dir}/*.yaml"].each do |yaml|
|
|||
name = yaml.match(/.*\/(.*).yaml/)[1]
|
|||
e577678a | Ohad Levy | puts "Importing #{name}"
|
|
956e2ed4 | Dmitri Dolguikh | puppet_facts = File.read(yaml)
|
|
facts_stripped_of_class_names = YAML::load(puppet_facts.gsub(/\!ruby\/object.*$/,''))
|
|||
e88536b2 | Daniel Lobato | Host.import_host_and_facts facts_stripped_of_class_names['name'], facts_stripped_of_class_names['values'].with_indifferent_access
|
|
e22af92d | Ohad Levy | end
|
|
d135ae69 | Telmo | end
|
|
326575f8 | Ohad Levy | end
|
|
95db4b8d | Ohad Levy | namespace :import do
|
|
e374699f | Ohad Levy | desc "
|
|
Update puppet environments and classes. Optional batch flag triggers run with no prompting\nUse proxy=<proxy name> to import from or get the first one by default"
|
|||
10ac0055 | Neil Miao | task :puppet_classes, [:batch, :envname] => :environment do | t, args |
|
|
41d40698 | Paul Kelly | args.batch = args.batch == "true"
|
|
e374699f | Ohad Levy | ||
f516c137 | Dmitri Dolguikh | proxies = SmartProxy.with_features("Puppet")
|
|
e374699f | Ohad Levy | if proxies.empty?
|
|
puts "ERROR: We did not find at least one configured Smart Proxy with the Puppet feature"
|
|||
exit 1
|
|||
end
|
|||
if ENV["proxy"]
|
|||
proxy = proxies.select{|p| p.name == ENV["proxy"]}.first
|
|||
unless proxy.is_a?(SmartProxy)
|
|||
puts "Smart Proxies #{ENV["proxy"]} was not found, aborting"
|
|||
exit 1
|
|||
end
|
|||
end
|
|||
proxy ||= proxies.first
|
|||
# Evaluate any changes that exist between the database of environments and puppetclasses and
|
|||
41d40698 | Paul Kelly | # the on-disk puppet installation
|
|
begin
|
|||
puts "Evaluating possible changes to your installation" unless args.batch
|
|||
10ac0055 | Neil Miao | importer = PuppetClassImporter.new({ :url => proxy.url, :env => args.envname })
|
|
eefbf33f | Daniel Lobato | changes = importer.changes
|
|
41d40698 | Paul Kelly | rescue => e
|
|
67799065 | Ohad Levy | if args.batch
|
|
e374699f | Ohad Levy | Rails.logger.error "Failed to refresh puppet classes: #{e}"
|
|
67799065 | Ohad Levy | else
|
|
41d40698 | Paul Kelly | puts "Problems were detected during the evaluation phase"
|
|
puts
|
|||
puts e.message.gsub(/<br\/>/, "\n") + "\n"
|
|||
puts
|
|||
puts "Please fix these issues and try again"
|
|||
end
|
|||
e374699f | Ohad Levy | exit 1
|
|
41d40698 | Paul Kelly | end
|
|
67799065 | Ohad Levy | if changes["new"].empty? and changes["obsolete"].empty?
|
|
puts "No changes detected" unless args.batch
|
|||
else
|
|||
41d40698 | Paul Kelly | unless args.batch
|
|
bb9a1ad1 | Paul Kelly | puts "Scheduled changes to your environment"
|
|
bb9d0a07 | Dominic Cleal | ["new", "updated"].each do |c|
|
|
puts "#{c.titleize} environments"
|
|||
for env, classes in changes[c]
|
|||
print "%-15s: %s\n" % [env, classes.keys.to_sentence]
|
|||
end
|
|||
bb9a1ad1 | Paul Kelly | end
|
|
puts "Delete environments"
|
|||
for env, classes in changes["obsolete"]
|
|||
if classes.include? "_destroy_"
|
|||
print "%-15s: %s\n" % [env, "Remove environment"]
|
|||
else
|
|||
print "%-15s: %s\n" % [env, classes.to_sentence]
|
|||
end
|
|||
end
|
|||
41d40698 | Paul Kelly | puts
|
|
print "Proceed with these modifications? <yes|no> "
|
|||
response = $stdin.gets
|
|||
bb9a1ad1 | Paul Kelly | exit(0) unless response =~ /^yes/
|
|
41d40698 | Paul Kelly | end
|
|
errors = ""
|
|||
# Apply the filtered changes to the database
|
|||
begin
|
|||
bb9d0a07 | Dominic Cleal | ['new', 'updated', 'obsolete'].each { |kind| changes[kind].each_key { |k| changes[kind.to_s][k] = changes[kind.to_s][k].to_json } }
|
|
errors = PuppetClassImporter.new.obsolete_and_new(changes)
|
|||
bb9a1ad1 | Paul Kelly | rescue => e
|
|
errors = e.message + "\n" + e.backtrace.join("\n")
|
|||
41d40698 | Paul Kelly | end
|
|
unless args.batch
|
|||
unless errors.empty?
|
|||
puts "Problems were detected during the execution phase"
|
|||
puts
|
|||
67799065 | Ohad Levy | puts errors.each { |e| e.gsub(/<br\/>/, "\n") } << "\n"
|
|
41d40698 | Paul Kelly | puts
|
|
puts "Import failed"
|
|||
else
|
|||
puts "Import complete"
|
|||
end
|
|||
else
|
|||
5b6d1303 | Ohad Levy | Rails.logger.warn "Failed to refresh puppet classes: #{errors}"
|
|
41d40698 | Paul Kelly | end
|
|
end
|
|||
95db4b8d | Ohad Levy | end
|
|
2b15ea6f | Daniel Lobato | ||
desc "Imports only the puppet environments from SmartProxy source."
|
|||
task :environments_only, [:batch] => :environment do | t, args |
|
|||
args.batch = args.batch == "true"
|
|||
puts " ================================================================ "
|
|||
puts "Import starts: #{Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")}"
|
|||
f516c137 | Dmitri Dolguikh | proxies = SmartProxy.with_features("Puppet")
|
|
2b15ea6f | Daniel Lobato | if proxies.empty?
|
|
puts "ERROR: We did not find at least one configured Smart Proxy with the Puppet feature"
|
|||
exit 1
|
|||
end
|
|||
if ENV["proxy"]
|
|||
proxy = proxies.select{|p| p.name == ENV["proxy"]}.first
|
|||
unless proxy.is_a?(SmartProxy)
|
|||
puts "Smart Proxies #{ENV["proxy"]} was not found, aborting"
|
|||
exit 1
|
|||
end
|
|||
end
|
|||
proxy ||= proxies.first
|
|||
# Evaluate any changes that exist between the database of environments and the on-disk puppet installation
|
|||
begin
|
|||
puts "Importing environments" unless args.batch
|
|||
importer = PuppetClassImporter.new({ :url => proxy.url })
|
|||
puts "New environments: #{importer.new_environments.join(', ')} "
|
|||
puts "Old environments: #{importer.old_environments.join(', ')} "
|
|||
importer.new_environments.each { |new_environment| Environment.create!(:name => new_environment) }
|
|||
importer.old_environments.each { |old_environment| Environment.find_by_name(old_environment).destroy }
|
|||
rescue => e
|
|||
puts "Problems were detected during the evaluation phase"
|
|||
puts
|
|||
puts e.message.gsub(/<br\/>/, "\n") + "\n"
|
|||
puts
|
|||
puts "Please fix these issues and try again"
|
|||
exit 1
|
|||
end
|
|||
puts "Import ends: #{Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")}"
|
|||
puts " ================================================================ "
|
|||
end
|
|||
95db4b8d | Ohad Levy | end
|
|
41d40698 | Paul Kelly | ||
816465f2 | Ohad Levy | namespace :import do
|
|
desc "
|
|||
Import your hosts classes and parameters classifications from another external node source.
|
|||
define script=/dir/node as the script which provides the external nodes information.
|
|||
This will only scan for hosts that already exists in our database, if you want to
|
|||
import hosts, use one of the other importers.
|
|||
YOU Must import your classes first!"
|
|||
task :external_nodes => :environment do
|
|||
if Puppetclass.count == 0
|
|||
$stdout.puts "You dont have any classes defined.. aborting!"
|
|||
exit(1)
|
|||
end
|
|||
if (script = ENV['script']).nil?
|
|||
$stdout.puts "You must define the old external nodes script to use. script=/path/node"
|
|||
exit(1)
|
|||
end
|
|||
Host.find_each do |host|
|
|||
$stdout.print "processing #{host.name} "
|
|||
nodeinfo = YAML::load %x{#{script} #{host.name}}
|
|||
if nodeinfo.is_a?(Hash)
|
|||
$stdout.puts "DONE" if host.importNode nodeinfo
|
|||
else
|
|||
cf2f7656 | Ohad Levy | $stdout.puts "ERROR: invalid output from external nodes"
|
|
816465f2 | Ohad Levy | end
|
|
0da5bcf1 | Ohad Levy | $stdout.flush
|
|
816465f2 | Ohad Levy | end
|
|
end
|
|||
end
|
|||
d135ae69 | Telmo | end
|