[ SEA-GHOST MINI SHELL]

Path : /proc/2/root/var/lib/zabbix/
FILE UPLOADER :
Current File : //proc/2/root/var/lib/zabbix/windows_vm_import.py

#!/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