├── License.md ├── README.md ├── check_s3_file.py ├── zabbix.template.export.py └── zabbixMaintenance.py /License.md: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2016, `Chegg Inc.` 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zabbix-scripts 2 | This is a collection of python scripts created by Chegg Inc to aide in our infrastructure monitoring. 3 | 4 | Table of Contents 5 | ================= 6 | 7 | * [zabbix-scripts](#zabbix-scripts) 8 | * [check_s3_file.py](#check_s3_filepy) 9 | * [Arguments](#arguments) 10 | * [zabbixMaintenance.py](#zabbixmaintenancepy) 11 | * [Arguments](#arguments-1) 12 | * [Disable Example](#disable-example) 13 | * [Maintence Mode](#maintence-mode) 14 | * [Delete](#delete) 15 | * [Create](#create) 16 | * [zabbix.template.export.py](#zabbixtemplateexportpy) 17 | * [Arguments](#arguments-2) 18 | * [License](#license) 19 | 20 | 21 | ## check_s3_file.py 22 | This is a tool to check files in AWS S3. You can use it to check Age, contents, existence. Returns "FOUND-OK" if everything is fine. Gives error with reason otherwise. Requires python boto. (sudo pip install boto). This check should work with both Nagios and Zabbix 23 | 24 | Requires: 25 | 26 | * [https://github.com/boto/boto](https://github.com/boto/boto) ```pip install boto``` 27 | 28 | ### Arguments 29 | 30 | ``` 31 | example-host user$ ./check_s3_file.py --help 32 | usage: check_s3_file.py [-h] --url URL [--regex REGEX] [--ttl TTL] 33 | [--access_key ACCESS_KEY] [--secret_key SECRET_KEY] 34 | [--aws_profile AWS_PROFILE] [--debug] 35 | 36 | optional arguments: 37 | -h, --help Show this help message and exit 38 | --url URL Path to s3 file (ex: s3://zabbix-ops/monitors/check_special_job_output.txt) 39 | --regex REGEX Simple regex to apply to file contents 40 | --ttl TTL File age in seconds 41 | --access_key ACCESS_KEY AWS Access key ID 42 | --secret_key SECRET_KEY AWS Secret Password 43 | --aws_profile AWS_PROFILE AWS profile to use from ~/.aws/credentials file 44 | --debug Enable debug mode, this will show you all the json-rpc calls and responses. 45 | ``` 46 | 47 | 48 | 49 | 50 | 51 | 52 | ## zabbixMaintenance.py 53 | This is a tool for modifying hosts (or multiple host contained in a hostgroup). It has the ability to disable, enable, place in maintenance mode, end a maintenance mode or even delete host(s). 54 | 55 | Requires: 56 | 57 | * [https://github.com/blacked/py-zabbix](https://github.com/blacked/py-zabbix) ```pip install py-zabbix``` 58 | 59 | 60 | ### Arguments 61 | 62 | ``` 63 | example-host user$ ./zabbixMaintenance.py -h 64 | usage: zabbixMaintenance.py [-h] [--hostname HOSTNAME] [--asset-tag ASSET_TAG] 65 | [--hostgroup HOSTGROUP] [--delete] [--create] 66 | [--ip IP] [--port PORT] [--templates TEMPLATES] 67 | [--groups GROUPS] [--enable] [--disable] 68 | [--maintenance] [--maintenance-length] 69 | [--end-maintenance] [--debug] --url URL --user 70 | USER --password PASSWORD 71 | 72 | This is a tool for modifying hosts (or multiple host contained in a 73 | hostgroup). It has the ability to disable, enable, place in maintenance mode, 74 | end a maintenance mode or even delete host(s). 75 | 76 | optional arguments: 77 | -h, --help show this help message and exit 78 | --hostname HOSTNAME Hostname to modify 79 | --asset-tag ASSET_TAG Find host by asset tag instead of hostname 80 | --hostgroup HOSTGROUP Hostgroup to modify 81 | --delete Flag that indicates we want to delete the host in question 82 | --create Flag that indicates we want to create the host in zabbix 83 | --ip IP Specify the ip for a host when creating a new host in zabbix 84 | --port PORT Specify the zabbix agent port for a host when creating a new host in zabbix. (default: 10050) 85 | --templates TEMPLATES Add the following comma separated templates to a host, used when creating a new host. 86 | --groups GROUPS Add the following comma separated groups to a host, used when creating a new host 87 | --enable Flag that indicates we want to enable the host in question 88 | --disable Flag that indicates we want to disable the host in question 89 | --maintenance Flag that indicates we want to place the host in maintenance mode 90 | --maintenance-length How long in seconds to be in maintenance mode. (default: 3600) 91 | --end-maintenance Flag that indicates we want to disable maintenance mode 92 | --debug Enable debug mode, this will show you all the json-rpc calls and responses 93 | --url URL URL to the zabbix server (example: https://monitor.example.com/zabbix) 94 | --user USER The zabbix api user 95 | --password PASSWORD The zabbix api password 96 | ``` 97 | 98 | ### Disable Example 99 | This is helpful if you are gonna need to shutdown a host or a group of hosts for a while and don't want to zabbix keep monitoring the hosts. Replace ```--disable``` with ```--enable``` when you want to bring the host(s) back online. 100 | 101 | ``` 102 | example-host user$ ./zabbixMaintenance.py --url https://monitor.example.com/zabbix --user jdoe --password='secret123' --hostname='web01.example.com' --disable 103 | ``` 104 | 105 | If you give a --hostgroup instead of a hostname, it will find all hosts in the hostgroup and disable each host 106 | 107 | ``` 108 | example-host user$ ./zabbixMaintenance.py --url https://monitor.example.com/zabbix --user jdoe --password='secret123' --hostgroup='webservers' --disable 109 | ``` 110 | 111 | ### Maintence Mode 112 | If you are deploying code and need to place host(s) in maintenance mode you can use the ```--maintenance``` flag. If you've configured your alert actions to have the normal condition of ```Maintenance status not in maintenance``` then no alerts will be sent while in maintenance mode. By default the maintenance window is one hour (3600) seconds. You can customize this time with the ```--maintenance-length``` flag. This is a very helpful script to add to your jenkins deployment scripts. 113 | 114 | 115 | ``` 116 | example-host user$ ./zabbixMaintenance.py --url https://monitor.example.com/zabbix --user jdoe --password='secret123' --hostgroup='webservers' --maintenance 117 | ``` 118 | 119 | When you are done with your deployment you can either let the maintenance window expire or you can use the ```--end-maintenance``` flag to to update the end time of the maintenance window to the current time effectively ending the maintenance window. 120 | 121 | ### Delete 122 | This is helpful if you need to remove zabbix hosts when you terminate the hosts. Perhaps as a hook in your cloudtrail host clean up processes or in your unit test that may create hosts as part of their test. 123 | 124 | 125 | ``` 126 | example-host user$ ./zabbixMaintenance.py --url https://monitor.example.com/zabbix --user jdoe --password='secret123' --hostname='web-sd8dcs2c.example.com' --delete 127 | ``` 128 | 129 | ### Create 130 | If you need to define a new host in the zabbix server you can use the ```--create``` flag to create a new host entry in zabbix. It accepts optional ```--templates``` & ```--groups``` flags to specify templates and groups to assign the host to. The templates and groups should be comma separated. Also be sure to include the ```--ip``` argument with the host IP address. 131 | 132 | ``` 133 | example-host user$ ./zabbixMaintenance.py --url https://monitor.example.com/zabbix --user jdoe --password='secret123' --hostname='web-sd8dcs2c.example.com' --ip 10.2.3.4 --templates=Linux,aws --groups=ops --create 134 | ``` 135 | 136 | 137 | 138 | ## zabbix.template.export.py 139 | This is a simple tool to export zabbix templates for backup. Please note it will always set the date on export to 1/1/2016 so git wont update unless something substantial happens. Please note that due to a [known bug in Zabbix](https://support.zabbix.com/browse/ZBXNEXT-178) it does not currently backup Web scenarios. This has supposedly been patched in pre-3.1.0 (trunk). 140 | 141 | Using this script you could potentialy automate backing up Zabbix templates. Here's a basic example of the process. 142 | 143 | ``` 144 | #!/bin/bash 145 | 146 | cd /var/lib/zabbix/backup 147 | ./zabbix.template.export.py --url https://monitor.example.com/zabbix \ 148 | --user='zabbix-api-user' \ 149 | --password='super-secret' \ 150 | --out-dir zabbix-tempaltes 151 | 152 | cd zabbix-tempaltes 153 | git add . 154 | git commit -am 'automated template backup' 155 | ``` 156 | 157 | ### Arguments 158 | 159 | ``` 160 | example-host user$ ./zabbix.template.export.py --help 161 | usage: zabbix.template.export.py [-h] [--templates TEMPLATES] 162 | [--out-dir OUT_DIR] [--debug] --url URL 163 | --user USER --password PASSWORD 164 | 165 | optional arguments: 166 | -h, --help Show this help message and exit 167 | --templates TEMPLATES Name of specific template to export 168 | --out-dir OUT_DIR Directory to output templates to. 169 | --debug Enable debug mode, this will show you all the json-rpc calls and responses 170 | --url URL URL to the zabbix server (example: https://monitor.example.com/zabbix ) 171 | --user USER The zabbix api user 172 | --password PASSWORD The zabbix api password 173 | ``` 174 | 175 | 176 | 177 | ## License 178 | 179 | Copyright (c) 2016, `Chegg Inc.` 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /check_s3_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import argparse 4 | import logging 5 | import time 6 | import os 7 | import re 8 | from boto.s3.connection import S3Connection 9 | from urlparse import urlparse 10 | from sys import exit 11 | from datetime import datetime 12 | 13 | 14 | parser = argparse.ArgumentParser(description='This is a tool to check files in AWS S3. You can use it to check Age, contents, existence. Returns "FOUND-OK" if everything is fine. Gives error with reason otherwise. Requires python boto. (sudo pip install boto) ') 15 | parser.add_argument('--url', help='path to s3 file (ex: s3://zabbix-ops/monitors/check_table_partition.txt)',required = True) 16 | parser.add_argument('--regex', help='Simple regex to apply to file contents') 17 | parser.add_argument('--ttl', help='File age in seconds') 18 | parser.add_argument('--access_key', help='AWS Access key ID') 19 | parser.add_argument('--secret_key', help='AWS Secret Password') 20 | parser.add_argument('--aws_profile', help='AWS profile to use from ~/.aws/credentials file') 21 | parser.add_argument('--debug', help='Enable debug mode, this will show you all the json-rpc calls and responses', action="store_true") 22 | 23 | args = parser.parse_args() 24 | 25 | if args.debug: 26 | logging.basicConfig(level = logging.DEBUG, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') 27 | logger = logging.getLogger(__name__) 28 | 29 | def main(): 30 | global args 31 | tmpfile = '/tmp/.s3.tmp' 32 | 33 | o = urlparse(args.url) 34 | if args.debug: 35 | print o 36 | 37 | if args.access_key and args.secret_key: 38 | conn = S3Connection(args.access_key, args.secret_key) 39 | elif args.aws_profile: 40 | conn = S3Connection(profile_name=args.aws_profile) 41 | else: 42 | conn = S3Connection() 43 | 44 | bucket = conn.get_bucket(o.netloc) 45 | s3_file = bucket.get_key(o.path) 46 | s3_file.get_contents_to_filename(tmpfile) 47 | if args.debug: 48 | print s3_file 49 | 50 | 51 | if args.ttl: 52 | stats = os.stat(tmpfile) 53 | n = int(time.time()) 54 | delta = int(n - stats.st_mtime) 55 | if args.debug: 56 | print "Delta =",delta,", ttl =",args.ttl 57 | if int(args.ttl) < int(delta): 58 | print 'Error: file too old' 59 | exit(-1) 60 | 61 | 62 | if args.regex: 63 | mys3temp = open(tmpfile,"r") 64 | fc = mys3temp.read() 65 | m = re.search(args.regex,fc) 66 | if args.debug: 67 | print fc 68 | if m: 69 | pass 70 | else: 71 | print "Error: regex failed to match '%s'" % args.regex 72 | exit(-2) 73 | 74 | os.remove(tmpfile) 75 | print "FOUND-OK" 76 | 77 | if __name__ == '__main__': 78 | main() -------------------------------------------------------------------------------- /zabbix.template.export.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import argparse 4 | import logging 5 | import time 6 | import os 7 | import json 8 | import xml.dom.minidom 9 | from zabbix.api import ZabbixAPI 10 | from sys import exit 11 | from datetime import datetime 12 | 13 | parser = argparse.ArgumentParser(description='This is a simple tool to export zabbix templates for backup. Please note it will always set the data on export to 1/1/2016 so git wont update unless something substantial happens.') 14 | parser.add_argument('--templates', help='Name of specific template to export',default='All') 15 | parser.add_argument('--out-dir', help='Directory to output templates to.',default='./templates') 16 | parser.add_argument('--debug', help='Enable debug mode, this will show you all the json-rpc calls and responses', action="store_true") 17 | parser.add_argument('--url', help='URL to the zabbix server (example: https://monitor.example.com/zabbix)',required = True) 18 | parser.add_argument('--user', help='The zabbix api user',required = True) 19 | parser.add_argument('--password', help='The zabbix api password',required = True) 20 | args = parser.parse_args() 21 | 22 | if args.debug: 23 | logging.basicConfig(level = logging.DEBUG, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') 24 | logger = logging.getLogger(__name__) 25 | 26 | def main(): 27 | global args 28 | global parser 29 | 30 | if None == args.url : 31 | print "Error: Missing --url\n\n" 32 | exit(2) 33 | 34 | if None == args.user : 35 | print "Error: Missing --user\n\n" 36 | exit(3) 37 | 38 | if None == args.password : 39 | print "Error: Missing --password\n\n" 40 | exit(4) 41 | 42 | if False == os.path.isdir(args.out_dir): 43 | os.mkdir(args.out_dir) 44 | 45 | zm = ZabbixTemplates( args.url, args.user, args.password ) 46 | 47 | zm.exportTemplates(args) 48 | 49 | 50 | class ZabbixTemplates: 51 | 52 | def __init__(self,_url,_user,_password): 53 | self.zapi = ZabbixAPI(url=_url, user=_user, password=_password) 54 | 55 | def exportTemplates(self,args): 56 | request_args = { 57 | "output": "extend" 58 | } 59 | 60 | if args.templates != 'All': 61 | request_args.filter = { 62 | "host": [args.tempaltes] 63 | } 64 | 65 | result = self.zapi.do_request('template.get',request_args) 66 | if not result['result']: 67 | print "No matching host found for '{}'".format(hostname) 68 | exit(-3) 69 | 70 | if result['result']: 71 | for t in result['result']: 72 | dest = args.out_dir+'/'+t['host']+'.xml' 73 | self.exportTemplate(t['templateid'],dest) 74 | 75 | def exportTemplate(self,tid,oput): 76 | 77 | print "tempalteid:",tid," output:",oput 78 | args = { 79 | "options": { 80 | "templates": [tid] 81 | }, 82 | "format": "xml" 83 | } 84 | 85 | result = self.zapi.do_request('configuration.export',args) 86 | template = xml.dom.minidom.parseString(result['result'].encode('utf-8')) 87 | date = template.getElementsByTagName("date")[0] 88 | # We are backing these up to git, steralize date so it doesn't appear to change 89 | # each time we export the templates 90 | date.firstChild.replaceWholeText('2016-01-01T01:01:01Z') 91 | f = open(oput, 'w+') 92 | f.write(template.toprettyxml().encode('utf-8')) 93 | f.close() 94 | 95 | 96 | if __name__ == '__main__': 97 | main() 98 | -------------------------------------------------------------------------------- /zabbixMaintenance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import argparse 4 | import logging 5 | import time 6 | from zabbix.api import ZabbixAPI 7 | from sys import exit 8 | from datetime import datetime 9 | from os.path import basename 10 | 11 | parser = argparse.ArgumentParser(description='This is a tool for modifying hosts (or multiple host contained in a hostgroup). It has the ability to disable, enable, place in maintenance mode, end a maintenance mode or even delete host(s).') 12 | parser.add_argument('--hostname', help='Hostname to modify') 13 | parser.add_argument('--asset-tag', help='Find host by asset tag instead of hostname') 14 | parser.add_argument('--hostgroup', help='Hostgroup to modify') 15 | parser.add_argument('--delete', help='Flag that indicates we want to delete the host in question', action="store_true") 16 | parser.add_argument('--create', help='Flag that indicates we want to create the host in zabbix', action="store_true") 17 | parser.add_argument('--ip', help='Specify the ip for a host when creating a new host in zabbix') 18 | parser.add_argument('--port', help='Specify the zabbix agent port for a host when creating a new host in zabbix. (default: 10050)', default='10050') 19 | parser.add_argument('--proxy', help='If you are adding or updating a host and you want to specify a zabbix-proxy host to use.') 20 | parser.add_argument('--templates', help='Add the following comma separated templates to a host, used when creating a new host',default='Linux') 21 | parser.add_argument('--groups', help='Add the following comma separated groups to a host, used when creating a new host') 22 | parser.add_argument('--enable', help='Flag that indicates we want to enable the host in question', action="store_true") 23 | parser.add_argument('--disable', help='Flag that indicates we want to disable the host in question', action="store_true") 24 | parser.add_argument('--maintenance', help='Flag that indicates we want to place the host in maintenance mode', action="store_true") 25 | parser.add_argument('--maintenance-length', help='How long in seconds to be in maintenance mode. (default: 3600)', default=3600) 26 | parser.add_argument('--end-maintenance', help='Flag that indicates we want to disable maintenance mode', action="store_true") 27 | parser.add_argument('--debug', help='Enable debug mode, this will show you all the json-rpc calls and responses', action="store_true") 28 | parser.add_argument('--url', help='URL to the zabbix server (example: https://monitor.example.com/zabbix)',required = True) 29 | parser.add_argument('--user', help='The zabbix api user',required = True) 30 | parser.add_argument('--password', help='The zabbix api password',required = True) 31 | args = parser.parse_args() 32 | 33 | if args.debug: 34 | logging.basicConfig(level = logging.DEBUG, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') 35 | logger = logging.getLogger(__name__) 36 | 37 | def main(): 38 | global args 39 | global parser 40 | 41 | if None == args.hostname and None == args.hostgroup and None == args.asset_tag: 42 | print "Error: Missing --hostname, --asset-tag or --hostgroup\n\n" 43 | parser.print_help() 44 | exit(1) 45 | 46 | if None == args.url : 47 | print "Error: Missing --url\n\n" 48 | exit(2) 49 | 50 | if None == args.user : 51 | print "Error: Missing --user\n\n" 52 | exit(3) 53 | 54 | if None == args.password : 55 | print "Error: Missing --password\n\n" 56 | exit(4) 57 | 58 | 59 | zm = ZabbixMaintenance( args.url, args.user, args.password ) 60 | 61 | 62 | if args.delete: 63 | if args.hostname or args.asset_tag: 64 | zm.deleteHost( args ) 65 | elif args.hostgroup: 66 | zm.deleteHostgroup( args.hostgroup ) 67 | else: 68 | print "Error deleting, no hostname or group specified" 69 | elif args.create: 70 | zm.createHost( args ) 71 | elif args.enable: 72 | if args.hostname or args.asset_tag: 73 | zm.enableHost( args ) 74 | elif args.hostgroup: 75 | zm.enableHostgroup( args.hostgroup ) 76 | else: 77 | print "Error enabling, no hostname or group specified" 78 | elif args.disable: 79 | if args.hostname or args.asset_tag: 80 | zm.disableHost( args ) 81 | elif args.hostgroup: 82 | zm.disableHostgroup( args.hostgroup ) 83 | else: 84 | print "Error enabling, no hostname or group specified" 85 | elif args.maintenance: 86 | if args.hostname or args.asset_tag: 87 | zm.maintenanceMode( args,args.maintenance_length ) 88 | elif args.hostgroup: 89 | zm.maintenanceModeHostgroup( args.hostgroup,args.maintenance_length ) 90 | else: 91 | print "Error creating maintenance mode, no hostname or group specified" 92 | elif args.end_maintenance: 93 | if args.hostname or args.asset_tag: 94 | zm.endMaintenanceMode( args ) 95 | elif args.hostgroup: 96 | zm.endMaintenanceModeHostgroup( args.hostgroup ) 97 | else: 98 | print "Error creating maintenance mode, no hostname or group specified" 99 | else: 100 | print "Error: Must give either --enable, --disable, --delete, --maintenance or --end-maintenance flag\n\n" 101 | exit(-1) 102 | 103 | class ZabbixMaintenance: 104 | 105 | def __init__(self,_url,_user,_password): 106 | self.zapi = ZabbixAPI(url=_url, user=_user, password=_password) 107 | 108 | def getHostByName(self,hostname): 109 | args = { 110 | "output": [ 111 | "hostid", 112 | "host" 113 | ], 114 | "filter": { 115 | "host": hostname 116 | } 117 | } 118 | result = self.zapi.do_request('host.get',args) 119 | if not result['result']: 120 | print "No matching host found for '{}'".format(hostname) 121 | exit(-3) 122 | return result['result'][0] 123 | 124 | def getHostByAssetTag(self,asset_tag): 125 | args = { 126 | "output": [ 127 | "hostid", 128 | "host" 129 | ], 130 | "searchInventory": { 131 | "asset_tag": asset_tag 132 | } 133 | } 134 | result = self.zapi.do_request('host.get',args) 135 | if not result['result']: 136 | print "No matching host found for '{}'".format(asset_tag) 137 | exit(-3) 138 | return result['result'][0] 139 | 140 | def getTemplateIDs(self, template_string): 141 | templates = map(str.strip, template_string.split(",") ) 142 | template_ids = [] 143 | 144 | request_args = { 145 | "output": "extend", 146 | "filter": { 147 | "host": templates 148 | } 149 | } 150 | result = self.zapi.do_request('template.get',request_args) 151 | if result['result']: 152 | for t in result['result']: 153 | template_ids.append({"templateid": t['templateid']}) 154 | 155 | return template_ids 156 | 157 | def getGroupIDs(self, group_string): 158 | groups = map(str.strip, group_string.split(",") ) 159 | group_ids = [] 160 | 161 | request_args = { 162 | "output": "extend", 163 | "filter": { 164 | "name": groups 165 | } 166 | } 167 | result = self.zapi.do_request('hostgroup.get',request_args) 168 | if result['result']: 169 | for t in result['result']: 170 | group_ids.append({"groupid": t['groupid']}) 171 | 172 | return group_ids 173 | 174 | def createHost(self, args): 175 | hostname = args.hostname 176 | cmd = 'host.create' 177 | if args.ip: 178 | ip = args.ip 179 | else: 180 | ip = '' 181 | 182 | # We should check if this host already exists and make it an update if it is 183 | search_request = { 184 | "output": [ 185 | "hostid", 186 | "host" 187 | ], 188 | "filter": { 189 | "host": hostname 190 | } 191 | } 192 | search_result = self.zapi.do_request('host.get',search_request) 193 | 194 | request_args = { 195 | "host": hostname, 196 | "interfaces": [ 197 | { 198 | "type": 1, 199 | "main": 1, 200 | "useip": 1, 201 | "ip": ip, 202 | "dns": hostname, 203 | "port": args.port 204 | } 205 | ], 206 | "inventory_mode": 1, 207 | "inventory": { 208 | "installer_name": "Created with zabbixMaintenance" 209 | } 210 | } 211 | 212 | if args.proxy: 213 | request_args['proxy_hostid'] = self.findProxyID(args.proxy) 214 | 215 | # If we found a matching host, lets include the hostid to make this an update 216 | if search_result['result']: 217 | if search_result['result'][0]: 218 | if search_result['result'][0]['hostid']: 219 | request_args['hostid'] = search_result['result'][0]['hostid'] 220 | cmd = 'host.update' 221 | del request_args['interfaces'] 222 | self.updataeInterface(search_result['result'][0]['hostid'],hostname,ip,args.port) 223 | 224 | if args.templates: 225 | request_args['templates'] = self.getTemplateIDs(args.templates) 226 | 227 | if args.groups: 228 | request_args['groups'] = self.getGroupIDs(args.groups) 229 | 230 | try: 231 | result = self.zapi.do_request(cmd,request_args) 232 | return result 233 | except: 234 | print "Error creating host or updating host." 235 | return [] 236 | 237 | def findProxyID(self,proxy): 238 | cmd = 'proxy.get' 239 | request_args = { 240 | "output": "extend", 241 | "selectInterfaces": "extend", 242 | "filter": { 243 | "host": proxy 244 | } 245 | } 246 | 247 | try: 248 | result = self.zapi.do_request(cmd,request_args) 249 | return result['result'][0]['proxyid'] 250 | except: 251 | print "Error creating host or updating host." 252 | return [] 253 | 254 | 255 | def updataeInterface(self,hostid,hostname,ip,port): 256 | host_search_args = { 257 | "output": "extend", 258 | "hostids": hostid 259 | } 260 | 261 | try: 262 | host_search_result = self.zapi.do_request("hostinterface.get",host_search_args) 263 | 264 | #Find main int 265 | for zabbix_int in host_search_result['result']: 266 | if zabbix_int['main'] == "1": 267 | interface_update_args = { 268 | "interfaceid": zabbix_int['interfaceid'], 269 | "type": 1, 270 | "main": 1, 271 | "useip": 1, 272 | "ip": ip, 273 | "dns": hostname, 274 | "port": port 275 | } 276 | 277 | try: 278 | iterface_result = self.zapi.do_request("hostinterface.update",interface_update_args) 279 | return True 280 | except: 281 | print "Error updating host interface." 282 | except: 283 | print "Error finding host interface." 284 | 285 | return False 286 | 287 | def deleteHost(self,args): 288 | if args.asset_tag: 289 | _host = self.getHostByAssetTag(args.asset_tag) 290 | else: 291 | _host = self.getHostByName(args.hostname) 292 | 293 | request_args = [_host['hostid']] 294 | 295 | result = self.zapi.do_request('host.delete',request_args) 296 | return result 297 | 298 | def enableHost(self,args): 299 | if args.asset_tag: 300 | _host = self.getHostByAssetTag(args.asset_tag) 301 | else: 302 | _host = self.getHostByName(args.hostname) 303 | 304 | request_args = { 305 | "hostid": _host['hostid'], 306 | "status": 0 307 | } 308 | result = self.zapi.do_request('host.update',request_args) 309 | return result 310 | 311 | def disableHost(self,args): 312 | if args.asset_tag: 313 | _host = self.getHostByAssetTag(args.asset_tag) 314 | else: 315 | _host = self.getHostByName(args.hostname) 316 | 317 | request_args = { 318 | "hostid": _host['hostid'], 319 | "status": 1 320 | } 321 | result = self.zapi.do_request('host.update',request_args) 322 | return result 323 | 324 | def maintenanceMode(self,args,timeWindow): 325 | if args.asset_tag: 326 | _host = self.getHostByAssetTag(args.asset_tag) 327 | else: 328 | _host = self.getHostByName(args.hostname) 329 | 330 | d = datetime.now() 331 | currentDate = d.strftime("%c") 332 | request_args = { 333 | "name": "Generated by {0} on {1} for {2}".format(basename(__file__),currentDate,args.hostname), 334 | "active_since": int(time.time()), 335 | "active_till": int(time.time()+int(timeWindow)), 336 | "hostids": [ 337 | _host['hostid'] 338 | ], 339 | "timeperiods": [ 340 | { 341 | "timeperiod_type": 0, 342 | "period": timeWindow 343 | } 344 | ] 345 | } 346 | result = self.zapi.do_request('maintenance.create',request_args) 347 | return 348 | 349 | 350 | def getMaintenance(self,hostid): 351 | 352 | args = { 353 | "output": "extend", 354 | "selectTimeperiods": "extend", 355 | "hostids": hostid 356 | } 357 | result = self.zapi.do_request('maintenance.get',args) 358 | return result['result'] 359 | 360 | def endMaintenanceMode(self,args): 361 | if args.asset_tag: 362 | _host = self.getHostByAssetTag(args.asset_tag) 363 | else: 364 | _host = self.getHostByName(args.hostname) 365 | 366 | _maintenance = self.getMaintenance(_host['hostid']) 367 | _maintenance_ids = [] 368 | n = int(time.time()) 369 | 370 | for maintenance_id in _maintenance: 371 | if int(maintenance_id['active_since']) < int(n) and int(maintenance_id['active_till']) > int(n): 372 | _maintenance_ids.append(maintenance_id['maintenanceid']) 373 | maintenance_id['active_till'] = n 374 | maintenance_id['hostids'] = [ _host['hostid'] ] 375 | result = self.zapi.do_request('maintenance.update',maintenance_id) 376 | 377 | if not _maintenance_ids: 378 | if args.asset_tag: 379 | print "No valid maintenance windows defined for the asset-tag {0}".format(args.asset_tag) 380 | else: 381 | print "No valid maintenance windows defined for the host {0}".format(args.hostname) 382 | exit(-4) 383 | 384 | return _maintenance_ids 385 | 386 | 387 | def getHostGroupByName(self,hostgroup): 388 | args = { 389 | "selectHosts": "extend", 390 | "filter": { 391 | "name": hostgroup 392 | } 393 | } 394 | result = self.zapi.do_request('hostgroup.get',args) 395 | if not result['result']: 396 | print "No matching hostgroup found for '{}'".format(hostgroup) 397 | exit(-5) 398 | return result['result'][0] 399 | 400 | 401 | def deleteHostgroup(self,hostgroup): 402 | _hostgroup = self.getHostGroupByName(hostgroup) 403 | hosts = [] 404 | for h in _hostgroup['hosts']: 405 | hosts.append(h['hostid']) 406 | 407 | args = hosts 408 | 409 | result = self.zapi.do_request('host.delete',args) 410 | return result 411 | 412 | def enableHostgroup(self,hostgroup): 413 | _hostgroup = self.getHostGroupByName(hostgroup) 414 | hosts = [] 415 | for h in _hostgroup['hosts']: 416 | hosts.append({"hostid": h['hostid']}) 417 | 418 | args = { 419 | "hosts": hosts, 420 | "status": 0 421 | } 422 | result = self.zapi.do_request('host.massupdate',args) 423 | return result 424 | 425 | def disableHostgroup(self,hostgroup): 426 | _hostgroup = self.getHostGroupByName(hostgroup) 427 | hosts = [] 428 | for h in _hostgroup['hosts']: 429 | hosts.append({"hostid": h['hostid']}) 430 | 431 | args = { 432 | "hosts": hosts, 433 | "status": 1 434 | } 435 | result = self.zapi.do_request('host.massupdate',args) 436 | return result 437 | 438 | def maintenanceModeHostgroup(self,hostgroup,timeWindow): 439 | _hostgroup = self.getHostGroupByName(hostgroup) 440 | 441 | 442 | d = datetime.now() 443 | currentDate = d.strftime("%c") 444 | args = { 445 | "name": "Generated by {0} on {1} for hostgroup {2}".format(basename(__file__),currentDate,hostgroup), 446 | "active_since": int(time.time()), 447 | "active_till": int(time.time()+timeWindow), 448 | "groupids": [_hostgroup['groupid']], 449 | "timeperiods": [ 450 | { 451 | "timeperiod_type": 0, 452 | "period": timeWindow 453 | } 454 | ] 455 | } 456 | result = self.zapi.do_request('maintenance.create',args) 457 | return result 458 | 459 | def getMaintenanceByHostGroup(self,groupid): 460 | 461 | args = { 462 | "output": "extend", 463 | "selectTimeperiods": "extend", 464 | "groupids": groupid 465 | } 466 | result = self.zapi.do_request('maintenance.get',args) 467 | return result['result'] 468 | 469 | def endMaintenanceModeHostgroup(self,hostgroup): 470 | _hostgroup = self.getHostGroupByName(hostgroup) 471 | _maintenance = self.getMaintenanceByHostGroup(_hostgroup['groupid']) 472 | _maintenance_ids = [] 473 | n = int(time.time()) 474 | 475 | for maintenance_id in _maintenance: 476 | if int(maintenance_id['active_since']) < int(n) and int(maintenance_id['active_till']) > int(n): 477 | _maintenance_ids.append(maintenance_id['maintenanceid']) 478 | maintenance_id['active_till'] = n 479 | maintenance_id['groupids'] = [ _hostgroup['groupid'] ] 480 | 481 | print "maintenance.update args" 482 | print maintenance_id 483 | result = self.zapi.do_request('maintenance.update',maintenance_id) 484 | 485 | if not _maintenance_ids: 486 | print "No valid maintenance windows defined for the hostgroup {0}".format(hostgroup) 487 | exit(-4) 488 | 489 | return _maintenance_ids 490 | 491 | if __name__ == '__main__': 492 | main() 493 | --------------------------------------------------------------------------------