How do i register the python variables in a Ansible task - python

i'm trying to extract variables from a python script response, basically i have a task that executes a python script and i need to get the variables of that response, this python script parse a json and put the response in diferent variables
((python script)
import json
with open('dd.json') as f:
data = json.load(f)
for item in data['service-nat-pool-information'][0]['sfw-per-service-set-nat-pool']:
ifname = [b['data'] for b in item['interface-name']]
for q in item['service-nat-pool']:
name = [a['data'] for a in q['pool-name']]
rang = [n['data'] for n in q['pool-address-range-list'][0]['pool-address-range']] #linea agregada de stack
# ports = item['pool-port-range'][0]['data']
# use= item['pool-ports-in-use'][0]['data']
block= [j['data'] for j in q['effective-port-blocks']]
mblock= [m['data'] for m in q['effective-ports']]
maxp =[d['data'] for d in q['port-block-efficiency']]
print("|if-name",ifname,"|name:",name,"|ip-range:",rang,"|Effective-port-blocks:",block[0],"|Effective-port:",mblock[0],"|Port-Block-Efficiency:",maxp[0])
ansible playbook
---
- name: Parse
hosts: localhost
connection: local
vars:
pool: "{{ lookup('file','/etc/ansible/playbook/dd.json') | from_json }}"
tasks:
- name: Execute Script
command: python3.7 parsetry.py
i expected a task in ansible that gets the variables in the python script and store them in ansible variables

You have to use register. If you modify your script to output json that might ease your work a little bit.
- name: Execute Script
command: python3.7 parsetry.py
register: script_run
- name: Degug output
debug:
msg: "{{ script_run.stdout | from_json }}"
If you want to keep full python power under your fingers, you might as well consider turning your script in a custom module or a custom filter if it ever makes sense.

Related

Trying to get a ansible tower job to run on survey-variable based inventories?

I am using ansible tower and aiming to do something like this. Lets say I have these inventories defined in ansible tower
kanto-pkmn unova-pkmn johto-pkmn
a e c
b f d
Now I want the user to input variables (say he enters kanto and unova) then the script is only supposed to run on those hosts. However the catch is the hosts are supposed to mantain some form of variable that connects them to their respective inventory.
(ex. some sort of mapping should be there between a and kanto)
Ideas I have explored:
Multiple inventories seems like the best way but ansible tower only allows one inventory to be set during a job
Smart inventory is another option but it seems that it removes all the groups of the previous inventory so all I seem to obtain is
a
b
c
f
e
f
Is there any way I can get something like smart inventory with the groups intact or basically get something like
[kanto-pkmn] (or anything that can be mapped to the file)
a
b
[unova-pkmn]
e
f
Ansible Inventory
[kanto-pkmn]
a
b
[unova-pkmn]
e
f
[johto-pkmn]
c
d
[kantounova:children]
kanto-pkmn
unova-pkmn
Run aginst ansible inventory
ansible all -m setup **--> will run on all (builtin feature)**
ansible unova-pkmn -m setup **--> will run on c and d**
ansible kantounova -m setup **--> will run on a,b,e, and f**
Ansible Playbook
In your playbook or role you want to run you can add survey questions
- name: Install Lab Environment
become: true
hosts: johto-pkmn
vars_prompt:
- name: rhn_username *-->this is your variable name**
prompt: Enter Red Hat CDN username
private: no
- name: rhn_password
prompt: Enter Red Hat user CDN password
private: yes
- name: ORG
prompt: What is the name of your organization?
private: no
- name: LOC
prompt: Please enter the location of your env
private: no
tasks:
- name: Register with red hat cdn and attach rhel subscription
redhat_subscription:
username: "{{ rhn_username }}"
password: "{{ rhn_password }}"
state: present
pool: '^Red Hat Ansible Automation'
when:
- rhn_username != ""
- unova in group_names **<-- this would run on abc and d if they have a rhn_username**

How to run ansible from a python script

I am trying to run ansible playbooks within a python script used as a part of a flask server.
However, when trying to construct the playbook with python, it doesn't really work out the way its intended.
The original playbook should be:
---
- hosts: dc
gather_facts: no
tasks:
- name: create user omtest
win_domain_user:
name: omtest
firstname: om
surname: test
password: sjsd
state: present
attributes:
telephoneNumber: 123456
path: ou=Hilv,ou="Users",dc=ic,dc=com
password_expired: yes
groups:
- "_AV_NL"
and the python code for it:
play_ovirt = dict(
name="win-domain",
hosts=host_list,
gather_facts='no',
tasks=[
dict(action=dict(module='win_domain_user', args='dict(name='omtest', firstname='om', 'surname='test', password="sjsd', state='present', attributes='dict(telephoneNumber='123456')', path='ou=Hilv,ou="Users",dc=ic,dc=com', groups='['_AV_NL']', password_expired="yes"), register='shell_out')
]
)
I know there is something wrong with the python code but can't identify what is it.
Also this is my first time using ansible as part of a python code.

Ansible error of var type when passing to my custom module

I'm looking to make an ansible role and module abled to list all packages on a Linux System actually installed and register them to a var.
Then upgrade all of them and put the second list in an other var.
My module is here to make a diff of the two dictionaries (yum_packages1 and yum_packages2) and return it at the end of my role
When i'm trying to pass thoses two dictonaries into my modules and start my treatment i have a very strange error.
fatal: [centos7_]: FAILED! => {"changed": false, "msg": "argument yum_packages2 is of type and we were unable to convert to dict: cannot be converted to a dict"}
Ansible role task
---
# tasks file for ansible_yum_update_linux
- name: Listing Linux packages already installed
yum:
list: installed
register: yum_packages1
- name: Upgrade paquets Linux
yum:
name: '*'
state: latest
exclude: "{{ packages_exclude }}"
- name: Listing Linux packages installed and updated
yum:
list: installed
register: yum_packages2
- debug:
var: yum_packages1
- debug:
var: yum_packages2
- name: file compare
filecompare:
yum_packages1: "{{ yum_packages1.results }}"
yum_packages2: "{{ yum_packages2.results }}"
register: result
- debug:
var: result
Custome ansible module
#!/usr/bin/python
import json
from ansible.module_utils.basic import AnsibleModule
def diff_update(f1,f2):
#f3 = set(f1.keys()) == set(f2.keys())
upd1 = set(f1.values())
upd2 = set(f2.values())
f3 = (upd1.difference(upd2))
return f3
def main():
module = AnsibleModule(
argument_spec = dict(
yum_packages1 = dict(required=True, type='dict'),
yum_packages2 = dict(required=True, type='dict')
)
)
f3 = diff_update(module.params['yum_packages1'],module.params['yum_packages2'])
module.exit_json(changed=False, diff=f3)
if __name__ == '__main__':
main()
Do you have any idea why i get this error ?
Do you have any idea why i get this error ?
Because set is not json serializable:
import json
print(json.dumps(set("hello", "kaboom")))
cheerfully produces:
TypeError: set(['kaboom', 'hello']) is not JSON serializable
That's actually bitten me a couple of times in actual ansible modules, which is why I knew it was a thing; if you insist on using your custom module, you'll want to convert the set back to a list before returning it:
module.exit_json(changed=False, diff=list(f3))

Ansible playbook failing to find custom module [duplicate]

This question already has an answer here:
ERROR! 'file' is not a valid attribute for a Play [duplicate]
(1 answer)
Closed 5 years ago.
I have a module called "mysync" which is a small modification of synchronize. Bottom of this ticket is a diff between syncronize and mysync. It is placed it in the library directory:
library = /sites/utils/local/ansible/modules
when running the module in a playbook, the module is not found. Recommendations?
#> cat play.yml
- hosts: all
name: put shop onto server
mysync:
mode: pull
module: shop
src: rsync://#DEPOTHOST#::shop.ear
dest: /sites/MODULES/
archive: no
compress: yes
copy_links: yes
delete: yes
links: yes
times: yes
use_ssh_args: yes
verify_host: no
delegate_to: "{{ inventory_hostname }}"
#>ansible-playbook ./sync_shop.yml --limit tst37 -vvv
ERROR! 'mysync' is not a valid attribute for a Play
The error appears to have been in '/sites/utils/local/ansible/modules/sync_shop.yml': line 1, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- hosts: all
^ here
#>diff diff /Library/Python/2.7/site-packages/ansible/modules/files/synchronize.py ./mysync.py
26,28c26,28
< module: synchronize
< version_added: "1.4"
< short_description: A wrapper around rsync to make common tasks in your playbooks quick and easy.
---
> module: mySync
> version_added: "2.1"
> short_description: A custom wrapper around rsync to get src-host, src and dest from ldap
302a303,304
> import socket
> from ansible.module_utils.ldapData import ldapData
370a373,382
> #myInv = ldapData(self.args.debug,self.args.file,self.args.refresh)
> myInv = ldapData()
> host = socket.getfqdn()
> mydata = hosts[host][instances]
> for inst in mydata:
> if 'depothost' in inst:
> src_host=inst['depothost']
> if src_host is None:
> module.fail_json(msg='Could not determine depothost')
>
378a391
> source.replace('#DEPOTHOST#',src_host)
You should not "call" modules (custom or standard) directly from a play.
You should add them to a tasks dictionary which is missing in your play.
- hosts: all
tasks:
- name: put shop onto server
mysync:
mode: pull
module: shop
# etc.

How do I list hosts using Ansible 1.x API

Ansible-playbook has a --list-hosts cli switch that just outputs the hosts affected by each play in a playbook. I am looking for a way to access to same information through the python API.
The (very) basic script I am using to test right now is
#!/usr/bin/python
import ansible.runner
import ansible.playbook
import ansible.inventory
from ansible import callbacks
from ansible import utils
import json
# hosts list
hosts = ["127.0.0.1"]
# set up the inventory, if no group is defined then 'all' group is used by default
example_inventory = ansible.inventory.Inventory(hosts)
pm = ansible.runner.Runner(
module_name = 'command',
module_args = 'uname -a',
timeout = 5,
inventory = example_inventory,
subset = 'all' # name of the hosts group
)
out = pm.run()
print json.dumps(out, sort_keys=True, indent=4, separators=(',', ': '))
I just can't figure out what to add to ansible.runner.Runner() to make it output affected hosts and exit.
I'm not sure what are you trying to achieve, but ansible.runner.Runner is actually one task and not playbook.
Your script is a more kind of ansible CLI and not ansible-playbook.
And ansible doesn't have any kind of --list-hosts, while ansible-playbook does.
You can see how listhosts is done here.

Categories