030 Create custom facts

Extending example 312.

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
├── host_vars
│   ├── iocage_01
│   │   └── iocage.yml
│   └── iocage_02
│       └── iocage.yml
├── iocage-hosts.ini
├── pb-iocage.yml
└── pb-test-01.yml

Synopsis

  • On two iocage hosts:

    • iocage_01

    • iocage_02

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

    • create custom facts scripts.

    In the playbook pb-test-01.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

List all jails at iocage_01

[iocage_01]# iocage list -l
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| JID  |      NAME      | BOOT | STATE | TYPE |     RELEASE     |         IP4         | IP6 |    TEMPLATE    | BASEJAIL |
+======+================+======+=======+======+=================+=====================+=====+================+==========+
| None | ansible_client | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.198/24 | -   | -              | no       |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 3    | test_101       | off  | up    | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.101/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| 4    | test_102       | off  | up    | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.102/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
| None | test_103       | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.103/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+

List all jails at iocage_02

[iocage_02]# iocage list -l
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| JID  |      NAME      | BOOT | STATE | TYPE |     RELEASE     |        IP4        | IP6 |    TEMPLATE    | BASEJAIL |
+======+================+======+=======+======+=================+===================+=====+================+==========+
| None | ansible_client | off  | down  | jail | 14.1-RELEASE-p6 | em0|10.1.0.199/24 | -   | -              | no       |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| None | test_111       | off  | down  | jail | 14.1-RELEASE-p6 | em0|10.1.0.111/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 7    | test_112       | off  | up    | jail | 14.1-RELEASE-p6 | em0|10.1.0.112/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
| 8    | test_113       | off  | up    | jail | 14.1-RELEASE-p6 | em0|10.1.0.113/24 | -   | ansible_client | no       |
+------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+

Configuration ansible.cfg

[defaults]
gathering = explicit
callback_result_format = yaml

[connection]
pipelining = true

host_vars/iocage_01/iocage.yml

ansible_python_interpreter: /usr/local/bin/python3.9
ansible_become_password: admin

host_vars/iocage_02/iocage.yml

ansible_python_interpreter: /usr/local/bin/python3.11

Inventory iocage-hosts.ini

iocage_01 ansible_host=10.1.0.18
iocage_02 ansible_host=10.1.0.73

[iocage]
iocage_01
iocage_02

[iocage:vars]
ansible_user=admin
ansible_become=true

Playbook pb-iocage.yml

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

  roles:
    - vbotka.freebsd.iocage

Display versions

(env) > ansible-playbook pb-iocage.yml -i iocage-hosts.ini \
                                       -t freebsd_iocage_debug \
                                       -e freebsd_iocage_debug=true \
        | grep version

        freebsd_iocage_role_version: 0.5.0
        ansible_distribution_major_version: 13
        ansible_distribution_version: 13.1
        ansible_python_version: 3.9.16
        freebsd_iocage_role_version: 0.5.0
        ansible_distribution_major_version: 14
        ansible_distribution_version: 14.1
        ansible_python_version: 3.11.9

Create custom fact scripts

(env) > ansible-playbook pb-iocage.yml -i iocage-hosts.ini \
                                       -t freebsd_iocage_facts \
				       -e freebsd_iocage_facts=true

PLAY [Role vbotka.freebsd.iocage] ***********************************************************************************

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

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

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

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

Display custom fact script

shell> ssh admin@10.1.0.18 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-01.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

Display custom facts and variables

(env) > ansible-playbook pb-test-01.yml -i iocage-hosts.ini

PLAY [Get custom facts] ************************************************************************

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

TASK [Debug] ***********************************************************************************
ok: [iocage_01] => 
    ansible_local.iocage:
        jails: |-
            +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
            | JID  |      NAME      | BOOT | STATE | TYPE |     RELEASE     |         IP4         | IP6 |    TEMPLATE    | BASEJAIL |
            +======+================+======+=======+======+=================+=====================+=====+================+==========+
            | None | ansible_client | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.198/24 | -   | -              | no       |
            +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
            | 3    | test_101       | off  | up    | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.101/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
            | 4    | test_102       | off  | up    | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.102/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
            | None | test_103       | off  | down  | jail | 13.4-RELEASE-p2 | vnet0|10.1.0.103/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+---------------------+-----+----------------+----------+
        plugins: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
            +=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
        releases: |-
            13.3-RELEASE
            13.4-RELEASE
        templates: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+----------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
            +=====+======+======+=======+======+=========+=====+=====+==========+==========+
            +-----+------+------+-------+------+---------+-----+-----+----------+----------+
