Files
offline_kubespray/collection/community/zabbix/plugins/modules/zabbix_authentication.py
ByeonJungHun 360c6eef4a offline 작업
2024-02-19 16:02:29 +09:00

587 lines
21 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2022, ONODERA Masaru <masaru-onodera@ieee.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: zabbix_authentication
short_description: Update Zabbix authentication
description:
- This module allows you to modify Zabbix authentication setting.
author:
- ONODERA Masaru(@masa-orca)
requirements:
- "zabbix-api >= 0.5.4"
version_added: 1.6.0
options:
authentication_type:
description:
- Choose default authentication type.
required: false
type: str
choices: [ "internal", "ldap" ]
http_auth_enabled:
description:
- HTTP authentication will be enabled if C(true).
required: false
type: bool
http_login_form:
description:
- Choose default login form.
required: false
type: str
choices: [ "zabbix_login_form", "http_login_form" ]
http_strip_domains:
description:
- A list of domain names that should be removed from the username.
required: false
type: list
elements: str
http_case_sensitive:
description:
- Case sensitive login for HTTP authentication will be enabled if C(true).
required: false
type: bool
ldap_configured:
description:
- LDAP authentication will be enabled if C(true).
required: false
type: bool
ldap_host:
description:
- LDAP server name.
- e.g. C(ldap://ldap.zabbix.com)
- This setting is required if current value of I(ldap_configured) is C(false).
required: false
type: str
ldap_port:
description:
- A port number of LDAP server.
- This setting is required if current value of I(ldap_configured) is C(false).
required: false
type: int
ldap_base_dn:
description:
- Base DN of LDAP.
- This setting is required if current value of I(ldap_configured) is C(false).
required: false
type: str
ldap_search_attribute:
description:
- Search attribute of LDAP.
- This setting is required if current value of I(ldap_configured) is C(false).
required: false
type: str
ldap_bind_dn:
description:
- Bind DN of LDAP.
required: false
type: str
ldap_case_sensitive:
description:
- case sensitive login for LDAP authentication will be enabled if C(true).
required: false
type: bool
ldap_bind_password:
description:
- Bind password of LDAP.
required: false
type: str
saml_auth_enabled:
description:
- SAML authentication will be enabled if C(true).
required: false
type: bool
saml_idp_entityid:
description:
- SAML identify provider's entity ID.
- This setting is required if current value of I(saml_auth_enabled) is C(false).
required: false
type: str
saml_sso_url:
description:
- URL for single sign on service of SAML.
- This setting is required if current value of I(saml_auth_enabled) is C(false).
required: false
type: str
saml_slo_url:
description:
- URL for SAML single logout service.
required: false
type: str
saml_username_attribute:
description:
- User name attribute of SAML.
- This setting is required if current value of I(saml_auth_enabled) is C(false).
required: false
type: str
saml_sp_entityid:
description:
- Entity ID of SAML service provider.
- This setting is required if current value of I(saml_auth_enabled) is C(false).
required: false
type: str
saml_nameid_format:
description:
- Name identifier format of SAML service provider.
required: false
type: str
saml_sign_messages:
description:
- SAML sign messages will be enabled if C(true).
required: false
type: bool
saml_sign_assertions:
description:
- SAML sign assertions will be enabled if C(true).
required: false
type: bool
saml_sign_authn_requests:
description:
- SAML sign AuthN requests will be enabled if C(true).
required: false
type: bool
saml_sign_logout_requests:
description:
- SAML sign logout requests will be enabled if C(true).
required: false
type: bool
saml_sign_logout_responses:
description:
- SAML sign logout responses will be enabled if C(true).
required: false
type: bool
saml_encrypt_nameid:
description:
- SAML encrypt name ID will be enabled if C(true).
required: false
type: bool
saml_encrypt_assertions:
description:
- SAML encrypt assertions will be enabled if C(true).
required: false
type: bool
saml_case_sensitive:
description:
- Case sensitive login for SAML authentication will be enabled if C(true).
required: false
type: bool
passwd_min_length:
description:
- Minimal length of password.
- Choose from 1-70.
- This parameter is available since Zabbix 6.0.
required: false
type: int
passwd_check_rules:
description:
- Checking password rules.
- Select multiple from C(contain_uppercase_and_lowercase_letters),
C(contain_digits). C(contain_special_characters) and C(avoid_easy_to_guess).
- This parameter is available since Zabbix 6.0.
required: false
type: list
elements: str
notes:
- Zabbix 5.4 version and higher are supported.
extends_documentation_fragment:
- community.zabbix.zabbix
'''
EXAMPLES = '''
- name: Update all authentication setting
zabbix_authentication:
server_url: "http://zabbix.example.com/zabbix/"
login_user: Admin
login_password: secret
authentication_type: internal
http_auth_enabled: true
http_login_form: zabbix_login_form
http_strip_domains:
- comp
- any
http_case_sensitive: true
ldap_configured: true
ldap_host: 'ldap://localhost'
ldap_port: 389
ldap_base_dn: 'ou=Users,ou=system'
ldap_search_attribute: 'uid'
ldap_bind_dn: 'uid=ldap_search,ou=system'
ldap_case_sensitive: true
ldap_bind_password: 'password'
saml_auth_enabled: true
saml_idp_entityid: ''
saml_sso_url: 'https://localhost/SAML2/SSO'
saml_slo_url: 'https://localhost/SAML2/SLO'
saml_username_attribute: 'uid'
saml_sp_entityid: 'https://localhost'
saml_nameid_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
saml_sign_messages: true
saml_sign_assertions: true
saml_sign_authn_requests: true
saml_sign_logout_requests: true
saml_sign_logout_responses: true
saml_encrypt_nameid: true
saml_encrypt_assertions: true
saml_case_sensitive: true
passwd_min_length: 70
passwd_check_rules:
- contain_uppercase_and_lowercase_letters
- contain_digits
- contain_special_characters
- avoid_easy_to_guess
'''
RETURN = '''
msg:
description: The result of the operation
returned: success
type: str
sample: 'Successfully update authentication setting'
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase
from ansible_collections.community.zabbix.plugins.module_utils.version import LooseVersion
import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils
class Authentication(ZabbixBase):
def __init__(self, module, zbx=None, zapi_wrapper=None):
super(Authentication, self).__init__(module, zbx, zapi_wrapper)
if LooseVersion(self._zbx_api_version) < LooseVersion('5.4.0'):
module.fail_json(msg="This module doesn't support Zabbix versions lower than 5.4.0")
# get authentication setting
def get_authentication(self):
try:
return self._zapi.authentication.get({'output': 'extend'})
except Exception as e:
self._module.fail_json(msg="Failed to get authentication setting: %s" % e)
# update authentication setting
def update_authentication(
self,
current_authentication,
authentication_type,
http_auth_enabled,
http_login_form,
http_strip_domains,
http_case_sensitive,
ldap_configured,
ldap_host,
ldap_port,
ldap_base_dn,
ldap_search_attribute,
ldap_bind_dn,
ldap_case_sensitive,
ldap_bind_password,
saml_auth_enabled,
saml_idp_entityid,
saml_sso_url,
saml_slo_url,
saml_username_attribute,
saml_sp_entityid,
saml_nameid_format,
saml_sign_messages,
saml_sign_assertions,
saml_sign_authn_requests,
saml_sign_logout_requests,
saml_sign_logout_responses,
saml_encrypt_nameid,
saml_encrypt_assertions,
saml_case_sensitive,
passwd_min_length,
passwd_check_rules):
try:
params = {}
if authentication_type:
params['authentication_type'] = str(zabbix_utils.helper_to_numeric_value(
['internal', 'ldap'],
authentication_type
))
if isinstance(http_auth_enabled, bool):
params['http_auth_enabled'] = str(int(http_auth_enabled))
if http_login_form:
params['http_login_form'] = str(zabbix_utils.helper_to_numeric_value(
['zabbix_login_form', 'http_login_form'],
http_login_form
))
if http_strip_domains:
params['http_strip_domains'] = ','.join(http_strip_domains)
if isinstance(http_case_sensitive, bool):
params['http_case_sensitive'] = str(int(http_case_sensitive))
if isinstance(ldap_configured, bool):
params['ldap_configured'] = str(int(ldap_configured))
if ldap_host:
params['ldap_host'] = ldap_host
if ldap_port:
params['ldap_port'] = str(ldap_port)
if ldap_base_dn:
params['ldap_base_dn'] = ldap_base_dn
if ldap_search_attribute:
params['ldap_search_attribute'] = ldap_search_attribute
if ldap_bind_dn:
params['ldap_bind_dn'] = ldap_bind_dn
if isinstance(ldap_case_sensitive, bool):
params['ldap_case_sensitive'] = str(int(ldap_case_sensitive))
if ldap_bind_password:
params['ldap_bind_password'] = ldap_bind_password
if isinstance(saml_auth_enabled, bool):
params['saml_auth_enabled'] = str(int(saml_auth_enabled))
if saml_idp_entityid:
params['saml_idp_entityid'] = saml_idp_entityid
if saml_sso_url:
params['saml_sso_url'] = saml_sso_url
if saml_slo_url:
params['saml_slo_url'] = saml_slo_url
if saml_username_attribute:
params['saml_username_attribute'] = saml_username_attribute
if saml_sp_entityid:
params['saml_sp_entityid'] = saml_sp_entityid
if saml_nameid_format:
params['saml_nameid_format'] = saml_nameid_format
if isinstance(saml_sign_messages, bool):
params['saml_sign_messages'] = str(int(saml_sign_messages))
if isinstance(saml_sign_assertions, bool):
params['saml_sign_assertions'] = str(int(saml_sign_assertions))
if isinstance(saml_sign_authn_requests, bool):
params['saml_sign_authn_requests'] = str(int(saml_sign_authn_requests))
if isinstance(saml_sign_logout_requests, bool):
params['saml_sign_logout_requests'] = str(int(saml_sign_logout_requests))
if isinstance(saml_sign_logout_responses, bool):
params['saml_sign_logout_responses'] = str(int(saml_sign_logout_responses))
if isinstance(saml_encrypt_nameid, bool):
params['saml_encrypt_nameid'] = str(int(saml_encrypt_nameid))
if isinstance(saml_encrypt_assertions, bool):
params['saml_encrypt_assertions'] = str(int(saml_encrypt_assertions))
if isinstance(saml_case_sensitive, bool):
params['saml_case_sensitive'] = str(int(saml_case_sensitive))
if passwd_min_length:
if LooseVersion(self._zbx_api_version) < LooseVersion('6.0'):
self._module.warn('passwd_min_length is ignored with Zabbix 5.4.')
elif passwd_min_length < 1 or passwd_min_length > 70:
self._module.fail_json(msg="Please set 0-70 to passwd_min_length.")
else:
params['passwd_min_length'] = str(passwd_min_length)
if passwd_check_rules:
if LooseVersion(self._zbx_api_version) < LooseVersion('6.0'):
self._module.warn('passwd_check_rules is ignored with Zabbix 5.4.')
else:
passwd_check_rules_values = [
'contain_uppercase_and_lowercase_letters',
'contain_digits',
'contain_special_characters',
'avoid_easy_to_guess'
]
params['passwd_check_rules'] = 0
if isinstance(passwd_check_rules, str):
if passwd_check_rules not in passwd_check_rules_values:
self._module.fail_json(msg="%s is invalid value for passwd_check_rules." % passwd_check_rules)
params['passwd_check_rules'] += 2 ** zabbix_utils.helper_to_numeric_value(
passwd_check_rules_values, passwd_check_rules
)
elif isinstance(passwd_check_rules, list):
for _passwd_check_rules_value in passwd_check_rules:
if _passwd_check_rules_value not in passwd_check_rules_values:
self._module.fail_json(msg="%s is invalid value for passwd_check_rules." % _passwd_check_rules_value)
params['passwd_check_rules'] += 2 ** zabbix_utils.helper_to_numeric_value(
passwd_check_rules_values, _passwd_check_rules_value
)
params['passwd_check_rules'] = str(params['passwd_check_rules'])
future_authentication = current_authentication.copy()
future_authentication.update(params)
if (current_authentication['ldap_configured'] == '0'
and future_authentication['ldap_configured'] == '1'
and not ldap_host
and not ldap_port
and not ldap_search_attribute
and not ldap_base_dn):
self._module.fail_json(
msg="Please set ldap_host, ldap_search_attribute and ldap_base_dn when you change a value of ldap_configured to true."
)
if (current_authentication['saml_auth_enabled'] == '0'
and future_authentication['saml_auth_enabled'] == '1'
and not saml_idp_entityid
and not saml_sso_url
and not saml_username_attribute
and not saml_sp_entityid):
self._module.fail_json(
msg=' '.join([
"Please set saml_idp_entityid, saml_sso_url, saml_username_attribute and saml_sp_entityid",
"when you change a value of saml_auth_enabled to true."
])
)
if future_authentication != current_authentication:
if self._module.check_mode:
self._module.exit_json(changed=True)
self._zapi.authentication.update(params)
self._module.exit_json(changed=True, result="Successfully update authentication setting")
else:
self._module.exit_json(changed=False, result="Authentication setting is already up to date")
except Exception as e:
self._module.fail_json(msg="Failed to update authentication setting, Exception: %s" % e)
def main():
argument_spec = zabbix_utils.zabbix_common_argument_spec()
argument_spec.update(dict(
authentication_type=dict(type='str', choices=['internal', 'ldap']),
http_auth_enabled=dict(type='bool'),
http_login_form=dict(type='str', choices=['zabbix_login_form', 'http_login_form']),
http_strip_domains=dict(type='list', elements='str'),
http_case_sensitive=dict(type='bool'),
ldap_configured=dict(type='bool'),
ldap_host=dict(type='str'),
ldap_port=dict(type='int'),
ldap_base_dn=dict(type='str'),
ldap_search_attribute=dict(type='str'),
ldap_bind_dn=dict(type='str'),
ldap_case_sensitive=dict(type='bool'),
ldap_bind_password=dict(type='str', no_log=True),
saml_auth_enabled=dict(type='bool'),
saml_idp_entityid=dict(type='str'),
saml_sso_url=dict(type='str'),
saml_slo_url=dict(type='str'),
saml_username_attribute=dict(type='str'),
saml_sp_entityid=dict(type='str'),
saml_nameid_format=dict(type='str'),
saml_sign_messages=dict(type='bool'),
saml_sign_assertions=dict(type='bool'),
saml_sign_authn_requests=dict(type='bool'),
saml_sign_logout_requests=dict(type='bool'),
saml_sign_logout_responses=dict(type='bool'),
saml_encrypt_nameid=dict(type='bool'),
saml_encrypt_assertions=dict(type='bool'),
saml_case_sensitive=dict(type='bool'),
passwd_min_length=dict(type='int', no_log=False),
passwd_check_rules=dict(type='list', elements='str', no_log=False)
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
)
authentication_type = module.params['authentication_type']
http_auth_enabled = module.params['http_auth_enabled']
http_login_form = module.params['http_login_form']
http_strip_domains = module.params['http_strip_domains']
http_case_sensitive = module.params['http_case_sensitive']
ldap_configured = module.params['ldap_configured']
ldap_host = module.params['ldap_host']
ldap_port = module.params['ldap_port']
ldap_base_dn = module.params['ldap_base_dn']
ldap_search_attribute = module.params['ldap_search_attribute']
ldap_bind_dn = module.params['ldap_bind_dn']
ldap_case_sensitive = module.params['ldap_case_sensitive']
ldap_bind_password = module.params['ldap_bind_password']
saml_auth_enabled = module.params['saml_auth_enabled']
saml_idp_entityid = module.params['saml_idp_entityid']
saml_sso_url = module.params['saml_sso_url']
saml_slo_url = module.params['saml_slo_url']
saml_username_attribute = module.params['saml_username_attribute']
saml_sp_entityid = module.params['saml_sp_entityid']
saml_nameid_format = module.params['saml_nameid_format']
saml_sign_messages = module.params['saml_sign_messages']
saml_sign_assertions = module.params['saml_sign_assertions']
saml_sign_authn_requests = module.params['saml_sign_authn_requests']
saml_sign_logout_requests = module.params['saml_sign_logout_requests']
saml_sign_logout_responses = module.params['saml_sign_logout_responses']
saml_encrypt_nameid = module.params['saml_encrypt_nameid']
saml_encrypt_assertions = module.params['saml_encrypt_assertions']
saml_case_sensitive = module.params['saml_case_sensitive']
passwd_min_length = module.params['passwd_min_length']
passwd_check_rules = module.params['passwd_check_rules']
authentication = Authentication(module)
current_authentication = authentication.get_authentication()
authentication.update_authentication(
current_authentication,
authentication_type,
http_auth_enabled,
http_login_form,
http_strip_domains,
http_case_sensitive,
ldap_configured,
ldap_host,
ldap_port,
ldap_base_dn,
ldap_search_attribute,
ldap_bind_dn,
ldap_case_sensitive,
ldap_bind_password,
saml_auth_enabled,
saml_idp_entityid,
saml_sso_url,
saml_slo_url,
saml_username_attribute,
saml_sp_entityid,
saml_nameid_format,
saml_sign_messages,
saml_sign_assertions,
saml_sign_authn_requests,
saml_sign_logout_requests,
saml_sign_logout_responses,
saml_encrypt_nameid,
saml_encrypt_assertions,
saml_case_sensitive,
passwd_min_length,
passwd_check_rules
)
if __name__ == '__main__':
main()