bashclub / checkmk-opnsense-agent

75 stars 18 forks source link

"Error Status: 200" for ACME certificate #55

Open f-zappa opened 2 months ago

f-zappa commented 2 months ago

Hi everyone, I receive an "Error Status: 200" for an ACME cert, although the cert itself is fine. Relevant lines in agent output (when nc'ing it) read like this:

[...]
<<<local:sep(0)>>>
2 "ACME Cert: home.uli-baumann.de" age=0 Error Status: 200
[..]

Once an hour indeed the status turns to "Item not found in monitoring data", probably when the _certificate_parser is called. Same happens when running the agent from the command line using "--debug", and in this case we get a traceback:

Traceback (most recent call last):
  File "/usr/local/etc/rc.syshook.d/start/99-checkmk_agent", line 242, in do_checks
    _lines += getattr(self,_check)()
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/etc/rc.syshook.d/start/99-checkmk_agent", line 1068, in checklocal_acmeclient
    _certificate = self._get_certificate(_cert_info.get("certRefId"))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/etc/rc.syshook.d/start/99-checkmk_agent", line 397, in _get_certificate
    self._certificate_parser()
  File "/usr/local/etc/rc.syshook.d/start/99-checkmk_agent", line 393, in _certificate_parser
    self._certificate_store[_cert.get("refid")] = _cert
                            ^^^^^^^^^
AttributeError: 'str' object has no attribute 'get'

[ .. rest of agent output .. ]

<<<check_mk>>>
FailedPythonPlugins: acmeclient

I looked around the code but don't get why _cert happens to be a string. Maybe someone has an idea how to fix it ...

regards, Uli

f-zappa commented 2 months ago

OK, had some time today. This effect only occurs if there is only one cert in the store. This for loop expects a list of dicts, but if only one cert exists in store this will be returned as a bare dict.

for _cert in self._config_reader().get("cert"):

Fixed it in #56 with this code (maybe there is a more elegant way, but it fixed my problem):

_certs = self._config_reader().get("cert")
if not isinstance(_certs, list):
    _certs = [_certs]
for _cert in _certs:
    [...]