[ SEA-GHOST MINI SHELL]
#!/usr/bin/python
import pymssql
import json
import sys
import datetime
import itertools
# Uncomment if you need Debug output on console
#import logging
#logging.basicConfig(level=logging.DEBUG)
from pyzabbix.api import ZabbixAPI
today = datetime.datetime.today()
log_file = open("/var/log/import_windows_vm.log", "a")
log_file.write("#############################################################\n")
log_file.write( "Started at "+today.strftime("%d-%m-%Y %H:%M:%S\n\n"))
DBHOST = sys.argv[1]
DBUSER = sys.argv[2]
DBPASS = sys.argv[3]
DBNAME = sys.argv[4]
# Note: in the code you can find a lot of commented print
# they are left for troubleshooting if needed
# This list contain data with unformatted text data from database. Part of list as example:
# ('mumma_pryor', '10738665', '7901227', '1344', 'Standard Windows Server', 'Registered', 'vs-mumma_pryor.au.syrahost.com', 'Windows Server', 'NULL', '2012 R2', 'Hyper-V', '2012 R2', 'none', 'NULL', '850', 'Australia', '27.124.118.183', 'NULL', 'NULL'), ('bill@superoptical.com.au', '10529007', ...),...
list_of_raw_data = []
# List contain Service Level type and fqdn of VM
# VM that has Self-managed plan not included in this list
list_of_raw_plan = []
# This list contain only FQDN of hosts that in database with normal status (not deleted). Part of list as example:
# ['vs-mumma_pryor.au.syrahost.com', 'vs-billsuperoptica2.au.syrahost.com', 'vs-dohogroli.au.syrahost.com',...]
list_of_names = []
# This list contain FQDN of hosts that already exist in Zabbix-Customer in Microsoft* Groups.
# ['vs-Nomadic28.au.syrahost.com', 'vs-ledsig.au.syrahost.com', 'vs-jpccomps.au.syrahost.com',...]
list_of_names_in_groups = []
# In one period of time this list contain only one IP addresses of host from database.
list_IPaddress = []
# In one period of time this list contain only one Plan of host from database.
list_Plan = []
Plan = []
# This list contain hosts that in database marked as "Deleted"
deleted_hosts = []
host_for_delete_in_zabbix = []
# ID`s of our Groups in Zabbix-customer. 9 - Self-managed, 12- management, 21 - Full management
groups = [9,12,21]
# List with ID, name and Tarif
info_for_host = []
list1 = []
# List for store customer`s data such as name, surename, email
customers_data = []
zapi = ZabbixAPI('https://zabbix-customer.au.syrahost.com', user='zabbix-VPS-MS', password='Z;N8GqHVB1YO')
for i in groups:
groups_raw_output = zapi.do_request('host.get',{'filter': {'status': 0},'output': 'extend', 'groupids': i})
get_host_names = groups_raw_output.get("result")
for item in get_host_names:
list_of_names_in_groups.append(item["name"])
conn = pymssql.connect(server=DBHOST, user=DBUSER, password=DBPASS, database=DBNAME)
cursor = conn.cursor()
cursor.execute('SELECT * FROM "Customers"."dbo"."products";')
all_rows = cursor.fetchall()
cursor.execute('SELECT * FROM "Customers"."dbo"."product_ip";')
all_ip = cursor.fetchall()
cursor.execute('SELECT * FROM "Customers"."dbo"."customers";')
all_logins = cursor.fetchall()
# Plan or service level of current VM
service_level = []
service_level_intermediate = []
for k in all_rows:
if k[9] != 'deleted' and (k[6] == 'Service Level: Full Support' or k[6] == 'Service Level: Fully Managed' or k[6] == 'Service Level: Managed'):
service_level_intermediate.extend([k[14],k[6]])
service_level.append(service_level_intermediate)
service_level_intermediate = []
else:
pass
for k in all_rows:
# We are taking every tuple and analyze them one by one. k[9] here equal to the Status of the host in database.
if k[9] != 'deleted' and k[9] != 'expired' and (k[6] == 'Custom Server' or k[6] == 'Standard Windows Server' or k[6] == 'Professional Windows Server' or k[6] == 'Enterprise Windows Server' or k[6] == 'Windows Basic Server'):
list_of_raw_data.append(k)
#print("list_of_raw_data ---->",list_of_raw_data)
# get ID of record and check on uniq
#print(list_of_names)
if k[0] not in list_of_names:
list1.extend([k[0],k[1]])
else:
list1.append('')
# get fqdn of VM and check on dublicates
# it`s beacuse of database peculiar properties
# one VM can has several IP`s with different ID`s
if k[14] not in list_of_names:
list1.append(k[14])
#print("list1.append(k[14]) -->", list1)
else:
#if duplicate fqdn in list set it as empty
list1.append('')
# loop for get IP by Product_ID
for x in list(all_ip):
if list1[0] in x:
if x[1] != '':
list1.append(x[1])
info_for_host.append(list1)
# cut from info_for_host its excessive IP`s
for x in info_for_host:
# every element in list can contain more than 1 IP address
# that`s why we should leave only one (main) IP address
# 1 is uniq ID in database, 2 is customer ID, 3 is name, 4 is IP
# until that part of script element can look like:
# [9584873, 93124, 'vs-berginc.au.syrahost.com', '43.243.119.171', '43.243.119.170', '103.68.164.90']
# after handle it will look like [9584873, 93124, 'vs-berginc.au.syrahost.com', '43.243.119.171']
if len(x) >4:
del x[4:len(x)]
list1 = []
list_of_names.append(k[14])
# Hosts with status "Deleted" we are saving in separate list. We will use it for host delete function.
if k[9] == 'deleted' and k[14] != '' and (k[6] == 'Custom Server' or k[6] == 'Standard Windows Server' or k[6] == 'Professional Windows Server' or k[6] == 'Enterprise Windows Server' or k[6] == 'Windows Basic Server'):
deleted_hosts.append(k[14])
# delete duplicates
deleted_hosts = list(dict.fromkeys(deleted_hosts))
# This is complex construction for delete duplicates from list of list.
# Duplicates occur because of peculiar features of database.
info_for_host.sort()
info_for_host = list(info_for_host for info_for_host,_ in itertools.groupby(info_for_host))
# Remove empty ('') values with its list if such exist
for x in info_for_host:
for y in x:
if y == '':
info_for_host.remove(x)
# Fill up list customers_data with FQDN of VM, email of a customer, name, surname.
# In the end this list look like: [['vs-display12341.au.syrahost.com', 'darren@o4i.com.au', 'Darren', 'Pullar'], ['vs-fortunewt1.au.syrahost.com', 'SIMERAN_JIT@HOTMAIL.COM', 'Kanwaljit', 'Kaur'],...]
# all_logins variable contains tuple type of data. For every element in tuple we are getting product_id value and compare it
# if such ID exist in info_for_host. If so we add in the list customers_data fqdn value, email, name and surname
for x[0] in all_logins:
productid = x[0][0]
for y in info_for_host:
if productid == y[1]:
customers_data.append([y[2],x[0][5],x[0][3],x[0][4]])
# In this list will get only host names that exist in database but not in Zabbix yet. Such host names consider as new and they must be added in monitoring
not_in_zabbix = list(set(list_of_names) - set(list_of_names_in_groups))
not_in_zabbix = [i for i in not_in_zabbix if i != '']
def add_in_zabbix_self_managed(FQDN, IPaddress, Plan):
try:
zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':12}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':10110}]})
print("Self managed host added in Zabbix:",FQDN)
log_file.write( "Self managed host added in Zabbix: "+FQDN+"\n")
except:
print("Host with the name "+FQDN+" and Plan = Self can`t be added")
log_file.write("Error:Host with the name "+FQDN+" and Plan = Self can`t be added\n")
return None
def add_in_zabbix_managed(FQDN, IPaddress, Plan):
try:
zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':9}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':10110},{'templateid':15324}]})
print("Managed host added in Zabbix:",FQDN)
log_file.write("Managed host added in Zabbix: "+FQDN+"\m")
except:
print("Host with the name "+FQDN+" and Plan = Managed can`t be added")
log_file.write("Error:Host with the name "+FQDN+" and Plan = Managed can`t be added\n")
return None
def add_in_zabbix_full_managed(FQDN, IPaddress, Plan):
try:
zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':21}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':10110},{'templateid':15324},{'templateid':15328},{'templateid':15330}]})
print("Full managed host added in Zabbix: ",FQDN)
log_file.write("Full managed host added in Zabbix: "+FQDN+"\n")
except:
print("Host with the name "+FQDN+" and Plan = Full can`t be added")
log_file.write("Error:Host with the name "+FQDN+" and Plan = Full can`t be added\n")
return None
def delete_host(name):
try:
info_for_host = zapi.do_request('host.get',{'output':["hostid","host"],"filter":{"host":[name]}})
result = info_for_host.get("result")
hostid = result[0].get("hostid")
zapi.do_request('host.delete',[hostid])
print("Host "+str(name)+" deleted from monitoring")
log_file.write("Host "+str(name)+" deleted from monitoring\n")
except:
print("Host"+FQDN+"can`t be deleted")
log_file.write("Error:Host"+FQDN+"can`t be deleted\n")
#Delete host from monitoring
# Here we take decision which host should be deleted from monitoring.
# 1) every time "x" contain one hostname from "list_of_names_in_groups". list_of_names_in_groups - contain all hosts in monitoring.
# 2) and if this hostname not in database (by another words some one added this host manually) result will append to the variable "host_for_delete_in_zabbix"
# 3) also possible if host still in database but marked as "Deleted". That`s why we are checking if this hostname in deleted_hosts. And result
# also will append to the list "host_for_delete_in_zabbix"
#host_for_delete_in_zabbix = [x for x in list_of_names_in_groups + list_of_names if x not in list_of_names or x in deleted_hosts]
host_for_delete_in_zabbix = [x for x in list_of_names_in_groups if x not in list_of_names or x in deleted_hosts]
if host_for_delete_in_zabbix != []:
print("\nThese hosts in zabbix but not in DB or with status \"Deleted\" in DB:\n")
log_file.write("These hosts in zabbix but not in DB or with status \"Deleted\" in DB:\n")
for i in host_for_delete_in_zabbix:
# Call function for host delete
delete_host(i)
if not_in_zabbix != []:
#print("not_in_zabbix--->",not_in_zabbix)
# If variable is not empty than nothing new hosts should be added in monitoring
for element in not_in_zabbix:
FQDN = element
# By default plan = Self
Plan = "Self"
# In this list will get only one IP address from the database output.
for x in info_for_host:
if x[2] == FQDN:
IPaddress = x[3]
# In this list only Plan
for x in info_for_host:
if x[2] == FQDN:
for name in service_level:
if FQDN in name[0]:
Plan = name[1]
# taking out email,name,surname for future tag
for customer_info in customers_data:
if FQDN in customer_info[0]:
email = customer_info[1]
customer_name = customer_info[2]
customer_surname = customer_info[3]
# According to the Plan we are decide in which group should be added host and with which templates.
if Plan == 'none' or Plan == 'Self' or Plan == 'NULL':
add_in_zabbix_self_managed(FQDN,IPaddress,Plan)
elif Plan == 'Service Level: Managed':
add_in_zabbix_managed(FQDN,IPaddress,Plan)
elif Plan == 'Service Level: Full Support' or Plan == 'Service Level: Fully Managed':
add_in_zabbix_full_managed(FQDN,IPaddress,Plan)
else:
print("All hosts from the database added in Zabbix\n")
# log_file.write("All hosts from the database added in Zabbix\n\n")
print("\nDone")
log_file.write("\nDone at "+today.strftime("%d-%m-%Y %H:%M:%S\n"))
log_file.write("#############################################################\n\n")
log_file.close()
SEA-GHOST - SHELL CODING BY SEA-GHOST