예제 #1
0
    def check_if_mediatype_exists(self, name):
        """Checks if mediatype exists.

        Args:
            name: Zabbix mediatype name

        Returns:
            Tuple of (True, `id of the mediatype`) if mediatype exists, (False, None) otherwise
        """
        filter_key_name = 'description'
        if LooseVersion(self._zbx_api_version) >= LooseVersion('4.4'):
            # description key changed to name key from zabbix 4.4
            filter_key_name = 'name'

        try:
            mediatype_list = self._zapi.mediatype.get({
                'output': 'extend',
                'filter': {filter_key_name: [name]}
            })
            if len(mediatype_list) < 1:
                return False, None
            else:
                return True, mediatype_list[0]['mediatypeid']
        except Exception as e:
            self._module.fail_json(msg="Failed to get ID of the mediatype '{name}': {e}".format(name=name, e=e))
예제 #2
0
    def convert_user_medias_parameter_types(self, user_medias):
        copy_user_medias = copy.deepcopy(user_medias)
        for user_media in copy_user_medias:
            media_types = self._zapi.mediatype.get({'output': 'extend'})
            for media_type in media_types:
                if LooseVersion(self._zbx_api_version) < LooseVersion('4.4'):
                    if media_type['description'] == user_media['mediatype']:
                        user_media['mediatypeid'] = media_type['mediatypeid']
                        break
                else:
                    if media_type['name'] == user_media['mediatype']:
                        user_media['mediatypeid'] = media_type['mediatypeid']
                        break

            if 'mediatypeid' not in user_media:
                self._module.fail_json(msg="Media type not found: %s" % user_media['mediatype'])
            else:
                del user_media['mediatype']

            severity_binary_number = ''
            for severity_key in 'disaster', 'high', 'average', 'warning', 'information', 'not_classified':
                if user_media['severity'][severity_key]:
                    severity_binary_number = severity_binary_number + '1'
                else:
                    severity_binary_number = severity_binary_number + '0'
            user_media['severity'] = str(int(severity_binary_number, 2))

            if user_media['active']:
                user_media['active'] = '0'
            else:
                user_media['active'] = '1'

        return copy_user_medias
예제 #3
0
    def alias_key(self):
        """ Returns the key name for 'alias', which has been renamed to
        'username' in Zabbix 5.4.

        """
        if LooseVersion(self._zbx_api_version) >= LooseVersion('5.4'):
            return 'username'

        return 'alias'
예제 #4
0
 def create_host_macro(self, macro_name, macro_value, macro_type, host_id):
     try:
         if self._module.check_mode:
             self._module.exit_json(changed=True)
         if LooseVersion(self._zbx_api_version) >= LooseVersion('5.0'):
             self._zapi.usermacro.create({'hostid': host_id, 'macro': macro_name, 'value': macro_value, 'type': macro_type})
         else:
             self._zapi.usermacro.create({'hostid': host_id, 'macro': macro_name, 'value': macro_value})
         self._module.exit_json(changed=True, result="Successfully added host macro %s" % macro_name)
     except Exception as e:
         self._module.fail_json(msg="Failed to create host macro %s: %s" % (macro_name, e))
예제 #5
0
 def create_global_macro(self, macro_name, macro_value, macro_type,
                         macro_description):
     try:
         if self._module.check_mode:
             self._module.exit_json(changed=True)
         if LooseVersion(self._zbx_api_version) < LooseVersion('4.4.0'):
             self._zapi.usermacro.createglobal({
                 'macro': macro_name,
                 'value': macro_value
             })
             self._module.exit_json(
                 changed=True,
                 result="Successfully added global macro %s" % macro_name)
         if LooseVersion(self._zbx_api_version) >= LooseVersion('4.4.0'):
             if LooseVersion(
                     self._zbx_api_version) >= LooseVersion('5.0.0'):
                 if LooseVersion(self._zbx_api_version) >= LooseVersion(
                         '5.0.0') and LooseVersion(
                             self._zbx_api_version) < LooseVersion('5.4.0'):
                     if macro_type == '2':
                         macro_type = '0'
                 self._zapi.usermacro.createglobal({
                     'macro':
                     macro_name,
                     'value':
                     macro_value,
                     'type':
                     macro_type,
                     'description':
                     macro_description
                 })
                 self._module.exit_json(
                     changed=True,
                     result="Successfully added global macro %s" %
                     macro_name)
             else:
                 self._zapi.usermacro.createglobal({
                     'macro':
                     macro_name,
                     'value':
                     macro_value,
                     'description':
                     macro_description
                 })
                 self._module.exit_json(
                     changed=True,
                     result="Successfully added global macro %s" %
                     macro_name)
     except Exception as e:
         self._module.fail_json(msg="Failed to create global macro %s: %s" %
                                (macro_name, e))
