# Playbook to build new VMs in RHV Cluster
# Currently only builds RHEL VMs

# Create Host

- name: Preflight checks
  hosts: tag_build
  gather_facts: false
  tasks:
    - assert:
        that:
          - site == "sagely_dc"
          - is_virtual

- name: Ensure Primary IP exists and is in DNS
  hosts: tag_build
  gather_facts: false

  tasks:
    - name: Get unused IP Address from pool
      netbox.netbox.netbox_ip_address:
        netbox_url: "{{ netbox_api }}"
        netbox_token: "{{ netbox_token }}"
        data:
          prefix: 192.168.16.0/20
        state: new
      register: new_ip
      when: primary_ipv4 is undefined
      delegate_to: localhost

    - set_fact:
        primary_ipv4: "{{ new_ip.ip_address.address|ipaddr('address') }}"
        vm_hostname: "{{ inventory_hostname.split('.')[0] }}"
        vm_domain: "{{ inventory_hostname.split('.',1)[1] }}"
      delegate_to: localhost
      when: primary_ipv4 is undefined

    - name: Ensure IP Address in IdM
      freeipa.ansible_freeipa.ipadnsrecord:
        records:
          - name: "{{ vm_hostname }}"
            zone_name: "{{ vm_domain }}"
            record_type: A
            record_value:
              - "{{ new_ip.ip_address.address|ipaddr('address') }}"
            create_reverse: true
        ipaadmin_password: "{{ ipaadmin_password }}"
      delegate_to: idm1.mgmt.toal.ca

- name: Create VMs
  hosts: tag_build
  connection: local
  gather_facts: no
  collections:
    - netbox.netbox
  vars:
    # Workaround to get correct venv python interpreter
    ansible_python_interpreter: "{{ ansible_playbook_python }}"


  tasks:
    - name: Basic Disk Profile
      set_fact:
        vm_disks:
        -  name: '{{ inventory_hostname }}_boot'
           bootable: true
           sparse: true
           descr: '{{ inventory_hostname }} Boot / Root disk'
           interface: virtio
           size: '{{ disk|default(40) }}'
           state: present
           storage_domain: 'ssdvdo0'
           activate: true
      when: vm_disks is not defined

    - name: Create VM Disks
      ovirt_disk:
        auth: '{{ ovirt_auth }}'
        name: '{{ item.name }}'
        description: '{{ item.descr }}'
        interface: '{{ item.interface }}'
        size: '{{ item.size }}'
        state: '{{ item.state }}'
        sparse: '{{ item.sparse }}'
        wait: true
        storage_domain: '{{ item.storage_domain }}'
      async: 300
      poll: 15
      loop: '{{ vm_disks }}'


    - set_fact:
        nb_query_filter: "slug={{ platform }}"
    - debug: msg='{{ query("netbox.netbox.nb_lookup", "platforms", api_filter=nb_query_filter, api_endpoint=netbox_api, token=netbox_token)[0].value.name }}'

    - name: Create VM in RHV
      ovirt_vm:
        auth: '{{ ovirt_auth }}'
        name: '{{ inventory_hostname }}'
        state: present
        memory: '{{ memory }}MiB'
        memory_guaranteed: '{{ (memory / 2)|int }}MiB'
        disks: '{{ vm_disks }}'
        cpu_cores: '{{ vcpus }}'
        cluster: '{{ cluster }}'
        # This is ugly Can we do better?
        operating_system: '{{ query("netbox.netbox.nb_lookup", "platforms", api_filter=nb_query_filter, api_endpoint=netbox_api, token=netbox_token)[0].value.name }}'
        type: server
        graphical_console:
          protocol:
            - vnc
            - spice
        boot_devices:
          - hd
      async: 300
      poll: 15

    - name: Assign NIC
      ovirt_nic:
        auth: '{{ ovirt_auth }}'
        interface: virtio
        mac_address: '{{ item.mac_address|default(omit) }}'
        name: '{{ item.name }}'
        profile: ovirtmgmt
        network: '{{ item.untagged_vlan.name }}' # This is fragile
        state: '{{ (item.enabled == True) |ternary("plugged","unplugged") }}'
        linked: yes
        vm: '{{ inventory_hostname }}'
      loop: '{{ interfaces }}'

  handlers:
    - name: PXE Boot
      ovirt_vm:
        auth: "{{ ovirt_auth }}"
        name: "{{ inventory_hostname }}"
        boot_devices:
         - network
        state: running
      register: vm_build_result

- name: Ensure VM is running and reachable
  hosts: tag_build
  gather_facts: no
  connection: local
  vars:
    # Hack to work around virtualenv python interpreter
    ansible_python_interpreter: "{{ ansible_playbook_python }}"

  tasks:
    - name: VM is running
      ovirt_vm:
          auth: "{{ ovirt_auth }}"
          name: "{{ inventory_hostname }}"
          state: running
          boot_devices:
          - hd

    - name: Wait for SSH to be ready
      wait_for_connection:
        timeout: 1800
        sleep: 5

#TODO: Clear Build tag