030 Create custom facts

Extending example 020 Get inventory aliases from notes.

Use case

Create custom facts to provide a dictionary of iocage datasets lists. Use the filter vbotka.freebsd.iocage to parse them.

Tree

shell> tree .
.
├── ansible.cfg
├── iocage.ini
├── pb-iocage.yml
└── pb-test.yml

Synopsis

  • At two managed nodes:

    • iocage_02

    • iocage_04

    In the playbook pb-iocage.yml use the role vbotka.freebsd.iocage to:

    • create custom facts scripts.

    In the playbook pb-test.yml:

    • get the custom facts

    • use the filter vbotka.freebsd.iocage to parse the custom facts

    • create the inventory group test and compose variables

    • display the hosts and composed variables in the group test

    • display all groups.

Requirements

Notes

Jails at iocage_02

[iocage_02]# iocage list -l
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID  |   NAME   | BOOT | STATE | TYPE |     RELEASE     |        IP4         | IP6 |    TEMPLATE    | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 24ceb6f1 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | 29712c80 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | b65059d4 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | d58e1d10 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | fba6f241 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+

Jails at iocage_04

[iocage_04]# iocage list -l
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID  |   NAME   | BOOT | STATE | TYPE |     RELEASE     |        IP4         | IP6 |    TEMPLATE    | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | 026a1357 | off  | down  | jail | 15.0-RELEASE-p3 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| None | ff5a1f63 | off  | down  | jail | 15.0-RELEASE-p3 | DHCP (not running) | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+

ansible.cfg