예제 #6
0
    def filter_template(self, template_json):
        # Filter the template json to contain only the keys we will update
        keep_keys = set(['graphs', 'templates', 'triggers', 'value_maps'])
        unwanted_keys = set(template_json['zabbix_export']) - keep_keys
        for unwanted_key in unwanted_keys:
            del template_json['zabbix_export'][unwanted_key]

        # Versions older than 2.4 do not support description field within template
        desc_not_supported = False
        if LooseVersion(self._zbx_api_version) < LooseVersion('2.4'):
            desc_not_supported = True

        # Filter empty attributes from template object to allow accurate comparison
        for template in template_json['zabbix_export']['templates']:
            for key in list(template.keys()):
                if not template[key] or (key == 'description'
                                         and desc_not_supported):
                    template.pop(key)

        return template_json
예제 #7
0
 def update_host_macro(self, host_macro_obj, macro_name, macro_value, macro_type):
     host_macro_id = host_macro_obj['hostmacroid']
     if host_macro_obj['macro'] == macro_name:
         if LooseVersion(self._zbx_api_version) >= LooseVersion('5.0'):
             # no change only when macro type == 0. when type = 1 or 2 zabbix will not output value of it.
             if host_macro_obj['type'] == '0' and macro_type == '0' and host_macro_obj['value'] == macro_value:
                 self._module.exit_json(changed=False, result="Host macro %s already up to date" % macro_name)
         else:
             if host_macro_obj['value'] == macro_value:
                 self._module.exit_json(changed=False, result="Host macro %s already up to date" % macro_name)
     try:
         if self._module.check_mode:
             self._module.exit_json(changed=True)
         if LooseVersion(self._zbx_api_version) >= LooseVersion('5.0'):
             self._zapi.usermacro.update({'hostmacroid': host_macro_id, 'value': macro_value, 'type': macro_type})
         else:
             self._zapi.usermacro.update({'hostmacroid': host_macro_id, 'value': macro_value})
         self._module.exit_json(changed=True, result="Successfully updated host macro %s" % macro_name)
     except Exception as e:
         self._module.fail_json(msg="Failed to update host macro %s: %s" % (macro_name, e))
예제 #8
0
    def compile_interface_params(self, new_interface):
        old_interface = {}
        if 'interface' in self.existing_data and \
           len(self.existing_data['interface']) > 0:
            old_interface = self.existing_data['interface']

        for item in ['type', 'main']:
            new_interface.pop(item, False)

        if LooseVersion(self._zbx_api_version) >= LooseVersion('5.0.0'):
            if old_interface:
                old_interface['details'] = str(old_interface['details'])

        final_interface = old_interface.copy()
        final_interface.update(new_interface)
        final_interface = dict((k, str(v)) for k, v in final_interface.items())

        if final_interface != old_interface:
            return final_interface
        else:
            return {}
예제 #9
0
    def update_user(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout,
                    refresh, rows_per_page, url, user_medias, user_type, timezone, role_name, override_passwd):

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        user_ids = {}

        request_data = {
            'userid': zbx_user[0]['userid'],
            self.alias_key(): alias,
            'name': name,
            'surname': surname,
            'usrgrps': user_group_ids,
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }

        if override_passwd:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name) if role_name else None
            request_data['timezone'] = timezone

        request_data, _del_keys = helper_normalize_data(request_data)

        # In the case of zabbix 3.2 or less, it is necessary to use updatemedia method to update media.
        if LooseVersion(self._zbx_api_version) <= LooseVersion('3.2'):
            try:
                user_ids = self._zapi.user.update(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e))

            try:
                if user_medias:
                    user_ids = self._zapi.user.updatemedia({
                        'users': [{'userid': zbx_user[0]['userid']}],
                        'medias': user_medias
                    })
            except Exception as e:
                self._module.fail_json(msg="Failed to update user medias %s: %s" % (alias, e))

        if LooseVersion(self._zbx_api_version) >= LooseVersion('3.4'):
            try:
                if user_medias:
                    request_data['user_medias'] = user_medias
                user_ids = self._zapi.user.update(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e))

        return user_ids
