---
# vSphere Automation REST cookbook against the API simulator.
#   ansible-playbook -i inventory.ini vsphere_playbook.yml
#
# Requires: gateway https://localhost (or set vsphere_base).

- name: vSphere API simulator lifecycle
  hosts: simulator
  gather_facts: false
  vars:
    vsphere_base: "https://localhost"
    vsphere_user: "administrator@vsphere.local"
    vsphere_password: "VMware1!"
    vm_name: "ansible-lab-01"
  tasks:
    - name: Create CIS session
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/session"
        method: POST
        url_username: "{{ vsphere_user }}"
        url_password: "{{ vsphere_password }}"
        force_basic_auth: true
        validate_certs: false
        status_code: [200, 201]
        return_content: true
      register: session

    - name: Set session header
      ansible.builtin.set_fact:
        vsphere_headers:
          vmware-api-session-id: "{{ session.json }}"

    - name: List VMs
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm"
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        return_content: true
      register: vms

    - name: Show inventory size
      ansible.builtin.debug:
        msg: "VMs in inventory: {{ vms.json | length }}"

    - name: Create VM
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm"
        method: POST
        headers: "{{ vsphere_headers }}"
        body_format: json
        body:
          name: "{{ vm_name }}"
          guest_OS: OTHER_GUEST_64
          placement:
            folder: group-v23
            host: host-11
            datastore: datastore-31
            resource_pool: resgroup-22
          cpu:
            count: 1
          memory:
            size_MiB: 512
        validate_certs: false
        status_code: [200, 201]
        return_content: true
      register: created

    - name: Power on
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/power?action=start"
        method: POST
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        status_code: [200, 204]
        return_content: true
      register: power_on

    - name: Poll CIS task when returned
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/cis/tasks/{{ power_on.json.task }}"
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        return_content: true
      register: task
      when: power_on.json is mapping and power_on.json.task is defined
      until: task.json.status in ['SUCCEEDED', 'FAILED']
      retries: 30
      delay: 1

    - name: Write guest file (lab virtual FS)
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/guest/filesystem?path=/tmp/ansible-marker"
        method: PUT
        headers: "{{ vsphere_headers }}"
        body_format: json
        body:
          content: "ansible-ok"
        validate_certs: false
        status_code: [200, 204]

    - name: Power off
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/power?action=stop"
        method: POST
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        status_code: [200, 204]

    - name: Delete VM
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}"
        method: DELETE
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        status_code: [200, 204]

    - name: Delete session
      ansible.builtin.uri:
        url: "{{ vsphere_base }}/api/session"
        method: DELETE
        headers: "{{ vsphere_headers }}"
        validate_certs: false
        status_code: [200, 204]
