Skip to content

Instantly share code, notes, and snippets.

@bdowling
Last active January 18, 2019 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdowling/50f57bd2e6cff6e96ed48ae469b6f576 to your computer and use it in GitHub Desktop.
Save bdowling/50f57bd2e6cff6e96ed48ae469b6f576 to your computer and use it in GitHub Desktop.
Dead Simple Python Data Manipulation for Ansible
---
- hosts: localhost
vars:
people:
- {'id': 1, name: 'Bob', age: 35, sex: 'male', birthday: 1}
- {'id': 2, name: 'Sally', age: 22, sex: 'female', birthday: 12}
- {'id': 3, name: 'Sarah', age: 37, sex: 'female', birthday: 15}
- {'id': 4, name: 'Michael', age: 44, sex: 'male', birthday: 11}
- {'id': 5, name: 'Tom', age: 18, sex: 'male', birthday: 22}
one: [1,2,3,22,12,4,48]
two: [60,30,44,55,5]
nextweek: [10,11,13,14,15]
tasks:
- name: Filter data structures more easily
set_fact:
filtered: >
{{ people | pyeval('[x for x in data if x["sex"] == "female" or (x["age"] < 40 and x["age"] > 30)]') }}
- name: Combine and Sort Lists
set_fact:
combined: >
{{ one | pyexec('data.extend(two); data.sort()', two=two) }}
- name: List People having Birthdays this nextweek and how old
set_fact:
birthdays: >
{{ people | pyeval('["{name}'"'"'s birthday is on {birthday}th and will be".format(**x) +
" {} years old!".format(x["age"]+1)
for x in data if x["birthday"] in nextweek]', nextweek=nextweek) }}
#
# NOTE: I fully understand there are risks to eval() and exec() but honestly this is no more risk than if you
# allow your users to install modules or other code in your ansible enviorment.
#
# With that said, use at your own peril, caveat emptor, no warantees or fitness for any purpose
# (other than recovering parts of your sanity manipulating data in ansible).
#
# by Brian Dowling (2019-01)
#
from ansible import errors
class FilterModule(object):
''' Stupid Simple data manipulation with python as an Jinja2 filter for Ansible '''
def pyeval(self, data, raw_code, **kwargs):
''' Maniuplates input data and returns the result of the given code fragment, good for list/dict comprehension '''
kwargs['data'] = data
res = eval(raw_code, None, kwargs)
return res
def pyexec(self, data, raw_code, **kwargs):
''' Maniuplate data with a python code block. Code is expected to change `data` and data is returned
Useful when you need to call functions that alter the data but do not return, .extend(), .sort() etc
Multiple lines can be simulated with ';' separated fragments
'''
# debating on this:
# kwargs['data'] = copy.deepcopy(data)
kwargs['data'] = data
exec(raw_code, None, kwargs)
return kwargs['data']
def filters(self):
filters = {
'pyeval': self.pyeval,
'pyexec': self.pyexec,
}
return filters
TASK [Filter data structures more easily] **********************************************************************************************************************************************************************************************
task path: /home/bdowling/src/plays/kiss.yaml:14
ok: [localhost] => {
"ansible_facts": {
"filtered": [
{
"age": 35,
"birthday": 1,
"id": 1,
"name": "Bob",
"sex": "male"
},
{
"age": 22,
"birthday": 12,
"id": 2,
"name": "Sally",
"sex": "female"
},
{
"age": 37,
"birthday": 15,
"id": 3,
"name": "Sarah",
"sex": "female"
}
]
},
"changed": false
}
TASK [Combine and Sort Lists] **********************************************************************************************************************************************************************************************************
task path: /home/bdowling/src/plays/kiss.yaml:19
ok: [localhost] => {
"ansible_facts": {
"combined": [
1,
2,
3,
4,
5,
12,
22,
30,
44,
48,
55,
60
]
},
"changed": false
}
TASK [List People having Birthdays this nextweek and how old] **************************************************************************************************************************************************************************
task path: /home/bdowling/src/plays/kiss.yaml:24
ok: [localhost] => {
"ansible_facts": {
"birthdays": [
"Sarah's birthday is on 15th and will be 38 years old!",
"Michael's birthday is on 11th and will be 45 years old!"
]
},
"changed": false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment