2

I am writing some ansible playbooks that wrap the VirtualBox VBoxManage cli. The data that is returned is in a tabular colon-separated format, but I'd like it to be in something like JSON/YAML for better parsing.

For example I'd like to take the output of the following command:

$ VBoxManage list hostonlyifs -l   
                                                                               Name:            VirtualBox Host-Only Ethernet Adapter #2
GUID:            355aa3ae-0a32-49e6-8532-4d18fd9baea2
DHCP:            Disabled
IPAddress:       10.0.10.10
NetworkMask:     255.255.255.0
IPV6Address:     fe80::acc9:a7bd:d178:b911
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:3b
MediumType:      Ethernet
Wireless:        No
Status:          Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2

Name:            VirtualBox Host-Only Ethernet Adapter
GUID:            405a4779-a6f3-47d9-bf83-6a2503a093f2
DHCP:            Disabled
IPAddress:       192.168.56.1
NetworkMask:     255.255.255.0
IPV6Address:     fe80::ede5:3927:714c:3958
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:06
MediumType:      Ethernet
Wireless:        No
Status:          Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter

and reference the IP address for the HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2 interface.

An example ansible task approaching what I'm looking for:

#!/usr/bin/env ansible-playbook
- hosts: localhost
  become: false
  gather_facts: false
  vars_files:
  - vars/main.yml
  tasks:
  - name: List all host-only interfaces
    shell: "VBoxManage list hostonlyifs 
            | <magic>"
    changed_when: false
    register: vbox_hostonlyifs

  - name: Use information from the previous command somehow
    shell: "VBoxManage hostonlyif ipconfig 
            '{{ vbox_hostonlyifs.stdout | <magic> }}' 
            --ip 10.0.10.0"

I'm thinking maybe a combination of sed/regex can do the trick.

I have a regex expression that will capture the keys and values from all the blocks, but not the blocks themselves.

(^[a-zA-Z0-9]+:)(?:[ \t]+)(.*)$

Nick
  • 1,834
  • 20
  • 32

2 Answers2

2

You can take advantage of the fact that output is almost yaml, and just massage it a little to turn it into a list:

tasks:
- shell: VBoxManage list hostonlyifs | sed -e 's/^/  /; s/^  Name:/- Name:/'
  register: vblist
- set_fact:
    vbox_interfaces: '{{ vblist.stdout | from_yaml }}'

by prefixing the Name: key with - Name: it turns them into list items, and then the only other requirement is to indent the rest of the keys to match the same indentation as the - Name: to make them into objects

I have good reason to believe you can do that with pure jinja2, instead of using sed, but since you already mentioned sed it seems you're okay with a mixture of ansible and shell

Running that locally produces:

ok: [localhost] => {
    "vbox_interfaces": [
        {
            "DHCP": "Disabled",
            "GUID": "786f6276-656e-4074-8000-0a0027000000",
            "HardwareAddress": "0a:00:27:00:00:00",
            "Status": "Down",
...etc etc
            "VBoxNetworkName": "HostInterfaceNetworking-vboxnet0",
            "Wireless": false
        },
        {
            "DHCP": "Disabled",
            "GUID": "786f6276-656e-4374-8000-0a0027000003",
            "HardwareAddress": "0a:00:27:00:00:03",
...etc etc
        }
    ]
}
mdaniel
  • 31,240
  • 5
  • 55
  • 58
0

Same, but for Windows (my example for extpack):

- name: Get facts about Extension Pack 4 Windows
  when:
    - ansible_os_family == 'Windows'
  become: yes
  become_method: runas
  become_flags: logon_type=new_credentials logon_flags=netcredentials_only
  win_shell: |
    $for_yaml = VBoxManage list extpacks
    $for_yaml -replace '^', '  ' -replace '  Extension', '- Extension'
  register: vboxmanage_list_extpacks_windows

- set_fact:
    virtualbox_installed_extpack_info_fact:
      "{{ vboxmanage_list_extpacks_windows.stdout
      | from_yaml
      | first }}"

Result:

{
  "virtualbox_installed_extpack_info_fact": {
    "Description": "Oracle Cloud Infrastructure integration, USB 2.0 and USB 3.0 Host Controller, Host Webcam, VirtualBox RDP, PXE ROM, Disk Encryption, NVMe.",
    "Edition": null,
    "Extension Packs": 1,
    "Pack no. 0": "Oracle VM VirtualBox Extension Pack",
    "Revision": 149290,
    "Usable": true,
    "VRDE Module": "VBoxVRDP",
    "Version": "6.1.32",
    "Why unusable": null
  }
}
don Rumata
  • 203
  • 5
  • 9