Skip to content

Instantly share code, notes, and snippets.

@q1x
Created March 6, 2019 16:22
Show Gist options
  • Save q1x/c1d35a041ef65164a1316d9a2a18c89d to your computer and use it in GitHub Desktop.
Save q1x/c1d35a041ef65164a1316d9a2a18c89d to your computer and use it in GitHub Desktop.
Zabbix proxy dependencies
#!/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
import urllib3
from pprint import pprint
from pyzabbix import ZabbixAPI
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
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 hosts equipment to the Zabbix proxy that monitors the host, 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 proxy reachability check',required=True)
parser.add_argument('-1', '--pri', help='Trigger description of the primary host trigger',required=True)
parser.add_argument('-2', '--sec', help='Trigger description of the secondary host trigger',required=False)
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)
# 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","proxy_hostid"]})
# Find proxies devices
proxies = zapi.proxy.get(**{"output": ['host', 'proxy_id']})
if proxies:
for proxy in proxies:
proxyhost = None
proxyhost = zapi.host.get(**{"output": ["host","hostid","name"], "filter": {"host": proxy['host']}})
if proxyhost:
proxy[u'hostid'] = proxyhost[0]['hostid']
proxy[u'name'] = proxyhost[0]['name']
logger.debug("Found proxy %s (%s)", proxy['host'], proxy['name'])
master = None
master = zapi.trigger.get(**{"output" : ["description"],
"filter":{'hostid': proxy['hostid'],'description': args.trigger}
})
if master:
master = master[0]
logger.debug(" - Proxy reachablility trigger has id %d", int(master['triggerid']))
monitored_hosts = None
monitored_hosts = zapi.host.get(**{"output": ['host','name'], "filter": {'proxy_hostid': proxy['proxyid']}})
if monitored_hosts:
for host in monitored_hosts:
if host['hostid'] == proxy['hostid']:
continue
updated = 0
hostmaster = None
hostmaster = zapi.trigger.get(**{"output" : ["description"],
"filter":{'hostid': host['hostid'],'description': args.pri}
})
if not hostmaster and args.sec:
hostmaster = zapi.trigger.get(**{"output" : ["description"],
"filter":{'hostid': host['hostid'],'description': args.sec}
})
if hostmaster:
hostmaster = hostmaster[0]
logger.debug(" |- Found dependent host %s (%s), main trigger is %d", host['host'], host['name'], int(hostmaster['triggerid']))
slaves = zapi.trigger.get(**{"output" : ["description"],
"selectDependencies": 'extend',
"filter":{'hostid': host['hostid'],'flags': "0"}
})
for slave in slaves:
if slave['triggerid'] != master['triggerid']:
if not slave['dependencies']:
if slave['triggerid'] == hostmaster['triggerid']:
try:
zapi.trigger.adddependencies(**{'triggerid': slave['triggerid'],'dependsOnTriggerid': master['triggerid']})
logger.info(" ||- Trigger %d ('%s') was made dependent of proxy trigger %d", int(slave['triggerid']),slave['description'], int(master['triggerid']))
updated = updated+1
except:
logger.error("*** %s: Could not link %d ('%s') as a dependency to trigger %d ('%s': '%s')", host['host'],
int(slave['triggerid']), slave['description'], int(master['triggerid']), proxy['host'], master['description'])
else:
try:
zapi.trigger.adddependencies(**{'triggerid': slave['triggerid'],'dependsOnTriggerid': hostmaster['triggerid']})
logger.info(" ||- Trigger %d ('%s') was made dependent of host trigger %d", int(slave['triggerid']),slave['description'], int(hostmaster['triggerid']))
updated = updated+1
except:
logger.error("*** Could not link %d ('%s') as a dependency to trigger %d", int(slave['triggerid']),slave['description'], int(hostmaster['triggerid']))
if updated == 0:
logger.debug(" ||- No trigger dependencies were updated on this host")
else:
logger.warning('Could not find the specified reachability trigger on host %s', host['host'])
else:
logger.warning('Could not find any hosts monitored by proxy %s', proxy['host'])
else:
logger.warning('Could not find the specified reachability trigger on proxy %s', proxy['host'])
else:
logger.warning('Could not find monitored hostid for proxy %s, skipping! Make sure the proxy host is monitored with the same hostname.', proxy['host'])
else:
logger.info("*** Could not find any proxies")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment