Skip to content

Commit

Permalink
Add Module to Update Host Events (#1238)
Browse files Browse the repository at this point in the history
  • Loading branch information
aplathrop authored May 29, 2024
1 parent 64b6687 commit 7278802
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 0 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/pr_1238.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- zabbix_host_events_update module added
244 changes: 244 additions & 0 deletions plugins/modules/zabbix_host_events_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


DOCUMENTATION = r'''
---
module: zabbix_host_events_update
short_description: update the status of event(s).
description:
- Updates the status of event(s).
author:
- "Andrew Lathrop (@aplathrop)"
requirements:
- "python >= 2.6"
options:
params:
description:
- Parameters to update event(s) with.
- Parameters as defined at https://www.zabbix.com/documentation/current/en/manual/api/reference/event/acknowledge
- Additionally supported parameters are below
required: true
type: dict
suboptions:
action:
description:
- action to update the event with
- Overrides "action" in API docs
- Required when I(actions) is not used.
- Mutually exclusive with I(actions).
required: false
type: str
choices:
- close_problem
- close
- acknowledge_event
- acknowledge
- ack
- add_message
- message
- msg
- change_severity
- severity
- unacknowledge_event
- unacknowledge
- unack
- suppress_event
- suppress
- unsuppress_event
- unsuppress
- change_event_rank_to_cause
- convert_to_cause
- change_event_rank_to_symptom
- convert_to_symptom
actions:
description:
- actions to update the event with
- Overrides "action" in API docs
- Required when I(action) is not used.
- Mutually exclusive with I(action).
required: false
type: list
elements: str
choices:
- close_problem
- close
- acknowledge_event
- acknowledge
- ack
- add_message
- message
- msg
- change_severity
- severity
- unacknowledge_event
- unacknowledge
- unack
- suppress_event
- suppress
- unsuppress_event
- unsuppress
- change_event_rank_to_cause
- convert_to_cause
- change_event_rank_to_symptom
- convert_to_symptom
severity:
description:
- New severity for events.
- Overrides "severity" in API docs
required: False
type: str
choices:
- not_classified
- information
- warning
- average
- high
- disaster
msg:
description:
- Text of the message.
- Alias for "message" in API docs
required: False
type: str
extends_documentation_fragment:
- community.zabbix.zabbix
'''

EXAMPLES = r'''
# If you want to use Username and Password to be authenticated by Zabbix Server
- name: Set credentials to access Zabbix Server API
ansible.builtin.set_fact:
ansible_user: Admin
ansible_httpapi_pass: zabbix
# If you want to use API token to be authenticated by Zabbix Server
# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens
- name: Set API token
ansible.builtin.set_fact:
ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895
# Acknowledge single event
- name: ack event
community.zabbix.zabbix_host_events_update:
params:
eventids: 12345
actions: ack
- name: ack and close event with a message
community.zabbix.zabbix_host_events_update:
params:
eventids: [12345, 67890]
actions: ['ack', 'msg', 'close']
msg: 'closed by user'
'''

from ansible.module_utils.basic import AnsibleModule

from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase
import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils


class Hosteventsupdate(ZabbixBase):
ACTIONS = {'close_problem': 1,
'close': 1,
'acknowledge_event': 2,
'acknowledge': 2,
'ack': 2,
'add_message': 4,
'message': 4,
'msg': 4,
'change_severity': 8,
'severity': 8,
'unacknowledge_event': 16,
'unacknowledge': 16,
'unack': 16,
'suppress_event': 32,
'suppress': 32,
'unsuppress_event': 64,
'unsuppress': 64,
'change_event_rank_to_cause': 128,
'convert_to_cause': 128,
'change_event_rank_to_symptom': 256,
'convert_to_symptom': 256}

SEVERITY_TYPES = {'not_classified': 0,
'information': 1,
'warning': 2,
'average': 3,
'high': 4,
'disaster': 5}

def get_events(self, eventids):
try:
results = self._zapi.event.get({'eventids': eventids})
except Exception as e:
self._module.fail_json(msg="Failed to get event: %s" % e)
return results

def update_event(self, params):
if 'severity' in params:
if params['severity'] not in self.SEVERITY_TYPES:
self._module.fail_json(msg="%s is not a valid severity type" % params['severity'])
severity = self.SEVERITY_TYPES[params['severity']]
params['severity'] = severity
if 'action' in params:
if params['action'] not in self.ACTIONS:
self._module.fail_json(msg="%s is not a valid action" % params['action'])
action_id = self.ACTIONS[params['action']]
elif 'actions' in params:
action_id = 0
for action in params['actions']:
if action not in self.ACTIONS:
self._module.fail_json(msg="%s is not a valid action" % action)
action_id += self.ACTIONS[action]
params.pop('actions')
else:
self._module.fail_json(msg="params must contain either 'action' or 'actions'")
params['action'] = action_id
if 'msg' in params:
params['message'] = params['msg']
params.pop('msg')
if self._module.check_mode:
self._module.exit_json(changed=True)
try:
results = self._zapi.event.acknowledge(params)
except Exception as e:
self._module.fail_json(msg="Failed to update event: %s" % e)
return results

def check_events_changed(self, eventids, old_events):
new_events = self.get_events(eventids)
return old_events != new_events


def main():
argument_spec = zabbix_utils.zabbix_common_argument_spec()
argument_spec.update(
params=dict(type='dict', required=True))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
)

