Get data to MySQL database with callback

Hello,

I recently developed a module called « dpkg_custom » which return JSON result.

This module allows me to list, on a particular node, the installed packages, the version which is currently installed and the available version on the Debian repository.

Here is a (shortened) result of this module:

8< ---------------------------------------------------------------------------------------------------------------------

$ ansible 127.0.0.1 -u root -m dpkg_custom

127.0.0.1 | success >> {

“ansible_facts”: {

“packages”: [

{

“acpi”: {

“available_version”: “”,

“distribution”: “squeeze”,

“installed_version”: “1.5-2”,

“status”: “uptodate”

}

},

{

“acpi-support-base”: {

“available_version”: “”,

“distribution”: “squeeze”,

“installed_version”: “0.137-5”,

“status”: “uptodate”

}

},

]

},

“changed”: “False”

}

8< ---------------------------------------------------------------------------------------------------------------------

I also have a MySQL database that I want to be filled by my callback. Here are the first lines of my callback:

8< ---------------------------------------------------------------------------------------------------------------------

import os

import time

import MySQLdb as mdb

import sys

import json

dbname = ‘CMDB’

try:

connection = mdb.connect(‘localhost’, ‘ansible’, ‘***********’, dbname)

except:

pass

def log(host, data):

if type(data) == dict:

invocation = data.pop(‘invocation’, None)

if invocation is None:

return

if invocation.get(‘module_name’, None) != ‘setup’ :

return

facts = data.get(‘ansible_facts’, None)

try:

with connection:

cursor = connection.cursor()

sqlquery = “INSERT INTO packages_available (package_name, architecture, distribution, available_version) VALUES('” + str(facts.get(‘packages’, None)) + “‘,’” + str(facts.get(‘ansible_architecture’, None)) + “‘,’” + str(facts.get(‘ansible_distribution’, None)) + “‘,’” + str(facts.get(‘available_version’, None)) + “')”

cursor.execute(sqlquery)

connection.commit()

sqlquery = “SELECT id FROM packages_available WHERE package_name='” + str(facts.get(‘package’, None)) + “’ AND architecture='” + str(facts.get(‘ansible_architecture’, None)) + “’ AND distribution='” + str(facts.get(‘distribution’, None)) + “'”

cursor.execute(sqlquery)

connection.commit()

8< ---------------------------------------------------------------------------------------------------------------------

I’m a noob in Python development (oops :slight_smile: ) so please by kind :wink:

I’m looking for a method to get all my facts called “packages” in this callback to fill my database.

I think that it is possible with a “foreach” loop but I don’t really how to implement it.

Otherwise, in this callback I’m using both facts of the “setup” module and of my “dpkg_custom”. Is it possible?

Thank for your answers :slight_smile:

Regards

Ok so you already have:

    facts = data.get('ansible_facts', None)

Sounds like you just want an inner for loop like so:

    packages = facts.get('packages',)
    for p in packages:
          # do database stuff here

Hope that helps!

I modified my callback with added the new code lines. So, when I 'm launching my playbook I can’t enter into this loop. In verbose mode playbook, the result of my module dpkg_custom was called without result of the function print().

8< ---------------------------------------------------------------------------------------------------------------------

import os
import time
import MySQLdb as mdb
import sys
import json

dbname = ‘CMDB’

try:
connection = mdb.connect(‘localhost’, ‘ansible’, ‘*************’, dbname)
except:
pass

def log(host, data):

if type(data) == dict:
invocation = data.pop(‘invocation’, None)
if invocation is None:
return
if invocation.get(‘module_name’, None) != ‘setup’ :
return
facts = data.get(‘ansible_facts’, None)
packages = facts.get(‘packages’,)

try:

for p in packages:
with connection:
print(‘###################enter loop######################’)
cursor = connection.cursor()
sqlquery = “INSERT INTO packages_available (package_name, architecture, distribution, available_version) VALUES('” + str(facts.get(p, None)) + “‘,’” + str(facts.get(‘ansible_architecture’, None)) + “‘,’” + str(facts.get(‘ansible_distribution’, None)) + “‘,’” + str(facts.get(‘available_version’, None)) + “')”
cursor.execute(sqlquery)
connection.commit()

8< ---------------------------------------------------------------------------------------------------------------------

If I forget anything please let me now.

Regards.

2013/2/28 Michael DeHaan <michael.dehaan@gmail.com>

I modified my callback with added the new code lines. So, when I 'm
launching my playbook I can't enter into this loop. In verbose mode
playbook, the result of my module dpkg_custom was called without result of
the function print().

I am sorry, it is out of the scope of this mailing list to help with
non-ansible-specific python questions.

Wish I could help, but it seems the basic concept is already correct
and it's just a matter of you hammering out the python code for what
you want.

Sorry!

Ok, thank you very much for your help!
I’ll try to find a solution and then post it there (if I find it).
Thanks again.
Best regards

2013/2/28 Michael DeHaan <michael.dehaan@gmail.com>

Hi Acyl,

I think the problem is that your SQL part is called only for ‘setup’ module and not for ‘dpkg_custom’ module.

if invocation.get(‘module_name’, None) != ‘setup’ :

Try to replace setup with dpkg_custom but I’m not sure if facts from setup module will be available.

Best Regards,

Dusan

Dňa štvrtok, 28. februára 2013 17:56:29 UTC+1 Acyl napísal(-a):