ok: [iocage_02] => 
    ansible_local.iocage:
        jails: |-
            +------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
            | JID  |      NAME      | BOOT | STATE | TYPE |     RELEASE     |        IP4        | IP6 |    TEMPLATE    | BASEJAIL |
            +======+================+======+=======+======+=================+===================+=====+================+==========+
            | None | ansible_client | off  | down  | jail | 14.1-RELEASE-p6 | em0|10.1.0.199/24 | -   | -              | no       |
            +------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
            | None | test_111       | off  | down  | jail | 14.1-RELEASE-p6 | em0|10.1.0.111/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
            | 7    | test_112       | off  | up    | jail | 14.1-RELEASE-p6 | em0|10.1.0.112/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
            | 8    | test_113       | off  | up    | jail | 14.1-RELEASE-p6 | em0|10.1.0.113/24 | -   | ansible_client | no       |
            +------+----------------+------+-------+------+-----------------+-------------------+-----+----------------+----------+
        plugins: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | PORTAL | DOC_URL |
            +=====+======+======+=======+======+=========+=====+=====+==========+========+=========+
            +-----+------+------+-------+------+---------+-----+-----+----------+--------+---------+
        releases: |-
            14.1-RELEASE
        templates: |-
            +-----+------+------+-------+------+---------+-----+-----+----------+----------+
            | JID | NAME | BOOT | STATE | TYPE | RELEASE | IP4 | IP6 | TEMPLATE | BASEJAIL |
            +=====+======+======+=======+======+=========+=====+=====+==========+==========+
            +-----+------+------+-------+------+---------+-----+-----+----------+----------+

TASK [Debug] ***********************************************************************************
ok: [iocage_01] => 
    ansible_local.iocage | vbotka.freebsd.iocage:
        jails:
            ansible_client:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.198
                ip4_dict:
                    ip4:
                    -   ifc: vnet0
                        ip: 10.1.0.198
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: None
                release: 13.4-RELEASE-p2
                state: down
                template: '-'
                type: jail
            test_101:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.101
                ip4_dict:
                    ip4:
                    -   ifc: vnet0
                        ip: 10.1.0.101
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: '3'
                release: 13.4-RELEASE-p2
                state: up
                template: ansible_client
                type: jail
            test_102:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.102
                ip4_dict:
                    ip4:
                    -   ifc: vnet0
                        ip: 10.1.0.102
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: '4'
                release: 13.4-RELEASE-p2
                state: up
                template: ansible_client
                type: jail
            test_103:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.103
                ip4_dict:
                    ip4:
                    -   ifc: vnet0
                        ip: 10.1.0.103
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: None
                release: 13.4-RELEASE-p2
                state: down
                template: ansible_client
                type: jail
        plugins: {}
        releases:
        - 13.3-RELEASE
        - 13.4-RELEASE
        templates: {}
ok: [iocage_02] => 
    ansible_local.iocage | vbotka.freebsd.iocage:
        jails:
            ansible_client:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.199
                ip4_dict:
                    ip4:
                    -   ifc: em0
                        ip: 10.1.0.199
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: None
                release: 14.1-RELEASE-p6
                state: down
                template: '-'
                type: jail
            test_111:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.111
                ip4_dict:
                    ip4:
                    -   ifc: em0
                        ip: 10.1.0.111
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: None
                release: 14.1-RELEASE-p6
                state: down
                template: ansible_client
                type: jail
            test_112:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.112
                ip4_dict:
                    ip4:
                    -   ifc: em0
                        ip: 10.1.0.112
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: '7'
                release: 14.1-RELEASE-p6
                state: up
                template: ansible_client
                type: jail
            test_113:
                basejail: 'no'
                boot: 'off'
                ip4: 10.1.0.113
                ip4_dict:
                    ip4:
                    -   ifc: em0
                        ip: 10.1.0.113
                        mask: '24'
                    msg: ''
                ip6: '-'
                jid: '8'
                release: 14.1-RELEASE-p6
                state: up
                template: ansible_client
                type: jail
        plugins: {}
        releases:
        - 14.1-RELEASE
        templates: {}

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