--------------------
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 :-)