Created
March 8, 2018 09:24
-
-
Save q1x/1dda2ac0f17481c9312f6408a738683d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# | |
# import needed modules. | |
# pyzabbix is needed, see https://github.com/lukecyca/pyzabbix | |
# | |
import argparse | |
import ConfigParser | |
import os | |
import os.path | |
import time | |
import sys | |
import logging | |
import distutils.util | |
from pprint import pprint | |
from pyzabbix import ZabbixAPI | |
logger = logging.getLogger(__name__) | |
logger.addHandler(logging.StreamHandler()) | |
logger.setLevel(logging.WARNING) | |
# define config helper function | |
def ConfigSectionMap(section): | |
dict1 = {} | |
options = Config.options(section) | |
for option in options: | |
try: | |
dict1[option] = Config.get(section, option) | |
if dict1[option] == -1: | |
DebugPrint("skip: %s" % option) | |
except: | |
print("exception on %s!" % option) | |
dict1[option] = None | |
return dict1 | |
def PrintError(error): | |
sys.exit(error) | |
def hostfilter(hosts,field,value): | |
newlist=[] | |
for host in hosts: | |
if host['inventory'][field].lower() == value.lower(): | |
newlist.append(host) | |
return newlist | |
# set default vars | |
defconf = os.getenv("HOME") + "/.zbx.conf" | |
username = "" | |
password = "" | |
api = "" | |
noverify = "" | |
# Define commandline arguments | |
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,description='Creates Zabbix trigger dependencies for on-site equipment to the local default gateway, LLD triggers will be ignored.', epilog=""" | |
This program can use .ini style configuration files to retrieve the needed API connection information. | |
To use this type of storage, create a conf file (the default is $HOME/.zbx.conf) that contains at least the [Zabbix API] section and any of the other parameters: | |
[Zabbix API] | |
username=johndoe | |
password=verysecretpassword | |
api=https://zabbix.mycompany.com/path/to/zabbix/frontend/ | |
no_verify=true | |
""") | |
parser.add_argument('-u', '--username', help='User for the Zabbix api') | |
parser.add_argument('-p', '--password', help='Password for the Zabbix api user') | |
parser.add_argument('-a', '--api', help='Zabbix API URL') | |
parser.add_argument('--no-verify', help='Disables certificate validation when using a secure connection',action='store_true') | |
parser.add_argument('-c','--config', help='Config file location (defaults to $HOME/.zbx.conf)') | |
parser.add_argument('-v', '--verbose', help='Enables verbose output.',action='store_true') | |
parser.add_argument('-d', '--debug', help='Enables debug output.',action='store_true') | |
parser.add_argument('-t', '--trigger', help='Trigger description of the gateway reachability check',required=True) | |
parser.add_argument('-T', '--tag', help='Use "tag" inventory field to group devices, default is "contract_number"', action='store_true') | |
parser.add_argument('--gwtype', help='Value of the inventory "type" field for gateway devices, default type is "router"',default='router') | |
parser.add_argument('--types', help='Device types that need to be made dependent of the gateway device, default types are "router", "switch", "access-point", "camera" and "phone"',nargs='+',default=['router','switch', 'access-point', 'camera', 'phone']) | |
args = parser.parse_args() | |
# load config module | |
Config = ConfigParser.ConfigParser() | |
Config | |
# if configuration argument is set, test the config file | |
if args.config: | |
if os.path.isfile(args.config) and os.access(args.config, os.R_OK): | |
Config.read(args.config) | |
# if not set, try default config file | |
else: | |
if os.path.isfile(defconf) and os.access(defconf, os.R_OK): | |
Config.read(defconf) | |
# try to load available settings from config file | |
try: | |
username=ConfigSectionMap("Zabbix API")['username'] | |
password=ConfigSectionMap("Zabbix API")['password'] | |
api=ConfigSectionMap("Zabbix API")['api'] | |
noverify=bool(distutils.util.strtobool(ConfigSectionMap("Zabbix API")["no_verify"])) | |
except: | |
pass | |
# override settings if they are provided as arguments | |
if args.username: | |
username = args.username | |
if args.password: | |
password = args.password | |
if args.api: | |
api = args.api | |
if args.no_verify: | |
noverify = args.no_verify | |
# test for needed params | |
if not username: | |
sys.exit("Error: API User not set") | |
if not password: | |
sys.exit("Error: API Password not set") | |
if not api: | |
sys.exit("Error: API URL is not set") | |
if args.verbose: | |
logger.setLevel(logging.INFO) | |
if args.debug: | |
logger.setLevel(logging.DEBUG) | |
if args.tag: | |
item = 'tag' | |
else: | |
item = 'contract_number' | |
gateway_type = args.gwtype | |
devicetypes = args.types | |
# Setup Zabbix API connection | |
zapi = ZabbixAPI(api) | |
if noverify is True: | |
zapi.session.verify = False | |
# Login to the Zabbix API | |
zapi.login(username, password) | |
zapi.timeout=900 | |
################################## | |
# Start actual API logic | |
################################## | |
# Zabbix version | |
zversion=zapi.apiinfo.version() | |
logger.info("Zabbix API version: %s", str(zversion)) | |
# Fetch all hosts | |
hosts = zapi.host.get(**{"output" : ["host","name","inventory"], | |
"selectInventory" : ['type','tag','contract_number'], | |
"withInventory" : True | |
}) | |
# Find gateway devices | |
gateways = hostfilter(hosts,'type',gateway_type) | |
if gateways: | |
for gateway in gateways: | |
logger.debug("Found gateway %s (%s)", gateway['host'], gateway['name']) | |
master = zapi.trigger.get(**{"output" : ["description"], | |
"filter":{'hostid': gateway['hostid'],'description': args.trigger} | |
}) | |
if master: | |
master = master[0] | |
logger.debug(" - Gateway trigger has id %d", int(master['triggerid'])) | |
if gateway['inventory'][item].strip(): | |
devices = hostfilter(hosts,item,gateway['inventory'][item].strip()) | |
for device in devices: | |
updated = 0 | |
if device['inventory']['type'].lower() in devicetypes: | |
devmaster = zapi.trigger.get(**{"output" : ["description"], | |
"filter":{'hostid': device['hostid'],'description': args.trigger} | |
}) | |
if devmaster: | |
devmaster = devmaster[0] | |
logger.debug(" |- Found dependent device %s (%s), main trigger is %d", device['host'], device['name'], int(devmaster['triggerid'])) | |
slaves = zapi.trigger.get(**{"output" : ["description"], | |
"selectDependencies": 'extend', | |
"filter":{'hostid': device['hostid'],'flags': "0"} | |
}) | |
for slave in slaves: | |
if slave['triggerid'] != master['triggerid']: | |
if not slave['dependencies']: | |
if slave['triggerid'] == devmaster['triggerid']: | |
try: | |
zapi.trigger.adddependencies(**{'triggerid': slave['triggerid'],'dependsOnTriggerid': master['triggerid']}) | |
logger.info(" ||- Trigger %d ('%s') was made dependent of gateway trigger %d", int(slave['triggerid']),slave['description'], int(master['triggerid'])) | |
updated = updated+1 | |
except: | |
logger.error("*** Could not link %d ('%s') as a dependency to trigger %d", int(slave['triggerid']),slave['description'], int(master['triggerid'])) | |
else: | |
try: | |
zapi.trigger.adddependencies(**{'triggerid': slave['triggerid'],'dependsOnTriggerid': devmaster['triggerid']}) | |
logger.info(" ||- Trigger %d ('%s') was made dependent of device trigger %d", int(slave['triggerid']),slave['description'], int(devmaster['triggerid'])) | |
updated = updated+1 | |
except: | |
logger.error("*** Could not link %d ('%s') as a dependency to trigger %d", int(slave['triggerid']),slave['description'], int(devmaster['triggerid'])) | |
if updated == 0: | |
logger.debug(" ||- No trigger dependencies were updated on this host") | |
else: | |
logger.debug(" |- Ignoring device %s (%s) as it doesn't match filter", device['host'], device['name']) | |
else: | |
logger.info("*** No %s found on %s, can't find related devices.",item,gateway['host']) | |
else: | |
logger.info("*** Could not find trigger '%s' on %s",str(args.trigger),gateway['host']) | |
else: | |
logger.info("*** Could not find gateway devices of type '%s'",str(args.gwtype)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment