Bläddra i källkod

Merge pull request #513 from kwoodson/zbxupdates

Zabbix API updates
Wesley Hearn 9 år sedan
förälder
incheckning
d228350e4b
38 ändrade filer med 682 tillägg och 334 borttagningar
  1. 29 0
      filter_plugins/oo_zabbix_filters.py
  2. 0 51
      playbooks/adhoc/zabbix_setup/clean_zabbix.yml
  3. 0 57
      playbooks/adhoc/zabbix_setup/create_template.yml
  4. 0 31
      playbooks/adhoc/zabbix_setup/create_user.yml
  5. 0 1
      playbooks/adhoc/zabbix_setup/filter_plugins
  6. 0 1
      playbooks/adhoc/zabbix_setup/roles
  7. 0 38
      playbooks/adhoc/zabbix_setup/setup_zabbix.yml
  8. 38 0
      roles/lib_zabbix/README.md
  9. 0 0
      roles/lib_zabbix/library/__init__.py
  10. 0 0
      roles/lib_zabbix/library/test.yml
  11. 11 7
      roles/os_zabbix/library/zbx_application.py
  12. 0 0
      roles/lib_zabbix/library/zbx_discoveryrule.py
  13. 0 0
      roles/lib_zabbix/library/zbx_host.py
  14. 0 0
      roles/lib_zabbix/library/zbx_hostgroup.py
  15. 3 0
      roles/os_zabbix/library/zbx_item.py
  16. 0 0
      roles/lib_zabbix/library/zbx_itemprototype.py
  17. 20 1
      roles/os_zabbix/library/zbx_mediatype.py
  18. 12 6
      roles/os_zabbix/library/zbx_template.py
  19. 0 1
      roles/os_zabbix/library/zbx_trigger.py
  20. 8 3
      roles/os_zabbix/library/zbx_user.py
  21. 240 0
      roles/lib_zabbix/library/zbx_user_media.py
  22. 69 21
      roles/os_zabbix/library/zbx_usergroup.py
  23. 40 0
      roles/os_zabbix/README.md
  24. 1 0
      roles/os_zabbix/defaults/main.yml
  25. 1 0
      roles/os_zabbix/handlers/main.yml
  26. 0 115
      roles/os_zabbix/library/get_drule.yml
  27. 9 0
      roles/os_zabbix/meta/main.yml
  28. 47 0
      roles/os_zabbix/tasks/clean_zabbix.yml
  29. 56 0
      roles/os_zabbix/tasks/create_template.yml
  30. 11 0
      roles/os_zabbix/tasks/create_user.yml
  31. 30 0
      roles/os_zabbix/tasks/main.yml
  32. 1 0
      roles/os_zabbix/vars/main.yml
  33. 3 1
      playbooks/adhoc/zabbix_setup/vars/template_heartbeat.yml
  34. 0 0
      roles/os_zabbix/vars/template_host.yml
  35. 0 0
      roles/os_zabbix/vars/template_master.yml
  36. 0 0
      roles/os_zabbix/vars/template_node.yml
  37. 53 0
      playbooks/adhoc/zabbix_setup/vars/template_os_linux.yml
  38. 0 0
      roles/os_zabbix/vars/template_router.yml

+ 29 - 0
filter_plugins/oo_zabbix_filters.py

@@ -60,6 +60,17 @@ class FilterModule(object):
         return None
 
     @staticmethod
+    def oo_build_zabbix_collect(data, string, value):
+        ''' Build a list of dicts from a list of data matched on string attribute
+        '''
+        rval = []
+        for item in data:
+            if item[string] == value:
+                rval.append(item)
+
+        return rval
+
+    @staticmethod
     def oo_build_zabbix_list_dict(values, string):
         ''' Build a list of dicts with string as key for each value
         '''
@@ -68,6 +79,22 @@ class FilterModule(object):
             rval.append({string: value})
         return rval
 
+    @staticmethod
+    def oo_remove_attr_from_list_dict(data, attr):
+        ''' Remove a specific attribute from a dict
+        '''
+        attrs = []
+        if isinstance(attr, str):
+            attrs.append(attr)
+        else:
+            attrs = attr
+
+        for attribute in attrs:
+            for _entry in data:
+                _entry.pop(attribute, None)
+
+        return data
+
     def filters(self):
         ''' returns a mapping of filters to methods '''
         return {
@@ -76,4 +103,6 @@ class FilterModule(object):
             "oo_set_zbx_trigger_triggerid": self.oo_set_zbx_trigger_triggerid,
             "oo_build_zabbix_list_dict": self.oo_build_zabbix_list_dict,
             "create_data": self.create_data,
+            "oo_build_zabbix_collect": self.oo_build_zabbix_collect,
+            "oo_remove_attr_from_list_dict": self.oo_remove_attr_from_list_dict,
         }

+ 0 - 51
playbooks/adhoc/zabbix_setup/clean_zabbix.yml

@@ -1,51 +0,0 @@
----
-- hosts: localhost
-  gather_facts: no
-  vars:
-    g_zserver: http://localhost/zabbix/api_jsonrpc.php
-    g_zuser: Admin
-    g_zpassword: zabbix
-  roles:
-  - ../../../roles/os_zabbix
-  post_tasks:
-
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-      name: 'Template Heartbeat'
-    register: templ_heartbeat
-
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-      name: 'Template App Zabbix Server'
-    register: templ_zabbix_server
-
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-      name: 'Template App Zabbix Agent'
-    register: templ_zabbix_agent
-
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-    register: templates
-
-  - debug: var=templ_heartbeat.results
-
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: absent
-    with_items: "{{ templates.results | difference(templ_zabbix_agent.results) | difference(templ_zabbix_server.results) | oo_collect('host') }}"
-    when:  templ_heartbeat.results | length == 0

+ 0 - 57
playbooks/adhoc/zabbix_setup/create_template.yml

@@ -1,57 +0,0 @@
----
-- debug: var=ctp_template
-
-- name: Create Template
-  zbx_template:
-    server: "{{ ctp_zserver }}"
-    user: "{{ ctp_zuser }}"
-    password: "{{ ctp_zpassword }}"
-    name: "{{ ctp_template.name }}"
-  register: ctp_created_template
-
-- debug: var=ctp_created_template
-
-#- name: Create Application
-#  zbxapi:
-#    server: "{{ ctp_zserver }}"
-#    user: "{{ ctp_zuser }}"
-#    password: "{{ ctp_zpassword }}"
-#    zbx_class: Application
-#    state: present
-#    params:
-#      name: "{{ ctp_template.application.name}}"
-#      hostid: "{{ ctp_created_template.results[0].templateid }}"
-#      search:
-#        name: "{{ ctp_template.application.name}}"
-#  register: ctp_created_application
-
-#- debug: var=ctp_created_application
-
-- name: Create Items
-  zbx_item:
-    server: "{{ ctp_zserver }}"
-    user: "{{ ctp_zuser }}"
-    password: "{{ ctp_zpassword }}"
-    key: "{{ item.key }}"
-    name: "{{ item.name | default(item.key, true) }}"
-    value_type: "{{ item.value_type | default('int') }}"
-    template_name: "{{ ctp_template.name }}"
-  with_items: ctp_template.zitems
-  register: ctp_created_items
-
-#- debug: var=ctp_created_items
-
-- name: Create Triggers
-  zbx_trigger:
-    server: "{{ ctp_zserver }}"
-    user: "{{ ctp_zuser }}"
-    password: "{{ ctp_zpassword }}"
-    description: "{{ item.description }}"
-    expression: "{{ item.expression }}"
-    priority: "{{ item.priority }}"
-  with_items: ctp_template.ztriggers
-  when: ctp_template.ztriggers is defined
-
-#- debug: var=ctp_created_triggers
-
-

+ 0 - 31
playbooks/adhoc/zabbix_setup/create_user.yml

@@ -1,31 +0,0 @@
----
-# export PYTHONPATH='/usr/lib/python2.7/site-packages/:/home/kwoodson/git/openshift-tools'
-# ansible-playbook -e 'cli_password=zabbix' -e 'cli_new_password=new-zabbix' create_user.yml
-- hosts: localhost
-  gather_facts: no
-  vars_files:
-  - vars/template_heartbeat.yml
-  - vars/template_os_linux.yml
-  vars:
-    g_zserver: http://localhost/zabbix/api_jsonrpc.php
-    g_zuser: admin
-    g_zpassword: "{{ cli_password }}"
-  roles:
-  - ../../../roles/os_zabbix
-  post_tasks:
-  - zbx_user:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-    register: users
-
-  - debug: var=users
-
-  - name: Update zabbix creds for admin
-    zbx_user:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      alias: Admin
-      passwd: "{{ cli_new_password | default(g_zpassword, true) }}"

+ 0 - 1
playbooks/adhoc/zabbix_setup/filter_plugins

@@ -1 +0,0 @@
-../../../filter_plugins

+ 0 - 1
playbooks/adhoc/zabbix_setup/roles

@@ -1 +0,0 @@
-../../../roles/

+ 0 - 38
playbooks/adhoc/zabbix_setup/setup_zabbix.yml

@@ -1,38 +0,0 @@
----
-- hosts: localhost
-  gather_facts: no
-  vars_files:
-  - vars/template_heartbeat.yml
-  - vars/template_os_linux.yml
-  vars:
-    g_zserver: http://localhost/zabbix/api_jsonrpc.php
-    g_zuser: Admin
-    g_zpassword: zabbix
-  roles:
-  - ../../../roles/os_zabbix
-  post_tasks:
-  - zbx_template:
-      server: "{{ g_zserver }}"
-      user: "{{ g_zuser }}"
-      password: "{{ g_zpassword }}"
-      state: list
-    register: templates
-
-  - debug: var=templates
-
-  - name: Include Template
-    include: create_template.yml
-    vars:
-      ctp_template: "{{ g_template_heartbeat }}"
-      ctp_zserver: "{{ g_zserver }}"
-      ctp_zuser: "{{ g_zuser }}"
-      ctp_zpassword: "{{ g_zpassword }}"
-
-  - name: Include Template
-    include: create_template.yml
-    vars:
-      ctp_template: "{{ g_template_os_linux }}"
-      ctp_zserver: "{{ g_zserver }}"
-      ctp_zuser: "{{ g_zuser }}"
-      ctp_zpassword: "{{ g_zpassword }}"
-

+ 38 - 0
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

roles/os_zabbix/library/__init__.py → roles/lib_zabbix/library/__init__.py


roles/os_zabbix/library/test.yml → roles/lib_zabbix/library/test.yml


+ 11 - 7
roles/os_zabbix/library/zbx_application.py

@@ -60,8 +60,8 @@ def main():
     module = AnsibleModule(
         argument_spec=dict(
             server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
-            user=dict(default=None, type='str'),
-            password=dict(default=None, type='str'),
+            user=dict(default=os.environ['ZABBIX_USER'], type='str'),
+            password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'),
             name=dict(default=None, type='str'),
             template_name=dict(default=None, type='list'),
             debug=dict(default=False, type='bool'),
@@ -70,10 +70,10 @@ def main():
         #supports_check_mode=True
     )
 
-    user = module.params.get('user', os.environ['ZABBIX_USER'])
-    passwd = module.params.get('password', os.environ['ZABBIX_PASSWORD'])
-
-    zapi = ZabbixAPI(ZabbixConnection(module.params['server'], user, passwd, module.params['debug']))
+    zapi = ZabbixAPI(ZabbixConnection(module.params['server'],
+                                      module.params['user'],
+                                      module.params['password'],
+                                      module.params['debug']))
 
     #Set the instance and the application for the rest of the calls
     zbx_class_name = 'application'
@@ -83,7 +83,7 @@ def main():
     # get a applicationid, see if it exists
     content = zapi.get_content(zbx_class_name,
                                'get',
-                               {'search': {'host': aname},
+                               {'search': {'name': aname},
                                 'selectHost': 'hostid',
                                })
     if state == 'list':
@@ -121,6 +121,10 @@ def main():
         # 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,

roles/os_zabbix/library/zbx_discoveryrule.py → roles/lib_zabbix/library/zbx_discoveryrule.py


roles/os_zabbix/library/zbx_host.py → roles/lib_zabbix/library/zbx_host.py


roles/os_zabbix/library/zbx_hostgroup.py → roles/lib_zabbix/library/zbx_hostgroup.py


+ 3 - 0
roles/os_zabbix/library/zbx_item.py

@@ -63,6 +63,8 @@ def get_value_type(value_type):
 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}})
@@ -118,6 +120,7 @@ def main():
                                {'search': {'key_': key},
                                 'selectApplications': 'applicationid',
                                })
+
     if state == 'list':
         module.exit_json(changed=False, results=content['result'], state="list")
 

roles/os_zabbix/library/zbx_itemprototype.py → roles/lib_zabbix/library/zbx_itemprototype.py


+ 20 - 1
roles/os_zabbix/library/zbx_mediatype.py

@@ -40,6 +40,7 @@ def exists(content, key='result'):
         return False
 
     return True
