diff --git a/changelogs/fragments/zabbix-hostmacro.yml b/changelogs/fragments/zabbix-hostmacro.yml new file mode 100644 index 00000000000..f778694d4f5 --- /dev/null +++ b/changelogs/fragments/zabbix-hostmacro.yml @@ -0,0 +1,3 @@ +minor_changes: + - zabbix_hostmacro - ``macro_value`` is no longer required when ``state=absent`` + - zabbix_hostmacro - ``macro_name`` now accepts macros in zabbix native format as well (e.g. ``{$MACRO}``) diff --git a/lib/ansible/modules/monitoring/zabbix/zabbix_hostmacro.py b/lib/ansible/modules/monitoring/zabbix/zabbix_hostmacro.py index 68c2597e53b..c2644f6cc25 100644 --- a/lib/ansible/modules/monitoring/zabbix/zabbix_hostmacro.py +++ b/lib/ansible/modules/monitoring/zabbix/zabbix_hostmacro.py @@ -33,12 +33,12 @@ options: required: true macro_name: description: - - Name of the host macro without the enclosing curly braces and the leading dollar sign. + - Name of the host macro in zabbix native format C({$MACRO}) or simple format C(MACRO). required: true macro_value: description: - Value of the host macro. - required: true + - Required if I(state=present). state: description: - State of the macro. @@ -59,7 +59,7 @@ extends_documentation_fragment: ''' EXAMPLES = ''' -- name: Create a new host macro or update an existing macro's value +- name: Create new host macro or update an existing macro's value local_action: module: zabbix_hostmacro server_url: http://monitor.example.com @@ -69,6 +69,28 @@ EXAMPLES = ''' macro_name: EXAMPLE.MACRO macro_value: Example value state: present + +# Values with curly brackets need to be quoted otherwise they will be interpreted as a dictionary +- name: Create new host macro in Zabbix native format + local_action: + module: zabbix_hostmacro + server_url: http://monitor.example.com + login_user: username + login_password: password + host_name: ExampleHost + macro_name: "{$EXAMPLE.MACRO}" + macro_value: Example value + state: present + +- name: Delete existing host macro + local_action: + module: zabbix_hostmacro + server_url: http://monitor.example.com + login_user: username + login_password: password + host_name: ExampleHost + macro_name: "{$EXAMPLE.MACRO}" + state: absent ''' @@ -106,7 +128,7 @@ class HostMacro(object): def get_host_macro(self, macro_name, host_id): try: host_macro_list = self._zapi.usermacro.get( - {"output": "extend", "selectSteps": "extend", 'hostids': [host_id], 'filter': {'macro': '{$' + macro_name + '}'}}) + {"output": "extend", "selectSteps": "extend", 'hostids': [host_id], 'filter': {'macro': macro_name}}) if len(host_macro_list) > 0: return host_macro_list[0] return None @@ -118,7 +140,7 @@ class HostMacro(object): try: if self._module.check_mode: self._module.exit_json(changed=True) - self._zapi.usermacro.create({'hostid': host_id, 'macro': '{$' + macro_name + '}', 'value': macro_value}) + 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)) @@ -126,7 +148,7 @@ class HostMacro(object): # update host macro def update_host_macro(self, host_macro_obj, macro_name, macro_value): host_macro_id = host_macro_obj['hostmacroid'] - if host_macro_obj['macro'] == '{$' + macro_name + '}' and host_macro_obj['value'] == macro_value: + if host_macro_obj['macro'] == macro_name and 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: @@ -148,6 +170,22 @@ class HostMacro(object): self._module.fail_json(msg="Failed to delete host macro %s: %s" % (macro_name, e)) +def normalize_macro_name(macro_name): + # Zabbix handles macro names in upper case characters + if ':' in macro_name: + macro_name = ':'.join([macro_name.split(':')[0].upper(), ':'.join(macro_name.split(':')[1:])]) + else: + macro_name = macro_name.upper() + + # Valid format for macro is {$MACRO} + if not macro_name.startswith('{$'): + macro_name = '{$' + macro_name + if not macro_name.endswith('}'): + macro_name = macro_name + '}' + + return macro_name + + def main(): module = AnsibleModule( argument_spec=dict( @@ -159,11 +197,14 @@ def main(): validate_certs=dict(type='bool', required=False, default=True), host_name=dict(type='str', required=True), macro_name=dict(type='str', required=True), - macro_value=dict(type='str', required=True), + macro_value=dict(type='str', required=False), state=dict(default="present", choices=['present', 'absent']), timeout=dict(type='int', default=10), force=dict(type='bool', default=True) ), + required_if=[ + ['state', 'present', ['macro_value']] + ], supports_check_mode=True ) @@ -177,17 +218,12 @@ def main(): http_login_password = module.params['http_login_password'] validate_certs = module.params['validate_certs'] host_name = module.params['host_name'] - macro_name = (module.params['macro_name']) + macro_name = normalize_macro_name(module.params['macro_name']) macro_value = module.params['macro_value'] state = module.params['state'] timeout = module.params['timeout'] force = module.params['force'] - if ':' in macro_name: - macro_name = ':'.join([macro_name.split(':')[0].upper(), ':'.join(macro_name.split(':')[1:])]) - else: - macro_name = macro_name.upper() - zbx = None # login to zabbix try: