---
# file: roles/minio/tasks/main.yml

- name: "create minio-user group"
  ansible.builtin.group:
    name: minio-user
    system: true
  tags: minio

- name: "create minio-user user"
  ansible.builtin.user:
    name: minio-user
    system: true
    shell: "/usr/sbin/nologin"
  tags: minio

- name: "handle secret {{ ansible_hostname }}/minio_root_password"
  block:
    - name: "get {{ ansible_hostname }}/minio_root_password from hashicorp vault"
      ansible.builtin.set_fact:
        "minio_root_password": "{{ lookup('hashi_vault', 'secret=talas-kv/data/' + host_vars_location + '/' + ansible_hostname)['minio_root_password'] }}"
  rescue:
    - name: "generate a random password for {{ ansible_hostname }}/minio_root_password"
      ansible.builtin.set_fact:
        password: "{{ lookup('password','/dev/null chars=ascii_letters,digits length=50') }}"
    - name: "patching hashicorp vault with generated minio_root_password"
      ansible.builtin.command: "vault kv patch talas-kv/{{ host_vars_location }}/{{ ansible_hostname }} minio_root_password={{ password }}"
      delegate_to: localhost
      become: false
      register: result
      ignore_errors: True
    - name: "patch failed because the entry doesn't exist, creating it instead"
      ansible.builtin.command: "vault kv put talas-kv/{{ host_vars_location }}/{{ ansible_hostname }} minio_root_password={{ password }}"
      delegate_to: localhost
      become: false
      when:
        - result.failed
        - '"No value found" in result.stderr'
    - name: "assign password value to minio_root_password"
      ansible.builtin.set_fact:
        minio_root_password: "{{ password }}"
  tags:
    - minio
    - minio_server

- name: "/etc/default/minio"
  ansible.builtin.template:
    src: etc_default_minio.j2
    dest: /etc/default/minio
    group: minio-user
  register: minio_conf
  tags: minio

- name: "chown /srv/minio"
  ansible.builtin.file:
    path: /srv/minio
    state: directory
    owner: minio-user
    group: minio-user
  tags: minio

- name: "import minio_server tasks"
  ansible.builtin.import_tasks: minio_server.yml
  when: not ansible_check_mode
  tags:
    - minio
    - minio_server

- name: "make sure minio is enabled and started"
  ansible.builtin.systemd:
    name: minio
    enabled: true
    state: started
  tags: minio

- name: "restart minio if conf was changed"
  ansible.builtin.systemd:
    name: minio
    state: restarted
  when: minio_conf.changed
  tags: minio

- name: "set minio_port"
  ansible.builtin.set_fact:
    minio_port: "{% if minio_haproxy %}9002{% else %}9000{% endif %}"
  tags:
    - minio
    - minio_buckets
    - minio_users

- name: "handle mcli alias minio_on_localhost"
  block:
    - name: "mcli admin info minio_on_localhost --json"
      ansible.builtin.command: "mcli admin info minio_on_localhost --json"
      register: minio_info
      failed_when: "'success' not in minio_info.stdout|from_json|json_query('status')"
      changed_when: false
  rescue:
    - name: "mcli alias set minio_on_localhost http://localhost:{{ minio_port }} minioadmin"
      ansible.builtin.command: "mcli alias set minio_on_localhost http://localhost:{{ minio_port }} minioadmin {{ minio_root_password }}"
  tags: minio

- name: "include minio_buckets tasks"
  ansible.builtin.include_tasks:
    file: minio_buckets.yml
    apply:
      tags:
        - minio
        - minio_buckets
  loop: "{{ minio_buckets }}"
  loop_control:
    loop_var: minio_bucket
  when: minio_buckets is defined
  tags:
    - minio
    - minio_buckets

- name: "get ldap config"
  ansible.builtin.command:
    cmd: mcli idp ldap info minio_on_localhost --json
  register: check_ldap_config
  changed_when: false
  check_mode: false
  tags:
    - minio
    - minio_users

- name: "set up ldap connection"
  ansible.builtin.command:
    cmd: >
      mcli idp ldap add minio_on_localhost/ --json \
      server_addr=ldap.talas.com \
      lookup_bind_dn=uid={{ ansible_hostname }},ou=servers,dc=talas,dc=com \
      lookup_bind_password={{ ldappass }} \
      user_dn_search_base_dn=ou=people,dc=talas,dc=com \
      user_dn_search_filter='(&(uid=%s)(CosStatus=active)(|(objectClass=CosAccount)(objectClass=CosHostingAccount)(objectClass=CosBot)))'
      group_search_base_dn=ou=groups,dc=talas,dc=com \
      group_search_filter='(&(objectclass=posixGroup)(memberUid=%s))'
  register: setup_ldap
  failed_when: "'success' not in setup_ldap.stdout|from_json|json_query('status')"
  when:
    - minio_auth_type == "ldap"
    - not check_ldap_config.stdout|from_json|json_query('info')
  tags:
    - minio
    - minio_users

- name: "enable ldap auth_type"
  ansible.builtin.command:
    cmd: mcli idp ldap enable minio_on_localhost --json
  register: minio_ldap_enable
  when:
    - minio_auth_type == "ldap"
    - check_ldap_config.stdout|from_json|json_query(json_query_request)|length>0 and check_ldap_config.stdout|from_json|json_query(json_query_request)|first != "on"
  vars:
    json_query_request: "info[?key=='enable'].value"
  tags:
    - minio
    - minio_users

