#!/usr/bin/ansible-playbook --module-path=../../../library/
#
# ./oc_label.yml -e "cli_master_test=$OPENSHIFT_MASTER
#
---
- hosts: "{{ cli_master_test }}"
  gather_facts: no

  vars:
  - def_namespace: default
  - def_kind: node

  pre_tasks:
  - name: ensure needed vars are defined
    fail:
      msg: "{{ item }} not defined"
    when: item is not defined
    with_items:
    - cli_master_test  # ansible inventory instance to run playbook against

  tasks:
  - name: get list of nodes
    oc_obj:
      state: list
      kind: node
    register: obj_out

  - name: Set the node to work with
    set_fact:
      node_to_test: "{{ obj_out['module_results']['results'][0]['items'][0]['metadata']['name'] }}"

  - name: delete test labels (start from known starting position)
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
      - key: testlabel3

  - name: list to check whether our test labels already exist
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: original_labels
  - name: assert that testlabel2 and testlabel3 test labels don't exist
    assert:
      that:
      - original_labels['module_results']['labels'][0]['testlabel2'] is not defined
      - original_labels['module_results']['labels'][0]['testlabel3'] is not defined

  - name: add label
    oc_label:
      state: add
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
        value: "yes"
    register: label_out
  - name: assert adding label marked as changed
    assert:
      that: label_out['changed'] == True

  - name: test if add label succeeded
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: assert that testlabel2 label actually added
    assert:
      that:
      - label_out['module_results']['labels'][0]['testlabel2'] is defined
      - label_out['module_results']['labels'][0]['testlabel2'] == "yes"

  - name: test that re-adding does nothing
    oc_label:
      state: add
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
        value: "yes"
    register: label_out
  - name: assert that re-adding made no changes
    assert:
      that: label_out['changed'] == False

  - name: test that modifying existing label marked modified
    oc_label:
      state: add
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
        value: "different"
    register: label_out
  - name: assert that modifying existing label marked modified
    assert:
      that: label_out['changed'] == True

  - name: test if modify label actually did modification
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: assert that testlabel2 label actually modified
    assert:
      that:
      - label_out['module_results']['labels'][0]['testlabel2'] is defined
      - label_out['module_results']['labels'][0]['testlabel2'] == "different"

  - name: delete non-existant label
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabelnone
    register: label_out
  - name: assert that deleting non-existant label marked not changed
    assert:
      that: label_out['changed'] == False

  - name: delete label
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
    register: label_out
  - name: assert that deleting existing label marked changed
    assert:
      that: label_out['changed'] == True

  - name: re-delete label
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
    register: label_out
  - name: assert that re-deleting label marked not changed
    assert:
      that: label_out['changed'] == False

  - name: check whether really deleted
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: assert label actually deleted
    assert:
      that: label_out['module_results']['labels'][0]['testlabel2'] is not defined

  - name: add two labels
    oc_label:
      state: add
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
        value: "yes"
      - key: testlabel3
        value: "yes"
    register: label_out
  - name: assert that adding two labels marked as changed
    assert:
      that: label_out['changed'] == True

  - name: check whether both labels are there
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: assert that both labels actually exist
    assert:
      that:
      - label_out['module_results']['labels'][0]['testlabel2'] is defined
      - label_out['module_results']['labels'][0]['testlabel2'] == 'yes'
      - label_out['module_results']['labels'][0]['testlabel3'] is defined
      - label_out['module_results']['labels'][0]['testlabel3'] == 'yes'

  - name: check whether two deletes work
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
      - key: testlabel3
    register: label_out
  - name: assert that change were made when delete both labels
    assert:
      that: label_out['changed'] == True

  - name: check whether re-two deletes makes no changes
    oc_label:
      state: absent
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels:
      - key: testlabel2
      - key: testlabel3
    register: label_out
  - name: assert that change was not made when re-delete both labels
    assert:
      that: label_out['changed'] == False

  - set_fact:
      original_labels_as_key_value_list: "{{ original_labels['module_results']['labels'][0] | label_dict_to_key_value_list }}"

  - name: check that present with original label list makes no changes
    oc_label:
      state: present
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels: "{{ original_labels_as_key_value_list }}"
    register: label_out
  - name: assert that no changes are made when current list matches existing list
    assert:
      that: label_out['changed'] == False

  - name: check that present with extra item makes changes
    oc_label:
      state: present
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels: "{{ original_labels_as_key_value_list + [{'key': 'testlabel2', 'value': 'yes'}] }}"
    register: label_out
  - name: assert that changes were made
    assert:
      that: label_out['changed'] == True

  - name: get current label list
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: asssert that new label was actually added
    assert:
      that:
      - label_out['module_results']['labels'][0]['testlabel2'] is defined
      - label_out['module_results']['labels'][0]['testlabel2'] == 'yes'

  - name: check that present with changed item makes changes
    oc_label:
      state: present
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels: "{{ original_labels_as_key_value_list + [{'key': 'testlabel2', 'value': 'different'}]}}"
    register: label_out
  - name: assert that changes were made when existing key's value is changed
    assert:
      that: label_out['changed'] == True

  - name: get current label list
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: asssert that changed label was actually changed
    assert:
      that:
      - label_out['module_results']['labels'][0]['testlabel2'] is defined
      - label_out['module_results']['labels'][0]['testlabel2'] == 'different'

  - name: check that present with removed extra item makes changes
    oc_label:
      state: present
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
      labels: "{{ original_labels_as_key_value_list }}"
    register: label_out
  - name: assert that changes were made
    assert:
      that: label_out['changed'] == True

  - name: get current label list
    oc_label:
      state: list
      namespace: "{{ def_namespace }}"
      kind: "{{ def_kind }}"
      name: "{{ node_to_test }}"
    register: label_out
  - name: asssert that present-removed actually removed
    assert:
      that: label_out['module_results']['labels'][0]['testlabel2'] is not defined
