---

- name: "Initialze VARs due to hardcoded stuff in harbor API"
  set_fact:
    member_state: '{{ member.member_state | default("present") }}'
    harbor_member_roles:
      -
        name: projectadmin
        role_id: 1
      -
        name: developer
        role_id: 2
      -
        name: guest
        role_id: 3
      -
        name: maintainer
        role_id: 4
    harbor_member_grouptypes:
      -
        name: ldap
        group_type: 1 
      -
        name: http
        group_type: 2
      -
        name: oidc
        group_type: 3

- name: "Get all project members"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/projects/{{ project_name }}/members"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: GET
    body_format: json
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200]
  register: all_project_members
  delay: 10
  retries: 3

- name: "Set fact"
  set_fact:
    group_type: "{{ ( harbor_member_grouptypes | selectattr('name','==',( member.group_type | lower )) | list | first ).group_type }}"
    role_id: "{{ ( harbor_member_roles | selectattr('name','==',( member.role| lower ) ) | list | first ).role_id | int }}"

# creating body manual due to problems with IDs as integer - they will be converted to string in json
# => every API request will fail
# see also:
# https://stackoverflow.com/questions/69677986/converting-string-to-integer-in-ansible
- name: "Create membership"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/projects/{{ project_name }}/members"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: POST
    body_format: json
    body: >-
      {{
        (
          {
            "role_id": role_id | int,
            "member_group": {
              "group_name": member.group_name,
              "group_type": group_type | int
            }
          }
        ) | to_json }}
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200,201]
  register: create_project_member
  delay: 10
  retries: 3
  until: create_project_member.status in [200,201]
  when: 
    - all_project_members.json | selectattr('entity_name','equalto',member.group_name) | list | length == 0
    - member_state == 'present' 

- name: "Update member: <<{{ member.group_name }}>>"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/projects/{{ project_name }}/members/{{ ( all_project_members.json | selectattr('entity_name','equalto',member.group_name) | list | first ).id }}"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: PUT
    body_format: json
    body: >-
      {{
        (
          {
            "role_id": role_id | int,
            "member_group": {
              "group_name": member.group_name,
              "group_type": group_type | int
            }
          }
        ) | to_json }}
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200,201]
  register: update_project_member
  delay: 10
  retries: 3
  until: update_project_member.status in [200,201]
  when: 
    - all_project_members.json | selectattr('entity_name','equalto',member.group_name) | list | length == 1
    - member_state == 'present' 

- name: "Delete member: <<{{ member.group_name }}>>"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/projects/{{ project_name }}/members/{{ ( all_project_members.json | selectattr('entity_name','equalto',member.group_name) | list | first ).id }}"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: DELETE
    body_format: json
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200,201]
  register: delete_project_member
  delay: 10
  retries: 3
  until: delete_project_member.status in [200,201]
  when: 
    - all_project_members.json | selectattr('entity_name','equalto',member.group_name) | list | length == 1
    - member_state == 'absent'
