Get data to MySQL database with callback

504 views
Skip to first unread message

Acyl

unread,
Feb 28, 2013, 6:54:29 AM2/28/13
to ansible...@googlegroups.com

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 :-) ) so please by kind ;-)

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

Regards

Michael DeHaan

unread,
Feb 28, 2013, 8:47:22 AM2/28/13
to ansible...@googlegroups.com
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!
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Acyl GHANAY

unread,
Feb 28, 2013, 11:25:27 AM2/28/13
to ansible...@googlegroups.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().


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...@gmail.com>

Michael DeHaan

unread,
Feb 28, 2013, 11:34:56 AM2/28/13
to ansible...@googlegroups.com
On Thu, Feb 28, 2013 at 11:25 AM, Acyl GHANAY <aghana...@gv5.fr> wrote:
> 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!

Acyl GHANAY

unread,
Feb 28, 2013, 11:56:29 AM2/28/13
to ansible...@googlegroups.com
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...@gmail.com>

Dusan Sovic

unread,
Feb 28, 2013, 1:43:39 PM2/28/13
to ansible...@googlegroups.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):
Reply all
Reply to author
Forward
0 new messages