예제 #10
0
 def _get_element_type(self, data):
     types = {'host': 0, 'sysmap': 1, 'trigger': 2, 'group': 3, 'image': 4}
     element_type = {
         'elementtype': types['image'],
     }
     if LooseVersion(self._zbx_api_version) < LooseVersion('3.4'):
         element_type.update({
             'elementid': "0",
         })
     for type_name, type_id in sorted(types.items()):
         field_name = 'zbx_' + type_name
         if field_name in data:
             method_name = '_get_' + type_name + '_id'
             element_name = remove_quotes(data[field_name])
             get_element_id = getattr(self, method_name, None)
             if get_element_id:
                 elementid = get_element_id(element_name)
                 if elementid and int(elementid) > 0:
                     element_type.update({
                         'elementtype': type_id,
                         'label': element_name
                     })
                     if LooseVersion(
                             self._zbx_api_version) < LooseVersion('3.4'):
                         element_type.update({
                             'elementid': elementid,
                         })
                     else:
                         element_type.update({
                             'elements': [{
                                 type_name + 'id': elementid,
                             }],
                         })
                     break
                 else:
                     self._module.fail_json(
                         msg="Failed to find id for %s '%s'" %
                         (type_name, element_name))
     return element_type
예제 #11
0
 def _is_selements_equal(self, generated_selements, exist_selements):
     if len(generated_selements) != len(exist_selements):
         return False
     generated_selements_sorted = sorted(
         generated_selements, key=itemgetter(*self.selements_sort_keys))
     exist_selements_sorted = sorted(
         exist_selements, key=itemgetter(*self.selements_sort_keys))
     for (generated_selement,
          exist_selement) in zip(generated_selements_sorted,
                                 exist_selements_sorted):
         if LooseVersion(self._zbx_api_version) >= LooseVersion('3.4'):
             if not self._is_elements_equal(
                     generated_selement.get('elements', []),
                     exist_selement.get('elements', [])):
                 return False
         if not self._is_dicts_equal(generated_selement, exist_selement,
                                     ['selementid']):
             return False
         if not self._is_urls_equal(generated_selement.get('urls', []),
                                    exist_selement.get('urls', [])):
             return False
     return True
예제 #12
0
    def get_usergroups_by_name(self, usrgrps):
        params = {
            'output': ['usrgrpid', 'name', 'gui_access'],
            'filter': {
                'name': usrgrps
            }
        }
        res = self._zapi.usergroup.get(params)
        if res:
            ids = [{'usrgrpid': g['usrgrpid']} for g in res]
            # User can be created password-less only when all groups are of non-internal
            # authentication types
            # 0 = use system default authentication method
            # 1 = use internal authentication
            # 2 = use LDAP authentication
            # 3 = disable access to the frontend

            if bool([g for g in res if g['gui_access'] == '1']):
                require_password = True
            elif bool([g for g in res if g['gui_access'] == '2' or g['gui_access'] == '3']):
                require_password = False
            elif bool([g for g in res if g['gui_access'] == '0']):
                # Zabbix API for versions < 5.2 does not have a way to query the default auth type
                # so we must assume its set to internal
                if LooseVersion(self._zbx_api_version) >= LooseVersion('5.2'):
                    default_authentication = self.get_default_authentication()
                    require_password = True if default_authentication == 'internal' else False
                else:
                    default_authentication = "internal"
                    require_password = True

            not_found_groups = set(usrgrps) - set([g['name'] for g in res])
            if not_found_groups:
                self._module.fail_json(msg='User groups not found: %s' % not_found_groups)
            return ids, require_password
        else:
            self._module.fail_json(msg='No user groups found')
