# This test uses skip_host_check, so it will fail if not using
# FreeIPA version 4.7.0 or later.
#
# To test against earlier versions, use test_without_skip_host_check.yml.
#
# This test define 6 hosts:
#    - nohost_fqdn: a host with a DNS setup, not enrolled as a host in IPA.
#    - no.idontexist.info: a host without DNS and not present in IPA.
#    - svc.ihavenodns.inf: a host without DNS, but present in IPA.
#    - svc_fqdn: a host with DNS and present in IPA.
#    - host1_fqdn and host2_fqdn: used for member actions only.
#
---
- name: Test service
  hosts: "{{ ipa_test_host | default('ipaserver') }}"
  become: yes

  tasks:
  # setup
  - name: Include tasks ../env_freeipa_facts.yml
    ansible.builtin.include_tasks: ../env_freeipa_facts.yml

  # tests
  - name: Tests with skip_host_check, require IPA version 4.8.0+.
    when: ipa_version is version('4.7.0', '>=')
    block:
      - name: Setup test environment
        ansible.builtin.include_tasks: env_setup.yml

      - name: Ensure service is present
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          pac_type:
            - MS-PAC
            - PAD
          auth_ind: otp
          skip_host_check: no
          force: yes
          requires_pre_auth: yes
          ok_as_delegate: no
          ok_to_auth_as_delegate: no
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is present, again
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          pac_type:
            - MS-PAC
            - PAD
          auth_ind: otp
          skip_host_check: no
          force: no
          requires_pre_auth: yes
          ok_as_delegate: no
          ok_to_auth_as_delegate: no
        register: result
        failed_when: result.changed or result.failed

      - name: Modify service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          pac_type: NONE
          ok_as_delegate: yes
          ok_to_auth_as_delegate: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Modify service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          pac_type: NONE
          ok_as_delegate: yes
          ok_to_auth_as_delegate: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure service is present, without host object.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ nohost_fqdn }}"
          skip_host_check: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is present, without host object, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ nohost_fqdn }}"
          skip_host_check: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure service is present, with host not in DNS.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: HTTP/svc.ihavenodns.info
          skip_host_check: no
          force: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is present, with host not in DNS, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: HTTP/svc.ihavenodns.info
          skip_host_check: no
          force: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure service is present, whithout host object and with host not in DNS.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: HTTP/no.idontexist.info
          skip_host_check: yes
          force: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is present, whithout host object and with host not in DNS, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: HTTP/no.idontexist.info
          skip_host_check: yes
          force: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Principal host/test.example.com present in service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          principal:
            - host/test.example.com
          action: member
        register: result
        failed_when: not result.changed or result.failed

      - name: Principal host/test.example.com present in service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          principal:
            - host/test.example.com
          action: member
        register: result
        failed_when:
          result.changed or (result.failed and "already contains one or more values" not in result.msg)

      - name: Principal host/test.example.com absent in service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          principal:
            - host/test.example.com
          action: member
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Principal host/test.example.com absent in service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          principal:
            - host/test.example.com
          action: member
          state: absent
        register: result
        failed_when:
          result.changed or (result.failed and "does not contain 'one or more values to remove'" not in result.msg)

      - name: Ensure host can manage service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          action: member
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure host can manage service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          host: "{{ host1_fqdn }}"
          action: member
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure host cannot manage service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          action: member
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure host cannot manage service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          action: member
          state: absent
        register: result
        failed_when: result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_create_keytab_user:
          - user01
          - user02
          allow_create_keytab_group:
          - group01
          - group02
          allow_create_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_create_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
        register: result
        failed_when: not result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_create_keytab_user:
          - user01
          - user02
          allow_create_keytab_group:
          - group01
          - group02
          allow_create_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_create_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
        register: result
        failed_when: result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_create_keytab_user:
          - user01
          - user02
          allow_create_keytab_group:
          - group01
          - group02
          allow_create_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_create_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_create_keytab_user:
          - user01
          - user02
          allow_create_keytab_group:
          - group01
          - group02
          allow_create_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_create_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
          state: absent
        register: result
        failed_when: result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_retrieve_keytab_user:
          - user01
          - user02
          allow_retrieve_keytab_group:
          - group01
          - group02
          allow_retrieve_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_retrieve_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
        register: result
        failed_when: not result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_retrieve_keytab_user:
          - user01
          - user02
          allow_retrieve_keytab_group:
          - group01
          - group02
          allow_retrieve_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_retrieve_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
        register: result
        failed_when: result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_retrieve_keytab_user:
          - user01
          - user02
          allow_retrieve_keytab_group:
          - group01
          - group02
          allow_retrieve_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_retrieve_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          allow_retrieve_keytab_user:
          - user01
          - user02
          allow_retrieve_keytab_group:
          - group01
          - group02
          allow_retrieve_keytab_host:
          - "{{ host1_fqdn }}"
          - "{{ host2_fqdn }}"
          allow_retrieve_keytab_hostgroup:
          - hostgroup01
          - hostgroup02
          action: member
          state: absent
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure service is absent
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          continue: yes
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is absent, again
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          continue: yes
          state: absent
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure service is present, with multiple auth_ind values.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          auth_ind: otp,radius
          skip_host_check: no
          force: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure service is present, with multiple auth_ind values, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          auth_ind: otp,radius
          skip_host_check: no
          force: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Clear auth_ind.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          auth_ind: ""
          skip_host_check: no
          force: yes
        register: result
        failed_when: not result.changed or result.failed

      - name: Clear auth_ind, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "HTTP/{{ svc_fqdn }}"
          auth_ind: ""
          skip_host_check: no
          force: yes
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure services are absent.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name:
          - "HTTP/{{ svc_fqdn }}"
          - "HTTP/{{ nohost_fqdn }}"
          - HTTP/svc.ihavenodns.info
          - HTTP/no.idontexist.local
          continue: yes
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure services are absent.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name:
          - "HTTP/{{ svc_fqdn }}"
          - "HTTP/{{ nohost_fqdn }}"
          - HTTP/svc.ihavenodns.info
          - HTTP/no.idontexist.local
          continue: yes
          state: absent
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure SMB service is present.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "{{ host1_fqdn }}"
          pac_type: NONE
          smb: yes
          netbiosname: SAMBASVC
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure SMB service is again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "{{ host1_fqdn }}"
          pac_type: NONE
          smb: yes
          netbiosname: SAMBASVC
        register: result
        failed_when: result.changed or result.failed

      - name: Modify SMB service.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "{{ host1_fqdn }}"
          smb: yes
          netbiosname: SAMBASVC
          allow_retrieve_keytab_user:
            - user01
            - user02
          allow_retrieve_keytab_group:
            - group01
            - group02
        register: result
        failed_when: not result.changed or result.failed

      - name: Modify SMB service, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "{{ host1_fqdn }}"
          smb: yes
          netbiosname: SAMBASVC
          allow_retrieve_keytab_user:
            - user01
            - user02
          allow_retrieve_keytab_group:
            - group01
            - group02
        register: result
        failed_when: result.changed or result.failed

      - name: Ensure SMB service is absent.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "cifs/{{ host1_fqdn }}"
          continue: yes
          state: absent
        register: result
        failed_when: not result.changed or result.failed

      - name: Ensure SMB service is absent, again.
        ipaservice:
          ipaadmin_password: SomeADMINpassword
          ipaapi_context: "{{ ipa_context | default(omit) }}"
          name: "cifs/{{ host1_fqdn }}"
          continue: yes
          state: absent
        register: result
        failed_when: result.changed or result.failed

      # cleanup
      - name: Cleanup test environment
        ansible.builtin.include_tasks: env_cleanup.yml
