Last active
January 18, 2019 22:54
-
-
Save bdowling/50f57bd2e6cff6e96ed48ae469b6f576 to your computer and use it in GitHub Desktop.
Dead Simple Python Data Manipulation for Ansible
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
- 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) }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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