+
 def get_mtype(mtype):
     '''
     Transport used by the media type.
@@ -80,6 +81,10 @@ def main():
             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'),
             debug=dict(default=False, type='bool'),
             state=dict(default='present', type='str'),
         ),
@@ -109,16 +114,30 @@ def main():
         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['media_type']),
+                  '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

+ 12 - 6
roles/os_zabbix/library/zbx_template.py

@@ -48,8 +48,8 @@ def main():
     module = AnsibleModule(
         argument_spec=dict(
             server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
-            user=dict(default=None, type='str'),
-            password=dict(default=None, type='str'),
+            user=dict(default=os.environ['ZABBIX_USER'], type='str'),
+            password=dict(default=os.environ['ZABBIX_PASSWORD'], type='str'),
             name=dict(default=None, type='str'),
             debug=dict(default=False, type='bool'),
             state=dict(default='present', type='str'),
@@ -57,10 +57,10 @@ def main():
         #supports_check_mode=True
     )
 
-    user = module.params.get('user', os.environ['ZABBIX_USER'])
-    passwd = module.params.get('password', os.environ['ZABBIX_PASSWORD'])
-
-    zbc = ZabbixConnection(module.params['server'], user, passwd, module.params['debug'])
+    zbc = ZabbixConnection(module.params['server'],
+                           module.params['user'],
+                           module.params['password'],
+                           module.params['debug'])
     zapi = ZabbixAPI(zbc)
 
     #Set the instance and the template for the rest of the calls
@@ -84,6 +84,12 @@ def main():
         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")
 

+ 0 - 1
roles/os_zabbix/library/zbx_trigger.py

@@ -41,7 +41,6 @@ def exists(content, key='result'):
 
     return True
 
-
 def get_priority(priority):
     ''' determine priority
     '''

+ 8 - 3
roles/os_zabbix/library/zbx_user.py

@@ -88,7 +88,7 @@ def main():
             surname=dict(default=None, type='str'),
             user_type=dict(default=None, type='str'),
             passwd=dict(default=None, type='str'),
-            usergroups=dict(default=[], type='list'),
+            user_groups=dict(default=[], type='list'),
             debug=dict(default=False, type='bool'),
             state=dict(default='present', type='str'),
         ),
@@ -116,7 +116,7 @@ def main():
         module.exit_json(changed=False, results=content['result'], state="list")
 
     if state == 'absent':
-        if not exists(content):
+        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]])
@@ -125,7 +125,7 @@ def main():
     if state == 'present':
         params = {'alias': alias,
                   'passwd': module.params['passwd'],
-                  'usrgrps': get_usergroups(zapi, module.params['usergroups']),
+                  'usrgrps': get_usergroups(zapi, module.params['user_groups']),
                   'name': module.params['name'],
                   'surname': module.params['surname'],
                   'type': get_usertype(module.params['user_type']),
@@ -146,6 +146,11 @@ def main():
             if key == 'passwd':
                 differences[key] = value
 
+            elif 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
 

+ 240 - 0
roles/lib_zabbix/library/zbx_user_media.py

@@ -0,0 +1,240 @@
+#!/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 = {'userids': 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 main():
+    '''
+    Ansible zabbix module for mediatype
+    '''
+
+    module = AnsibleModule(
+        argument_spec=dict(
+            server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+            user=dict(default=None, type='str'),
+            password=dict(default=None, type='str'),
+            name=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'),
+            debug=dict(default=False, type='bool'),
+            state=dict(default='present', type='str'),
+        ),
+        #supports_check_mode=True
+    )
+
+    user = module.params.get('user', os.environ['ZABBIX_USER'])
+    passwd = module.params.get('password', os.environ['ZABBIX_PASSWORD'])
+
+    zapi = ZabbixAPI(ZabbixConnection(module.params['server'], user, passwd, module.params['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['name'])
+    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")
+
+        # TODO: Do we remove all the queried results?  This could be catastrophic or desired.
+        #ids = [med[idname] for med in content['result']]
+        ids = [content['result'][0][idname]]
+        content = zapi.get_content(zbx_class_name, 'deletemedia', ids)
+
+        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 = None
+        if module.params['mediatype']:
+            mtypeid = get_mtype(zapi, module.params['mediatype'])
+        elif module.params['mediatype_desc']:
+            mtypeid = get_mtype(zapi, 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
+        differences = {'medias': [], 'users': {}}
+        for media in params['medias']:
+            m_result = find_media(content['result'], media)
+            if not m_result:
+                differences['medias'].append(media)
+
+        if not differences['medias']:
+            module.exit_json(changed=False, results=content['result'], state="present")
+
+        for user in params['users']:
+            differences['users']['userid'] = user['userids']
+
+        # We have differences and need to update
+        content = zapi.get_content(zbx_class_name, 'updatemedia', 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()

+ 69 - 21
roles/os_zabbix/library/zbx_usergroup.py

@@ -44,6 +44,9 @@ def exists(content, key='result'):
 def get_rights(zapi, rights):
     '''Get rights
     '''
+    if rights == None:
+        return None
+
     perms = []
     for right in rights:
         hstgrp = right.keys()[0]
@@ -59,16 +62,49 @@ def get_rights(zapi, rights):
                           'permission': permission})
     return perms
 
-def get_userids(zapi, users):
-    ''' Get userids from user aliases
+def get_gui_access(access):
+    ''' Return the gui_access for a usergroup
     '''
-    userids = []
-    for alias in users:
-        content = zapi.get_content('user', 'get', {'search': {'alias': alias}})
-        if content['result']:
-            userids.append(content['result'][0]['userid'])
+    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 userids
+    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
@@ -79,21 +115,24 @@ def main():
     module = AnsibleModule(
         argument_spec=dict(
             server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
-            user=dict(default=None, type='str'),
-            password=dict(default=None, type='str'),
-            name=dict(default=None, type='str'),
-            rights=dict(default=[], type='list'),
-            users=dict(default=[], type='list'),
+            user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+            password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+            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'),
             debug=dict(default=False, type='bool'),
             state=dict(default='present', type='str'),
         ),
         #supports_check_mode=True
     )
 
-    user = module.params.get('user', os.environ['ZABBIX_USER'])
-    passwd = module.params.get('password', os.environ['ZABBIX_PASSWORD'])
-
-    zapi = ZabbixAPI(ZabbixConnection(module.params['server'], user, passwd, module.params['debug']))
+    zapi = ZabbixAPI(ZabbixConnection(module.params['server'],
+                                      module.params['user'],
+                                      module.params['password'],
+                                      module.params['debug']))
 
     zbx_class_name = 'usergroup'
     idname = "usrgrpid"
@@ -112,15 +151,24 @@ def main():
         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']),
-                  'userids': get_userids(zapi, module.params['users']),
+                  '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)
@@ -133,9 +181,9 @@ def main():
             if key == 'rights':
                 differences['rights'] = value
 
-            elif key == 'userids' and zab_results.has_key('users'):
-                if zab_results['users'] != value:
-                    differences['userids'] = 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

+ 40 - 0
roles/os_zabbix/README.md

@@ -0,0 +1,40 @@
+os_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
+--------------
+
+zab_server
+zab_username
+zab_password
+
+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

+ 1 - 0
roles/os_zabbix/defaults/main.yml

@@ -0,0 +1 @@
+---

+ 1 - 0
roles/os_zabbix/handlers/main.yml

@@ -0,0 +1 @@
+---

+ 0 - 115
roles/os_zabbix/library/get_drule.yml

@@ -1,115 +0,0 @@
----
-# This is a test playbook to create one of each of the zabbix ansible modules.
-# ensure that the zbxapi module is installed
-# ansible-playbook test.yml
-- name: Test zabbix ansible module
-  hosts: localhost
-  gather_facts: no
-  vars:
-#zbx_server: https://localhost/zabbix/api_jsonrpc.php
-#zbx_user: Admin
-#zbx_password: zabbix
-
-  pre_tasks:
-  - name: Template Discovery rules
-    zbx_template:
-      server: "{{ zbx_server }}"
-      user: "{{ zbx_user }}"
-      password: "{{ zbx_password }}"
-      name: 'Template App HaProxy'
-      state: list
-    register: template_output
-
-  - debug: var=template_output
-
-  - name: Discovery rules
-    zbx_discovery_rule:
-      server: "{{ zbx_server }}"
-      user: "{{ zbx_user }}"
-      password: "{{ zbx_password }}"
-      name: 'haproxy.discovery sender'
-      state: list
-    register: drule
-
-  - debug: var=drule
-
-#  - name: Create an application
-#    zbx_application:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      name: 'Test App'
-#      template_name: "test template"
-#    register: item_output
-#
-#  - name: Create an item
-#    zbx_item:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      name: 'test item'
-#      key: 'kenny.item.1'
-#      applications:
-#      - 'Test App'
-#      template_name: "test template"
-#    register: item_output
-#
-#  - debug: var=item_output
-#
-#  - name: Create an trigger
-#    zbx_trigger:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      expression: '{test template:kenny.item.1.last()}>2'
-#      description: 'Kenny desc'
-#    register: trigger_output
-#
-#  - debug: var=trigger_output
-#
-#  - name: Create a hostgroup
-#    zbx_hostgroup:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      name: 'kenny hostgroup'
-#    register: hostgroup_output
-#
-#  - debug: var=hostgroup_output
-#
-#  - name: Create a host
-#    zbx_host:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      name: 'kenny host'
-#      template_names:
-#      - test template
-#      hostgroup_names:
-#      - kenny hostgroup
-#    register: host_output
-#
-#  - debug: var=host_output
-#
-#  - name: Create a usergroup
-#    zbx_usergroup:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      name: kenny usergroup
-#      rights:
-#      - 'kenny hostgroup': rw
-#    register: usergroup_output
-#
-#  - debug: var=usergroup_output
-#
-#  - name: Create a user
-#    zbx_user:
-#      server: "{{ zbx_server }}"
-#      user: "{{ zbx_user }}"
-#      password: "{{ zbx_password }}"
-#      alias: kwoodson
-#      state: list
-#    register: user_output
-#
-#  - debug: var=user_output