예제 #13
0
    def get_update_params(self, mediatype_id, **kwargs):
        """Filters only the parameters that are different and need to be updated.

        Args:
            mediatype_id (int): ID of the mediatype to be updated.
            **kwargs: Parameters for the new mediatype.

        Returns:
            A tuple where the first element is a dictionary of parameters
            that need to be updated and the second one is a dictionary
            returned by diff() function with
            existing mediatype data and new params passed to it.
        """
        get_params = {'output': 'extend', 'mediatypeids': [mediatype_id]}
        if LooseVersion(self._zbx_api_version) >= LooseVersion('5.0'):
            get_params.update({'selectMessageTemplates': 'extend'})

        existing_mediatype = self._zapi.mediatype.get(get_params)[0]

        if existing_mediatype['type'] != kwargs['type']:
            return kwargs, diff(existing_mediatype, kwargs)
        else:
            params_to_update = {}
            for key in kwargs:
                # sort list of parameters to prevent mismatch due to reordering
                if key == 'parameters' and (kwargs[key] != [] or existing_mediatype[key] != []):
                    kwargs[key] = sorted(kwargs[key], key=lambda x: x['name'])
                    existing_mediatype[key] = sorted(existing_mediatype[key], key=lambda x: x['name'])

                if key == 'message_templates' and (kwargs[key] != [] or existing_mediatype[key] != []):
                    kwargs[key] = sorted(kwargs[key], key=lambda x: x['subject'])
                    existing_mediatype[key] = sorted(existing_mediatype[key], key=lambda x: x['subject'])

                if (not (kwargs[key] is None and existing_mediatype[key] == '')) and kwargs[key] != existing_mediatype[key]:
                    params_to_update[key] = kwargs[key]
            return params_to_update, diff(existing_mediatype, kwargs)
예제 #14
0
    def add_user(self, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout, refresh,
                 rows_per_page, url, user_medias, user_type, require_password, timezone, role_name):

        if role_name is None and LooseVersion(self._zbx_api_version) >= LooseVersion('5.2'):
            # This variable is to set the default value because the module must have a backward-compatible.
            # The default value will be removed at the version 2.0.0.
            # https://github.com/ansible-collections/community.zabbix/pull/382
            role_name = "User role"

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        user_ids = {}

        request_data = {
            self.alias_key(): alias,
            'name': name,
            'surname': surname,
            'usrgrps': user_group_ids,
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }
        if user_medias:
            request_data['user_medias'] = user_medias

        if LooseVersion(self._zbx_api_version) < LooseVersion('4.0') or require_password:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name)
            request_data['timezone'] = timezone

        request_data, _del_keys = helper_normalize_data(request_data)

        diff_params = {}
        if not self._module.check_mode:
            try:
                user_ids = self._zapi.user.create(request_data)
            except Exception as e:
                self._module.fail_json(msg="Failed to create user %s: %s" % (alias, e))
        else:
            diff_params = {
                "before": "",
                "after": request_data
            }

        return user_ids, diff_params
예제 #15
0
    def import_template(self, template_content, template_type='json'):
        if self._module.check_mode:
            self._module.exit_json(changed=True)

        # rules schema latest version
        update_rules = {
            'applications': {
                'createMissing': True,
                'deleteMissing': True
            },
            'discoveryRules': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'graphs': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'groups': {
                'createMissing': True
            },
            'httptests': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'items': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'templates': {
                'createMissing': True,
                'updateExisting': True
            },
            'templateLinkage': {
                'createMissing': True
            },
            'templateScreens': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'triggers': {
                'createMissing': True,
                'updateExisting': True,
                'deleteMissing': True
            },
            'valueMaps': {
                'createMissing': True,
                'updateExisting': True
            }
        }

        try:
            # updateExisting for application removed from zabbix api after 3.2
            if LooseVersion(self._zbx_api_version) <= LooseVersion('3.2'):
                update_rules['applications']['updateExisting'] = True

            # templateLinkage.deleteMissing only available in 4.0 branch higher .16 and higher 4.4.4
            # it's not available in 4.2 branches or lower 4.0.16
            if LooseVersion(self._zbx_api_version).version[:2] == LooseVersion('4.0').version and \
               LooseVersion(self._zbx_api_version).version[:3] >= LooseVersion('4.0.16').version:
                update_rules['templateLinkage']['deleteMissing'] = True
            if LooseVersion(self._zbx_api_version) >= LooseVersion('4.4.4'):
                update_rules['templateLinkage']['deleteMissing'] = True

            # templateScreens is named templateDashboards in zabbix >= 5.2
            # https://support.zabbix.com/browse/ZBX-18677
            if LooseVersion(self._zbx_api_version) >= LooseVersion('5.2'):
                update_rules["templateDashboards"] = update_rules.pop(
                    "templateScreens")

            # Zabbix 5.4 no longer supports applications
            if LooseVersion(self._zbx_api_version) >= LooseVersion('5.4'):
                update_rules.pop('applications', None)

            # The loaded unicode slash of multibyte as a string is escaped when parsing JSON by json.loads in Python2.
            # So, it is imported in the unicode string into Zabbix.
            # The following processing is removing the unnecessary slash in escaped for decoding correctly to the multibyte string.
            # https://github.com/ansible-collections/community.zabbix/issues/314
            if PY2:
                template_content = re.sub(r'\\\\u([0-9a-z]{,4})', r'\\u\1',
                                          template_content)

            import_data = {
                'format': template_type,
                'source': template_content,
                'rules': update_rules
            }
            self._zapi.configuration.import_(import_data)
        except Exception as e:
            self._module.fail_json(msg='Unable to import template',
                                   details=to_native(e),
                                   exception=traceback.format_exc())
