I have this script, that connects to service via XMLRPC, like:
import odoorpc
odoo = odoorpc.ODOO(host, protocol=protocol, port=port)
Task from yaml file:
- name: Change Odoo admin user password
ansible.builtin.script: "change-user-password \
{{ secrets_odoo_init_user_passwords_file }} --ignore-failed-login \
--host {{ ansible_host }} --port 443 --protocol jsonrpc+ssl"
become: true
become_user: "{{ app_user }}"
Call looks like this (from ansible logs):
<my-host> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=30m -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -tt my-host '/bin/sh -c '"'"'sudo -H -S -n -u odoo /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-lsrscdzqfzfliptrdleqjxcwaseuaggn ; /var/tmp/ansible-tmp-1635367335.375884-2165879-123865031409885/change-user-password /opt/odoo/.secrets/odoo_init_user_passwords_file --ignore-failed-login --host my-host --port 443 --protocol jsonrpc+ssl'"'"'"'"'"'"'"'"' && sleep 0'"'"''
The full traceback is:
NoneType: None
fatal: [dev]: FAILED! => {
"changed": true,
"msg": "non-zero return code",
"rc": 1,
"stderr": "Shared connection to my-host closed.\r\n",
"stderr_lines": [
"Shared connection to my-host closed."
],
"stdout": "Traceback (most recent call last):\r\n File \"/var/tmp/ansible-tmp-1635367335.375884-2165879-123865031409885/change-user-password\", line 109, in <module>\r\n odoo = login(\r\n File \"/var/tmp/ansible-tmp-1635367335.375884-2165879-123865031409885/change-user-password\", line 75, in login\r\n odoo = odoorpc.ODOO(host, protocol=protocol, port=port)\r\n File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/odoo.py\", line 95, in __init__\r\n self._connector = rpc.PROTOCOLS[protocol](\r\n File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 288, in __init__\r\n super(ConnectorJSONRPCSSL, self).__init__(\r\n File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 211, in __init__\r\n self._proxy_json, self._proxy_http = self._get_proxies()\r\n File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 235, in _get_proxies\r\n result = proxy_json('/web/webclient/version_info')['result']\r\n File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/jsonrpclib.py\", line 113, in __call__\r\n response = self._opener.open(request, timeout=self._timeout)\r\n File \"/usr/lib/python3.9/urllib/request.py\", line 523, in open\r\n response = meth(req, response)\r\n File \"/usr/lib/python3.9/urllib/request.py\", line 632, in http_response\r\n response = self.parent.error(\r\n File \"/usr/lib/python3.9/urllib/request.py\", line 561, in error\r\n return self._call_chain(*args)\r\n File \"/usr/lib/python3.9/urllib/request.py\", line 494, in _call_chain\r\n result = func(*args)\r\n File \"/usr/lib/python3.9/urllib/request.py\", line 641, in http_error_default\r\n raise HTTPError(req.full_url, code, msg, hdrs, fp)\r\nurllib.error.HTTPError: HTTP Error 502: Bad Gateway\r\n",
"stdout_lines": [
"Traceback (most recent call last):",
" File \"/var/tmp/ansible-tmp-1635367335.375884-2165879-123865031409885/change-user-password\", line 109, in <module>",
" odoo = login(",
" File \"/var/tmp/ansible-tmp-1635367335.375884-2165879-123865031409885/change-user-password\", line 75, in login",
" odoo = odoorpc.ODOO(host, protocol=protocol, port=port)",
" File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/odoo.py\", line 95, in __init__",
" self._connector = rpc.PROTOCOLS[protocol](",
" File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 288, in __init__",
" super(ConnectorJSONRPCSSL, self).__init__(",
" File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 211, in __init__",
" self._proxy_json, self._proxy_http = self._get_proxies()",
" File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/__init__.py\", line 235, in _get_proxies",
" result = proxy_json('/web/webclient/version_info')['result']",
" File \"/opt/odoo/.local/lib/python3.9/site-packages/odoorpc/rpc/jsonrpclib.py\", line 113, in __call__",
" response = self._opener.open(request, timeout=self._timeout)",
" File \"/usr/lib/python3.9/urllib/request.py\", line 523, in open",
" response = meth(req, response)",
" File \"/usr/lib/python3.9/urllib/request.py\", line 632, in http_response",
" response = self.parent.error(",
" File \"/usr/lib/python3.9/urllib/request.py\", line 561, in error",
" return self._call_chain(*args)",
" File \"/usr/lib/python3.9/urllib/request.py\", line 494, in _call_chain",
" result = func(*args)",
" File \"/usr/lib/python3.9/urllib/request.py\", line 641, in http_error_default",
" raise HTTPError(req.full_url, code, msg, hdrs, fp)",
"urllib.error.HTTPError: HTTP Error 502: Bad Gateway"
]
}
I read that people workaround this error by using headers={'User-Agent': 'Mozilla/5.0'}. But if I use script module via ansible, how can I specify such header?
The thing is, I only get this error if I run script via ansible. I tried running that script explicitly from my machine and from target machine. In those cases, it works fine.
ansible [core 2.11.6]
config file = /home/oerp/.ansible.cfg
configured module search path = ['/home/oerp/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/oerp/.local/lib/python3.8/site-packages/ansible
ansible collection location = /home/oerp/.ansible/collections:/usr/share/ansible/collections
executable location = /home/oerp/.local/bin/ansible
python version = 3.8.10 (default, Sep 28 2021, 16:10:42) [GCC 9.3.0]
jinja version = 3.0.1
libyaml = True
Update
Turn out the problem when XMLPRC call is made, service is not yet running, thus the error.
So I have to use RPC only when service is already running.
I tried using wait_for like this (note, my Odoo service port is not exposed via compose, its only accessible through docker network by nginx):
- name: Save Odoo container status
set_fact:
odoo_ip: "{{ docker_compose_output.services.odoo.app_odoo_1.networks.app_backend.IPAddress }}"
- name: Wait for IP to be active
wait_for:
host: "{{ odoo_ip }}"
delay: 1
state: drained
I do get this error:
The full traceback is:
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py", line 100, in <module>
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py", line 92, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible.modules.wait_for', init_globals=dict(_module_fqn='ansible.modules.wait_for', _modlib_path=modlib_path),
File "/usr/lib/python3.9/runpy.py", line 210, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/usr/lib/python3.9/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py", line 674, in <module>
File "/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py", line 657, in main
File "/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py", line 356, in __init__
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
fatal: [dev]: FAILED! => {
"changed": false,
"module_stderr": "Shared connection to my-host closed.\r\n",
"module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py\", line 100, in <module>\r\n _ansiballz_main()\r\n File \"/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py\", line 92, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File \"/root/.ansible/tmp/ansible-tmp-1635403378.5625799-2174550-176521610555803/AnsiballZ_wait_for.py\", line 40, in invoke_module\r\n runpy.run_module(mod_name='ansible.modules.wait_for', init_globals=dict(_module_fqn='ansible.modules.wait_for', _modlib_path=modlib_path),\r\n File \"/usr/lib/python3.9/runpy.py\", line 210, in run_module\r\n return _run_module_code(code, init_globals, run_name, mod_spec)\r\n File \"/usr/lib/python3.9/runpy.py\", line 97, in _run_module_code\r\n _run_code(code, mod_globals, init_globals,\r\n File \"/usr/lib/python3.9/runpy.py\", line 87, in _run_code\r\n exec(code, run_globals)\r\n File \"/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py\", line 674, in <module>\r\n File \"/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py\", line 657, in main\r\n File \"/tmp/ansible_wait_for_payload_pic_t21b/ansible_wait_for_payload.zip/ansible/modules/wait_for.py\", line 356, in __init__\r\nTypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
Its unclear what argument it is about.