lukecyca/pyzabbix

412 Client Error: Precondition Failed

exeral opened this issue · 2 comments

Hello,

I am trying to use pyzabbix into an AWS Lambda function.
it uses python 3.7 runtime

here is the piece of code

import json
import os
import sys
import logging
from pyzabbix import ZabbixAPI

stream = logging.StreamHandler(sys.stdout)
stream.setLevel(logging.DEBUG)
log = logging.getLogger('pyzabbix')
log.addHandler(stream)
log.setLevel(logging.DEBUG)

auth_token = os.environ['ZABBIX_API_TOKEN']

def lambda_handler(event, context):
    zapi = ZabbixAPI("http://zabbix.private.fqdn")
    print(zapi.api_version())
    #zapi.login(api_token=auth)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

the response i get is

JSON-RPC Server Endpoint: http://zabbix.private.fqdn/api_jsonrpc.php
[INFO]	2022-08-17T09:44:11.598Z	1820a2c5-424a-4907-a961-badd223948d8	JSON-RPC Server Endpoint: http://zabbix.private.fqdn/api_jsonrpc.php
Sending: {'jsonrpc': '2.0', 'method': 'apiinfo.version', 'params': {}, 'id': 0}
[DEBUG]	2022-08-17T09:44:11.598Z	1820a2c5-424a-4907-a961-badd223948d8	Sending: {'jsonrpc': '2.0', 'method': 'apiinfo.version', 'params': {}, 'id': 0}
Response Code: 412
[DEBUG]	2022-08-17T09:44:11.830Z	1820a2c5-424a-4907-a961-badd223948d8	Response Code: 412
[ERROR] HTTPError: 412 Client Error: Precondition Failed for url: https://zabbix.private.fqdn:443/api_jsonrpc.php
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 17, in lambda_handler
    print(zapi.api_version())
  File "/opt/python/pyzabbix/api.py", line 184, in api_version
    return self.apiinfo.version()
  File "/opt/python/pyzabbix/api.py", line 265, in __call__
    return self._parent.do_request(self._method, args or kwargs)["result"]
  File "/opt/python/pyzabbix/api.py", line 213, in do_request
    resp.raise_for_status()
  File "/opt/python/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)

when I check the zabbix nginx logs I see

10.100.2.119 - - [17/Aug/2022:11:42:45 +0200] "GET /api_jsonrpc.php HTTP/1.1" 412 5 "-" "python/pyzabbix"
10.100.2.119 - - [17/Aug/2022:11:44:11 +0200] "GET /api_jsonrpc.php HTTP/1.1" 412 5 "-" "python/pyzabbix"

if I run
curl -s -H 'Content-type:application/json' https://zabbix.private.fqdn/api_jsonrpc.php -d '{"jsonrpc": "2.0", "method": "apiinfo.version", "params": {}, "id": 0}'
it works well

why pyzabbix send GET requests ? it is supposed to send POST if i'm not wrong ..?!

lib versions:

  • certifi-2022.6.15
  • charset_normalizer-2.1.0
  • idna-3.3
  • packaging-21.3
  • pyzabbix-1.2.0
  • requests-2.28.1
  • urllib3-1.26.11

thanks for help

reproduced on a fresh install of Amazon Linux

[ec2-user@ip-10-99-40-114 ~]$ virtualenv pyzabbix
created virtual environment CPython3.7.10.final.0-64 in 1073ms
  creator CPython3Posix(dest=/home/ec2-user/pyzabbix, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/ec2-user/.local/share/virtualenv)
    added seed packages: pip==22.2.2, setuptools==63.4.1, wheel==0.37.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
[ec2-user@ip-10-99-40-114 ~]$ source pyzabbix/bin/activate
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ python --version
Python 3.7.10
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ pip install pyzabbix
Collecting pyzabbix
  Downloading pyzabbix-1.2.0-py3-none-any.whl (6.8 kB)
Collecting packaging
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.8/40.8 kB 7.7 MB/s eta 0:00:00
Collecting requests>=1.0
  Downloading requests-2.28.1-py3-none-any.whl (62 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.8/62.8 kB 12.1 MB/s eta 0:00:00
Collecting idna<4,>=2.5
  Downloading idna-3.3-py3-none-any.whl (61 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.2/61.2 kB 11.9 MB/s eta 0:00:00
Collecting charset-normalizer<3,>=2
  Downloading charset_normalizer-2.1.0-py3-none-any.whl (39 kB)
Collecting certifi>=2017.4.17
  Downloading certifi-2022.6.15-py3-none-any.whl (160 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.2/160.2 kB 24.3 MB/s eta 0:00:00
Collecting urllib3<1.27,>=1.21.1
  Downloading urllib3-1.26.11-py2.py3-none-any.whl (139 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.9/139.9 kB 25.3 MB/s eta 0:00:00
Collecting pyparsing!=3.0.5,>=2.0.2
  Downloading pyparsing-3.0.9-py3-none-any.whl (98 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.3/98.3 kB 18.5 MB/s eta 0:00:00
Installing collected packages: urllib3, pyparsing, idna, charset-normalizer, certifi, requests, packaging, pyzabbix
Successfully installed certifi-2022.6.15 charset-normalizer-2.1.0 idna-3.3 packaging-21.3 pyparsing-3.0.9 pyzabbix-1.2.0 requests-2.28.1 urllib3-1.26.11
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ vim code.py
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ ls
code.py  pyzabbix
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ cat code.py
from pyzabbix import ZabbixAPI

zapi = ZabbixAPI("http://zabbix.private.fqdn")
zapi.login("username", "******")
# You can also authenticate using an API token instead of user/pass with Zabbix >= 5.4
# zapi.login(api_token='xxxxx')
print("Connected to Zabbix API Version %s" % zapi.api_version())

for h in zapi.host.get(output="extend"):
    print(h['hostid'])
(pyzabbix) [ec2-user@ip-10-99-40-114 ~]$ python code.py
Traceback (most recent call last):
  File "code.py", line 4, in <module>
    zapi.login("username", "****")
  File "/home/ec2-user/pyzabbix/lib/python3.7/site-packages/pyzabbix/api.py", line 120, in login
    self.version = Version(self.api_version())
  File "/home/ec2-user/pyzabbix/lib/python3.7/site-packages/pyzabbix/api.py", line 184, in api_version
    return self.apiinfo.version()
  File "/home/ec2-user/pyzabbix/lib/python3.7/site-packages/pyzabbix/api.py", line 265, in __call__
    return self._parent.do_request(self._method, args or kwargs)["result"]
  File "/home/ec2-user/pyzabbix/lib/python3.7/site-packages/pyzabbix/api.py", line 213, in do_request
    resp.raise_for_status()
  File "/home/ec2-user/pyzabbix/lib/python3.7/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 412 Client Error: Precondition Failed for url: https://zabbix.private.fqdn:443/api_jsonrpc.php

same with pyzabbix==1.1.0
same with python3.8

added requests logging

logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): zabbix.private.fqdn:80
DEBUG:urllib3.connectionpool:http://zabbix.private.fqdn:80 "POST /api_jsonrpc.php HTTP/1.1" 301 134
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): zabbix.private.fqdn:443
DEBUG:urllib3.connectionpool:https://zabbix.private.fqdn:443 "GET /api_jsonrpc.php HTTP/1.1" 412 None

the loadbalancer was doing an https -> https redirect, because I misstyped httpS in url endpoint ...!