예제 #16
0
def main():
    argument_spec = zabbix_utils.zabbix_common_argument_spec()
    argument_spec.update(dict(
        alias=dict(type='str', required=True, aliases=['username']),
        name=dict(type='str'),
        surname=dict(type='str'),
        usrgrps=dict(type='list'),
        passwd=dict(type='str', required=False, no_log=True),
        override_passwd=dict(type='bool', required=False, default=False, no_log=False),
        lang=dict(type='str', choices=['en_GB', 'en_US', 'zh_CN', 'cs_CZ', 'fr_FR',
                                       'he_IL', 'it_IT', 'ko_KR', 'ja_JP', 'nb_NO',
                                       'pl_PL', 'pt_BR', 'pt_PT', 'ru_RU', 'sk_SK',
                                       'tr_TR', 'uk_UA', 'default']),
        theme=dict(type='str', choices=['default', 'blue-theme', 'dark-theme']),
        autologin=dict(type='bool'),
        autologout=dict(type='str'),
        refresh=dict(type='str'),
        rows_per_page=dict(type='str'),
        after_login_url=dict(type='str'),
        user_medias=dict(type='list', elements='dict',
                         options=dict(mediatype=dict(type='str', default='Email'),
                                      sendto=dict(type='str', required=True),
                                      period=dict(type='str', default='1-7,00:00-24:00'),
                                      severity=dict(type='dict',
                                                    options=dict(
                                                        not_classified=dict(type='bool', default=True),
                                                        information=dict(type='bool', default=True),
                                                        warning=dict(type='bool', default=True),
                                                        average=dict(type='bool', default=True),
                                                        high=dict(type='bool', default=True),
                                                        disaster=dict(type='bool', default=True)),
                                                    default=dict(
                                                        not_classified=True,
                                                        information=True,
                                                        warning=True,
                                                        average=True,
                                                        high=True,
                                                        disaster=True)),
                                      active=dict(type='bool', default=True))),
        timezone=dict(type='str'),
        role_name=dict(type='str'),
        type=dict(type='str', choices=['Zabbix user', 'Zabbix admin', 'Zabbix super admin']),
        state=dict(type='str', default="present", choices=['present', 'absent'])
    ))
    module = AnsibleModule(
        argument_spec=argument_spec,
        required_if=[
            ['state', 'present', ['usrgrps']]
        ],
        supports_check_mode=True
    )

    alias = module.params['alias']
    name = module.params['name']
    surname = module.params['surname']
    usrgrps = module.params['usrgrps']
    passwd = module.params['passwd']
    override_passwd = module.params['override_passwd']
    lang = module.params['lang']
    theme = module.params['theme']
    autologin = module.params['autologin']
    autologout = module.params['autologout']
    refresh = module.params['refresh']
    rows_per_page = module.params['rows_per_page']
    after_login_url = module.params['after_login_url']
    user_medias = module.params['user_medias']
    user_type = module.params['type']
    timezone = module.params['timezone']
    role_name = module.params['role_name']
    state = module.params['state']

    if autologin is not None:
        if autologin:
            autologin = '******'
        else:
            autologin = '******'

    user_type_dict = {
        'Zabbix user': '******',
        'Zabbix admin': '2',
        'Zabbix super admin': '3'
    }
    user_type = user_type_dict[user_type] if user_type else None

    user = User(module)

    user_ids = {}
    zbx_user = user.check_user_exist(alias)
    if state == 'present':
        user_group_ids, require_password = user.get_usergroups_by_name(usrgrps)
        if LooseVersion(user._zbx_api_version) < LooseVersion('4.0') or require_password:
            if passwd is None:
                module.fail_json(msg='User password is required. One or more groups are not LDAP based.')

        if zbx_user:
            diff_check_result, diff_params = user.user_parameter_difference_check(zbx_user, alias, name, surname,
                                                                                  user_group_ids, passwd, lang, theme,
                                                                                  autologin, autologout, refresh,
                                                                                  rows_per_page, after_login_url,
                                                                                  user_medias, user_type, timezone,
                                                                                  role_name, override_passwd)

            if not module.check_mode and diff_check_result:
                user_ids = user.update_user(zbx_user, alias, name, surname, user_group_ids, passwd, lang,
                                            theme, autologin, autologout, refresh, rows_per_page, after_login_url,
                                            user_medias, user_type, timezone, role_name, override_passwd)
        else:
            diff_check_result = True
            user_ids, diff_params = user.add_user(alias, name, surname, user_group_ids, passwd, lang, theme, autologin,
                                                  autologout, refresh, rows_per_page, after_login_url, user_medias,
                                                  user_type, require_password, timezone, role_name)

    if state == 'absent':
        if zbx_user:
            diff_check_result = True
            user_ids, diff_params = user.delete_user(zbx_user, alias)
        else:
            diff_check_result = False
            diff_params = {}

    if not module.check_mode:
        if user_ids:
            module.exit_json(changed=True, user_ids=user_ids)
        else:
            module.exit_json(changed=False)
    else:
        if diff_check_result:
            module.exit_json(changed=True, diff=diff_params)
        else:
            module.exit_json(changed=False, diff=diff_params)
