---

### tags:
###   harbor-configure-base

- name: "Initialze VARs"
  set_fact:
    token_object_combined: {}
  tags:
    - harbor-configure-robots

- name: "Get all robot tokens"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/robots"
    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_robot_tokens
  delay: 10
  retries: 3
  no_log: true
  tags:
    - harbor-configure-robots

- name: "Create robot token"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/robots"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: POST
    body_format: json
    body: '{{ token_object | to_json }}'
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200,201]
  register: create
  delay: 10
  retries: 3
  until: create.status in [200,201]
  when:
    - all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | length == 0
    - token_state == 'present'
  tags:
    - harbor-configure-robots

- name: "Set VARs if current robot token object already exists"
  set_fact:
    robots_id: "{{ ( all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | first ).id }}"
    remote_robot_token_object: "{{ all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | first }}"
    token_object_combined: "{{ all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | first | combine(token_object, recursive=True) }}"
    token_object_dropped: {}
  when:
    - all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | length == 1
  tags:
    - harbor-configure-robots

- name: "Refresh the robot secret"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/robots/{{ robots_id }}"
    user: '{{ harbor_admin_username }}'
    password: '{{ harbor_admin_password }}'
    method: PATCH
    body_format: json
    body: >-
        {{
          (
            {
              "secret": token_object.secret
            }
          )
        }}
    force_basic_auth: yes
    headers:
      Content-Type: application/json
    status_code: [200]
  register: update
  delay: 10
  retries: 3
  until: update.status in [200]
  when:
    - all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | length == 1
    - token_state == 'present'
    - token_object.secret_refresh is defined
    - token_object.secret_refresh
  no_log: true
  tags:
    - harbor-configure-robots

- name: "Block to Update robot token data"
  block:
  - name: "DEBUG"
    debug:
      msg: "DEBUGGING before dropping - combined token_object_combined: {{ token_object_combined }}"
    when:
      - debug
    tags:
      - harbor-configure-robots

  # unknown param/key in object robot-token will result in errors with harbor API
  # therefore we drop $keys from dict
  - name: "Drop some keys from updated robot token object"
    set_fact:
      token_object_dropped: "{{ token_object_dropped | combine( { item.key: item.value } ) }}"
    with_dict: "{{ token_object_combined }}"
    when:
      - item.key not in ['secret','secret_refresh']
    tags:
      - harbor-configure-robots

  # harbor API behaviour:
  # in case of initial creation for robot token objects, harbor creates a name for this
  # in form of << robot$OBJECT_NAME >> - plz be aware of the dollar sign!
  # but only the OBJECT_NAME was defined in object declaration.
  # In case of updating we have to make sure that the << robot$OBJECT_NAME >> is used in the
  # updated object thrown against harbor API.
  #
  # so harbor API forces me to create this workaround to avoid such errors
  #
  # part 1: define name of object
  - name: "Set fact"
    set_fact:
      robot_token_name_cleaned:
        name: 'robot${{ token_object_dropped.name }}'
    tags:
      - harbor-configure-robots

  # part 2: override name with new defined name of object
  - name: "Set fact"
    set_fact:
      token_object_finished: '{{ token_object_dropped | combine(robot_token_name_cleaned, recursive=True) }}'
    tags:
      - harbor-configure-robots

  - name: "DEBUG"
    debug:
      msg: "DEBUGGING after dropping - combined token_object_finished: {{ token_object_finished }}"
    when:
      - debug

  # to update a robot token, the following conditions must be satisfied
  #   1. ALL params of robot token object must be set
  #   1.1. except the secret param - it must be removed/rejected from object - it will be updated with PATCH-method instead of PUT-method
  #   2. the update (of parameter) itself
  #
  # there is no possibility to update if one of mentioned conditions is not statisfied.
  # the API call will fail with one of the following errors:
  #    - HTTP 400 - "cannot update the level or name of robot"
  #    - HTTP 400 - "bad request error level input:"
  #
  - name: "Update robot token object"
    delegate_to: 127.0.0.1
    become: false
    uri:
      url: "{{ harbor_external_url }}/api/v2.0/robots/{{ robots_id }}"
      user: '{{ harbor_admin_username }}'
      password: '{{ harbor_admin_password }}'
      method: PUT
      body_format: json
      body: '{{ token_object_finished | to_json }}'
      force_basic_auth: yes
      headers:
        Content-Type: application/json
      status_code: [200]
    register: update
    delay: 10
    retries: 3
    until: update.status in [200]
    no_log: true
    tags:
      - harbor-configure-robots

# when - part of BLOCK-statement
  when:
    - all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | length == 1
    - token_state == 'present'
  tags:
    - harbor-configure-robots
# end of BLOCK to Update robot token data

- name: "Delete robot token"
  delegate_to: 127.0.0.1
  become: false
  uri:
    url: "{{ harbor_external_url }}/api/v2.0/robots/{{ robots_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]
  register: delete_project_member
  delay: 10
  retries: 3
  until: delete_project_member.status in [200]
  when:
    - all_robot_tokens.json | selectattr('name','contains',token_object.name) | list | length == 1
    - token_state == 'absent'
