# Test code for ssh_config module
# Copyright (c) 2021, Abhijeet Kasurde (@Akasurde) <akasurde@redhat.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Install required libs
  pip:
    name:
      - stormssh
      - 'paramiko<3.0.0'
    state: present
    extra_args: "-c {{ remote_constraints }}"

- set_fact:
    output_test_dir: '{{ remote_tmp_dir }}/test_ssh_config'

- set_fact:
    ssh_config_test: '{{ output_test_dir }}/ssh_config_test'
    ssh_private_key: '{{ output_test_dir }}/fake_id_rsa'

- name: create a temporary directory
  file:
    path: "{{ output_test_dir }}"
    state: directory

- name: Copy sample config file
  copy:
    src: 'files/ssh_config_test'
    dest: '{{ ssh_config_test }}'

- name: Copy sample private key file
  copy:
    src: 'files/fake_id_rsa'
    dest: '{{ ssh_private_key }}'

- name: Fail for required argument
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
  ignore_errors: yes
  register: host_required

- name: Check if ssh_config fails for required parameter host
  assert:
    that:
      - not host_required.changed

- name: Add a host in check mode
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: host_add
  check_mode: yes

- name: Check if changes are made in check mode
  assert:
    that:
      - host_add.changed
      - "'example.com' in host_add.hosts_added"
      - host_add.hosts_changed is defined
      - host_add.hosts_removed is defined

- name: Add a host
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: host_add

- name: Check if changes are made
  assert:
    that:
      - host_add.changed
      - "'example.com' in host_add.hosts_added"
      - host_add.hosts_changed is defined
      - host_add.hosts_removed is defined

- name: Add same host again for idempotency
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: host_add_again

- name: Check for idempotency
  assert:
    that:
      - not host_add_again.changed
      - host_add.hosts_changed is defined
      - host_add.hosts_removed is defined
      - host_add.hosts_added is defined

- name: Update host
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2224'
    state: present
  register: host_update

- name: Check for update operation
  assert:
    that:
      - host_update.changed
      - host_update.hosts_changed is defined
      - "'example.com' in host_update.hosts_changed"
      - host_update.hosts_removed is defined
      - host_update.hosts_added is defined
      - host_update.hosts_change_diff is defined

- name: Update host again
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2224'
    state: present
  register: host_update

- name: Check update operation for idempotency
  assert:
    that:
      - not host_update.changed
      - host_update.hosts_changed is defined
      - host_update.hosts_removed is defined
      - host_update.hosts_added is defined
      - host_update.hosts_change_diff is defined

- name: Delete a host
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    state: absent
  register: host_delete

- name: Check if changes are made
  assert:
    that:
      - host_delete.changed
      - "'example.com' in host_delete.hosts_removed"
      - host_delete.hosts_changed is defined
      - host_delete.hosts_added is defined

- name: Delete same host again for idempotency
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "example.com"
    hostname: github.com
    state: absent
  register: host_delete_again

- name: Check for idempotency
  assert:
    that:
      - not host_delete_again.changed
      - host_delete_again.hosts_changed is defined
      - host_delete_again.hosts_removed is defined
      - host_delete_again.hosts_added is defined

- name: Check if user and ssh_config_file are mutually exclusive
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    user: root
    host: "example.com"
    hostname: github.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: mut_ex
  ignore_errors: yes

- name: Check mutual exclusive test - user and ssh_config_file
  assert:
    that:
      - not mut_ex.changed
      - "'parameters are mutually exclusive' in mut_ex.msg"

- name: Add a full name host
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "full_name"
    hostname: full_name.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: full_name

- name: Check if changes are made
  assert:
    that:
      - full_name is changed
      - full_name.hosts_added == ["full_name"]
      - full_name.hosts_changed == []
      - full_name.hosts_removed == []

- name: Add a host with name which is contained in full name host
  community.general.ssh_config:
    ssh_config_file: "{{ ssh_config_test }}"
    host: "full"
    hostname: full.com
    identity_file: '{{ ssh_private_key }}'
    port: '2223'
    state: present
  register: short_name

- name: Check that short name host is added and full name host is not updated
  assert:
    that:
      - short_name is changed
      - short_name.hosts_added == ["full"]
      - short_name.hosts_changed == []
      - short_name.hosts_removed == []

- name: Include integration tests for additional options (e.g. proxycommand)
  include: 'options.yml'
