ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
830 stars 1.53k forks source link

Dynamic inventory for Proxmox can not compose ansible_host variables for qemu vms #4854

Open meyayl opened 2 years ago

meyayl commented 2 years ago

Summary

When I want the dynamic inventory for my Proxmox host to be created, the vm's and container do not pre_polulate the ansible_host variable.

I want to use the compose feature provided by the dynamic inventory plugin, but it doesn't work because the mac address and ip address in the agent interface section use dashes instead of underscores.

Issue Type

Bug Report

Component Name

inventory/proxmox.py

Ansible Version

$ ansible --version
ansible 2.9.6
  config file = /home/me/proxmox-ansible-rke2/ansible.cfg
  configured module search path = ['/home/me/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0]

Community.general Version

$ ansible-galaxy collection list community.general
usage: ansible-galaxy collection [-h] COLLECTION_ACTION ...
ansible-galaxy collection: error: argument COLLECTION_ACTION: invalid choice: 'list' (choose from 'init', 'build', 'publish', 'install')

As the list action seems not to be available in my installation, I got the version from here:

cat ~/.ansible/collections/ansible_collections/community/general/CHANGELOG.rst | head -n10
===============================
Community General Release Notes
===============================

.. contents:: Topics

This changelog describes changes after version 4.0.0.

v5.1.1
======

Configuration

doesn't apply

OS / Environment

doesn't apply

Steps to Reproduce

plugin: community.general.proxmox
# export shell variables before exeuction
# export PROXMOX_URL=https://xxx.xxx.xxx.xxx:8006/
# export PROXMOX_USERNAME=xxx
# export PROXMOX_PASSWORD=xxx
# export PROXMOX_INVALID_CERT=True
want_facts: true
keyed_groups:
  - key: proxmox_tags_parsed
    separator: ""
    prefix: group_
filters:
  - proxmox_status == "running"
  - "proxmox_tags_parsed is defined and 'ansible' in proxmox_tags_parsed"
groups:
  etcd3: "'etcd3' in (proxmox_tags_parsed|list)"

compose:
  ansible_host: proxmox_net0.ip | default(proxmox_agent_interfaces[1].ip-addresses[0]) | ipaddr('address')
want_proxmox_nodes_ansible_host: false

Expected Results

I expect the ansible_host variable to be filled by expression used in the compose for qemu_vm and lxc hosts.

Actual Results

Instead the ansible_host entry is no rendered at all..

Further notes:

This works for lxc containers only:

compose:
  ansible_host: proxmox_net0.ip | ipaddr('address')

If the inventory/proxmox.py file is changed from:

            for iface in ifaces:
                result.append({
                    'name': iface['name'],
                    'mac-address': iface['hardware-address'] if 'hardware-address' in iface else '',
                    'ip-addresses': ["%s/%s" % (ip['ip-address'], ip['prefix']) for ip in iface['ip-addresses']] if 'ip-addresses' in iface else []
                })

to use underscores instead of dashes for the key names:

            for iface in ifaces:
                result.append({
                    'name': iface['name'],
                    'mac_address': iface['hardware-address'] if 'hardware-address' in iface else '',
                    'ip_addresses': ["%s/%s" % (ip['ip-address'], ip['prefix']) for ip in iface['ip-addresses']] if 'ip-addresses' in iface else []
                })

following compose expression works:

compose:
  ansible_host: proxmox_net0.ip | default(proxmox_agent_interfaces[1].ip_addresses[0]) | ipaddr('address')

Code of Conduct

ansibullbot commented 2 years ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 2 years ago

cc @Ajpantuso @Thulium-Drake @UnderGreen @joshainglis @karmab @tleguern click here for bot help

meyayl commented 2 years ago

component name plugins/inventory/proxmox.py

felixfontein commented 2 years ago

!component =plugins/inventory/proxmox.py

ansibullbot commented 2 years ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 2 years ago

cc @ilijamt click here for bot help

BongoEADGC6 commented 2 years ago

@meyayl I found a temporary solution here that requires no code change. Jinja doesn't like dashes in tokens, so using get() allows you to reference the value required to get qemu VM IPs via compose.

ansible_host: proxmox_agent_interfaces[1].get("ip-addresses")[0] | default(proxmox_net0.ip) | ipaddr("address")

Ultimately, I'd call this a workaround as the facts don't conform to proper Ansible fact formatting which uses underscores instead of dashes.

felixfontein commented 2 years ago

Note that instead of .get(x) you can also write [x], i.e.

ansible_host: proxmox_agent_interfaces[1]["ip-addresses"][0] | default(proxmox_net0.ip) | ipaddr("address")

should also work.

Ultimately, I'd call this a workaround as the facts don't conform to proper Ansible fact formatting which uses underscores instead of dashes.

There's always the discussion how much modules should modify the data returned by services. There is no definite standard on how names should be, and what is better depends a lot on personal taste and use cases.

ansibullbot commented 9 months ago

cc @krauthosting click here for bot help