diff --git a/playbooks/groups/zabbix.yml b/playbooks/groups/zabbix.yml index 0dd5a4c961..f72644c3a3 100644 --- a/playbooks/groups/zabbix.yml +++ b/playbooks/groups/zabbix.yml @@ -27,6 +27,13 @@ tasks: - import_tasks: "{{ tasks_path }}/motd.yml" + - name: Sync sysadmin-noc membership to the zabbix server + include_role: + name: zabbix_server + tasks_from: sync_sysadmin_noc + apply: + tags: + - sync_users handlers: - import_tasks: "{{ handlers_path }}/restart_services.yml" diff --git a/roles/zabbix/zabbix_server/library/zabbix_sync_sysadmin_noc_group_membership.py b/roles/zabbix/zabbix_server/library/zabbix_sync_sysadmin_noc_group_membership.py new file mode 100644 index 0000000000..975b702fbb --- /dev/null +++ b/roles/zabbix/zabbix_server/library/zabbix_sync_sysadmin_noc_group_membership.py @@ -0,0 +1,170 @@ +#!/usr/bin/python + +# Copyright: (c) 2018, Terry Jones +# 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 + +import json +import re +import requests + +from ansible.module_utils.basic import AnsibleModule +from requests_kerberos import HTTPKerberosAuth + +__metaclass__ = type + +DOCUMENTATION = r""" +--- +module: zabbix_retrieve_sysadmin_noc_group_membership + +short_description: Retrieve fasjson sysadmin-noc group membership from FAS then sync to Zabbix. + +version_added: "0.0.1" + +description: This module retrieves fasjson group membership data for the sysadmin-noc group, then +synchronises to the Zabbix server. + +options: + keytab_path: + description: This is the location on disk where the kerberos keytab is stored. + required: true + type: str + principal: + description: The is the kerberos principal. + required: true + type: str + fasjson_host: + description: The is the fasjson hostname. + required: true + type: str + group_name: + description: This is the group name to search fasjson for. + required: true + type: str + +author: + - David Kirwan (dkirwan@redhat.com) +""" + +EXAMPLES = r""" +- name: Retrieve fasjson group membership + zabbix_retrieve_sysadmin_noc_group_membership: + keytab_path: "{{ kerberos_keytab_path }}" + principal: "{{ kerberos_principal }}" + fasjson_host: "{{ fasjson_host }}" + group_name: "{{ fasjson_group_name }}" + register: fasjson_response +""" + +RETURN = r""" +# These are examples of possible return values, and in general should use other names for return +# values. +group: + description: The groups and their users which match the regex pattern supplied. + type: str + returned: always + sample: +[ + { + "group_name": "communishift-yyy", + "group_members": [ + "uuu", + "iii", + "eee", + "zqq" + ] + } +] + +msg: + description: The output message that the module generates. + type: str + returned: always + sample: 'Successfully retrieved group membership from fasjson.' +""" + + +# Helper function to create the http requests +def get_http_client(keytab_path, principal): + try: + kerberos_auth = HTTPKerberosAuth(principal=principal) + except Exception as e: + print("Error trying to authenticate with Kerberos", e) + raise + session = requests.Session() + session.auth = kerberos_auth + return session + + +# Helper function to retrieve fasjson group members +def get_group_members(http_client, fasjson_host, group_name): + response = http_client.get( + "https://%s/v1/groups/%s/members/" % (fasjson_host, group_name) + ) + if response.ok: + return response.json() + + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + keytab_path=dict(type="str", required=True), + principal=dict(type="str", required=True), + fasjson_host=dict(type="str", required=True), + group_name=dict(type="str", required=True), + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict(changed=False, original_message="", message="") + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + if module.check_mode: + module.exit_json(**result) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + keytab_path = module.params["keytab_path"] + principal = module.params["principal"] + fasjson_host = module.params["fasjson_host"] + group_name = module.params["group_name"] + + try: + http_client = get_http_client(keytab_path, principal) + + group = {"groupname": group_name, "groupmembers": []} + group_member_res = get_group_members(http_client, fasjson_host, group_name) + # print(json.dumps(group_member_res)) + + for i in group_member_res["result"]: + group["groupmembers"].append(i["username"]) + + result["group"] = json.dumps(group) + result["changed"] = True + result["msg"] = "Successfully retrieved group membership from fasjson." + except Exception: + raise + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/roles/zabbix/zabbix_server/tasks/sync_sysadmin_noc.yml b/roles/zabbix/zabbix_server/tasks/sync_sysadmin_noc.yml new file mode 100644 index 0000000000..e55f4a600f --- /dev/null +++ b/roles/zabbix/zabbix_server/tasks/sync_sysadmin_noc.yml @@ -0,0 +1,56 @@ +--- +# If you want to use API token to be authenticated by Zabbix Server +# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens +- name: Set API token + tags: + - never + - sync_users + set_fact: + ansible_zabbix_auth_key: "{{ (env == 'staging')|ternary(zabbix_stg_apikey, zabbix_apikey) }}" + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_host: "{{ (env == 'staging')|ternary(zabbix_stg_hostname, zabbix_hostname) }}" + ansible_zabbix_url_path: "" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + +- name: Retrieve fasjson group membership + tags: + - never + - sync_users + zabbix_retrieve_sysadmin_noc_group_membership: + keytab_path: "{{ (env == 'staging')|ternary(zabbix_stg_kerberos_keytab_path, zabbix_kerberos_keytab_path) }}" + principal: "{{ (env == 'staging')|ternary(zabbix_stg_kerberos_principal, zabbix_kerberos_principal) }}" + fasjson_host: "{{ (env == 'staging')|ternary(zabbix_stg_fasjson_host, zabbix_fasjson_host) }}" + group_name: "{{ zabbix_fasjson_group_name }}" + register: zabbix_fasjson_response + +- name: Print fasjson response + tags: + - never + - sync_users + ansible.builtin.debug: + msg: "{{ zabbix_fasjson_response['group'] }}" + +- set_fact: + tags: + - never + - sync_users + zabbix_sysadmin_noc_members: "{{ zabbix_fasjson_response['group']|from_json }}" + +- name: Create a the zabbix user for each sysadmin-noc member. + # set task level variables as we change ansible_connection plugin here + tags: + - never + - sync_users + community.zabbix.zabbix_user: + username: "{{ item }}" + name: "{{ item }}" + surname: "{{ item }}" + role_name: Admin role + usrgrps: + - Zabbix administrators + passwd: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits,ascii_uppercase,punctuation length=15') }}" + state: present + with_items: "{{ zabbix_sysadmin_noc_members['groupmembers'] }}"