+ 9 - 0
roles/os_zabbix/meta/main.yml

@@ -0,0 +1,9 @@
+---
+galaxy_info:
+  author: OpenShift
+  description:  ZabbixAPI
+  company: Red Hat, Inc
+  license: ASL 2.0
+  min_ansible_version: 1.2
+dependencies:
+- lib_zabbix

+ 47 - 0
roles/os_zabbix/tasks/clean_zabbix.yml

@@ -0,0 +1,47 @@
+---
+- name: CLEAN List template for heartbeat
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    state: list
+    name: 'Template Heartbeat'
+  register: templ_heartbeat
+
+- name: CLEAN List template app zabbix server
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    state: list
+    name: 'Template App Zabbix Server'
+  register: templ_zabbix_server
+
+- name: CLEAN List template app zabbix server
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    state: list
+    name: 'Template App Zabbix Agent'
+  register: templ_zabbix_agent
+
+- name: CLEAN List all templates
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    state: list
+  register: templates
+
+- debug: var=templ_heartbeat.results
+
+- name: Remove templates if heartbeat template is missing
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    name: "{{ item }}"
+    state: absent
+  with_items: "{{ templates.results | difference(templ_zabbix_agent.results) | difference(templ_zabbix_server.results) | oo_collect('host') }}"
+  when:  templ_heartbeat.results | length == 0

+ 56 - 0
roles/os_zabbix/tasks/create_template.yml

@@ -0,0 +1,56 @@
+---
+- debug: var=template
+
+- name: Template Create Template
+  zbx_template:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    name: "{{ template.name }}"
+  register: created_template
+
+- debug: var=created_template
+
+- name: Create Application
+  zbx_application:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    password: "{{ password }}"
+    name: "{{ item }}"
+    template_name: "{{ template.name }}"
+  with_items: template.zapplications
+  register: created_application
+  when: template.zapplications is defined
+
+- debug: var=created_application
+
+- name: Create Items
+  zbx_item:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    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.application }}"
+  with_items: template.zitems
+  register: created_items
+  when: template.zitems is defined
+
+#- debug: var=ctp_created_items
+
+- name: Create Triggers
+  zbx_trigger:
+    server: "{{ server }}"
+    user: "{{ user }}"
+    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
+
+

+ 11 - 0
roles/os_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

+ 30 - 0
roles/os_zabbix/tasks/main.yml

@@ -0,0 +1,30 @@
+---
+- name: Main List all templates
+  zbx_template:
+    server: "{{ ozb_server }}"
+    user: "{{ ozb_user }}"
+    password: "{{ ozb_password }}"
+    state: list
+  register: templates
+
+- debug: var=templates
+
+- include_vars: template_heartbeat.yml
+- include_vars: template_os_linux.yml
+
+- name: Include Template Heartbeat
+  include: create_template.yml
+  vars:
+    template: "{{ g_template_heartbeat }}"
+    server: "{{ ozb_server }}"
+    user: "{{ ozb_user }}"
+    password: "{{ ozb_password }}"
+
+#- name: Include Template os_linux
+#  include: create_template.yml
+#  vars:
+#    template: "{{ g_template_os_linux }}"
+#    server: "{{ ozb_server }}"
+#    user: "{{ ozb_user }}"
+#    password: "{{ ozb_password }}"
+

+ 1 - 0
roles/os_zabbix/vars/main.yml

@@ -0,0 +1 @@
+---

+ 3 - 1
playbooks/adhoc/zabbix_setup/vars/template_heartbeat.yml

