diff --git a/monitoring/zabbix_maintenance b/monitoring/zabbix_maintenance new file mode 100644 index 00000000000..84a8e5b6362 --- /dev/null +++ b/monitoring/zabbix_maintenance @@ -0,0 +1,352 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2013, Alexander Bulimov +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + + +DOCUMENTATION = ''' + +module: zabbix_maintenance +short_description: Create Zabbix maintenance windows +description: + - This module will let you create Zabbix maintenance windows. +version_added: "1.5" +author: Alexander Bulimov +requirements: + - zabbix-api python module +options: + state: + description: + - Create or remove a maintenance window. + required: true + default: null + choices: [ "present", "absent" ] + server: + description: + - Url of Zabbix server, with schema (http or https). + required: true + default: null + aliases: [ "url" ] + user: + description: + - Zabbix user name. + required: true + default: null + passwd: + description: + - Zabbix user password. + required: true + default: null + hosts: + description: + - Hosts to manage maintenance window for. Separate multiple hosts with commas. + C(host) is an alias for C(hosts). + B(Required) option when C(state) is I(present) and no C(groups) specified. + required: false + default: null + aliases: [ "host" ] + groups: + description: + - Host groups to manage maintenance window for. Separate multiple groups with commas. + C(group) is an alias for C(groups). + B(Required) option when C(state) is I(present) and no C(hosts) specified. + required: false + default: null + aliases: [ "group" ] + minutes: + description: + - Length of maintenance window in minutes. + required: false + default: 10 + name: + description: + - Unique name of maintenance window. + required: true + default: null + desc: + description: + - Short description of maintenance window. + required: true + default: Created by Ansible + collect_data: + description: + - Type of maintenance. With data collection, or without. + required: false + default: "true" +notes: + - Useful for setting hosts in maintenance mode before big update, + and removing maintenance window after update. + - Module creates maintenance window from now() to now() + minutes, + so if Zabbix server's time and host's time are not synchronized, + you will get strange results. + - Install required module with 'pip install zabbix-api' command. + - Checks existance only by maintenance name. +''' + +EXAMPLES = ''' +# Create maintenance window named "Update of www1" +# for host www1.example.com for 90 minutes +- zabbix_maintenance: name="Update of www1" + host=www1.example.com + state=present + minutes=90 + server=https://monitoring.example.com + user=ansible + passwd=pAsSwOrD + +# Create maintenance window named "Mass update" +# for host www1.example.com and host groups Office and Dev +- zabbix_maintenance: name="Update of www1" + host=www1.example.com + group=Office,Dev + state=present + server=https://monitoring.example.com + user=ansible + passwd=pAsSwOrD + +# Remove maintenance window named "Test1" +- zabbix_maintenance: name=Test1" + state=absent + server=https://monitoring.example.com + user=ansible + passwd=pAsSwOrD +''' + +import datetime, time + +try: + from zabbix_api import ZabbixAPI + HAS_ZABBIX_API = True +except ImportError: + HAS_ZABBIX_API = False + +def create_maintenance(zbx, group_ids, host_ids, start_time, maintenance_type, period, name, desc): + end_time = start_time + period + try: + zbx.maintenance.create( + { + "groupids": group_ids, + "hostids": host_ids, + "name": name, + "maintenance_type": maintenance_type, + "active_since": str(start_time), + "active_till": str(end_time), + "description": desc, + "timeperiods": [{ + "timeperiod_type": "0", + "start_date": str(start_time), + "period": str(period), + }] + } + ) + except BaseException as e: + return 1, None, str(e) + return 0, None, None + +def get_maintenance_id(zbx, name): + try: + result = zbx.maintenance.get( + { + "filter": + { + "name": name, + } + } + ) + except BaseException as e: + return 1, None, str(e) + + maintenance_ids = [] + for res in result: + maintenance_ids.append(res["maintenanceid"]) + + return 0, maintenance_ids, None + +def delete_maintenance(zbx, maintenance_id): + try: + result = zbx.maintenance.delete(maintenance_id) + except BaseException as e: + return 1, None, str(e) + return 0, None, None + +def check_maintenance(zbx, name): + try: + result = zbx.maintenance.exists( + { + "name": name + } + ) + except BaseException as e: + return 1, None, str(e) + return 0, result, None + +def get_group_ids(zbx, group_names): + group_ids = [] + for group in group_names: + try: + result = zbx.hostgroup.get( + { + "output": "extend", + "filter": + { + "name": group + } + } + ) + except BaseException as e: + return 1, None, str(e) + + if not result: + return 1, None, "Group id for group %s not found"%group + + group_ids.append(result[0]["groupid"]) + + return 0, group_ids, None + +def get_host_ids(zbx, host_names): + host_ids = [] + for host in host_names: + try: + result = zbx.host.get( + { + "output": "extend", + "filter": + { + "name": host + } + } + ) + except BaseException as e: + return 1, None, str(e) + + if not result: + return 1, None, "Host id for host %s not found"%host + + host_ids.append(result[0]["hostid"]) + + return 0, host_ids, None + + +def main(): + module = AnsibleModule( + argument_spec=dict( + state=dict(required=True, default=None, choices=['present', 'absent']), + server=dict(required=True, default=None, aliases=['url']), + hosts=dict(type='list', required=False, default=None, aliases=['host']), + minutes=dict(type='int', required=False, default=10), + groups=dict(type='list', required=False, default=None, aliases=['group']), + user=dict(required=True, default=None), + passwd=dict(required=True, default=None), + name=dict(required=True, default=None), + desc=dict(required=False, default="Created by Ansible"), + collect_data=dict(type='bool', required=False, default=True), + ), + supports_check_mode=True, + ) + + if not HAS_ZABBIX_API: + module.fail_json(msg="Missing requried zabbix-api module (check docs or install with: pip install zabbix-api)") + + hosts = module.params['hosts'] + groups = module.params['groups'] + state = module.params['state'] + user = module.params['user'] + passwd = module.params['passwd'] + minutes = module.params['minutes'] + name = module.params['name'] + desc = module.params['desc'] + server = module.params['server'] + collect_data = module.params['collect_data'] + if collect_data: + maintenance_type = 0 + else: + maintenance_type = 1 + + + try: + zbx = ZabbixAPI(server) + zbx.login(user, passwd) + except BaseException as e: + module.fail_json(msg="Failed to connect to Zabbix server: %s"%e) + + changed = False + + if state == "present": + + now = datetime.datetime.now() + start_time = time.mktime(now.timetuple()) + period = 60 * int(minutes) #N * 60 seconds + + if groups: + (rc, group_ids, error) = get_group_ids(zbx, groups) + if rc != 0: + module.fail_json(msg="Failed to get group_ids: %s"%error) + else: + group_ids = [] + + if hosts: + (rc, host_ids, error) = get_host_ids(zbx, hosts) + if rc != 0: + module.fail_json(msg="Failed to get host_ids: %s"%error) + else: + host_ids = [] + + (rc, exists, error) = check_maintenance(zbx, name) + if rc != 0: + module.fail_json(msg="Failed to check maintenance %s existance: %s"%(name, error)) + + if not exists: + if not hosts and not groups: + module.fail_json(msg="At least one host or host group must be defined for each created maintenance.") + + if module.check_mode: + changed = True + else: + (rc, _, error) = create_maintenance(zbx, group_ids, host_ids, start_time, maintenance_type, period, name, desc) + if rc == 0: + changed = True + else: + module.fail_json(msg="Failed to create maintenance: %s"%error) + + if state == "absent": + + (rc, exists, error) = check_maintenance(zbx, name) + if rc != 0: + module.fail_json(msg="Failed to check maintenance %s existance: %s"%(name, error)) + + if exists: + (rc, maintenance, error) = get_maintenance_id(zbx, name) + if rc != 0: + module.fail_json(msg="Failed to get maintenance id: %s"%error) + + if maintenance: + if module.check_mode: + changed = True + else: + (rc, _, error) = delete_maintenance(zbx, maintenance) + if rc == 0: + changed = True + else: + module.fail_json(msg="Failed to remove maintenance: %s"%error) + + + module.exit_json(changed=changed) + +# include magic from lib/ansible/module_common.py +#<> +main()