---

### tags:
###   users
###   install
###   upgrade
###   config
###   update_etc_hosts
###   root_authorized_keys

- name: "Set hostname to <{{ inventory_hostname }}>"
  hostname:
    name: "{{ inventory_hostname }}"

- name: "Setting hosts configuration in /etc/hosts"
  blockinfile:
    marker: "# {mark} managed by ansible (hosts config for {{ inventory_hostname }})"
    path: "/etc/hosts"
    mode: '0644'
    state: present
    create: yes
    block: |
      {% for host in shared_service_hosts %}
      {{ host.ip }} {{ host.name }}
      {% endfor %}
  when:
    - "'hcloud' in group_names"
  tags:
    - update_etc_hosts

- name: "Adding authorized keys for root"
  ansible.posix.authorized_key:
    user: root
    state: present
    key: "{{ lookup('file', 'users/' + item + '/ssh.pub') }}"
  loop: '{{ smardigo_plattform_users }}'
  tags:
    - users
    - root_authorized_keys

# ansible-lint related hint
# https://github.com/ansible-community/ansible-lint/issues/1621
# => issue whitelisted
- name: "Removing outdated authorized keys for root" # noqa deprecated-bare-vars
  ansible.posix.authorized_key:
    user: root
    state: absent
    key: "{{ lookup('file', 'users/outdated/' + item.path) }}"
  with_community.general.filetree: users/outdated/
  tags:
    - users
    - root_authorized_keys

- name: "Read current users" # noqa risky-shell-pipe
  shell: "getent passwd | awk -F: '$3 > 999 {print $1}'"
  register: current_users
  changed_when: false
  tags:
    - users

- name: "Remove outdated users"
  user: name={{ item }} state=absent remove=yes
  with_items: "{{ current_users.stdout_lines }}"
  when: not ((item in default_users) or (item in smardigo_plattform_users))
  tags:
    - users

- name: "Create users"
  ansible.builtin.user:
    name: '{{ item }}'
    groups: '{{ sudo_group }}'
    shell: '/bin/bash'
    state: present
    append: yes
  loop: '{{ smardigo_plattform_users }}'
  loop_control:
    index_var: index
  tags:
    - users

- name: "Enable passwordless sudo"
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    state: present
    regexp: '^%sudo'
    line: '%sudo ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'
  tags:
    - users

# TODO check usage of key_options "no-agent-forwarding, no-agent-forwarding, no-X11-forwarding"
- name: "Set up authorized users"
  ansible.posix.authorized_key:
    user: '{{ item }}'
    state: present
    exclusive: true
    key: "{{ lookup('file', '{{ playbook_dir }}/users/{{ item }}/ssh.pub') }}"
  loop: '{{ smardigo_plattform_users | difference(["elastic"]) }}'
  tags:
    - users

- name: "Update available package list"
  apt:
    update_cache: yes
  tags:
    - install
    - upgrade
  when: ansible_distribution == "Ubuntu"

- name: "Ensure docker configuration directory exists"
  file:
    path: '/home/{{ item }}/.docker/'
    state: directory
    owner: '{{ item }}'
    group: '{{ item }}'
    mode: '0755'
  loop: '{{ smardigo_plattform_users }}'
  when: docker_enabled
  tags:
    - users
    - config

- name: "Insert/Update docker configuration"
  template:
    src: 'configs/docker/config.json.j2'
    dest: '/home/{{ item }}/.docker/config.json'
    owner: '{{ item }}'
    group: '{{ item }}'
    mode: 0600
  loop: '{{ smardigo_plattform_users }}'
  when:
    - docker_enabled
    - docker_config_enabled
  tags:
    - users
    - config

- name: "Install apt-dependencies for {{ inventory_hostname }}"
  apt:
    name: "{{ item }}"
    state: 'present'
  loop: "{{ common_apt_dependencies + additional_apt_dependencies | default([]) }}"
  when: ansible_distribution == "Ubuntu"
  tags:
    - install

- name: "Install python3-pip dependencies for {{ inventory_hostname }}"
  pip:
    name: "{{ item }}"
    state: present
  become: True
  loop: "{{ common_pip_dependencies + additional_pip_dependencies | default([]) }}"
  tags:
    - install

- name: 'Ensures </etc/bash_completion.d> directory exists'
  file:
    state: directory
    path: '/etc/bash_completion.d'
    mode: '0755'
  tags:
    - install

- name: "Download docker bash completion"
  ansible.builtin.get_url:
    url: https://raw.githubusercontent.com/docker/cli/v20.10.6/contrib/completion/bash/docker
    dest: /etc/bash_completion.d/docker
    mode: '644'
  when: docker_enabled
  tags:
    - install

- name: "Download docker-compose bash completion"
  ansible.builtin.get_url:
    url: "https://raw.githubusercontent.com/docker/compose/{{ docker_compose_version }}/contrib/completion/bash/docker-compose"
    dest: "/etc/bash_completion.d/docker-compose"
    mode: '0644'
  when: docker_enabled
  tags:
    - install

- name: "Ensure docker configuration directory exists"
  file:
    path: '/root/.docker/'
    state: directory
    owner: 'root'
    group: 'root'
    mode: '0755'
  when: docker_enabled
  tags:
    - config

- name: "Insert/Update docker configuration"
  template:
    src: 'configs/docker/config.json.j2'
    dest: '/root/.docker/config.json'
    owner: 'root'
    group: 'root'
    mode: 0600
  when:
    - docker_enabled
    - docker_config_enabled
  tags:
    - config

- name: "Ensure docker daemon configuration directory exists"
  file:
    path: '/etc/docker'
    state: directory
    owner: 'root'
    group: 'root'
    mode: '0755'
  when: docker_enabled
  tags:
    - config

- name: "Remove docker daemon configuration when docker_enabled=false"
  file:
    state: absent
    path: '/etc/docker/daemon.json'
  when: not docker_enabled
  tags:
    - config

- name: "Insert/Update docker daemon configuration"
  template:
    src: 'configs/docker/daemon.json.j2'
    dest: '/etc/docker/daemon.json'
    owner: 'root'
    group: 'root'
    mode: 0600
  when: docker_enabled
  tags:
    - config

- name: "Create Docker network"
  community.docker.docker_network:
    name: "{{ item }}"
  when: docker_enabled
  loop:
    - front-tier
    - back-tier

- name: sshd configuration file update
  template:
    src: 'configs/sshd/sshd_config.j2'
    dest: '/etc/ssh/sshd_config.new'
    owner: 'root'
    group: 'root'
    mode: 0644
  notify:
    - restart ssh

# elasticsearch production mode requirements
- name: "Set vm.max_map_count"
  sysctl:
    name: vm.max_map_count
    value: '262144'
    sysctl_set: yes
    state: present
  tags:
    - config

# elasticsearch production mode requirements
- name: "Set fs.file-max"
  sysctl:
    name: fs.file-max
    value: '65536'
    sysctl_set: yes
    state: present
  tags:
    - config

- name: "configure ssh_hardening"
  include_role:
    # include role from collection called 'devsec'
    name: devsec.hardening.ssh_hardening
    apply:
      tags:
        - ssh_hardening
  tags:
    - ssh_hardening
