Tuesday, July 5, 2016

Developing Ansible Modules Troubleshooting Steps

In this post I wanted to show my troubleshooting process using print statements and interactive prompt for small programs. As network engineers starts to write code, there are inevitably times when something that does not go as planned and you need to troubleshoot. For small programs, simple print statements should be able to do the job.

I am going thru the Ansible tutorial for developing modules, http://docs.ansible.com/ansible/developing_modules.html#tutorial. The second iteration of timetest.py seems to have contained some errors. The file as-is copied and pasted into the file, timetest.py simply printed out the same result as the original timetest.py.

echou-a10:playbooks echou$ ansible/hacking/test-module -m ./timetest.py -a "time=\"March 14 12:23\""
* including generated source, if any, saving to: /Users/echou/.ansible_module_generated
* this may offset any line numbers in tracebacks/debuggers!
***********************************
RAW OUTPUT
{"time": "2016-06-29 17:48:16.553883"}


***********************************
PARSED OUTPUT
{
    "time": "2016-06-29 17:48:16.553883"
}
echou-a10:playbooks echou$

Which is clearly not the desired result indicated on the tutorial:
{"changed": true, "time": "2012-03-14 12:23:00.000307"}

Upon some troubleshooting, it seems that the syntax "WANT_JSON", even commented out in the file and not in the -a syntax, causes the args interpreted to be JSon.

 22
 23 arguments = shlex.split(args_data)
 24
 25 print("args_data: ", args_data, "arguments: ", arguments)
 26
 27 for arg in arguments:
 28     print("arg: ", arg)
 29     # ignore any arguments without an equals in it
 30     if "=" in arg:

***********************************
RAW OUTPUT
('args_data: ', '{"time": "March 14 12:23"}', 'arguments: ', ['{time:', 'March 14 12:23}'])

If you take out that line, the args_data will now be the string as it was explained in the tutorial and enter into the loop. However, it is now giving me the error:

***********************************
RAW OUTPUT
{"msg": "failed setting the time", "failed": true}


***********************************
PARSED OUTPUT
{
    "failed": true,
    "msg": "failed setting the time"
}

Upon reading the file, it looks like this error message is generated under the condition where rc != 0. Therefore if we insert a print statement in line 44:

 43             rc = os.system("date -s \"%s\"" % value)
 44             print("rc: ", rc, "value: ", value)

the output shows:

RAW OUTPUT
('rc: ', 256, 'value: ', 'March 14 12:23')

A quick interactive prompt test:

echou-a10:playbooks echou$ python
Python 2.7.11 |Anaconda 2.5.0 (x86_64)| (default, Dec  6 2015, 18:57:58)
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> import os
>>> value = 'March 14 12:23'
>>> rc = os.system("date -s \"%s\"" % value)
date: illegal option -- s
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
>>> rc
256
>>> exit()
echou-a10:playbooks echou$

Which gave me an error indicating 'date' command under OS-X does not have a '-s' option. Quickly trying it out on a Ubuntu machine shows that even when the '-s' option is available, the process will still return a non-zero value because the date command cannot be executed (need to be root, also I dont want to execute the script as root that sets my date).

echou@a10-ubuntu3:~$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> value = 'March 14 12:23'
>>> rc = os.system("date -s \"%s\"" % value)
date: cannot set date: Operation not permitted
Mon Mar 14 12:23:00 PDT 2016
>>> rc
256
>>> exit()
echou@a10-ubuntu3:~$

At this point, it is probably easier to force the value of rc to be 0:

 42
 43             #rc = os.system("date -s \"%s\"" % value)
 44             rc = 0
 45

Now the output is good:

echou-a10:playbooks echou$ ansible/hacking/test-module -m ./timetest.py -a "time=\"March 14 12:23\""
* including generated source, if any, saving to: /Users/echou/.ansible_module_generated
***********************************
RAW OUTPUT
{"changed": true, "time": "2016-06-29 18:57:06.625650"}


***********************************
PARSED OUTPUT
{
    "changed": true,
    "time": "2016-06-29 18:57:06.625650"
}
echou-a10:playbooks echou$

I just wanted to show that the process that I go thru for troubleshooting. Everybody go about the troubleshooting process a little differently, this is just my process that can hopefully help other network engineers who are perhaps newer to Python.


Happy coding.








No comments:

Post a Comment