예제 #17
0
    def user_parameter_difference_check(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme,
                                        autologin, autologout, refresh, rows_per_page, url, user_medias, user_type,
                                        timezone, role_name, override_passwd):

        if user_medias:
            user_medias = self.convert_user_medias_parameter_types(user_medias)

        # existing data
        existing_data = copy.deepcopy(zbx_user[0])
        usrgrpids = []
        for usrgrp in existing_data['usrgrps']:
            usrgrpids.append({'usrgrpid': usrgrp['usrgrpid']})

        existing_data['usrgrps'] = sorted(usrgrpids, key=lambda x: x['usrgrpid'])

        # Processing for zabbix 4.0 and above.
        # In zabbix 4.0 and above, Email sendto is of type list.
        # This module, one media supports only one Email sendto.
        # Therefore following processing extract one Email from list.
        if LooseVersion(self._zbx_api_version) >= LooseVersion('4.0'):
            for media in existing_data['medias']:
                if isinstance(media['sendto'], list):
                    media['sendto'] = media['sendto'][0]

        existing_data['user_medias'] = sorted(existing_data['medias'], key=lambda x: x['sendto'])
        for del_key in ['medias', 'attempt_clock', 'attempt_failed', 'attempt_ip', 'debug_mode', 'users_status',
                        'gui_access']:
            del existing_data[del_key]

        for user_media in existing_data['user_medias']:
            for del_key in ['mediaid', 'userid']:
                del user_media[del_key]

        # request data
        request_data = {
            'userid': zbx_user[0]['userid'],
            self.alias_key(): alias,
            'name': name,
            'surname': surname,
            'usrgrps': sorted(user_group_ids, key=lambda x: x['usrgrpid']),
            'lang': lang,
            'theme': theme,
            'autologin': autologin,
            'autologout': autologout,
            'refresh': refresh,
            'rows_per_page': rows_per_page,
            'url': url,
        }

        if user_medias:
            request_data['user_medias'] = sorted(user_medias, key=lambda x: x['sendto'])
        else:
            del existing_data['user_medias']

        if override_passwd:
            request_data['passwd'] = passwd

        # The type key has changed to roleid key since Zabbix 5.2
        if LooseVersion(self._zbx_api_version) < LooseVersion('5.2'):
            request_data['type'] = user_type
        else:
            request_data['roleid'] = self.get_roleid_by_name(role_name) if role_name else None
            request_data['timezone'] = timezone

        request_data, del_keys = helper_normalize_data(request_data)
        existing_data, _del_keys = helper_normalize_data(existing_data, del_keys)

        user_parameter_difference_check_result = True
        if existing_data == request_data:
            user_parameter_difference_check_result = False

        diff_params = {
            "before": existing_data,
            "after": request_data
        }

        return user_parameter_difference_check_result, diff_params
