diff options
| author | Kenny Woodson <kwoodson@redhat.com> | 2015-08-21 17:44:30 -0400 | 
|---|---|---|
| committer | Kenny Woodson <kwoodson@redhat.com> | 2015-08-27 14:40:09 -0400 | 
| commit | 693be4802c2b3886b82681c5c1666b9f13d9ca36 (patch) | |
| tree | 4a6cee11c72601298535c262f5654a4b43ffba14 /roles/lib_zabbix | |
| parent | 2f5486c7174eeacdd52938442daa2ddfa6a8e277 (diff) | |
| download | openshift-693be4802c2b3886b82681c5c1666b9f13d9ca36.tar.gz openshift-693be4802c2b3886b82681c5c1666b9f13d9ca36.tar.bz2 openshift-693be4802c2b3886b82681c5c1666b9f13d9ca36.tar.xz openshift-693be4802c2b3886b82681c5c1666b9f13d9ca36.zip | |
Updates for zbx ans module
Diffstat (limited to 'roles/lib_zabbix')
| -rw-r--r-- | roles/lib_zabbix/README.md | 38 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/__init__.py | 3 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_application.py | 139 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_discoveryrule.py | 177 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_host.py | 163 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_hostgroup.py | 116 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_item.py | 178 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_itemprototype.py | 241 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_mediatype.py | 168 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_template.py | 132 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_trigger.py | 173 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_user.py | 190 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_user_media.py | 245 | ||||
| -rw-r--r-- | roles/lib_zabbix/library/zbx_usergroup.py | 208 | ||||
| -rw-r--r-- | roles/lib_zabbix/tasks/create_template.yml | 61 | ||||
| -rw-r--r-- | roles/lib_zabbix/tasks/create_user.yml | 11 | 
16 files changed, 2243 insertions, 0 deletions
| diff --git a/roles/lib_zabbix/README.md b/roles/lib_zabbix/README.md new file mode 100644 index 000000000..69debc698 --- /dev/null +++ b/roles/lib_zabbix/README.md @@ -0,0 +1,38 @@ +zabbix +========= + +Automate zabbix tasks. + +Requirements +------------ + +This requires the openshift_tools rpm be installed for the zbxapi.py library.  It can be found here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now. + +Role Variables +-------------- + +None + +Dependencies +------------ + +This depeonds on the zbxapi.py library located here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now. + +Example Playbook +---------------- + +  - zbx_host: +      server: zab_server +      user: zab_user +      password: zab_password +      name: 'myhost' + +License +------- + +ASL 2.0 + +Author Information +------------------ + +OpenShift operations, Red Hat, Inc diff --git a/roles/lib_zabbix/library/__init__.py b/roles/lib_zabbix/library/__init__.py new file mode 100644 index 000000000..0c7e19e41 --- /dev/null +++ b/roles/lib_zabbix/library/__init__.py @@ -0,0 +1,3 @@ +''' +ZabbixAPI ansible module +''' diff --git a/roles/lib_zabbix/library/zbx_application.py b/roles/lib_zabbix/library/zbx_application.py new file mode 100644 index 000000000..ffa00e052 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_application.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +''' +Ansible module for application +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix application 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. +# + +# 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_template_ids(zapi, template_names): +    ''' +    get related templates +    ''' +    template_ids = [] +    # Fetch templates by name +    for template_name in template_names: +        content = zapi.get_content('template', 'get', {'search': {'host': template_name}}) +        if content.has_key('result'): +            template_ids.append(content['result'][0]['templateid']) +    return template_ids + +def main(): +    ''' Ansible module for application +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            template_name=dict(default=None, type='list'), +            state=dict(default='present', type='str'), +        ), +        #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 application for the rest of the calls +    zbx_class_name = 'application' +    idname = 'applicationid' +    aname = module.params['name'] +    state = module.params['state'] +    # get a applicationid, see if it exists +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'name': aname}, +                                'selectHost': 'hostid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        params = {'hostid': get_template_ids(zapi, module.params['template_name'])[0], +                  'name': aname, +                 } +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): +            if key == 'templates' and zab_results.has_key('parentTemplates'): +                if zab_results['parentTemplates'] != value: +                    differences[key] = value +            elif zab_results[key] != str(value) and zab_results[key] != value: +                differences[key] = value + +        if not differences: +            module.exit_json(changed=False, results=content['result'], state="present") + +        # We have differences and need to update +        differences[idname] = zab_results[idname] +        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_discoveryrule.py b/roles/lib_zabbix/library/zbx_discoveryrule.py new file mode 100644 index 000000000..79ee91180 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_discoveryrule.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +''' +Zabbix discovery rule ansible module +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   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. +# + +# 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_template(zapi, template_name): +    '''get a template by name +    ''' +    content = zapi.get_content('template', +                               'get', +                               {'search': {'host': template_name}, +                                'output': 'extend', +                                'selectInterfaces': 'interfaceid', +                               }) +    if not content['result']: +        return None +    return content['result'][0] + +def get_type(vtype): +    ''' +    Determine which type of discoverrule this is +    ''' +    _types = {'agent': 0, +              'SNMPv1': 1, +              'trapper': 2, +              'simple': 3, +              'SNMPv2': 4, +              'internal': 5, +              'SNMPv3': 6, +              'active': 7, +              'external': 10, +              'database monitor': 11, +              'ipmi': 12, +              'ssh': 13, +              'telnet': 14, +              'JMX': 16, +             } + +    for typ in _types.keys(): +        if vtype in typ or vtype == typ: +            _vtype = _types[typ] +            break +    else: +        _vtype = 2 + +    return _vtype + +def main(): +    ''' +    Ansible module for zabbix discovery rules +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            key=dict(default=None, type='str'), +            interfaceid=dict(default=None, type='int'), +            ztype=dict(default='trapper', type='str'), +            delay=dict(default=60, type='int'), +            lifetime=dict(default=30, type='int'), +            template_name=dict(default=[], type='list'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'discoveryrule' +    idname = "itemid" +    dname = module.params['name'] +    state = module.params['state'] + +    # selectInterfaces doesn't appear to be working but is needed. +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'name': dname}, +                                #'selectDServices': 'extend', +                                #'selectDChecks': 'extend', +                                #'selectDhosts': 'dhostid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        template = get_template(zapi, module.params['template_name']) +        params = {'name': dname, +                  'key_':  module.params['key'], +                  'hostid':  template['templateid'], +                  'interfaceid': module.params['interfaceid'], +                  'lifetime': module.params['lifetime'], +                  'type': get_type(module.params['ztype']), +                 } +        if params['type'] in [2, 5, 7, 11]: +            params.pop('interfaceid') + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_host.py b/roles/lib_zabbix/library/zbx_host.py new file mode 100644 index 000000000..7be03653e --- /dev/null +++ b/roles/lib_zabbix/library/zbx_host.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +''' +Zabbix host ansible module +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   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. +# + +# 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_group_ids(zapi, hostgroup_names): +    ''' +    get hostgroups +    ''' +    # Fetch groups by name +    group_ids = [] +    for hgr in hostgroup_names: +        content = zapi.get_content('hostgroup', 'get', {'search': {'name': hgr}}) +        if content.has_key('result'): +            group_ids.append({'groupid': content['result'][0]['groupid']}) + +    return group_ids + +def get_template_ids(zapi, template_names): +    ''' +    get related templates +    ''' +    template_ids = [] +    # Fetch templates by name +    for template_name in template_names: +        content = zapi.get_content('template', 'get', {'search': {'host': template_name}}) +        if content.has_key('result'): +            template_ids.append({'templateid': content['result'][0]['templateid']}) +    return template_ids + +def main(): +    ''' +    Ansible module for zabbix host +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            hostgroup_names=dict(default=[], type='list'), +            template_names=dict(default=[], type='list'), +            state=dict(default='present', type='str'), +            interfaces=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 = 'host' +    idname = "hostid" +    hname = module.params['name'] +    state = module.params['state'] + +    # selectInterfaces doesn't appear to be working but is needed. +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'host': hname}, +                                'selectGroups': 'groupid', +                                'selectParentTemplates': 'templateid', +                                'selectInterfaces': 'interfaceid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        ifs = module.params['interfaces'] or [{'type':  1,         # interface type, 1 = agent +                                               'main':  1,         # default interface? 1 = true +                                               'useip':  1,        # default interface? 1 = true +                                               'ip':  '127.0.0.1', # default interface? 1 = true +                                               'dns':  '',         # dns for host +                                               'port':  '10050',   # port for interface? 10050 +                                              }] +        params = {'host': hname, +                  'groups':  get_group_ids(zapi, module.params['hostgroup_names']), +                  'templates':  get_template_ids(zapi, module.params['template_names']), +                  'interfaces': ifs, +                 } + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if key == 'templates' and zab_results.has_key('parentTemplates'): +                if zab_results['parentTemplates'] != 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_hostgroup.py b/roles/lib_zabbix/library/zbx_hostgroup.py new file mode 100644 index 000000000..f161d3d9f --- /dev/null +++ b/roles/lib_zabbix/library/zbx_hostgroup.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +''' Ansible module for hostgroup +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix hostgroup 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. +# + +# 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 main(): +    ''' ansible module for hostgroup +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'hostgroup' +    idname = "groupid" +    hname = module.params['name'] +    state = module.params['state'] + +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'name': hname}, +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        params = {'name': hname} + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): +            if 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_item.py b/roles/lib_zabbix/library/zbx_item.py new file mode 100644 index 000000000..60da243fe --- /dev/null +++ b/roles/lib_zabbix/library/zbx_item.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python +''' + Ansible module for zabbix items +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix item 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. +# + +# 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_value_type(value_type): +    ''' +    Possible values: +    0 - numeric float; +    1 - character; +    2 - log; +    3 - numeric unsigned; +    4 - text +    ''' +    vtype = 0 +    if 'int' in value_type: +        vtype = 3 +    elif 'char' in value_type: +        vtype = 1 +    elif 'str' in value_type: +        vtype = 4 + +    return vtype + +def get_app_ids(zapi, application_names): +    ''' get application ids from names +    ''' +    if isinstance(application_names, str): +        application_names = [application_names] +    app_ids = [] +    for app_name in application_names: +        content = zapi.get_content('application', 'get', {'search': {'name': app_name}}) +        if content.has_key('result'): +            app_ids.append(content['result'][0]['applicationid']) +    return app_ids + +def main(): +    ''' +    ansible zabbix module for zbx_item +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            key=dict(default=None, type='str'), +            template_name=dict(default=None, type='str'), +            zabbix_type=dict(default=2, type='int'), +            value_type=dict(default='int', type='str'), +            applications=dict(default=[], type='list'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'item' +    idname = "itemid" +    state = module.params['state'] +    key = module.params['key'] +    template_name = module.params['template_name'] + +    content = zapi.get_content('template', 'get', {'search': {'host': template_name}}) +    templateid = None +    if content['result']: +        templateid = content['result'][0]['templateid'] +    else: +        module.exit_json(changed=False, +                         results='Error: Could find template with name %s for item.' % template_name, +                         state="Unkown") + +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'key_': key}, +                                'selectApplications': 'applicationid', +                               }) + +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        params = {'name': module.params.get('name', module.params['key']), +                  'key_': key, +                  'hostid': templateid, +                  'type': module.params['zabbix_type'], +                  'value_type': get_value_type(module.params['value_type']), +                  'applications': get_app_ids(zapi, module.params['applications']), +                 } + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if key == 'applications': +                zab_apps = set([item['applicationid'] for item in zab_results[key]]) +                if zab_apps != set(value): +                    differences[key] = zab_apps + +            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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_itemprototype.py b/roles/lib_zabbix/library/zbx_itemprototype.py new file mode 100644 index 000000000..47100f613 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_itemprototype.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python +''' +Zabbix discovery rule ansible module +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   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. +# + +# 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_rule_id(zapi, discoveryrule_name): +    '''get a discoveryrule by name +    ''' +    content = zapi.get_content('discoveryrule', +                               'get', +                               {'search': {'name': discoveryrule_name}, +                                'output': 'extend', +                               }) +    if not content['result']: +        return None +    return content['result'][0]['itemid'] + +def get_template(zapi, template_name): +    '''get a template by name +    ''' +    content = zapi.get_content('template', +                               'get', +                               {'search': {'host': template_name}, +                                'output': 'extend', +                                'selectInterfaces': 'interfaceid', +                               }) +    if not content['result']: +        return None +    return content['result'][0] + +def get_type(ztype): +    ''' +    Determine which type of discoverrule this is +    ''' +    _types = {'agent': 0, +              'SNMPv1': 1, +              'trapper': 2, +              'simple': 3, +              'SNMPv2': 4, +              'internal': 5, +              'SNMPv3': 6, +              'active': 7, +              'aggregate': 8, +              'external': 10, +              'database monitor': 11, +              'ipmi': 12, +              'ssh': 13, +              'telnet': 14, +              'calculated': 15, +              'JMX': 16, +             } + +    for typ in _types.keys(): +        if ztype in typ or ztype == typ: +            _vtype = _types[typ] +            break +    else: +        _vtype = 2 + +    return _vtype + +def get_value_type(value_type): +    ''' +    Possible values: +    0 - numeric float; +    1 - character; +    2 - log; +    3 - numeric unsigned; +    4 - text +    ''' +    vtype = 0 +    if 'int' in value_type: +        vtype = 3 +    elif 'char' in value_type: +        vtype = 1 +    elif 'str' in value_type: +        vtype = 4 + +    return vtype + +def get_status(status): +    ''' Determine status +    ''' +    _status = 0 +    if status == 'disabled': +        _status = 1 +    elif status == 'unsupported': +        _status = 3 + +    return _status + +def get_app_ids(zapi, application_names): +    ''' get application ids from names +    ''' +    app_ids = [] +    for app_name in application_names: +        content = zapi.get_content('application', 'get', {'search': {'name': app_name}}) +        if content.has_key('result'): +            app_ids.append(content['result'][0]['applicationid']) +    return app_ids + +def main(): +    ''' +    Ansible module for zabbix discovery rules +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            key=dict(default=None, type='str'), +            interfaceid=dict(default=None, type='int'), +            ztype=dict(default='trapper', type='str'), +            value_type=dict(default='float', type='str'), +            delay=dict(default=60, type='int'), +            lifetime=dict(default=30, type='int'), +            template_name=dict(default=[], type='list'), +            state=dict(default='present', type='str'), +            status=dict(default='enabled', type='str'), +            discoveryrule_name=dict(default=None, type='str'), +            applications=dict(default=[], 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 = 'itemprototype' +    idname = "itemid" +    dname = module.params['name'] +    state = module.params['state'] + +    # selectInterfaces doesn't appear to be working but is needed. +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'name': dname}, +                                'selectApplications': 'applicationid', +                                'selectDiscoveryRule': 'itemid', +                                #'selectDhosts': 'dhostid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        template = get_template(zapi, module.params['template_name']) +        params = {'name': dname, +                  'key_':  module.params['key'], +                  'hostid':  template['templateid'], +                  'interfaceid': module.params['interfaceid'], +                  'ruleid': get_rule_id(zapi, module.params['discoveryrule_name']), +                  'type': get_type(module.params['ztype']), +                  'value_type': get_value_type(module.params['value_type']), +                  'applications': get_app_ids(zapi, module.params['applications']), +                 } +        if params['type'] in [2, 5, 7, 8, 11, 15]: +            params.pop('interfaceid') + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if key == 'ruleid': +                if value != zab_results['discoveryRule']['itemid']: +                    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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_mediatype.py b/roles/lib_zabbix/library/zbx_mediatype.py new file mode 100644 index 000000000..cc72cc9a8 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_mediatype.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +''' + Ansible module for mediatype +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix mediatype 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. +# + +# 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_mtype(mtype): +    ''' +    Transport used by the media type. +    Possible values: +    0 - email; +    1 - script; +    2 - SMS; +    3 - Jabber; +    100 - Ez Texting. +    ''' +    mtype = mtype.lower() +    media_type = None +    if mtype == 'script': +        media_type = 1 +    elif mtype == 'sms': +        media_type = 2 +    elif mtype == 'jabber': +        media_type = 3 +    elif mtype == 'script': +        media_type = 100 +    else: +        media_type = 0 + +    return media_type + +def main(): +    ''' +    Ansible zabbix module for mediatype +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            description=dict(default=None, type='str'), +            mtype=dict(default=None, type='str'), +            smtp_server=dict(default=None, type='str'), +            smtp_helo=dict(default=None, type='str'), +            smtp_email=dict(default=None, type='str'), +            passwd=dict(default=None, type='str'), +            path=dict(default=None, type='str'), +            username=dict(default=None, type='str'), +            status=dict(default='enabled', type='str'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'mediatype' +    idname = "mediatypeid" +    description = module.params['description'] +    state = module.params['state'] + +    content = zapi.get_content(zbx_class_name, 'get', {'search': {'description': description}}) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        status = 1 +        if module.params['status']: +            status = 0 +        params = {'description': description, +                  'type': get_mtype(module.params['mtype']), +                  'smtp_server': module.params['smtp_server'], +                  'smtp_helo': module.params['smtp_helo'], +                  'smtp_email': module.params['smtp_email'], +                  'passwd': module.params['passwd'], +                  'exec_path': module.params['path'], +                  'username': module.params['username'], +                  'status': status, +                 } + +        # Remove any None valued params +        _ = [params.pop(key, None) for key in params.keys() if params[key] is None] + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) + +            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') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): +            if 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_template.py b/roles/lib_zabbix/library/zbx_template.py new file mode 100644 index 000000000..1592fa268 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_template.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +''' +Ansible module for template +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix template 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. +# + +# 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 main(): +    ''' Ansible module for template +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            name=dict(default=None, type='str'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'template' +    idname = 'templateid' +    tname = module.params['name'] +    state = module.params['state'] +    # get a template, see if it exists +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'host': tname}, +                                'selectParentTemplates': 'templateid', +                                'selectGroups': 'groupid', +                                'selectApplications': 'applicationid', +                                'selectDiscoveries': 'extend', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    if state == 'absent': +        if not exists(content): +            module.exit_json(changed=False, state="absent") + +        if not tname: +            module.exit_json(failed=True, +                             changed=False, +                             results='Must specifiy a template name.', +                             state="absent") + +        content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        params = {'groups': module.params.get('groups', [{'groupid': '1'}]), +                  'host': tname, +                 } + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): +            if key == 'templates' and zab_results.has_key('parentTemplates'): +                if zab_results['parentTemplates'] != value: +                    differences[key] = value +            elif zab_results[key] != str(value) and zab_results[key] != value: +                differences[key] = value + +        if not differences: +            module.exit_json(changed=False, results=content['result'], state="present") + +        # We have differences and need to update +        differences[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_trigger.py b/roles/lib_zabbix/library/zbx_trigger.py new file mode 100644 index 000000000..ffad5b40a --- /dev/null +++ b/roles/lib_zabbix/library/zbx_trigger.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python +''' +ansible module for zabbix triggers +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix trigger 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. +# + +# 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_priority(priority): +    ''' determine priority +    ''' +    prior = 0 +    if 'info' in priority: +        prior = 1 +    elif 'warn' in priority: +        prior = 2 +    elif 'avg' == priority or 'ave' in priority: +        prior = 3 +    elif 'high' in priority: +        prior = 4 +    elif 'dis' in priority: +        prior = 5 + +    return prior + +def get_deps(zapi, deps): +    ''' get trigger dependencies +    ''' +    results = [] +    for desc in deps: +        content = zapi.get_content('trigger', +                                   'get', +                                   {'search': {'description': desc}, +                                    'expandExpression': True, +                                    'selectDependencies': 'triggerid', +                                   }) +        if content.has_key('result'): +            results.append({'triggerid': content['result'][0]['triggerid']}) + +    return results + +def main(): +    ''' +    Create a trigger in zabbix + +    Example: +    "params": { +        "description": "Processor load is too high on {HOST.NAME}", +        "expression": "{Linux server:system.cpu.load[percpu,avg1].last()}>5", +        "dependencies": [ +            { +                "triggerid": "14062" +            } +        ] +    }, + +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            expression=dict(default=None, type='str'), +            description=dict(default=None, type='str'), +            dependencies=dict(default=[], type='list'), +            priority=dict(default='avg', type='str'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'trigger' +    idname = "triggerid" +    state = module.params['state'] +    description = module.params['description'] + +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'description': description}, +                                'expandExpression': True, +                                'selectDependencies': 'triggerid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    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][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        params = {'description': description, +                  'expression':  module.params['expression'], +                  'dependencies': get_deps(zapi, module.params['dependencies']), +                  'priority': get_priority(module.params['priority']), +                 } + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_user.py b/roles/lib_zabbix/library/zbx_user.py new file mode 100644 index 000000000..a9906d773 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_user.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +''' +ansible module for zabbix users +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix user 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. +# +# 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_usergroups(zapi, usergroups): +    ''' Get usergroups +    ''' +    ugroups = [] +    for ugr in usergroups: +        content = zapi.get_content('usergroup', +                                   'get', +                                   {'search': {'name': ugr}, +                                    #'selectUsers': 'userid', +                                    #'getRights': 'extend' +                                   }) +        if content['result']: +            ugroups.append({'usrgrpid': content['result'][0]['usrgrpid']}) + +    return ugroups or None + +def get_passwd(passwd): +    '''Determine if password is set, if not, return 'zabbix' +    ''' +    if passwd: +        return passwd + +    return 'zabbix' + +def get_usertype(user_type): +    ''' +    Determine zabbix user account type +    ''' +    if not user_type: +        return None + +    utype = 1 +    if 'super' in user_type: +        utype = 3 +    elif 'admin' in user_type or user_type == 'admin': +        utype = 2 + +    return utype + +def main(): +    ''' +    ansible zabbix module for users +    ''' + +    ##def user(self, name, state='present', params=None): + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            login=dict(default=None, type='str'), +            first_name=dict(default=None, type='str'), +            last_name=dict(default=None, type='str'), +            user_type=dict(default=None, type='str'), +            password=dict(default=None, type='str'), +            update_password=dict(default=False, type='bool'), +            user_groups=dict(default=[], type='list'), +            state=dict(default='present', type='str'), +        ), +        #supports_check_mode=True +    ) + +    zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'], +                                      module.params['zbx_user'], +                                      module.params['zbx_password'], +                                      module.params['zbx_debug'])) + +    ## before we can create a user media and users with media types we need media +    zbx_class_name = 'user' +    idname = "userid" +    state = module.params['state'] + +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'output': 'extend', +                                'search': {'alias': module.params['login']}, +                                "selectUsrgrps": 'usergrpid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    if state == 'absent': +        if not exists(content) or len(content['result']) == 0: +            module.exit_json(changed=False, state="absent") + +        content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': + +        params = {'alias': module.params['login'], +                  'passwd': get_passwd(module.params['password']), +                  'usrgrps': get_usergroups(zapi, module.params['user_groups']), +                  'name': module.params['first_name'], +                  'surname': module.params['last_name'], +                  'type': get_usertype(module.params['user_type']), +                 } + +        # Remove any None valued params +        _ = [params.pop(key, None) for key in params.keys() if params[key] is None] + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) + +            if content.has_key('Error'): +                module.exit_json(failed=True, changed=False, results=content, state='present') + +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} + +        # Update password +        if not module.params['update_password']: +            params.pop('passwd', None) + +        zab_results = content['result'][0] +        for key, value in params.items(): + +            if key == 'usrgrps': +                # this must be done as a list of ordered dictionaries fails comparison +                if not all([True for _ in zab_results[key][0] if _ in value[0]]): +                    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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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_user_media.py b/roles/lib_zabbix/library/zbx_user_media.py new file mode 100644 index 000000000..aad3554dd --- /dev/null +++ b/roles/lib_zabbix/library/zbx_user_media.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python +''' + Ansible module for user media +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix user media  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. +# + +# 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_mtype(zapi, mtype): +    '''Get mediatype + +       If passed an int, return it as the mediatypeid +       if its a string, then try to fetch through a description +    ''' +    if isinstance(mtype, int): +        return mtype +    try: +        return int(mtype) +    except ValueError: +        pass + +    content = zapi.get_content('mediatype', 'get', {'search': {'description': mtype}}) +    if content.has_key['result'] and content['result']: +        return content['result'][0]['mediatypeid'] + +    return None + +def get_user(zapi, user): +    ''' Get userids from user aliases +    ''' +    content = zapi.get_content('user', 'get', {'search': {'alias': user}}) +    if content['result']: +        return content['result'][0] + +    return None + +def get_severity(severity): +    ''' determine severity +    ''' +    if isinstance(severity, int) or \ +       isinstance(severity, str): +        return severity + +    val = 0 +    sev_map = { +        'not': 2**0, +        'inf': 2**1, +        'war': 2**2, +        'ave':  2**3, +        'avg':  2**3, +        'hig': 2**4, +        'dis': 2**5, +    } +    for level in severity: +        val |= sev_map[level[:3].lower()] +    return val + +def get_zbx_user_query_data(zapi, user_name): +    ''' If name exists, retrieve it, and build query params. +    ''' +    query = {} +    if user_name: +        zbx_user = get_user(zapi, user_name) +        query = {'userid': zbx_user['userid']} + +    return query + +def find_media(medias, user_media): +    ''' Find the user media in the list of medias +    ''' +    for media in medias: +        if all([media[key] == user_media[key] for key in user_media.keys()]): +            return media +    return None + +def get_active(in_active): +    '''Determine active value +    ''' +    active = 1 +    if in_active: +        active = 0 + +    return active + +def get_mediatype(zapi, mediatype, mediatype_desc): +    ''' Determine mediatypeid +    ''' +    mtypeid = None +    if mediatype: +        mtypeid = get_mtype(zapi, mediatype) +    elif mediatype_desc: +        mtypeid = get_mtype(zapi, mediatype_desc) + +    return mtypeid + +def main(): +    ''' +    Ansible zabbix module for mediatype +    ''' + +    module = AnsibleModule( +        argument_spec=dict( +            zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), +            zbx_user=dict(default=os.environ['ZABBIX_USER'], type='str'), +            zbx_password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'), +            zbx_debug=dict(default=False, type='bool'), +            login=dict(default=None, type='str'), +            active=dict(default=False, type='bool'), +            medias=dict(default=None, type='list'), +            mediaid=dict(default=None, type='int'), +            mediatype=dict(default=None, type='str'), +            mediatype_desc=dict(default=None, type='str'), +            #d-d,hh:mm-hh:mm;d-d,hh:mm-hh:mm... +            period=dict(default=None, type='str'), +            sendto=dict(default=None, type='str'), +            severity=dict(default=None, type='str'), +            state=dict(default='present', type='str'), +        ), +        #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 = 'user' +    idname = "mediaid" +    state = module.params['state'] + +    # User media is fetched through the usermedia.get +    zbx_user_query = get_zbx_user_query_data(zapi, module.params['login']) +    content = zapi.get_content('usermedia', 'get', zbx_user_query) + +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    if state == 'absent': +        if not exists(content) or len(content['result']) == 0: +            module.exit_json(changed=False, state="absent") + +        if not module.params['login']: +            module.exit_json(failed=True, changed=False, results='Must specifiy a user login.', state="absent") + +        content = zapi.get_content(zbx_class_name, 'deletemedia', [content['result'][0][idname]]) + +        if content.has_key('error'): +            module.exit_json(changed=False, results=content['error'], state="absent") + +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': +        active = get_active(module.params['active']) +        mtypeid = get_mediatype(zapi, module.params['mediatype'], module.params['mediatype_desc']) + +        medias = module.params['medias'] +        if medias == None: +            medias = [{'mediatypeid': mtypeid, +                       'sendto': module.params['sendto'], +                       'active': active, +                       'severity': int(get_severity(module.params['severity'])), +                       'period': module.params['period'], +                      }] + +        params = {'users': [zbx_user_query], +                  'medias': medias, +                  'output': 'extend', +                 } + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'addmedia', params) + +            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') + +        # mediaid signifies an update +        # If user params exists, check to see if they already exist in zabbix +        # if they exist, then return as no update +        # elif they do not exist, then take user params only +        diff = {'medias': [], 'users': {}} +        _ = [diff['medias'].append(media) for media in params['medias'] if not find_media(content['result'], media)] + +        if not diff['medias']: +            module.exit_json(changed=False, results=content['result'], state="present") + +        for user in params['users']: +            diff['users']['userid'] = user['userid'] + +        # We have differences and need to update +        content = zapi.get_content(zbx_class_name, 'updatemedia', diff) + +        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_usergroup.py b/roles/lib_zabbix/library/zbx_usergroup.py new file mode 100644 index 000000000..297d8ef91 --- /dev/null +++ b/roles/lib_zabbix/library/zbx_usergroup.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +''' +zabbix ansible module for usergroups +''' +# vim: expandtab:tabstop=4:shiftwidth=4 +# +#   Zabbix usergroup 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. +# + +# 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_rights(zapi, rights): +    '''Get rights +    ''' +    if rights == None: +        return None + +    perms = [] +    for right in rights: +        hstgrp = right.keys()[0] +        perm = right.values()[0] +        content = zapi.get_content('hostgroup', 'get', {'search': {'name': hstgrp}}) +        if content['result']: +            permission = 0 +            if perm == 'ro': +                permission = 2 +            elif perm == 'rw': +                permission = 3 +            perms.append({'id': content['result'][0]['groupid'], +                          'permission': permission}) +    return perms + +def get_gui_access(access): +    ''' Return the gui_access for a usergroup +    ''' +    access = access.lower() +    if access == 'internal': +        return 1 +    elif access == 'disabled': +        return 2 + +    return 0 + +def get_debug_mode(mode): +    ''' Return the debug_mode for a usergroup +    ''' +    mode = mode.lower() +    if mode == 'enabled': +        return 1 + +    return 0 + +def get_user_status(status): +    ''' Return the user_status for a usergroup +    ''' +    status = status.lower() +    if status == 'enabled': +        return 0 + +    return 1 + + +#def get_userids(zapi, users): +#    ''' Get userids from user aliases +#    ''' +#    if not users: +#        return None +# +#    userids = [] +#    for alias in users: +#        content = zapi.get_content('user', 'get', {'search': {'alias': alias}}) +#        if content['result']: +#            userids.append(content['result'][0]['userid']) +# +#    return userids + +def main(): +    ''' Ansible module for usergroup +    ''' + +    ##def usergroup(self, name, rights=None, users=None, state='present', params=None): + +    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'), +            debug_mode=dict(default='disabled', type='str'), +            gui_access=dict(default='default', type='str'), +            status=dict(default='enabled', type='str'), +            name=dict(default=None, type='str', required=True), +            rights=dict(default=None, type='list'), +            #users=dict(default=None, type='list'), +            state=dict(default='present', type='str'), +        ), +        #supports_check_mode=True +    ) + +    zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'], +                                      module.params['zbx_user'], +                                      module.params['zbx_password'], +                                      module.params['zbx_debug'])) + +    zbx_class_name = 'usergroup' +    idname = "usrgrpid" +    uname = module.params['name'] +    state = module.params['state'] + +    content = zapi.get_content(zbx_class_name, +                               'get', +                               {'search': {'name': uname}, +                                'selectUsers': 'userid', +                               }) +    if state == 'list': +        module.exit_json(changed=False, results=content['result'], state="list") + +    if state == 'absent': +        if not exists(content): +            module.exit_json(changed=False, state="absent") + +        if not uname: +            module.exit_json(failed=True, changed=False, results='Need to pass in a user.', state="error") + +        content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]]) +        module.exit_json(changed=True, results=content['result'], state="absent") + +    if state == 'present': + +        params = {'name': uname, +                  'rights': get_rights(zapi, module.params['rights']), +                  'users_status': get_user_status(module.params['status']), +                  'gui_access': get_gui_access(module.params['gui_access']), +                  'debug_mode': get_debug_mode(module.params['debug_mode']), +                  #'userids': get_userids(zapi, module.params['users']), +                 } + +        _ = [params.pop(key, None) for key in params.keys() if params[key] == None] + +        if not exists(content): +            # if we didn't find it, create it +            content = zapi.get_content(zbx_class_name, 'create', params) +            module.exit_json(changed=True, results=content['result'], state='present') +        # already exists, we need to update it +        # let's compare properties +        differences = {} +        zab_results = content['result'][0] +        for key, value in params.items(): +            if key == 'rights': +                differences['rights'] = value + +            #elif key == 'userids' and zab_results.has_key('users'): +                #if zab_results['users'] != value: +                    #differences['userids'] = 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[idname] = zab_results[idname] +        content = zapi.get_content(zbx_class_name, 'update', differences) +        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/tasks/create_template.yml b/roles/lib_zabbix/tasks/create_template.yml new file mode 100644 index 000000000..022ca52f2 --- /dev/null +++ b/roles/lib_zabbix/tasks/create_template.yml @@ -0,0 +1,61 @@ +--- +- debug: var=template + +- name: Template Create Template +  zbx_template: +    zbx_server: "{{ server }}" +    zbx_user: "{{ user }}" +    zbx_password: "{{ password }}" +    name: "{{ template.name }}" +  register: created_template + +- debug: var=created_template + +- set_fact: +    lzbx_applications: "{{ template.zitems | oo_select_keys_from_list(['applications']) | oo_flatten | unique }}" + +- debug: var=lzbx_applications + +- name: Create Application +  zbx_application: +    zbx_server: "{{ server }}" +    zbx_user: "{{ user }}" +    zbx_password: "{{ password }}" +    name: "{{ item }}" +    template_name: "{{ template.name }}" +  with_items: lzbx_applications +  register: created_application +  when: template.zitems is defined + +- debug: var=created_application + +- name: Create Items +  zbx_item: +    zbx_server: "{{ server }}" +    zbx_user: "{{ user }}" +    zbx_password: "{{ password }}" +    key: "{{ item.key }}" +    name: "{{ item.name | default(item.key, true) }}" +    value_type: "{{ item.value_type | default('int') }}" +    template_name: "{{ template.name }}" +    applications: "{{ item.applications }}" +  with_items: template.zitems +  register: created_items +  when: template.zitems is defined + +#- debug: var=ctp_created_items + +- name: Create Triggers +  zbx_trigger: +    zbx_server: "{{ server }}" +    zbx_user: "{{ user }}" +    zbx_password: "{{ password }}" +    description: "{{ item.description }}" +    expression: "{{ item.expression }}" +    priority: "{{ item.priority }}" +  with_items: template.ztriggers +  when: template.ztriggers is defined + +#- debug: var=ctp_created_triggers + + diff --git a/roles/lib_zabbix/tasks/create_user.yml b/roles/lib_zabbix/tasks/create_user.yml new file mode 100644 index 000000000..1f752a9e1 --- /dev/null +++ b/roles/lib_zabbix/tasks/create_user.yml @@ -0,0 +1,11 @@ +--- +- name: Update zabbix credentialss for a user +  zbx_user: +    server: "{{ ozb_server }}" +    user: "{{ ozb_user }}" +    password: "{{ ozb_password }}" +    alias: "{{ ozb_username }}" +    passwd: "{{ ozb_new_password | default(ozb_password, true) }}" +  register: user + +- debug: var=user.results | 
