# Ansible, URLs, proxies and connection refused

So today I was trying to fix a problem with the deployment of some software with Ansible. I am using get_url in combination with a http_proxy environment setting in order to pull a file in from a HTTP URL. However, when I ran the playbook I was greeted with a [Errno 111] Connection refused error message. After fixing the proxy to have the netblock properly configured I tested again and was again greeted by the error. The problem became more confounding when I ran a test with curl on the command line using the proxy parameters, this test actually worked. So the proxy was running as it should. After some long testing and trying to figure out just what was going wrong, I replaced the get_url with a command: curl set up to test if it might be Ansible itself. The output of curl was enlightening, it turned out the HTTP URL was 301 redirecting to another HTTP URL, which in turn was 302 redirecting to a HTTPS URL! And since I wanted to be explicit I had not added the https_proxy environment variable.

The problem however now comes in how to to fix this. Is it documentation? Ansible code fix? Python code fix?

# Selenium, Chromedriver2, and SSL pages

If you are doing Selenium testing using Chromedriver2 0.8 and are having problems with self-signed SSL certificates, this is a known problem and will be fixed in a subsequent release. In the meantime I found that using the Chromedriver 26.0.1383.0 still worked without problems for Chrome 27 and also did not have this SSL certificate regression in it.

# Mercurial and safely storing passwords

Mercurial allows for tying in keyring configuration for those of us who do not want to store passwords in plain-text in our .hgrc files or constantly using SSH.

First install the Python keyring library by running pip install keyring. After that is installed, checkout https://bitbucket.org/Mekk/mercurial_keyring/ and add to $HOME/.hgrc the following: [extensions] mercurial_keyring = ~/path/to/mercurial_keyring/mercurial_keyring.py Next up, configure your repositories, e.g. in the case of Bitbucket I use: [auth] bitbucket.prefix = bitbucket.org/asmodai bitbucket.username = asmodai bitbucket.schemes = https Mercurial keyring will automatically decide on the best keyring to use. On a FreeBSD system with no Gnome or other systems providing a keyring, if you do not specify a specific keyring, the system will use the file ~/.local/share/python_keyring/keyring_pass.cfg. This keyring file stores the passwords encoded in Base64 in plain-text. This is not quite what you would want from a security point of view. You can configure which backend store to use by editing $HOME/.local/share/python-keyring/keyringrc.cfg. To get a plain-text file with encrypted keys use the following configuration:

[backend] default-keyring=keyring.backend.CryptedFileKeyring

This will create the file ~/.local/share/python-keyring/crypted_pass.cfg after initializing the backend store with a password. Look at the documentation for keyring on what other configuration options are available.

Note: make sure the PyCrypto dependency is installed with the _fastmath module. This in turn depends on the gmp library.

# PyCharm 1.1.1 released

PyCharm 1.1.1 was released yesterday. It consists mostly of bugfixes, find the full release notes on their site.

# PyCharm and external lint tools

PyCharm already has a number of features present in various tools to lint/check your source code with, but offers a way to hook up external tools. Under File > Settings is a section called IDE Settings. One of the headings here is called External Tools. Select this heading and then press the Add... button on the right hand pane to configure a new external tool.

In the Edit Tool window that now appeared fill in a name, e.g. PEP8 and a group name Lint and add a description. Next point the Program to the location of the pep8.exe executable, e.g. C:\Python27\Scripts\pep8.exe. For Parameters you need to use $FilePath and Working directory should be filled in by default. Once done, you can close it by pressing the OK button. Now, pyflakes has no .exe or .bat file to accompany it. You will need to add a pyflakes.bat in your Scripts directory inside Python with the following contents: @echo off rem Use python to execute the python script having the same name as this batch rem file, but without any extension, located in the same directory as this rem batch file python "%~dpn0" %* Within PyCharm you follow largely the same settings as for pep8, however make sure to point to the batch file of pyflakes under Program. Close the external tools configuration windows by clicking OK twice. Under the menu heading Tools you should see an submenu heading Lint which, in turn, should contain two menu items: PEP8 and Pyflakes. Now open a Python file, go to Tools > Lint > PEP8 and you should get output like the following in your Run (4) window: D:\Python26\Scripts\pep8.exe D:\pprojects\babel\babel\tests\__init__.py D:\pprojects\babel\babel\tests\__init__.py:16:1: E302 expected 2 blank lines, found 1 Process finished with exit code 1  # PyCharm 1.0 So I was so impressed by PyCharm that I purchased a license. I haven’t noticed much of any delays or slowdowns that other people have complained about. # docutils: ImportError: No module named roman For some reason setup.py can fail with docutils complaining it cannot find the roman module. One thing that works is just removing docutils from your site-packages and reinstall it. # JSONP with Werkzeug So I had implemented a simple JSON data server with Werkzeug for a classroom experiment. Unfortunately in my haste to get everything up and running I totally forgot about the fact that, since we cannot allow uploads to this server of various custom made webpages, using jQuery’s $.ajax() everything just fails since it will then be a cross-site scripting request.

So, normally you would do something like the following in order to return JSON data:

return json.dumps(data)

Which would be used with the $.ajax() call in a way like the following: $.ajax({ type: "POST", url: "http://example.com/json/something", data: "parameter=value", dataType: "json", error: function(XMLHttpRequest, textStatus, errorThrown){}, success: function(data, msg){} });

Which is perfectly fine for scripts getting and using the data on the same host/domain. But, as said before, this will fail with warnings similar to: "Access to restricted URI denied" code: "1012" nsresult: "0xdeadc0de (NS_ERROR_DOM_BAD_URI)".

One way out of this is using JSONP. jQuery has a $.getJSON() function, which loads JSON data using a HTTP GET request. Now, the simplistic way to convert your code would be to change it as such: $.getJSON("http://example.com/json/something", function(data){} );

But this causes another issue. Since $.getJSON() GETs the JSON data, but doesn’t use eval() on it, but instead pulls the result into script tags, it somehow causes,on Firefox at least, an invalid label error. In order to fix this you need to set up the JSON data server to properly support a callback argument, to use $.getJSON() how it is meant to be used:

\$.getJSON("http://example.com/json/something?jsoncallback=?", function(data){} );

In the code above the additional parameter jsoncallback will, thanks to jQuery, get the question mark replaced by an alphanumeric string (typically in the form of jsonp followed by a timestamp). This value should be used to wrap the resulting JSON data with. This means you would have to change the initial Python code to something like this:

return request.args.get('jsoncallback') + '(' + json.dumps(data) + ')'

Of course this causes problems when you want to reuse the code for both AJAX use on the same host/domain and use it from outside. So in order to make both work you can test on whether or not the callback parameter is available and return the appropriate data. I came up with this little snippet for that:

def jsonwrapper(self, request, data): callback = request.args.get('jsoncallback')   if callback: return callback + '(' + json.dumps(data) + ')' else: return json.dumps(data)