Skip to content

Instantly share code, notes, and snippets.

@sergiopena
Last active December 14, 2015 00:59
Show Gist options
  • Save sergiopena/5003315 to your computer and use it in GitHub Desktop.
Save sergiopena/5003315 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
#
# Authors:
# Marc Cirauqui
# Sergio Pena
#
# OS dependencies
#
# yum -y install mysql-devel gcc make
# gem install mysql
# gem install rest-client
# gem install logger
# gem install xml-simple
# gem install taulukko
#
require 'rubygems'
require 'mysql'
require 'restclient'
require 'logger'
require 'xmlsimple'
require 'taulukko'
#
# Database configuration parameters
#########################################
Conf_dbhost = '10.60.11.3'
Conf_dbuser = 'root'
Conf_dbpass = ''
Conf_dbname = 'kinton'
#
# VSM api version configuration
#########################################
#$VSM_api_version = "2.0"
$VSM_api_version = "2.3"
#
# Logger configuration
#########################################
$log = Logger.new(STDOUT)
$log.level = Logger::INFO
#$log.level = Logger::DEBUG
# $log.datetime_format = "%Y-%m-%d %H:%M:%S"
$log.datetime_format = ""
############################################################################################
####################### Do not modify any parameter beyond this line #######################
############################################################################################
def get_nc(con,idDatacenter)
query_hypervisors = "select h.ip,h.user,h.password,h.type from hypervisor h, physicalmachine pm where h.idPhysicalMachine = pm.idPhysicalmachine and pm.idDatacenter = "
query_nc_uri = "select uri from remote_service where remoteServiceType = 'NODE_COLLECTOR' AND idDatacenter = #{idDatacenter};"
nc_list = Hash.new
vm_list_from_nc = Array.new()
vm_list_from_hyp = Array.new()
$log.info "Querying Node Collector of datacenter #{idDatacenter}"
$log.debug "Retrieving nodecollector URI for datacenter #{idDatacenter}"
nc_uri = con.query(query_nc_uri).fetch_row
nc_list[idDatacenter] = Hash.new
#
# Query node collector for hypervisor
hypervisor_list = con.query(query_hypervisors+idDatacenter)
hypervisor_list.each_hash do |hypervisor|
nc_list[idDatacenter][hypervisor['ip']] = Array.new
$log.debug nc_uri
url_nc_hyp = "#{nc_uri[0]}/#{hypervisor['ip']}/virtualsystem?hyp=#{hypervisor['type']}&user=#{hypervisor['user']}&passwd=#{hypervisor['password']}"
$log.debug "Trying to retrieve: #{url_nc_hyp}"
data = nil
begin
response = RestClient.get(url_nc_hyp)
$log.debug "Response from restclient: #{response}"
data = XmlSimple.xml_in(response)
$log.debug "Parsed xml data: #{data}"
rescue => e
e.response
end
if data.respond_to?("each")
if data['virtualSystems'].respond_to?("each")
nc_list_tmp = Array.new()
table = Taulukko.new
$log.info "HYPERVISOR [#{hypervisor['ip']}] - Node collector"
table = Taulukko.new
table.headings = ["Name",'State','CPU','RAM','HD','Datastore','VNC Port']
data['virtualSystems'].each do |x|
tmpsys = "#{x['name']}|#{x['status']}|#{x['cpu']}|#{x['ram']}|#{x['resources'][0]['units']}|#{x['resources'][0]['connection']}|#{x['vport']}"
table << tmpsys.split("|")
nc_list_tmp.push(tmpsys)
end
table.to_s.each { |l| $log.info l.strip}
nc_list[idDatacenter][hypervisor['ip']] = nc_list_tmp
# $log.info "According NC => VMs in hypervisor #{hypervisor['ip']} = #{nc_list_tmp.length}"
$log.info "-"
end
end
end
return nc_list
end
def get_vsm(con,idDatacenter)
#
# VSM call
query_uri_vsm = "select uri from remote_service where remoteServiceType = 'VIRTUAL_SYSTEM_MONITOR' AND idDatacenter = #{idDatacenter};"
vsm = con.query(query_uri_vsm)
$log.debug "Launch query #{query_uri_vsm}"
vsm_list = Hash.new
# vm_list_from_nc = Array.new()
# vm_list_from_hyp = Array.new()
$log.debug "Gathering data from vsm"
vsm_uri = vsm.fetch_row
$log.info "Querying VSM of datacenter #{idDatacenter}"
vsm_list[idDatacenter] = Array.new
#
# Query vsm
$log.debug $VSM_api_version
case $VSM_api_version
when "2.3"
$url_vsm = "#{vsm_uri[0]}/subscriptions"
when "2.0"
$url_vsm = "#{vsm_uri[0]}/api/subscriptions"
end
$log.debug "Trying to retrieve: #{$url_vsm}"
data = nil
begin
vsm_accept = "application/xml"
response = RestClient.get $url_vsm, :accept => vsm_accept
$log.debug "Response from restclient: #{response}"
data = XmlSimple.xml_in(response)
$log.debug "Parsed xml data: #{data}"
rescue => e
$log.error e.to_s
end
if data.respond_to?("each")
if data['subscription'].respond_to?("each")
table = Taulukko.new
table.headings = ["Name",'State','Monitor']
data['subscription'].each do |subs|
$log.debug 'SUBSCRIPTION'
$log.debug subs.inspect
if not subs['monitor']
monitor_ip = 'NONE'
else
monitor_ip = subs['monitor'][0]['address'][0].split("/")[2].split(":")[0]
end
vsm_entry_tmp = "#{subs['uuid']}|#{subs['notified']}|#{monitor_ip}"
vsm_entry_tmp = "#{subs['uuid']}|OFF|#{monitor_ip}" if subs['notified'][0] == 'POWER_OFF'
vsm_entry_tmp = "#{subs['uuid']}|ON|#{monitor_ip}" if subs['notified'][0] == 'POWER_ON'
vsm_list[idDatacenter].push vsm_entry_tmp
table << vsm_entry_tmp.split("|")
$log.debug vsm_list.inspect
end
table.to_s.each { |l| $log.info l.strip}
$log.info "-"
end
end
return vsm_list
end
def get_data_mysql(con,idDatacenter)
#
# Generate list from mysql
$log.info "Querying database for datacenter #{idDatacenter}"
my_list = Hash.new
my_vsm_list = Hash.new
my_list[idDatacenter] = Hash.new
my_vsm_list[idDatacenter] = Array.new
my_hypervisors = con.query("select h.ip,h.id from hypervisor h, physicalmachine pm where h.idPhysicalmachine = pm.idPhysicalmachine and pm.idDatacenter = #{idDatacenter}")
my_hypervisors.each_hash do |h|
my_list[idDatacenter][h['ip']] = Array.new
my_vms = con.query("SELECT vm.name as name,
vm.uuid as uuid,
vm.vdrpPort as vport,
vm.ram<<20 as ram,
vm.cpu as cpu,
vm.state as state,
vm.hd as hd,
ds.name as datastore
FROM virtualmachine vm,
datastore ds
WHERE vm.idDatastore = ds.idDatastore
and idHypervisor = #{h['id']}")
my_list_tmp = Array.new
my_vsm_list_tmp = Array.new
$log.info "HYPERVISOR [#{h['ip']}] - Database"
table = Taulukko.new
table.headings = ['Name','State','CPU','RAM','HD','Datastore','VCN Port']
my_vms.each_hash do |vm|
tmpsys = "#{vm['name']}|#{vm['state']}|#{vm['cpu']}|#{vm['ram']}|#{vm['hd']}|#{vm['datastore']}|#{vm['vport']}"
tmpvsmsys = "#{vm['name']}|#{vm['state']}|#{h['ip']}"
table << tmpsys.split("|")
my_list_tmp.push(tmpsys)
my_vsm_list_tmp.push(tmpvsmsys)
end
table.to_s.each { |l| $log.info l.strip }
$log.info "-"
# $log.info "According DB => VMs in hypervisor #{h['ip']} = #{my_list_tmp.length}"
my_list[idDatacenter][h['ip']] = my_list_tmp
my_vsm_list[idDatacenter].concat my_vsm_list_tmp
$log.debug "#my_vsm_list_tmp #{my_vsm_list_tmp.inspect}"
$log.debug "datacenterid #{idDatacenter}"
$log.debug "my_vsm_list[idDatacenter] #{my_vsm_list[idDatacenter]}"
end
$log.debug "Returning my_vsm_list #{my_vsm_list.inspect}"
$log.debug "Returning my_list #{my_list.inspect}"
return my_list, my_vsm_list
end
def compare_nc_vs_db(nc_list, my_list)
#
# FIND vms in NC output on DB
# FOR each VM in NC output info, will check if DB matches
#
nc_list_keys = nc_list.keys
nc_list_keys.each do |datacenterid|
# $log.info "NC -- Entering DC #{datacenterid}"
$log.info "Checking NC vs DB - Datacenter #{datacenterid}"
dc_hypervisors = nc_list[datacenterid].keys
dc_hypervisors.each do |hypervisor_ip|
$log.info "Analysing hypervisor #{hypervisor_ip} from NC"
ncc_hyp_list = my_list[datacenterid][hypervisor_ip]
ncc_nc_list = nc_list[datacenterid][hypervisor_ip]
ncc_hyp_list.sort
ncc_nc_list.sort
ncc_nc_list.each do |vm_nc_record|
$entry_found = 0
nc_name, nc_state, nc_cpu, nc_ram = vm_nc_record.split("|")
if ncc_hyp_list.include? vm_nc_record
$log.info "VM #{nc_name} matches NC and DB"
$entry_found = 1
else
nc_name, nc_state, nc_cpu, nc_ram, nc_hd, nc_datastore, nc_vport = vm_nc_record.split("|")
ncc_hyp_list.each do |db_record|
db_name, db_state, db_cpu, db_ram, db_hd, db_datastore, db_vport = db_record.split("|")
$log.debug "NC"
$log.debug vm_nc_record
$log.debug "DB"
$log.debug db_record
if vm_nc_record.start_with? db_name
$log.error "Inconsistence found in VM running in hypervisor #{hypervisor_ip}!!"
table = Taulukko.new
table.headings = ["Property","Node Collector","Database"]
table << ['Name',nc_name,db_name]
table << ['State',nc_state,db_state]
table << ['CPU',nc_cpu,db_cpu]
table << ['RAM',nc_ram,db_ram]
table << ['HD',nc_hd,db_hd]
table << ['Datastore',nc_datastore,db_datastore]
table << ['VNC Port',nc_vport,db_vport]
table.to_s.each { |x| $log.error x.strip }
$entry_found = 1
end
end
end
if $entry_found == 0
$log.error "VM [#{nc_name}] running on [#{hypervisor_ip}] NOT FOUND IN DATABASE!"
else
$entry_found == 0
end
end
end
end
end
def compare_db_vs_nc(my_list, nc_list)
#
# FIND vms in DB output on NC
# FOR each VM in DB query info, will check if NC matches
#
my_list_keys = my_list.keys
my_list_keys.each do |datacenterid|
$log.info "Checking DB vs NC - Datacenter #{datacenterid}"
dc_hypervisors = my_list[datacenterid].keys
dc_hypervisors.each do |hypervisor_ip|
$log.info "Analysing hypervisor #{hypervisor_ip} from DB"
dbc_db_list = my_list[datacenterid][hypervisor_ip]
dbc_nc_list = nc_list[datacenterid][hypervisor_ip]
dbc_db_list.sort
dbc_nc_list.sort
dbc_db_list.each do |vm_db_record|
$entry_found = 0
db_name, db_uuid, db_state, db_cpu, db_ram, db_hd, db_datastore, db_vport = vm_db_record.split("|")
# fix to find incorrectly configurations
# if dbc_nc_list.include? vm_db_record
# $log.info "VM #{name} matches NC and DB"
# else
# $log.error "VM #{name} configured on DB and not running on hypervisor"
# end
dbc_nc_list.each do |vm_nc_record|
nc_name, nc_uuid, nc_state, nc_cpu, nc_ram, nc_hd, nc_datastore, nc_vport = vm_nc_record.split("|")
if vm_db_record.start_with? nc_name
$log.info "VM #{db_name} configured on DB and running on hypervisor"
$entry_found = 1
end
end
if $entry_found == 0
$log.error "VM [#{db_name}] configured on DB NOT RUNNING on [#{hypervisor_ip}]!"
else
$entry_found == 0
end
#$log.error "-"
end
end
end
end
def compare_vsm_vs_db(vsm_list, my_vsm_list)
$log.debug "my_vsm_list #{my_vsm_list.inspect}"
$log.debug "vsm_list #{vsm_list.inspect}"
#
# FIND vms in DB output on VSM
# FOR each VM in DB query info, will check if VSM matches
#
my_list_keys = vsm_list.keys
my_list_keys.each do |datacenterid|
$log.info "Checking VSM vs DB - Datacenter #{datacenterid}"
$log.debug "my_vsm_list entry: #{my_vsm_list[datacenterid]}"
$log.debug "vsm_list entry: #{vsm_list[datacenterid]}"
vsm_list[datacenterid].each do |vsm_entry|
$log.debug "Does the list include: #{vsm_entry}"
$entry_found = 0
vsm_name, vsm_state, vsm_hypervisor = vsm_entry.split("|")
my_vsm_list[datacenterid].each do |vsm_db_entry|
db_name, db_state, db_hypervisor = vsm_db_entry.split("|")
if vsm_entry.start_with? db_name
$log.info "FOUND #{db_name} subscribed and configured on database ok"
$entry_found = 1
end
end
if $entry_found == 0
$log.error "VM [#{vsm_name}] subscribed on hypervisor [#{vsm_hypervisor}] but it does not exist on database!"
else
$entry_found = 0
end
end
end
end
def compare_db_vs_vsm(my_vsm_list, vsm_list)
$log.debug "my_vsm_list #{my_vsm_list.inspect}"
$log.debug "vsm_list #{vsm_list.inspect}"
#
# FIND vms in DB output on VSM
# FOR each VM in DB query info, will check if VSM matches
#
my_list_keys = my_vsm_list.keys
my_list_keys.each do |datacenterid|
$log.info "Checking DB vs VSM - Datacenter #{datacenterid}"
$log.debug "my_vsm_list entry: #{my_vsm_list[datacenterid]}"
$log.debug "vsm_list entry: #{vsm_list[datacenterid]}"
my_vsm_list[datacenterid].each do |vsm_db_entry|
$log.debug "Does the list include: #{vsm_db_entry}"
$entry_found = 0
if vsm_list[datacenterid].include? vsm_db_entry
$log.info "FOUND #{vsm_db_entry.split("|")[0]} configured on db and subscribed ok"
$entry_found = 1
else
vsm_list[datacenterid].each do |vsm_entry|
$log.debug "TESTING DB #{vsm_entry.inspect} VSM #{vsm_entry.split("|")[0]}"
db_name, db_state, db_hypervisor = vsm_db_entry.split("|")
vsm_name, vsm_state, vsm_hypervisor = vsm_entry.split("|")
if vsm_db_entry.start_with? vsm_name
table = Taulukko.new
$log.error "INCONSISTENCE FOUND"
table.headings = ["Property","VSM Subscription","Database"]
table << ['Name',vsm_name,db_name]
table << ['State',vsm_state,db_state]
table << ['Hypervisor',vsm_hypervisor,db_hypervisor]
table.to_s.each { |x| $log.error x.strip }
$log.error "-"
$entry_found = 1
end
end
end
if $entry_found == 0
db_name, db_state, db_hypervisor = vsm_db_entry.split("|")
$log.error "VM [#{db_name}] configured on database on [#{db_hypervisor}] is not being monitored!"
else
$entry_found = 0
end
end
end
end
begin
con = Mysql.new(Conf_dbhost, Conf_dbuser, Conf_dbpass, Conf_dbname)
query_datacenters = "select idDatacenter FROM datacenter;"
datacenters = con.query(query_datacenters)
$log.debug "#{datacenters.inspect}"
datacenters.each do |dc|
$log.info "=== DATACENTER #{dc.inspect} ==="
nc_list = get_nc(con,dc.to_s)
vsm_list = get_vsm(con,dc.to_s)
my_list, my_vsm_list = get_data_mysql(con,dc.to_s)
compare_db_vs_nc(my_list,nc_list)
compare_nc_vs_db(nc_list,my_list)
compare_db_vs_vsm(my_vsm_list,vsm_list)
compare_vsm_vs_db(vsm_list,my_vsm_list)
end
rescue Mysql::Error => e
puts e.errno
puts e.error
ensure
con.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment