diff options
Diffstat (limited to 'roles/lib_zabbix/library')
-rw-r--r-- | roles/lib_zabbix/library/zbx_action.py | 137 | ||||
-rw-r--r-- | roles/lib_zabbix/library/zbx_graph.py | 331 | ||||
-rw-r--r-- | roles/lib_zabbix/library/zbx_graphprototype.py | 331 | ||||
-rw-r--r-- | roles/lib_zabbix/library/zbx_httptest.py | 10 |
4 files changed, 798 insertions, 11 deletions
diff --git a/roles/lib_zabbix/library/zbx_action.py b/roles/lib_zabbix/library/zbx_action.py index d64cebae1..c08bef4f7 100644 --- a/roles/lib_zabbix/library/zbx_action.py +++ b/roles/lib_zabbix/library/zbx_action.py @@ -1,8 +1,8 @@ #!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 ''' Ansible module for zabbix actions ''' -# vim: expandtab:tabstop=4:shiftwidth=4 # # Zabbix action ansible module # @@ -30,6 +30,17 @@ # pylint: disable=import-error from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection, ZabbixAPIError +CUSTOM_SCRIPT_ACTION = '0' +IPMI_ACTION = '1' +SSH_ACTION = '2' +TELNET_ACTION = '3' +GLOBAL_SCRIPT_ACTION = '4' + +EXECUTE_ON_ZABBIX_AGENT = '0' +EXECUTE_ON_ZABBIX_SERVER = '1' + +OPERATION_REMOTE_COMMAND = '1' + def exists(content, key='result'): ''' Check if key exists in content or the size of content[key] > 0 ''' @@ -70,6 +81,40 @@ def filter_differences(zabbix_filters, user_filters): return rval +def host_in_zabbix(zab_hosts, usr_host): + ''' Check whether a particular user host is already in the + Zabbix list of hosts ''' + + for usr_hst_key, usr_hst_val in usr_host.items(): + for zab_host in zab_hosts: + if usr_hst_key in zab_host and \ + zab_host[usr_hst_key] == str(usr_hst_val): + return True + + return False + +def hostlist_in_zabbix(zab_hosts, usr_hosts): + ''' Check whether user-provided list of hosts are already in + the Zabbix action ''' + + if len(zab_hosts) != len(usr_hosts): + return False + + for usr_host in usr_hosts: + if not host_in_zabbix(zab_hosts, usr_host): + return False + + return True + +def opcommand_diff(zab_op_cmd, usr_op_cmd): + ''' Check whether user-provided opcommand matches what's already + stored in Zabbix ''' + + for usr_op_cmd_key, usr_op_cmd_val in usr_op_cmd.items(): + if zab_op_cmd[usr_op_cmd_key] != str(usr_op_cmd_val): + return True + return False + # This logic is quite complex. We are comparing two lists of dictionaries. # The outer for-loops allow us to descend down into both lists at the same time # and then walk over the key,val pairs of the incoming user dict's changes @@ -89,6 +134,9 @@ def operation_differences(zabbix_ops, user_ops): for zab, user in zip(zabbix_ops, user_ops): for key, val in user.items(): if key == 'opconditions': + if len(zab[key]) != len(val): + rval[key] = val + break for z_cond, u_cond in zip(zab[key], user[key]): if not all([str(u_cond[op_key]) == z_cond[op_key] for op_key in \ ['conditiontype', 'operator', 'value']]): @@ -113,6 +161,18 @@ def operation_differences(zabbix_ops, user_ops): if usr_ids != zab_usr_ids: rval[key] = val + elif key == 'opcommand': + if opcommand_diff(zab[key], val): + rval[key] = val + break + + # opcommand_grp can be treated just like opcommand_hst + # as opcommand_grp[] is just a list of groups + elif key == 'opcommand_hst' or key == 'opcommand_grp': + if not hostlist_in_zabbix(zab[key], val): + rval[key] = val + break + elif zab[key] != str(val): rval[key] = val return rval @@ -285,7 +345,7 @@ def get_condition_type(event_source, inc_condition): def get_operation_type(inc_operation): ''' determine the correct operation type''' o_types = {'send message': 0, - 'remote command': 1, + 'remote command': OPERATION_REMOTE_COMMAND, 'add host': 2, 'remove host': 3, 'add to host group': 4, @@ -298,7 +358,64 @@ def get_operation_type(inc_operation): return o_types[inc_operation] -def get_action_operations(zapi, inc_operations): +def get_opcommand_type(opcommand_type): + ''' determine the opcommand type ''' + oc_types = {'custom script': CUSTOM_SCRIPT_ACTION, + 'IPMI': IPMI_ACTION, + 'SSH': SSH_ACTION, + 'Telnet': TELNET_ACTION, + 'global script': GLOBAL_SCRIPT_ACTION, + } + + return oc_types[opcommand_type] + +def get_execute_on(execute_on): + ''' determine the execution target ''' + e_types = {'zabbix agent': EXECUTE_ON_ZABBIX_AGENT, + 'zabbix server': EXECUTE_ON_ZABBIX_SERVER, + } + + return e_types[execute_on] + +def action_remote_command(ansible_module, zapi, operation): + ''' Process remote command type of actions ''' + + if 'type' not in operation['opcommand']: + ansible_module.exit_json(failed=True, changed=False, state='unknown', + results="No Operation Type provided") + + operation['opcommand']['type'] = get_opcommand_type(operation['opcommand']['type']) + + if operation['opcommand']['type'] == CUSTOM_SCRIPT_ACTION: + + if 'execute_on' in operation['opcommand']: + operation['opcommand']['execute_on'] = get_execute_on(operation['opcommand']['execute_on']) + + # custom script still requires the target hosts/groups to be set + operation['opcommand_hst'] = [] + operation['opcommand_grp'] = [] + for usr_host in operation['target_hosts']: + if usr_host['target_type'] == 'zabbix server': + # 0 = target host local/current host + operation['opcommand_hst'].append({'hostid': 0}) + elif usr_host['target_type'] == 'group': + group_name = usr_host['target'] + gid = get_host_group_id_by_name(zapi, group_name) + operation['opcommand_grp'].append({'groupid': gid}) + elif usr_host['target_type'] == 'host': + host_name = usr_host['target'] + hid = get_host_id_by_name(zapi, host_name) + operation['opcommand_hst'].append({'hostid': hid}) + + # 'target_hosts' is just to make it easier to build zbx_actions + # not part of ZabbixAPI + del operation['target_hosts'] + else: + ansible_module.exit_json(failed=True, changed=False, state='unknown', + results="Unsupported remote command type") + + +def get_action_operations(ansible_module, zapi, inc_operations): '''Convert the operations into syntax for api''' for operation in inc_operations: operation['operationtype'] = get_operation_type(operation['operationtype']) @@ -312,9 +429,8 @@ def get_action_operations(zapi, inc_operations): else: operation['opmessage']['default_msg'] = 0 - # NOT supported for remote commands - elif operation['operationtype'] == 1: - continue + elif operation['operationtype'] == OPERATION_REMOTE_COMMAND: + action_remote_command(ansible_module, zapi, operation) # Handle Operation conditions: # Currently there is only 1 available which @@ -330,9 +446,9 @@ def get_action_operations(zapi, inc_operations): condition['operator'] = 0 if condition['value'] == 'acknowledged': - condition['operator'] = 1 + condition['value'] = 1 else: - condition['operator'] = 0 + condition['value'] = 0 return inc_operations @@ -454,14 +570,15 @@ def main(): if not exists(content): module.exit_json(changed=False, state="absent") - content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['itemid']]) + content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['actionid']]) module.exit_json(changed=True, results=content['result'], state="absent") # Create and Update if state == 'present': conditions = get_action_conditions(zapi, module.params['event_source'], module.params['conditions_filter']) - operations = get_action_operations(zapi, module.params['operations']) + operations = get_action_operations(module, zapi, + module.params['operations']) params = {'name': module.params['name'], 'esc_period': module.params['escalation_time'], 'eventsource': get_event_source(module.params['event_source']), diff --git a/roles/lib_zabbix/library/zbx_graph.py b/roles/lib_zabbix/library/zbx_graph.py new file mode 100644 index 000000000..121ec3dee --- /dev/null +++ b/roles/lib_zabbix/library/zbx_graph.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +''' + Ansible module for zabbix graphs +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +# Zabbix graphs ansible module +# +# +# Copyright 2015 Red Hat Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#--- +#- hosts: localhost +# gather_facts: no +# tasks: +# - zbx_graph: +# zbx_server: https://zabbixserver/zabbix/api_jsonrpc.php +# zbx_user: Admin +# zbx_password: zabbix +# name: Test Graph +# height: 300 +# width: 500 +# graph_items: +# - item_name: openshift.master.etcd.create.fail +# color: red +# line_style: bold +# - item_name: openshift.master.etcd.create.success +# color: red +# line_style: bold +# +# + +# This is in place because each module looks similar to each other. +# These need duplicate code as their behavior is very similar +# but different for each zabbix class. +# pylint: disable=duplicate-code + +# pylint: disable=import-error +from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection + +def exists(content, key='result'): + ''' Check if key exists in content or the size of content[key] > 0 + ''' + if not content.has_key(key): + return False + + if not content[key]: + return False + + return True + +def get_graph_type(graphtype): + ''' + Possible values: + 0 - normal; + 1 - stacked; + 2 - pie; + 3 - exploded; + ''' + gtype = 0 + if 'stacked' in graphtype: + gtype = 1 + elif 'pie' in graphtype: + gtype = 2 + elif 'exploded' in graphtype: + gtype = 3 + + return gtype + +def get_show_legend(show_legend): + '''Get the value for show_legend + 0 - hide + 1 - (default) show + ''' + rval = 1 + if 'hide' == show_legend: + rval = 0 + + return rval + +def get_template_id(zapi, template_name): + ''' + get related templates + ''' + # Fetch templates by name + content = zapi.get_content('template', + 'get', + {'filter': {'host': template_name},}) + + if content.has_key('result'): + return content['result'][0]['templateid'] + + return None + +def get_color(color_in): + ''' Receive a color and translate it to a hex representation of the color + + Will have a few setup by default + ''' + colors = {'black': '000000', + 'red': 'FF0000', + 'pink': 'FFC0CB', + 'purple': '800080', + 'orange': 'FFA500', + 'gold': 'FFD700', + 'yellow': 'FFFF00', + 'green': '008000', + 'cyan': '00FFFF', + 'aqua': '00FFFF', + 'blue': '0000FF', + 'brown': 'A52A2A', + 'gray': '808080', + 'grey': '808080', + 'silver': 'C0C0C0', + } + if colors.has_key(color_in): + return colors[color_in] + + return color_in + +def get_line_style(style): + '''determine the line style + ''' + line_style = {'line': 0, + 'filled': 1, + 'bold': 2, + 'dot': 3, + 'dashed': 4, + 'gradient': 5, + } + + if line_style.has_key(style): + return line_style[style] + + return 0 + +def get_calc_function(func): + '''Determine the caclulation function''' + rval = 2 # default to avg + if 'min' in func: + rval = 1 + elif 'max' in func: + rval = 4 + elif 'all' in func: + rval = 7 + elif 'last' in func: + rval = 9 + + return rval + +def get_graph_item_type(gtype): + '''Determine the graph item type + ''' + rval = 0 # simple graph type + if 'sum' in gtype: + rval = 2 + + return rval + +def get_graph_items(zapi, gitems): + '''Get graph items by id''' + + r_items = [] + for item in gitems: + content = zapi.get_content('item', + 'get', + {'filter': {'name': item['item_name']}}) + _ = item.pop('item_name') + color = get_color(item.pop('color')) + drawtype = get_line_style(item.get('line_style', 'line')) + func = get_calc_function(item.get('calc_func', 'avg')) + g_type = get_graph_item_type(item.get('graph_item_type', 'simple')) + + if content.has_key('result'): + tmp = {'itemid': content['result'][0]['itemid'], + 'color': color, + 'drawtype': drawtype, + 'calc_fnc': func, + 'type': g_type, + } + r_items.append(tmp) + + return r_items + +def compare_gitems(zabbix_items, user_items): + '''Compare zabbix results with the user's supplied items + return True if user_items are equal + return False if any of the values differ + ''' + if len(zabbix_items) != len(user_items): + return False + + for u_item in user_items: + for z_item in zabbix_items: + if u_item['itemid'] == z_item['itemid']: + if not all([str(value) == z_item[key] for key, value in u_item.items()]): + return False + + return True + +# The branches are needed for CRUD and error handling +# pylint: disable=too-many-branches +def main(): + ''' + ansible zabbix module for zbx_graphs + ''' + + module = AnsibleModule( + argument_spec=dict( + zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), + zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'), + zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'), + zbx_debug=dict(default=False, type='bool'), + name=dict(default=None, type='str'), + height=dict(default=None, type='int'), + width=dict(default=None, type='int'), + graph_type=dict(default='normal', type='str'), + show_legend=dict(default='show', type='str'), + state=dict(default='present', type='str'), + graph_items=dict(default=None, type='list'), + ), + #supports_check_mode=True + ) + + zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'], + module.params['zbx_user'], + module.params['zbx_password'], + module.params['zbx_debug'])) + + #Set the instance and the template for the rest of the calls + zbx_class_name = 'graph' + state = module.params['state'] + + content = zapi.get_content(zbx_class_name, + 'get', + {'filter': {'name': module.params['name']}, + #'templateids': templateid, + 'selectGraphItems': 'extend', + }) + + #******# + # GET + #******# + if state == 'list': + module.exit_json(changed=False, results=content['result'], state="list") + + #******# + # DELETE + #******# + if state == 'absent': + if not exists(content): + module.exit_json(changed=False, state="absent") + + content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['graphid']]) + module.exit_json(changed=True, results=content['result'], state="absent") + + # Create and Update + if state == 'present': + + params = {'name': module.params['name'], + 'height': module.params['height'], + 'width': module.params['width'], + 'graphtype': get_graph_type(module.params['graph_type']), + 'show_legend': get_show_legend(module.params['show_legend']), + 'gitems': get_graph_items(zapi, module.params['graph_items']), + } + + # Remove any None valued params + _ = [params.pop(key, None) for key in params.keys() if params[key] is None] + + #******# + # CREATE + #******# + if not exists(content): + content = zapi.get_content(zbx_class_name, 'create', params) + + if content.has_key('error'): + module.exit_json(failed=True, changed=True, results=content['error'], state="present") + + module.exit_json(changed=True, results=content['result'], state='present') + + + ######## + # UPDATE + ######## + differences = {} + zab_results = content['result'][0] + for key, value in params.items(): + + if key == 'gitems': + if not compare_gitems(zab_results[key], value): + differences[key] = value + + elif zab_results[key] != value and zab_results[key] != str(value): + differences[key] = value + + if not differences: + module.exit_json(changed=False, results=zab_results, state="present") + + # We have differences and need to update + differences['graphid'] = zab_results['graphid'] + content = zapi.get_content(zbx_class_name, 'update', differences) + + if content.has_key('error'): + module.exit_json(failed=True, changed=False, results=content['error'], state="present") + + module.exit_json(changed=True, results=content['result'], state="present") + + module.exit_json(failed=True, + changed=False, + results='Unknown state passed. %s' % state, + state="unknown") + +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled +# import module snippets. This are required +from ansible.module_utils.basic import * + +main() diff --git a/roles/lib_zabbix/library/zbx_graphprototype.py b/roles/lib_zabbix/library/zbx_graphprototype.py new file mode 100644 index 000000000..8287c1e2d --- /dev/null +++ b/roles/lib_zabbix/library/zbx_graphprototype.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +''' + Ansible module for zabbix graphprototypes +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +# Zabbix graphprototypes ansible module +# +# +# Copyright 2015 Red Hat Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#--- +#- hosts: localhost +# gather_facts: no +# tasks: +# - zbx_graphprototype: +# zbx_server: https://zabbixserver/zabbix/api_jsonrpc.php +# zbx_user: Admin +# zbx_password: zabbix +# name: Test Graph +# height: 300 +# width: 500 +# graph_items: +# - item_name: Bytes per second IN on network interface {#OSO_NET_INTERFACE} +# color: red +# line_style: bold +# item_type: prototype +# - item_name: Template OS Linux: Bytes per second OUT on network interface {#OSO_NET_INTERFACE} +# item_type: prototype +# +# + +# This is in place because each module looks similar to each other. +# These need duplicate code as their behavior is very similar +# but different for each zabbix class. +# pylint: disable=duplicate-code + +# pylint: disable=import-error +from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection + +def exists(content, key='result'): + ''' Check if key exists in content or the size of content[key] > 0 + ''' + if not content.has_key(key): + return False + + if not content[key]: + return False + + return True + +def get_graph_type(graphtype): + ''' + Possible values: + 0 - normal; + 1 - stacked; + 2 - pie; + 3 - exploded; + ''' + gtype = 0 + if 'stacked' in graphtype: + gtype = 1 + elif 'pie' in graphtype: + gtype = 2 + elif 'exploded' in graphtype: + gtype = 3 + + return gtype + +def get_show_legend(show_legend): + '''Get the value for show_legend + 0 - hide + 1 - (default) show + ''' + rval = 1 + if 'hide' == show_legend: + rval = 0 + + return rval + +def get_template_id(zapi, template_name): + ''' + get related templates + ''' + # Fetch templates by name + content = zapi.get_content('template', + 'get', + {'filter': {'host': template_name},}) + + if content.has_key('result'): + return content['result'][0]['templateid'] + + return None + +def get_color(color_in='black'): + ''' Receive a color and translate it to a hex representation of the color + + Will have a few setup by default + ''' + colors = {'black': '000000', + 'red': 'FF0000', + 'pink': 'FFC0CB', + 'purple': '800080', + 'orange': 'FFA500', + 'gold': 'FFD700', + 'yellow': 'FFFF00', + 'green': '008000', + 'cyan': '00FFFF', + 'aqua': '00FFFF', + 'blue': '0000FF', + 'brown': 'A52A2A', + 'gray': '808080', + 'grey': '808080', + 'silver': 'C0C0C0', + } + if colors.has_key(color_in): + return colors[color_in] + + return color_in + +def get_line_style(style): + '''determine the line style + ''' + line_style = {'line': 0, + 'filled': 1, + 'bold': 2, + 'dot': 3, + 'dashed': 4, + 'gradient': 5, + } + + if line_style.has_key(style): + return line_style[style] + + return 0 + +def get_calc_function(func): + '''Determine the caclulation function''' + rval = 2 # default to avg + if 'min' in func: + rval = 1 + elif 'max' in func: + rval = 4 + elif 'all' in func: + rval = 7 + elif 'last' in func: + rval = 9 + + return rval + +def get_graph_item_type(gtype): + '''Determine the graph item type + ''' + rval = 0 # simple graph type + if 'sum' in gtype: + rval = 2 + + return rval + +def get_graph_items(zapi, gitems): + '''Get graph items by id''' + + r_items = [] + for item in gitems: + content = zapi.get_content('item%s' % item.get('item_type', ''), + 'get', + {'filter': {'name': item['item_name']}}) + _ = item.pop('item_name') + color = get_color(item.pop('color', 'black')) + drawtype = get_line_style(item.get('line_style', 'line')) + func = get_calc_function(item.get('calc_func', 'avg')) + g_type = get_graph_item_type(item.get('graph_item_type', 'simple')) + + if content.has_key('result'): + tmp = {'itemid': content['result'][0]['itemid'], + 'color': color, + 'drawtype': drawtype, + 'calc_fnc': func, + 'type': g_type, + } + r_items.append(tmp) + + return r_items + +def compare_gitems(zabbix_items, user_items): + '''Compare zabbix results with the user's supplied items + return True if user_items are equal + return False if any of the values differ + ''' + if len(zabbix_items) != len(user_items): + return False + + for u_item in user_items: + for z_item in zabbix_items: + if u_item['itemid'] == z_item['itemid']: + if not all([str(value) == z_item[key] for key, value in u_item.items()]): + return False + + return True + +# The branches are needed for CRUD and error handling +# pylint: disable=too-many-branches +def main(): + ''' + ansible zabbix module for zbx_graphprototypes + ''' + + module = AnsibleModule( + argument_spec=dict( + zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), + zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'), + zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'), + zbx_debug=dict(default=False, type='bool'), + name=dict(default=None, type='str'), + height=dict(default=None, type='int'), + width=dict(default=None, type='int'), + graph_type=dict(default='normal', type='str'), + show_legend=dict(default='show', type='str'), + state=dict(default='present', type='str'), + graph_items=dict(default=None, type='list'), + ), + #supports_check_mode=True + ) + + zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'], + module.params['zbx_user'], + module.params['zbx_password'], + module.params['zbx_debug'])) + + #Set the instance and the template for the rest of the calls + zbx_class_name = 'graphprototype' + state = module.params['state'] + + content = zapi.get_content(zbx_class_name, + 'get', + {'filter': {'name': module.params['name']}, + #'templateids': templateid, + 'selectGraphItems': 'extend', + }) + + #******# + # GET + #******# + if state == 'list': + module.exit_json(changed=False, results=content['result'], state="list") + + #******# + # DELETE + #******# + if state == 'absent': + if not exists(content): + module.exit_json(changed=False, state="absent") + + content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['graphid']]) + module.exit_json(changed=True, results=content['result'], state="absent") + + # Create and Update + if state == 'present': + + params = {'name': module.params['name'], + 'height': module.params['height'], + 'width': module.params['width'], + 'graphtype': get_graph_type(module.params['graph_type']), + 'show_legend': get_show_legend(module.params['show_legend']), + 'gitems': get_graph_items(zapi, module.params['graph_items']), + } + + # Remove any None valued params + _ = [params.pop(key, None) for key in params.keys() if params[key] is None] + + #******# + # CREATE + #******# + if not exists(content): + content = zapi.get_content(zbx_class_name, 'create', params) + + if content.has_key('error'): + module.exit_json(failed=True, changed=True, results=content['error'], state="present") + + module.exit_json(changed=True, results=content['result'], state='present') + + + ######## + # UPDATE + ######## + differences = {} + zab_results = content['result'][0] + for key, value in params.items(): + + if key == 'gitems': + if not compare_gitems(zab_results[key], value): + differences[key] = value + + elif zab_results[key] != value and zab_results[key] != str(value): + differences[key] = value + + if not differences: + module.exit_json(changed=False, results=zab_results, state="present") + + # We have differences and need to update + differences['graphid'] = zab_results['graphid'] + content = zapi.get_content(zbx_class_name, 'update', differences) + + if content.has_key('error'): + module.exit_json(failed=True, changed=False, results=content['error'], state="present") + + module.exit_json(changed=True, results=content['result'], state="present") + + module.exit_json(failed=True, + changed=False, + results='Unknown state passed. %s' % state, + state="unknown") + +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled +# import module snippets. This are required +from ansible.module_utils.basic import * + +main() diff --git a/roles/lib_zabbix/library/zbx_httptest.py b/roles/lib_zabbix/library/zbx_httptest.py index 96733b3d1..6b28117ad 100644 --- a/roles/lib_zabbix/library/zbx_httptest.py +++ b/roles/lib_zabbix/library/zbx_httptest.py @@ -131,6 +131,14 @@ def steps_equal(zab_steps, user_steps): return True +def process_steps(steps): + '''Preprocess the step parameters''' + for idx, step in enumerate(steps): + if not step.has_key('no'): + step['no'] = idx + 1 + + return steps + # The branches are needed for CRUD and error handling # pylint: disable=too-many-branches def main(): @@ -218,7 +226,7 @@ def main(): 'hostid': hostid, 'agent': module.params['agent'], 'retries': module.params['retries'], - 'steps': module.params['steps'], + 'steps': process_steps(module.params['steps']), 'applicationid': get_app_id(zapi, module.params['application']), 'delay': module.params['interval'], 'verify_host': get_verify_host(module.params['verify_host']), |