예제 #18
0
 def update_global_macro(self, global_macro_obj, macro_name, macro_value,
                         macro_type, macro_description):
     global_macro_id = global_macro_obj['globalmacroid']
     try:
         if LooseVersion(self._zbx_api_version) < LooseVersion('4.4.0'):
             if global_macro_obj['macro'] == macro_name and global_macro_obj[
                     'value'] == macro_value:
                 self._module.exit_json(
                     changed=False,
                     result="Global macro %s already up to date" %
                     macro_name)
             if self._module.check_mode:
                 self._module.exit_json(changed=True)
             self._zapi.usermacro.updateglobal({
                 'globalmacroid': global_macro_id,
                 'macro': macro_name,
                 'value': macro_value
             })
             self._module.exit_json(
                 changed=True,
                 result="Successfully updated global macro %s" % macro_name)
         elif LooseVersion(self._zbx_api_version) >= LooseVersion('5.0.0'):
             if LooseVersion(
                     self._zbx_api_version) >= LooseVersion('5.4.0'):
                 if macro_type == '1':
                     macro_type = '0'
             if LooseVersion(self._zbx_api_version) >= LooseVersion(
                     '5.0.0') and LooseVersion(
                         self._zbx_api_version) < LooseVersion('5.4.0'):
                 if macro_type == '2' or macro_type == '1':
                     macro_type = '0'
             if global_macro_obj['type'] == '0' or global_macro_obj[
                     'type'] == '2':
                 if (global_macro_obj['macro'] == macro_name
                         and global_macro_obj['value'] == macro_value
                         and global_macro_obj['type'] == macro_type
                         and global_macro_obj['description']
                         == macro_description):
                     self._module.exit_json(
                         changed=False,
                         result="Global macro %s already up to date" %
                         macro_name)
             if self._module.check_mode:
                 self._module.exit_json(changed=True)
             self._zapi.usermacro.updateglobal({
                 'globalmacroid':
                 global_macro_id,
                 'macro':
                 macro_name,
                 'value':
                 macro_value,
                 'type':
                 macro_type,
                 'description':
                 macro_description
             })
             self._module.exit_json(
                 changed=True,
                 result="Successfully updated global macro %s" % macro_name)
         else:
             if (global_macro_obj['macro'] == macro_name
                     and global_macro_obj['value'] == macro_value and
                     global_macro_obj['description'] == macro_description):
                 self._module.exit_json(
                     changed=False,
                     result="Global macro %s already up to date" %
                     macro_name)
             if self._module.check_mode:
                 self._module.exit_json(changed=True)
             self._zapi.usermacro.updateglobal({
                 'globalmacroid':
                 global_macro_id,
                 'macro':
                 macro_name,
                 'value':
                 macro_value,
                 'description':
                 macro_description
             })
             self._module.exit_json(
                 changed=True,
                 result="Successfully updated global macro %s" % macro_name)
     except Exception as e:
         self._module.fail_json(msg="Failed to update global macro %s: %s" %
                                (macro_name, e))
