[ SEA-GHOST MINI SHELL]

Path : /proc/2/cwd/proc/self/root/var/lib/zabbix/
FILE UPLOADER :
Current File : //proc/2/cwd/proc/self/root/var/lib/zabbix/vmware_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_vmware_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]

# This list contain data with unformatted text data from database. Part of list as example:
# [(1149561, 1657991, 1344, 505, 'Professional Linux Server', 'vs-jaseptyltd_1149561', 'Self-Managed', 'active', 0, datetime.datetime(2018, 3, 5, 14, 14, 12, 570000), datetime.datetime(2023, 4, 16, 0, 0), 0, 'vs-jaseptyltd.au.syrahost.com', 'au', 'none', 'CentOS6.8', 'root', 'root'), (1149589, 956239, 1344, 512, 'Standard Linux Server - Managed', 'vs-perthbars_1149589', 'Self-Managed', 'active', 0, datetime.datetime(2020, 4, 16, 22, 31, 56, 683000), datetime.datetime(2020, 5, 21, 13, 43, 6), 0, 'vs-perthbars.au.syrahost.com', 'au', 'cPanel and WHM', 'CentOS6.7', 'root', 'root'),...]
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-skikaos.au.syrahost.com', 'vs-tefvps.au.syrahost.com',...]
list_of_names = []

# This list contain FQDN of hosts that already exist in Zabbix-Customer in Virtual Servers* 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. 18 - Self-managed, 8 - management, 20 - Full management
groups = [18,8,20]

# 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-vmware', password='nESxba5uQD58DLn5zq6')
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 "vmware-crms-automation"."dbo"."products";')

all_rows = cursor.fetchall()

cursor.execute('SELECT * FROM "vmware-crms-automation"."dbo"."product_ip";')
all_ip = cursor.fetchall()

cursor.execute('SELECT * FROM "vmware-crms-automation"."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[7] == 'active' and (k[6] == 'Service Level: Full Support' or k[6] == 'Service Level: Fully Managed' or k[6] == 'Service Level: Managed' or k[6] == 'Self-Managed'):
        service_level_intermediate.extend([k[12],k[6]])
        service_level.append(service_level_intermediate)
        service_level_intermediate = []

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[7] == 'active' and (k[4] == 'Standard Linux Server' or k[4] == 'My Linux Server Plus' or k[4] == 'Enterprise Linux Server' or k[4] == 'Professional Linux Server - Managed' or k[4] == 'Standard Linux Server - Managed' or k[4] == 'Professional Linux Server' or k[4] == 'My Linux Server' or k[4] == 'Linux Basic Server' or k[4] == 'My Linux Server Plus' or k[4] == 'Linux Server 50GB' or k[4] == 'Linux Server 100GB'):
        list_of_raw_data.append(k)
        # get ID of record and check on uniq
        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[12])
        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[12])
    
    # Hosts with status "Deleted" we are saving in separate list. We will use it for host delete function.
    if k[7] == 'deleted' or k[7] == 'expired' and k[12] != '' and (k[4] == 'Standard Linux Server' or k[4] == 'My Linux Server Plus' or k[4] == 'Enterprise Linux Server' or k[4] == 'Professional Linux Server - Managed' or k[4] == 'Standard Linux Server - Managed' or k[4] == 'Professional Linux Server' or k[4] == 'My Linux Server' or k[4] == 'Linux Basic Server' or k[4] == 'My Linux Server Plus' or k[4] == 'Linux Server 50GB' or k[4] == 'Linux Server 100GB'):
        deleted_hosts.append(k[12])

# 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:
        if email != None or customer_name != None and customer_surname != None:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':18}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':15177}]})
            print("Self managed host added in Zabbix:",FQDN)
        else:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':18}],'templates':[{'templateid':15177}]})
            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:
        if email != None or customer_name != None and customer_surname != None:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':8}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':15177},{'templateid':15173},{'templateid':15172},{'templateid':10099},{'templateid':15180},{'templateid':15175},{'templateid':15179},{'templateid':15170}]})
            print("Managed host added in Zabbix:",FQDN)
        else:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':8}],'templates':[{'templateid':15177},{'templateid':15173},{'templateid':15172},{'templateid':10099},{'templateid':15180},{'templateid':15175},{'templateid':15179},{'templateid':15170}]})
            print("Managed host added in Zabbix:",FQDN)
            log_file.write("Error: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:
        if email != None or customer_name != None and customer_surname != None:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':20}],'tags':[{'tag':'email','value':email},{'tag':'name','value':customer_name},{'tag':'surname','value':customer_surname}],'templates':[{'templateid':15177},{'templateid':15173},{'templateid':15172},{'templateid':10099},{'templateid':15180},{'templateid':15175},{'templateid':15179},{'templateid':15170},{'templateid':15169},{'templateid':15178},{'templateid':10073},{'templateid':10102},{'templateid':15171}]})
            print("Full managed host added in Zabbix: ",FQDN)
        else:
            zapi.do_request('host.create',{'host':FQDN,'interfaces':[{'type':1,'main':1,'useip':1,'ip':IPaddress,'dns':FQDN,'port':10050}],'groups':[{'groupid':20}],'templates':[{'templateid':15177},{'templateid':15173},{'templateid':15172},{'templateid':10099},{'templateid':15180},{'templateid':15175},{'templateid':15179},{'templateid':15170},{'templateid':15169},{'templateid':15178},{'templateid':10073},{'templateid':10102},{'templateid':15171}]})
            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 i contains a hostname marked "deleted" in database
# 2) Every x contains an FQDN from the list "list_of_names"
# 3) If hostname from deleted_hosts in info_for_host we are exclude this hostname from the list for delete. It is possible
# only in situations when the same hostname must be added but already exist in databse with status "deleted" and another ID.

if deleted_hosts != []:
    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 deleted_hosts:
        for x in list_of_names:
            if i == x:
                deleted_hosts.remove(i)
print("\n-----------------------------\n")
log_file.write("\n-----------------------------\n")

# After above we can compare if some host in Zabbix in list for delete. Such hosts add in list host_for_delete_in_zabbix
host_for_delete_in_zabbix = [x for x in list_of_names_in_groups if x in deleted_hosts and x not in list_of_names]
for i in host_for_delete_in_zabbix:
    delete_host(i)

if 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' or Plan == 'Self-Managed':
            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