Project

General

Profile

Download (3.17 KB) Statistics
| Branch: | Tag: | Revision:
# TRANSLATORS: do not translate
desc <<-EOT
When Foreman imports a new host by reading its facts it will create the host and
set its model to a value based upon the facts. This can result in a multiplicity
of similarly named models. These may be condensed donw into a few basic models
by comparing the names against a list of model types and regular expressions that
can be found in the config/model.mappings file.
EOT
namespace :models do
desc 'Reduce the many vendor supplied model names to a few sensible model definitions'
task :consolidate, [:dryrun] => :environment do |t, args|
dryrun = args.dryrun
# Give ourselves permission to edit stuff
User.current = User.anonymous_admin

map_file = "config/model.mappings"
if File.exist? map_file
mappings = YAML.load_file map_file
# Turn off any remote operations that may be called if we modify a host
if SETTINGS[:unattended]
puts "Please turn off unattended mode in config/settings.yaml before running this rake task."
exit(-1)
end
names = mappings.map{|m| m["name"]}
if names.count != names.uniq.count
puts "There are duplicate entries in the the mapping file: " + (names - names.uniq).to_sentence
exit(-1)
end
consolidate mappings, dryrun
else
puts "Unable to find #{map_file}. Please copy this from config/model.mappings.sample or download a newer version from theforeman.org."
end
end
end

def consolidate mappings, dryrun
mapped = []
for mapping in mappings
unless (rex = mapping.delete("rex"))
puts "No regular expression found for #{mapping["name"]}"
next
end
unless mapping.has_key?("name") and mapping.has_key?("vendor_class") and mapping.has_key?("info") and mapping.has_key?("hardware_model")
puts "There is a problem with the entry with regular expression #{rex}"
next
end
original_models = Model.count
matcher = %r{#{rex}}
if (model = Model.find_by_name(mapping["name"]))
puts "Using existing model for #{mapping["name"]}"
model.update_attributes! mapping unless dryrun
elsif (model = Model.new(mapping))
puts "Creating new model #{mapping["name"]}"
end
for original in Model.all
if original.name =~ matcher
puts "Mapping #{original.name} to #{mapping["name"]}"
mapped << original
# Validate before we do block assignments
valid_hosts = []
for host in original.hosts
if host.valid?
valid_hosts << host
else
puts "#{host.name}: #{host.errors.full_messages.to_sentence}"
end
end
unless dryrun
model.hosts << valid_hosts
model.save(:validate => false)
if model.errors.empty?
original.delete if original.hosts.count == 0
else
puts "#{model.name} has these errors:" + model.errors.full_messages.to_sentence
end
end
end
end
end
puts "Models that were not recognized and converted: " + (Model.all - mapped).map(&:name).to_sentence
final_models = Model.count
puts "Condensed #{original_models} models down into #{final_models}" unless original_models == final_models
end
(17-17/31)