20/06/2015

Ansible module to list groups in inventory - Python.

Update 1/11/2015: I updated the module and made a Github repository "List Ansible inventory groups".

--------------------

I'm really in love with Ansible, it's very simple, very handy ... it's Awesome! You can master it in no time at all! Get Started now!

As far as I remember, I've been started using Ansible since v1.7, and at the time of writing this post latest version of Ansible is v1.9.1. I wanted to list groups in inventory file, but not all hosts as in option "--list-hosts", also I wanted to display number of group members.

After small search, I found the "--list-hosts" was able to list groups as well hosts, but reported as a bug because it's called "--list-hosts" not "--list-groups" (and this is actually logical :D)

Anyway, the last year, I decided to make an "Ansible module" to do this, I'm always scripting with Bash and AWK, in fact Ansible does not care about language of module, JSON output is just what matters.

However, this time I decided to write the module with Python, I can read Python syntax and I wrote some simple scripts, but practically I don't do Python a lot, so this was a nice chance to do some Python again.

I ended up with this:
#! /bin/python
#Ansible module with Python to list groups in inventory (version 0.2 :D)
#You can print output like "pretty-print" outside Ansible by using:
#./listgroups | python -m json.too

import os
import re
import json

#Get hosts inventory from ansible.cfg file.
ansible_conf_file = open("ansible.cfg").read()
hosts_file = re.findall('^hostfile\s*=\s*(.*)', ansible_conf_file, re.MULTILINE)[0]

#Get data from hostsfile.
hosts_file = open(hosts_file)
groups_and_members = hosts_file.read().splitlines()
hosts_file.close()

#Preste for counting loop.
first_element = 0
number_of_group_members = 0
gropus_list= {}

#Get groups and number of its members from inventory file and add it to dictionary. 
for line in groups_and_members:
  if re.match("^\[", line) and first_element == 0:
    group_name = re.sub(r'[\[\]]', '', line)
    first_element=1

  elif not re.match("(^\[|#|^$)", line) and first_element != 0:
    number_of_group_members += 1

  elif re.match("^\[", line) and first_element != 0:
    gropus_list[group_name] = number_of_group_members
    group_name = re.sub(r'[\[\]]', '', line)
    number_of_group_members = 0

#Print output in json format.
print '{"Inventory Groups": ' + json.dumps(gropus_list) + '}'

Output example:
Raw:
{"Inventory Groups": {"Group1": 5, "Group2": 3, "Group3": 7}}

With python -m json.tool:
{
    "Inventory Groups": {
        "Group1": 5,
        "Group2": 3,
        "Group3": 7,
    }
}

Oh yeah, it's working as expected, but I can smell Bash style in this snippet :D
So, I had asked in one of geeks groups to review my code and suggest how to make it simpler and more Pythonic, and Mohammad Tayseer did the following:
#! /bin/python
# Ansible module to list groups in inventory (Python version) :D
# You can print output like "pretty-print" outside Ansible by using:
#./listgroups /path/to/ansible.cfg | python -m json.tool 

import sys
import re
import json
 
#get hosts inventory from ansible.cfg file.
ansible_conf_file = open(sys.argv[1]).read()
hosts_file = re.findall('hostfile\s*=\s*(.*)', ansible_conf_file)[0]
 
#Get groups from inventory file and add it to array. 
cat_hosts_file = open(hosts_file).readlines()
group = 'Default' # for hosts without a group
groups_list = {group: 0}
for line in cat_hosts_file:

  # Skip comments & empty lines
  line = line.strip()
  if not line or line.startswith('#'):
    continue

  if line.startswith('['): # group
    group = re.sub(r'[\[\]]', '', line)
    groups_list[group] = 0
  else: # host
    groups_list[group] += 1
 
#Print output in json format.
print '{"Inventory Groups": ' + json.dumps(groups_list) + '}'
Now I call this Python :D The module working fine, and it was a cool experience, and since that I started doing more Python :-)
Powered by Blogger.

Hello, my name is Ahmed AbouZaid and this is my "lite" technical blog!

I'm a passionate DevOps, Linux system administrator, RedHat Certified Engineer (RHCE), AWS SysOps/Solutions Architect, Free/Open source geek, author, interested in environment, calligraphy, and I believe that “Details Matter”!

Automation, data, and metrics are my preferred areas. I have a built-in monitoring chip, and too lazy to do anything manually :D

Popular Posts