@@ -1,9 +1,11 @@
 ---
 g_template_heartbeat:
   name: Template Heartbeat
+  zapplications:
+  - Heartbeat
   zitems:
   - name: Heartbeat Ping
-    hostid:
+    application: Heartbeat
     key: heartbeat.ping
   ztriggers:
   - description: 'Heartbeat.ping has failed on {HOST.NAME}'

playbooks/adhoc/zabbix_setup/vars/template_host.yml → roles/os_zabbix/vars/template_host.yml


playbooks/adhoc/zabbix_setup/vars/template_master.yml → roles/os_zabbix/vars/template_master.yml


playbooks/adhoc/zabbix_setup/vars/template_node.yml → roles/os_zabbix/vars/template_node.yml


+ 53 - 0
playbooks/adhoc/zabbix_setup/vars/template_os_linux.yml

@@ -1,90 +1,143 @@
 ---
 g_template_os_linux:
   name: Template OS Linux
+  zapplications:
+  - Disk
+  - Memory
+  - Kernel
   zitems:
   - key: kernel.uname.sysname
+    application: Kernel
     value_type: string
 
   - key: kernel.all.cpu.wait.total
+    application: Kernel
     value_type: int
 
   - key: kernel.all.cpu.irq.hard
+    application: Kernel
     value_type: int
 
   - key: kernel.all.cpu.idle
+    application: Kernel
     value_type: int
 
   - key: kernel.uname.distro
+    application: Kernel
     value_type: string
 
   - key: kernel.uname.nodename
+    application: Kernel
     value_type: string
 
   - key: kernel.all.cpu.irq.soft
+    application: Kernel
     value_type: int
 
   - key: kernel.all.load.15_minute
+    application: Kernel
     value_type: float
 
   - key: kernel.all.cpu.sys
+    application: Kernel
     value_type: int
 
   - key: kernel.all.load.5_minute
+    application: Kernel
     value_type: float
 
   - key: mem.freemem
+    application: Memory
     value_type: int
 
   - key: kernel.all.cpu.nice
+    application: Kernel
     value_type: int
 
   - key: mem.util.bufmem
+    application: Memory
     value_type: int
 
   - key: swap.used
+    application: Memory
     value_type: int
 
   - key: kernel.all.load.1_minute
+    application: Kernel
     value_type: float
 
   - key: kernel.uname.version
+    application: Kernel
     value_type: string
 
   - key: swap.length
+    application: Memory
     value_type: int
 
   - key: mem.physmem
+    application: Memory
     value_type: int
 
   - key: kernel.all.uptime
+    application: Kernel
     value_type: int
 
   - key: swap.free
+    application: Memory
     value_type: int
 
   - key: mem.util.used
+    application: Memory
     value_type: int
 
   - key: kernel.all.cpu.user
+    application: Kernel
     value_type: int
 
   - key: kernel.uname.machine
+    application: Kernel
     value_type: string
 
   - key: hinv.ncpu
+    application: Kernel
     value_type: int
 
   - key: mem.util.cached
+    application: Memory
     value_type: int
 
   - key: kernel.all.cpu.steal
+    application: Kernel
     value_type: int
 
   - key: kernel.all.pswitch
+    application: Kernel
     value_type: int
 
   - key: kernel.uname.release
+    application: Kernel
     value_type: string
 
   - key: proc.nprocs
+    application: Kernel
     value_type: int
+
+  - key: filesys.avail
+    application: Disk
+    value_type: int
+
+  - key: filesys.capacity
+    application: Disk
+    value_type: int
+
+  - key: filesys.free
+    application: Disk
+    value_type: int
+
+  - key: filesys.full
+    application: Disk
+    value_type: float
+
+  - key: filesys.used
+    application: Disk
+    value_type: float

playbooks/adhoc/zabbix_setup/vars/template_router.yml → roles/os_zabbix/vars/template_router.yml