#  Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved.
#
#  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.
---

- name: Initialize ds389_status
  set_fact:
    ds389_status: false

- name: Fetch hostname
  command: hostname
  register: new_serv_hostname
  changed_when: false

- name: Set fact for server hostname
  set_fact:
    server_hostname_ms: "{{ new_serv_hostname.stdout }}"

- name: Check password policy in 389-ds
  command: dsconf -w {{ ms_directory_manager_password }} -D "cn=Directory Manager" ldap://{{ server_hostname_ms }} pwpolicy get
  changed_when: true
  failed_when: false
  no_log: true
  register: ds389_pwpolicy_check

- name: Check ds389_status admin authentication
  shell: set -o pipefail && echo {{ ms_kerberos_admin_password }} | kinit {{ ms_ipa_admin_username }}
  changed_when: false
  failed_when: false
  no_log: true
  register: ds389_status_authentication

- name: Gathering service facts
  service_facts:

- name: Modify ds389_status
  set_fact:
    ds389_status: true
  when: 
    - ds389_status_authentication.rc == 0
    - ds389_pwpolicy_search_key in ds389_pwpolicy_check.stdout
    - "'sssd.service' in ansible_facts.services"
    - sssd_install_search_key in ansible_facts.services['sssd.service'].state

- block:
    - name: Install 389-ds
      zypper:
        name: "{{ ds389_packages }}"
        state: present 

    - name: Check ldap instance is running or not
      command: dsctl {{ ldap_instance }} status
      changed_when: false
      failed_when: false
      register: ldap1_status

    - name: Create the ldap1.inf file
      copy:
        src: "{{ role_path }}/files/temp_ldap1.inf"
        dest: "{{ ldap1_config_path }}"
        mode: "{{ file_mode }}"
      when: ldap1_search_key in ldap1_status.stdout       

    - name: Configure ldap1.inf with domain name
      lineinfile:
        path: "{{ ldap1_config_path }}"
        regexp: "^suffix = dc=omnia,dc=test"
        line: "suffix = dc={{ domain_name.split('.')[0] }},dc={{ domain_name.split('.')[1] }}"
      when: ldap1_search_key in ldap1_status.stdout

    - name: Configure ldap1.inf with directory manager password
      lineinfile:
        path: "{{ ldap1_config_path }}"
        regexp: "^root_password = password"
        line: "root_password = {{ ms_directory_manager_password }}"
      no_log: true
      when: ldap1_search_key in ldap1_status.stdout

    - name: Creating 389 directory server instance
      shell: dscreate -v from-file {{ ldap1_config_path }} | tee {{ ldap1_output_path }}
      changed_when: true
      when: ldap1_search_key in ldap1_status.stdout
      
    - name: Remove the ldap1.inf
      file:
        path: "{{ ldap1_config_path }}"
        state: absent

    - name: Start dirsrv service
      systemd:
        name: "dirsrv@{{ ldap_instance }}.service"
        state: started
        enabled: yes

    - name: Create the dsrc file
      copy:
        src: "{{ role_path }}/files/temp_dsrc"
        dest: "{{ dsrc_path }}"
        mode: "{{ file_mode }}"

    - name: Configure dsrc file with domain name
      lineinfile:
        path: "{{ dsrc_path }}"
        regexp: "^basedn = dc=omnia,dc=test"
        line: "basedn = dc={{ domain_name.split('.')[0] }},dc={{ domain_name.split('.')[1] }}"

    - name: Permit traffic in default zone for ldap and ldaps service
      firewalld:
        service: "{{ item }}"
        permanent: yes
        state: enabled
      with_items: "{{ ldap_services }}"

    - name: Reload firewalld
      command: firewall-cmd --reload
      changed_when: true

    - name: Install kerberos packages
      zypper:
        name: "{{ kerberos_packages }}"
        state: present 

    - name: Check kerberos principal is created or not
      stat:
        path: "{{ kerberos_principal_path }}"
      register: principal_status

    - name: Create the kerberos conf file
      copy:
        src: "{{ role_path }}/files/temp_krb5.conf"
        dest: "{{ kerberos_conf_path }}"
        mode: "{{ file_mode }}"
      when: not principal_status.stat.exists      

    - name: Configure kerberos conf file with domain name
      replace:
        path: "{{ kerberos_conf_path }}"
        regexp: "omnia.test"
        replace: "{{ domain_name }}"
      when: not principal_status.stat.exists

    - name: Configure kerberos conf file with realm name
      replace:
        path: "{{ kerberos_conf_path }}"
        regexp: "OMNIA.TEST"
        replace: "{{ realm_name }}"
      when: not principal_status.stat.exists

    - name: Configure kerberos conf file with hostname
      replace:
        path: "{{ kerberos_conf_path }}"
        regexp: "hostname"
        replace: "{{ short_hostname.stdout }}"
      when: not principal_status.stat.exists

    - block:
        - name: Setting up the kerberos database
          command: "kdb5_util -r {{ realm_name }} -P {{ ms_directory_manager_password }} create -s"
          no_log: true
          changed_when: true
          register: setting_database
          environment:
            PATH: "{{ ansible_env.PATH }}:{{ kerberos_env_path }}"
          when: not principal_status.stat.exists
      rescue:
        - name: Setting up the kerberos database failed
          fail:
            msg: "Error: {{ setting_database.stderr }}"

    - name: Start krb5kdc and kadmind services
      systemd:
        name: "{{ item }}"
        state: started
        enabled: yes
      with_items:
        - krb5kdc
        - kadmind

    - block:
        - name: Create admin principal
          command: kadmin.local -q "ank -pw {{ ms_kerberos_admin_password }} admin"
          no_log: true
          changed_when: true
          register: create_admin_principal
          environment:
            PATH: "{{ ansible_env.PATH }}:{{ kerberos_env_path }}"
      rescue:
        - name: Create admin principal failed
          fail:
            msg: "Error: {{ create_admin_principal.stderr }}"
    
    - block:
        - name: Authenticate as admin
          shell: set -o pipefail && echo {{ ms_kerberos_admin_password }} | kinit admin
          no_log: true
          changed_when: false
          register: authenticate_admin
      rescue:
        - name: Authenticate as admin failed
          fail:
            msg: "Error: {{ authenticate_admin.stderr }}"

    - name: Install sssd packages
      zypper:
        name: "{{ sssd_packages }}"
        state: present
      
    - name: Stop and disable nscd
      systemd:
        name: nscd
        state: stopped
        enabled: no
      when: "'nscd.service' in ansible_facts.services"

    - name: Check admin group in 389-ds
      command: dsidm {{ ldap_instance }} group list
      register: check_admin_group
      changed_when: false

    - name: Create admin group in 389-ds
      shell: set -o pipefail && echo {{ admin_group_name }} |  dsidm {{ ldap_instance }} group create
      changed_when: true
      when: admin_group_name not in check_admin_group.stdout

    - name: Create the sssd.conf file
      copy:
        src: "{{ role_path }}/files/temp_sssd.conf"
        dest: "{{ sssd_config_path }}"
        mode: "{{ sssd_file_mode }}"       

    - name: Configure sssd.conf with domain name
      replace:
        path: "{{ sssd_config_path }}"
        regexp: "dc=omnia,dc=test"
        replace: "dc={{ domain_name.split('.')[0] }},dc={{ domain_name.split('.')[1] }}"

    - name: Start sssd service
      systemd:
        name: sssd
        state: started
        enabled: yes

    - block:
        - name: Configure password policy in 389-ds
          command: dsconf -w {{ ms_directory_manager_password }} -D "cn=Directory Manager" ldap://{{ server_hostname_ms }} pwpolicy set --pwdlockoutduration {{ lockout_duration }} --pwdmaxfailures {{ max_failures }} --pwdresetfailcount {{ failure_reset_interval }}
          no_log: true
          changed_when: true
          register: configure_pwpolicy
      rescue:
        - name: Configure password policy in 389-ds failed
          fail:
            msg: "Error: {{ configure_pwpolicy.stderr }}"
  when: not ds389_status