tools/reconnect_hosts.rb
#!/usr/bin/env ruby
require File.expand_path('../config/environment', __dir__)
require "optimist"
opts = Optimist.options do
opt :ems_id, "The ID of the ExtManagementSystem to reconnect Hosts for", :type => :integer
opt :ems_name, "The name of the ExtManagementSystem to reconnect Hosts for", :type => :string
opt :by, "Property to treat as unique, defaults to :hostname", :type => :string, :default => "hostname"
opt :dry_run, "Just print out what would be done without modifying anything", :type => :boolean, :default => true
end
if opts[:ems_id].nil? && opts[:ems_name].nil?
Optimist.die :ems_id, "Must pass either --ems-id or --ems-name"
end
ems = if opts[:ems_id].present?
ExtManagementSystem.find_by(:id => opts[:ems_id])
else
ExtManagementSystem.find_by(:name => opts[:ems_id])
end
if ems.nil?
print "Failed to find EMS [#{opts.fetch(:ems_id) { opts[:ems_name] }}]"
exit
end
ems_id = ems.id
# Find all Hosts which match the unique key
hosts_index = Host.where(opts[:by] => ems.hosts.pluck(opts[:by])).group_by { |host| host.send(opts[:by]) }
# Select where there are exactly two with the same unique property, one archived and one active
duplicate_hosts = hosts_index.select { |_by, hosts| hosts.count == 2 && hosts.select(&:has_active_ems?).count == 1 }
puts "Found #{duplicate_hosts.count} duplicate Hosts..."
if opts[:dry_run]
puts "**** This is a dry-run, nothing will be updated! ****"
else
puts "**** THIS WILL MODIFY YOUR HOSTS ****"
puts " Press Enter to Continue: "
STDIN.getc
end
activated_hosts = duplicate_hosts.map do |_by, hosts|
active_hosts, inactive_hosts = hosts.partition(&:has_active_ems?)
# There should only be one of each
active_host = active_hosts.first
inactive_host = inactive_hosts.first
next if active_host.nil? || inactive_host.nil?
next if active_host.created_on < inactive_host.created_on # Always pick the older Host
# Disconnect the new Host and activate the old Host
puts "Disconnecting Host [#{active_host.name}] id [#{active_host.id}] uid_ems [#{active_host.uid_ems}] ems_ref [#{active_host.ems_ref}]"
active_host.disconnect_inv unless opts[:dry_run]
puts "Activating Host [#{inactive_host.name}] id [#{inactive_host.id}] uid_ems [#{inactive_host.uid_ems}] ems_ref [#{inactive_host.ems_ref}]"
inactive_host.update!(:ems_id => ems_id, :uid_ems => active_host.uid_ems, :ems_ref => active_host.ems_ref) unless opts[:dry_run]
inactive_host
end.compact
puts "Activated #{activated_hosts.count} Hosts:\n#{activated_hosts.map(&:name).join(", ")}"