- name: "disable ldap auth_type"
  ansible.builtin.command:
    cmd: mcli idp ldap disable minio_on_localhost --json
  register: minio_ldap_disable
  when:
    - minio_auth_type == "local"
    - check_ldap_config.stdout|from_json|json_query(json_query_request)|length>0 and check_ldap_config.stdout|from_json|json_query(json_query_request)|first == "on"
  vars:
    json_query_request: "info[?key=='enable'].value"
  tags:
    - minio
    - minio_users

- name: "restart minio if required and if minio_restart_on_auth_type_change is true"
  ansible.builtin.systemd:
    name: "minio.service"
    state: restarted
  when:
    - setup_ldap is not skipped or minio_ldap_disable is not skipped or minio_ldap_enable is not skipped
    - minio_restart_on_auth_type_change
  tags:
    - minio
    - minio_users

- name: "include minio_ldap_users tasks"
  ansible.builtin.include_tasks:
    file: minio_ldap_users.yml
    apply:
      tags:
        - minio
        - minio_users
  loop: "{{ minio_users }}"
  loop_control:
    loop_var: minio_user
  when:
    - minio_auth_type == "ldap"
    - minio_users is defined
  tags:
    - minio
    - minio_users

- name: "include minio_local_users tasks"
  ansible.builtin.include_tasks:
    file: minio_local_users.yml
    apply:
      tags:
        - minio
        - minio_users
  loop: "{{ minio_users }}"
  loop_control:
    loop_var: minio_user
  when:
    - minio_users is defined
    - minio_auth_type == "local"
  tags:
    - minio
    - minio_users

- name: "/home/minio-user/policies"
  ansible.builtin.file:
    path: /home/minio-user/policies
    state: directory
    owner: minio-user
    group: minio-user
    mode: 0750
  tags:
    - minio
    - minio_policies

- name: "set minio_bucket_policies.policy"
  ansible.builtin.set_fact:
    minio_bucket_policies: "{{ (minio_bucket_policies | difference([item.1])) + ([ item.1 | combine({'policy' : item.1.bucket + '_' + item.1.permissions })]) }}"
  with_indexed_items: "{{ minio_bucket_policies }}"
  when: minio_bucket_policies is defined
  tags:
    - minio
    - minio_policies

- name: "/home/minio-user/policies/minio_policy.json"
  ansible.builtin.template:
    src: "minio_policy.json.j2"
    dest: "/home/minio-user/policies/{{ item.policy }}.json"
    backup: true
  register: minio_upload_policies
  loop: "{{ minio_bucket_policies }}"
  when: minio_bucket_policies is defined
  tags:
    - minio
    - minio_policies

- name: "add changed policy {{ item.item.policy }}"
  ansible.builtin.command: "mcli admin policy create minio_on_localhost {{ item.item.policy }} /home/minio-user/policies/{{ item.item.policy }}.json --json"
  register: add_policy
  failed_when: "'success' not in add_policy.stdout|from_json|json_query('status')"
  loop: "{{ minio_upload_policies.results }}"
  when:
    - minio_bucket_policies is defined
    - item.changed
  tags:
    - minio
    - minio_policies

- name: "get policy {{ item.policy }}"
  ansible.builtin.command: "mcli admin policy info minio_on_localhost {{ item.policy }} --json"
  failed_when: false
  changed_when: false
  check_mode: false
  register: minio_get_policy
  loop: "{{ minio_bucket_policies }}"
  when:
    - minio_bucket_policies is defined
  tags:
    - minio
    - minio_policies

- name: "add policy missing {{ item.item.policy }}"
  ansible.builtin.command: "mcli admin policy create minio_on_localhost {{ item.item.policy }} /home/minio-user/policies/{{ item.item.policy }}.json --json"
  register: add_policy
  failed_when: "'success' not in add_policy.stdout|from_json|json_query('status')"
  loop: "{{ minio_get_policy.results }}"
  when:
    - minio_bucket_policies is defined
    - "'success' not in item.stdout|from_json|json_query('status')"
  tags:
    - minio
    - minio_policies

- name: "include minio_policies tasks buckets"
  ansible.builtin.include_tasks:
    file: minio_policies.yml
    apply:
      tags:
        - minio
        - minio_policies
  loop: "{{ minio_bucket_policies }}"
  loop_control:
    loop_var: minio_policy
  when: minio_bucket_policies is defined
  tags:
    - minio
    - minio_policies

- name: "include minio_anonymous_policies tasks buckets"
  ansible.builtin.include_tasks:
    file: minio_anonymous_policies.yml
    apply:
      tags:
        - minio
        - minio_policies
  loop: "{{ minio_anonymous_policies }}"
  when: minio_anonymous_policies is defined
  tags:
    - minio
    - minio_policies

- name: "include minio_policies tasks add ldap group minio-admin policy consoleAdmin"
  ansible.builtin.set_fact:
    minio_global_policies: "{{ minio_global_policies | default([]) + minio_global_admin }}"
  vars:
    minio_global_admin:
      - policy: "consoleAdmin"
        groups:
          - "cn=minio-admin,ou=system,ou=groups,dc=talas,dc=com"
  when: minio_auth_type == "ldap"
  tags:
    - minio
    - minio_policies

- name: "include minio_policies tasks global"
  ansible.builtin.include_tasks:
    file: minio_policies.yml
    apply:
      tags:
        - minio
        - minio_policies
  loop: "{{ minio_global_policies }}"
  loop_control:
    loop_var: minio_policy
  when: minio_global_policies is defined
  tags:
    - minio
    - minio_policies
