Is it possible to natively convert a 3 letter country code to a 2 letter one (e.g. USA -> US)

Hi everyone,

I’m migrating most of my code from python 2.7 to ansible and would like to know if there’s a way to natively convert a 3 letter country code to 2 letter one.

It was really easy to do in python:

`

from iso3166 import countries

country_code_2l = countries.get(country_code_3l).alpha2

`

, but can’t find a way to do it with ansible.

Format does not work as the correlation table is normalized.

I can of course create a python module that does this, but would like to avoid it if such a feature already exists.

Best regards,
Sabrina

I don't think something like that exist, but you could do this

{{ lookup('pipe', 'python -c "from iso3166 import countries; print countries.get(\"NOR\").alpha2"') }}

Or create a filter plugin

country_code_3to2.py

Thanks a lot Kai, I haven’t thought about this.

The command successfully run as root, in the shell command line:

`

python -c “from iso3166 import countries; print countries.get(‘USA’).alpha2”

US
`

So, it looks like we’re definitively on the right tracks, but I can’t managed to pass the variable``` to the function countries.get(), even hard coded (see below):`

`

Convert the 3 letter country code to 2 letters

  • set_fact:
    tenant_country_code_2l: “{{ lookup(‘pipe’, ‘python -c "from iso3166 import countries; print countries.get("USA").alpha2"’) }}”

TASK […/…/roles/isam : set_fact] **************************************************************************************************************************************************************
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘USA’ is not defined
fatal: [runner_ansible]: FAILED! => {
“failed”: true
}

MSG:

An unhandled exception occurred while running the lookup plugin ‘pipe’. Error was a <class ‘ansible.errors.AnsibleError’>, original message: lookup_plugin.pipe(python -c “from iso3166 import countries; print countries.get(“USA”).alpha2”) returned 1

`

Would you know how to do it? I’ve tried several solutions but can’t work this out… I guess I’m missing sthg in ansible…

Best regards,
Sabrina

The problem is the first quote after the colon, what I do to in these situation is to use multi line YAML since you then don't need the quotes.

   - set_fact:
       tenant_country_code_2l: |-
         {{ lookup('pipe', 'python -c "from iso3166 import countries; print countries.get(\"USA\").alpha2"') }}

Thanks Kai for your quick answer.

However ansible does not like this syntax (I’m using version 2.6.2 and can’t update to an higher version).

`

cat ./roles/tasks/the_task.yml

Convert the 3 letter country code to 2 letters

  • set_fact:
    tenant_country_code_2l: |-
    {{ lookup(‘pipe’, ‘python -c “from iso3166 import countries;
    print countries.get("USA").alpha2”’) }}

ansible-playbook …

ERROR! Syntax Error while loading YAML.

The error appears to have been in ‘/nfs/home/slautier/git/odm-oncloud/operate/roles/isam/tasks/create_customer_and_update_subscription_in_ops_db.yml’: line 20, column 1, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  • name: Print the 2 letters country code
    ^ here

exception type: <class ‘yaml.scanner.ScannerError’>
exception: while scanning a simple key
in “”, line 18, column 1
could not find expected ‘:’
in “”, line 20, column 1

`

I have never heard of ‘|-’, what is it?

It works :)!

`

  • set_fact:
    tenant_country_code_2l: |
    {{ lookup(‘pipe’, ‘python -c “from iso3166 import countries; print countries.get("USA").alpha2”’) }}
    `

Thanks again, I didn’t know about “|” but read the doc https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html and I know now :).

Thanks a thousand.

Well, it’s not totally solved as I need know to make the ansible variable recognized to the python command…

This does not work as variable country_code is unknown:

`

  • set_fact:
    country_code_2l: |
    {{ lookup(‘pipe’, ‘python -c “print country_code”’) }}
    `

I guess the question really is: how to pass the ansible variable country_code to the python command line.
Any clue will be welcome, I’m still searching/testing… but haven’t found anything yet…

Best,
Sabrina

Hi,

Well, it's not totally solved as I need know to make the ansible
variable recognized to the python command...

This does not work as variable *country_code* is unknown:
- set_fact:
    country_code_2l: |
      {{ lookup('pipe', 'python -c "print country_code"') }}

I guess the question really is: how to pass the ansible variable
country_code to the python command line.

you should be able to do it like this:

- set_fact:
     country_code_2l: |
       {{ lookup('pipe', 'python -c "print \"' ~ country_code ~ '\""') }}

The tilde is Jinja's string concatenation. Note that this does no
sanitizing, so if country_code happens to include a double quote (or
backslash), you have a problem.

Cheers,
Felix

Thanks a million, it works and I learnt a lot (I didn’t know about the ‘~’, I’m pretty new in ansible, I started 1 month ago, still a lot to learn…).
Best,
Sabrina

It works :)!

- set_fact:
    tenant_country_code_2l: |
      {{ lookup('pipe', 'python -c "from iso3166 import countries; print
countries.get(\"USA\").alpha2"') }}

You need to have the minus sign after the pipe to remove the new line at the end.
If you add this you'll see that it's there

   - debug: var=tenant_country_code_2l

The minus after the pipe say strip newline at the end.

Thanks again, I didn't know about "|" but read the doc
https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
and I know now :).

This answer is a good reference on YAML multi line
https://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines#21699210