params = module.params['params']

hosteventsupdate = Hosteventsupdate(module)

events = hosteventsupdate.get_events(params['eventids'])
results = hosteventsupdate.update_event(params)
changed = hosteventsupdate.check_events_changed(params['eventids'], events)
module.exit_json(changed=changed, result=results)


if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dependencies:
- setup_zabbix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: test - do not run tests for Zabbix < 6.4
meta: end_play
when: zabbix_version is version('6.4', '<')

# setup stuff
- include_tasks: zabbix_setup.yml

# zabbix_item module tests
- include_tasks: zabbix_tests.yml

# tear down stuff set up earlier
- include_tasks: zabbix_teardown.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---

- name: Create example template
community.zabbix.zabbix_template:
template_name: ExampleTemplate
template_groups:
- Templates

- name: Create example host
community.zabbix.zabbix_host:
host_name: ExampleHost
host_groups:
- Linux servers
- Zabbix servers
link_templates:
- ExampleTemplate
status: enabled
state: present
interfaces:
- type: 1
main: 1
useip: 1
ip: 10.1.1.1
dns: ""
port: "10050"

- name: create ping item
community.zabbix.zabbix_item:
name: ping
template_name: ExampleTemplate
params:
type: zabbix_agent_active
key: agent.ping
value_type: numeric_unsigned
interval: 20s
state: present

- name: create ping trigger
community.zabbix.zabbix_trigger:
name: ping
template_name: ExampleTemplate
params:
severity: warning
expression: 'nodata(/ExampleTemplate/agent.ping,1m)=1'
manual_close: True
state: present

- name: Wait to ensure triggers are firing
ansible.builtin.wait_for:
timeout: 120

- name: get events for host
community.zabbix.zabbix_host_events_info:
host_identifier: ExampleHost
host_id_type: hostname
trigger_severity: warning
register: zabbix_host_events

- name: get eventid
ansible.builtin.set_fact:
zabbix_eventid: "{{ zabbix_host_events.triggers_problem[0].last_event.eventid }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: remove example host
community.zabbix.zabbix_host:
host_name: ExampleHost
state: absent

- name: remove example template
community.zabbix.zabbix_template:
template_name: ExampleTemplate
state: absent
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---

- name: test - acknowledge event
community.zabbix.zabbix_host_events_update:
params:
eventids: "{{ zabbix_eventid }}"
action: ack
msg: "event acknowledged"
register: zbxevent_ack

- name: assert that event was changed
ansible.builtin.assert:
that: zbxevent_ack is changed

- name: get events updated status
community.zabbix.zabbix_host_events_info:
host_identifier: ExampleHost
host_id_type: hostname
trigger_severity: warning
register: zabbix_host_events_ack

- name: assert that event was acknowledged
ansible.builtin.assert:
that: zabbix_host_events_ack.triggers_problem[0].last_event.acknowledged

- name: test - change severity and unacknowledge
community.zabbix.zabbix_host_events_update:
params:
eventids: "{{ zabbix_eventid }}"
actions: ['severity', 'unack']
severity: high
register: zbxevent_sev

- name: assert that event was changed
ansible.builtin.assert:
that: zbxevent_sev is changed

- name: get events updated status
community.zabbix.zabbix_host_events_info:
host_identifier: ExampleHost
host_id_type: hostname
trigger_severity: warning
register: zabbix_host_events_unack

- name: assert that event was unacknowledged
ansible.builtin.assert:
that: zabbix_host_events_unack.triggers_problem[0].last_event.acknowledged == "0"

- name: test - change severity to same
community.zabbix.zabbix_host_events_update:
params:
eventids: "{{ zabbix_eventid }}"
action: severity
severity: high
register: zbxevent_sev_existing

- name: assert that event was not changed
ansible.builtin.assert:
that: zbxevent_sev_existing is not changed

0 comments on commit 7278802

Please sign in to comment.