예제 #19
0
    def construct_parameters(self):
        """Translates data to a format suitable for Zabbix API and filters
        the ones that are related to the specified mediatype type.

        Returns:
            A dictionary of arguments that are related to transport type,
            and are in a format that is understandable by Zabbix API.
        """
        truths = {'False': '0', 'True': '1'}
        parameters = dict(
            status='0' if self._module.params['status'] == 'enabled' else '1',
            type={
                'email': '0',
                'script': '1',
                'sms': '2',
                'jabber': '3',
                'webhook': '4',
                'ez_texting': '100'
            }.get(self._module.params['type']),
        )

        if LooseVersion(self._zbx_api_version) >= LooseVersion('4.4'):
            parameters.update(dict(
                name=self._module.params['name'],
                description=self._module.params['description'],
            ))
        else:
            parameters.update(dict(description=self._module.params['name']))

        if LooseVersion(self._zbx_api_version) >= LooseVersion('3.4'):
            parameters.update(dict(
                maxsessions=str(self._module.params['max_sessions']),
                maxattempts=str(self._module.params['max_attempts']),
                attempt_interval=str(self._module.params['attempt_interval'])
            ))

        if self._module.params['message_templates'] and LooseVersion(self._zbx_api_version) >= LooseVersion('5.0'):
            msg_templates = []
            for template in self._module.params['message_templates']:
                msg_templates.append(dict(
                    eventsource={
                        'triggers': '0',
                        'discovery': '1',
                        'autoregistration': '2',
                        'internal': '3'}.get(template['eventsource']),
                    recovery={
                        'operations': '0',
                        'recovery_operations': '1',
                        'update_operations': '2'}.get(template['recovery']),
                    subject=template['subject'],
                    message=template['body']
                ))
            parameters.update(dict(message_templates=msg_templates))

        if self._module.params['type'] == 'email':
            parameters.update(dict(
                smtp_server=self._module.params['smtp_server'],
                smtp_port=str(self._module.params['smtp_server_port']),
                smtp_helo=self._module.params['smtp_helo'],
                smtp_email=self._module.params['smtp_email'],
                smtp_security={'None': '0', 'STARTTLS': '1', 'SSL/TLS': '2'}.get(str(self._module.params['smtp_security'])),
                smtp_authentication=truths.get(str(self._module.params['smtp_authentication'])),
                smtp_verify_host=truths.get(str(self._module.params['smtp_verify_host'])),
                smtp_verify_peer=truths.get(str(self._module.params['smtp_verify_peer'])),
                username=self._module.params['username'],
                passwd=self._module.params['password']
            ))
            return parameters

        elif self._module.params['type'] == 'script':
            if self._module.params['script_params'] is None:
                _script_params = ''  # ZBX-15706
            else:
                _script_params = '\n'.join(str(i) for i in self._module.params['script_params']) + '\n'
            parameters.update(dict(
                exec_path=self._module.params['script_name'],
                exec_params=_script_params
            ))
            return parameters

        elif self._module.params['type'] == 'sms':
            parameters.update(dict(gsm_modem=self._module.params['gsm_modem']))
            return parameters

        elif self._module.params['type'] == 'webhook' and LooseVersion(self._zbx_api_version) >= LooseVersion('4.4'):
            parameters.update(dict(
                script=self._module.params['webhook_script'],
                timeout=self._module.params['webhook_timeout'],
                process_tags=truths.get(str(self._module.params['process_tags'])),
                show_event_menu=truths.get(str(self._module.params['event_menu'])),
                parameters=self._module.params['webhook_params']
            ))
            if self._module.params['event_menu']:
                parameters.update(dict(
                    event_menu_url=self._module.params['event_menu_url'],
                    event_menu_name=self._module.params['event_menu_name']
                ))
            return parameters

        elif self._module.params['type'] == 'jabber' and LooseVersion(self._zbx_api_version) <= LooseVersion('4.2'):
            parameters.update(dict(
                username=self._module.params['username'],
                passwd=self._module.params['password']
            ))
            return parameters

        elif self._module.params['type'] == 'ez_texting' and LooseVersion(self._zbx_api_version) <= LooseVersion('4.2'):
            parameters.update(dict(
                username=self._module.params['username'],
                passwd=self._module.params['password'],
                exec_path={'USA': '0', 'Canada': '1'}.get(self._module.params['message_text_limit']),
            ))
            return parameters

        self._module.fail_json(msg="%s is unsupported for Zabbix version %s" % (parameters['unsupported_parameter'], parameters['zbx_api_version']))
예제 #20
0
 def _get_selements_sort_keys(self):
     keys_to_sort = ['label']
     if LooseVersion(self._zbx_api_version) < LooseVersion('3.4'):
         keys_to_sort.insert(0, 'elementid')
     return keys_to_sort