[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false

[connection]
pipelining = true

Inventory iocage.ini

iocage_02 ansible_host=10.1.0.73
iocage_04 ansible_host=10.1.0.29

[iocage]
iocage_02
iocage_04

[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent

Playbook pb-iocage.yml

- name: Role vbotka.freebsd.iocage
  hosts: iocage
  gather_facts: true

  roles:
    - vbotka.freebsd.iocage

Playbook output - Display versions

(env) > ansible-playbook pb-iocage.yml -i iocage.ini \
                                       -t freebsd_iocage_debug \
                                       -e freebsd_iocage_debug=true \
        | grep version
        freebsd_iocage_role_version: 1.2.0
        ansible_facts.distribution_major_version: 14
        ansible_facts.distribution_version: 14.2
        ansible_facts.python_version: 3.11.12
        freebsd_iocage_role_version: 1.2.0
        ansible_facts.distribution_major_version: 15
        ansible_facts.distribution_version: 15.0
        ansible_facts.python_version: 3.11.14

Playbook output - Create custom fact scripts

(env) > ansible-playbook pb-iocage.yml -i iocage.ini \
                                       -t freebsd_iocage_facts \
                                       -e freebsd_iocage_facts=true
PLAY [Role vbotka.freebsd.iocage] **********************************************

TASK [Gathering Facts] *********************************************************
ok: [iocage_04]
ok: [iocage_02]

TASK [vbotka.freebsd.iocage : Facts: create directory /etc/ansible/facts.d] ****
ok: [iocage_04]
ok: [iocage_02]

TASK [vbotka.freebsd.iocage : Facts: copy scipts to /etc/ansible/facts.d] ******
ok: [iocage_04] => (item=iocage.fact)
ok: [iocage_02] => (item=iocage.fact)

PLAY RECAP *********************************************************************
iocage_02                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
iocage_04                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Display custom fact script

[iocage_02]# cat /etc/ansible/facts.d/iocage.fact
#!/usr/local/bin/python

import json
import os
from subprocess import Popen, PIPE

data = {}

my_env = os.environ.copy()
my_env.update({'CRYPTOGRAPHY_OPENSSL_NO_LEGACY': '1'})

cmds = {'jails': ['--long'],
        'plugins': ['--plugins'],
        'releases': ['--release', '--header'],
        'templates': ['--template', '--long']
        }

cmd = ['iocage', 'list']

for list, attrs in cmds.items():
    my_cmd = cmd + attrs
    p = Popen(my_cmd, stdout=PIPE, stderr=PIPE, env=my_env)
    stdout, stderr = p.communicate()
    data[list] = stdout.decode("utf-8")

json_formatted_str = json.dumps(data, indent=2)

print(json_formatted_str)

Playbook pb-test.yml

- name: Get custom facts
  hosts: iocage

  tasks:

    - name: Get custom facts
      ansible.builtin.setup:
        filter: ansible_local

    - name: Debug
      ansible.builtin.debug:
        var: ansible_local.iocage

    - name: Debug
      ansible.builtin.debug:
        var: ansible_local.iocage | vbotka.freebsd.iocage

Playbook output - Display custom facts

(env) > ansible-playbook pb-test.yml -i iocage.ini
PLAY [Get custom facts] ********************************************************

TASK [Get custom facts] ********************************************************
ok: [iocage_04]
ok: [iocage_02]

TASK [Debug] *******************************************************************
ok: [iocage_02] => 
    ansible_local.iocage:
        jails: |-
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | JID  |   NAME   | BOOT | STATE | TYPE |     RELEASE     |        IP4         | IP6 |    TEMPLATE    | BASEJAIL |
            +======+==========+======+=======+======+=================+====================+=====+================+==========+
            | None | 24ceb6f1 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | None | 29712c80 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | None | b65059d4 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | None | d58e1d10 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | None | fba6f241 | off  | down  | jail | 14.3-RELEASE-p8 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
        plugins: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
            +=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
        releases: |-
            14.2-RELEASE
            14.3-RELEASE
        templates: |-
            +------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
            | JID  |      NAME      | BOOT | STATE |   TYPE   |     RELEASE     |        IP4         | IP6 | TEMPLATE | BASEJAIL |
            +======+================+======+=======+==========+=================+====================+=====+==========+==========+
            | None | ansible_client | off  | down  | template | 14.3-RELEASE-p8 | DHCP (not running) | -   | -        | no       |
            +------+----------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
ok: [iocage_04] => 
    ansible_local.iocage:
        jails: |-
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | JID  |   NAME   | BOOT | STATE | TYPE |     RELEASE     |        IP4         | IP6 |    TEMPLATE    | BASEJAIL |
            +======+==========+======+=======+======+=================+====================+=====+================+==========+
            | None | 026a1357 | off  | down  | jail | 15.0-RELEASE-p3 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
            | None | ff5a1f63 | off  | down  | jail | 15.0-RELEASE-p3 | DHCP (not running) | -   | ansible_client | no       |
            +------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
        plugins: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
            +=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
        releases: |-
            14.3-RELEASE
            15.0-RELEASE
        templates: |-
            +------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
            | JID  |         NAME          | BOOT | STATE |   TYPE   |     RELEASE     |        IP4         | IP6 | TEMPLATE | BASEJAIL |
            +======+=======================+======+=======+==========+=================+====================+=====+==========+==========+
            | None | ansible_client        | off  | down  | template | 15.0-RELEASE-p3 | DHCP (not running) | -   | -        | no       |
            +------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
            | None | ansible_client_apache | off  | down  | template | 15.0-RELEASE-p3 | DHCP (not running) | -   | -        | no       |
            +------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+
            | None | ansible_client_pull   | off  | down  | template | 15.0-RELEASE-p3 | DHCP (not running) | -   | -        | no       |
            +------+-----------------------+------+-------+----------+-----------------+--------------------+-----+----------+----------+

TASK [Debug] *******************************************************************
ok: [iocage_04] => 
    ansible_local.iocage | vbotka.freebsd.iocage:
        jails:
            026a1357:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 15.0-RELEASE-p3
                state: down
                template: ansible_client
                type: jail
            ff5a1f63:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 15.0-RELEASE-p3
                state: down
                template: ansible_client
                type: jail
        plugins: {}
        releases:
        - 14.3-RELEASE
        - 15.0-RELEASE
        templates:
            ansible_client:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 15.0-RELEASE-p3
                state: down
                template: '-'
                type: template
            ansible_client_apache:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 15.0-RELEASE-p3
                state: down
                template: '-'
                type: template
            ansible_client_pull:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 15.0-RELEASE-p3
                state: down
                template: '-'
                type: template
ok: [iocage_02] => 
    ansible_local.iocage | vbotka.freebsd.iocage:
        jails:
            24ceb6f1:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: ansible_client
                type: jail
            29712c80:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: ansible_client
                type: jail
            b65059d4:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: ansible_client
                type: jail
            d58e1d10:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: ansible_client
                type: jail
            fba6f241:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: ansible_client
                type: jail
        plugins: {}
        releases:
        - 14.2-RELEASE
        - 14.3-RELEASE
        templates:
            ansible_client:
                basejail: 'no'
                boot: 'off'
                ip4: '-'
                ip4_dict:
                    ip4: []
                    msg: DHCP (not running)
                ip6: '-'
                jid: None
                release: 14.3-RELEASE-p8
                state: down
                template: '-'
                type: template

PLAY RECAP *********************************************************************
iocage_02                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
iocage_04                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0