Rest-Api: Klassischen Nagios-Check per Rest-Api anlegen

Hallo zusammen,

für die Migration auf die 2.3 muß ich einige alte Rules, die wir bisher manuell in Config-Files gepflegt haben, in das neue Python-Format für die Wato-Rules überführen. Am Einfachsten ist die m.E., wenn ich die Checks (es sind hunderte) per Rest-Api neu in Check_MK anlege. Leider scheitere ich aber derzeit an der Syntax.

Ich möchte httpi nutzen, mit folgendem Aufruf teste ich:

#!/bin/bash
HOST_NAME="myhostname.fqdn"
SITE_NAME="mytestsite"
API_URL="https://$HOST_NAME/$SITE_NAME/check_mk/api/1.0"

USERNAME="automation"
PASSWORD="geheim"

# Requires httpie version >= 3


http POST "$API_URL/domain-types/rule/collections/all" \
    "Authorization: Bearer $USERNAME $PASSWORD" \
    "Accept: application/json" \
    'Content-Type:application/json' \
    ruleset='custom_checks'\
    folder='~testhosts'\
    properties[disabled]:=false\
    value_raw="{'command_line': 'check_miwu_http -U https://google.de ', 'has_perfdata': True, 'service_description': 'check_google'}"

Beim Aufruf erhalte ich dann immer folgenden Fehler:

HTTP/1.1 400 BAD REQUEST
Connection: close
Content-Length: 157
(...)

{
    "detail": "These fields have problems: properties[disabled]",
    "fields": {
        "properties[disabled]": [
            "Unknown field."
        ]
    },
    "status": 400,
    "title": "Bad Request"
}

Wo liegt hier mein Fehler? Die Zeile "properties[disabled]:=false" hatte ich 1:1 aus der Doku übernommen.

Ich bin für jede Hilfe dankbar.

Das Feld heißt nicht properties[disabled], sondern properties selber ist ein Dictionary:

"properties": {
          "disabled": false
        },

Die Beispiele für httpie scheinen aber öfter nicht korrekt zu sein. Versuch es mal mit properties='{"disabled": false}' wie auch bei value_raw.

Hallo Robert,

danke für Deine Hilfe.

Leider klappt es so auch nicht. Ich habe versucht:

#!/bin/bash
HOST_NAME="myhostname.fqdn"
SITE_NAME="mytestsite"
API_URL="https://$HOST_NAME/$SITE_NAME/check_mk/api/1.0"

USERNAME="automation"
PASSWORD="geheim"

# Requires httpie version >= 3


http POST "$API_URL/domain-types/rule/collections/all" \
    "Authorization: Bearer $USERNAME $PASSWORD" \
    "Accept: application/json" \
    'Content-Type:application/json' \
    ruleset='custom_checks'\
    folder='~testhosts'\
    properties="{'disabled': false}"\
    value_raw="{'command_line': 'check_miwu_http -U https://google.de ', 'has_perfdata': True, 'service_description': 'check_google'}"

und bekomme dann:

HTTP/1.1 400 BAD REQUEST
Connection: close
(...)

{
    "detail": "These fields have problems: properties",
    "fields": {
        "properties": {
            "_schema": [
                "Invalid input type."
            ]
        }
    },
    "status": 400,
    "title": "Bad Request"
}

Immerhin ist die Fehlermeldung eine Andere.

Die einfachen und doppelten Hochkommas hatte ich auch in der anderen Variante probiert, das Ergebnis ist das Gleiche.

Hast Du noch eine Idee?

Versuch es mal mit dem curl-Beispiel oder einem Python-Skript. Meine Erfahrungen mit httpie sind sehr limitiert.

1 Like

Möglicherweise kann man

auch ganz weglassen? disabled=False dürfte doch wohl die default-Einstellung sein, wenn man Regeln anlegt. Das ist aber nur geraten.

1 Like

Das stimmt. Vielleicht soll ja aber auch mal eine Regel mit disabled=True angelegt werden.

1 Like

Wenn ich die “properties”-Zeile aus dem Aufruf rausnehme wirds noch schlimmer:

#!/bin/bash
HOST_NAME="myhostname.fqdn"
SITE_NAME="mytestsite"
API_URL="https://$HOST_NAME/$SITE_NAME/check_mk/api/1.0"

USERNAME="automation"
PASSWORD="geheim"

# Requires httpie version >= 3


http POST "$API_URL/domain-types/rule/collections/all" \
    "Authorization: Bearer $USERNAME $PASSWORD" \
    "Accept: application/json" \
    'Content-Type:application/json' \
    ruleset='custom_checks'\
    folder='~testhosts'\
    value_raw="{'command_line': 'check_miwu_http -U https://google.de ', 'has_perfdata': True, 'service_description': 'check_google'}"

Das Ergebnis ist ein Crash:

HTTP/1.1 500 INTERNAL SERVER ERROR
Connection: close
Content-Length: 4625
Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' ssh: rdp:; img-src 'self' data: https://*.tile.openstreetmap.org/ ; connect-src 'self' https://crash.checkmk.com/ https://license.checkmk.com/api/verify; frame-ancestors 'self' ; base-uri 'self'; form-action 'self' javascript: 'unsafe-inline'; object-src 'self'; worker-src 'self' blob:
Content-Type: application/problem+json
Date: Tue, 27 Feb 2024 09:34:59 GMT
Permissions-Policy: accelerometer=(), autoplay=(), camera=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), usb=()
Referrer-Policy: origin-when-cross-origin
Server: Apache
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block

{
    "detail": "KeyError: conditions. Crash report generated. Please submit.",
    "ext": {
        "core": "cmc",
        "crash_type": "rest_api",
        "details": {
            "check_mk_info": {
                "check_mk_user": {
                    "authorized_sites": [
                        "mytestsite",
                        "mytestsite_slave"
                    ],
                    "user_id": "automation",
                    "user_roles": [
                        "admin"
                    ]
                },
                "site": "mytestsite"
            },
            "crash_report_url": {
                "href": "http://myhostname.fqdn/mytestsite/check_mk/crash.py?crash_id=7aba421a-d553-11ee-9b98-005056a2a9c5&site=mytestsite",
                "method": "get",
                "rel": "cmk/crash-report",
                "type": "text/html"
            },
            "request_info": {
                "data_received": {
                    "folder": "~testhosts",
                    "ruleset": "custom_checks",
                    "value_raw": "{'command_line': 'check_miwu_http -U https://google.de ', 'has_perfdata': True, 'service_description': 'sc_https_google'}"
                },
                "endpoint_url": "/mytestsite/check_mk/api/1.0/domain-types/rule/collections/all",
                "headers": {
                    "accept": "application/json",
                    "content_type": "application/json"
                },
                "method": "POST"
            }
        },
        "edition": "cee",
        "exc_traceback": [
            "Traceback (most recent call last):",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/wsgi/applications/rest_api.py\", line 435, in wsgi_app",
            "    return wsgi_endpoint(environ, start_response)",
            "           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/wsgi/applications/utils.py\", line 47, in __call__",
            "    return self.wsgi_app(environ, start_response)",
            "           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/wsgi/applications/rest_api.py\", line 164, in wsgi_app",
            "    wsgi_app = self.endpoint.wrapped(ParameterDict(path_args))",
            "               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/plugins/openapi/restful_objects/decorators.py\", line 1003, in _wrapper",
            "    response = func(param)",
            "               ^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/plugins/openapi/restful_objects/decorators.py\", line 992, in _validating_wrapper",
            "    return self._validate_response(response_schema, _params)",
            "           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/plugins/openapi/restful_objects/decorators.py\", line 789, in _validate_response",
            "    response = self.func(_params)",
            "               ^^^^^^^^^^^^^^^^^^",
            "  File \"/omd/sites/mytestsite/lib/python3/cmk/gui/plugins/openapi/endpoints/rule/__init__.py\", line 202, in create_rule",
            "    host_tags=body[\"conditions\"].get(\"host_tags\"),",
            "              ~~~~^^^^^^^^^^^^^^",
            "KeyError: 'conditions'",
            ""
        ],
        "exc_type": "KeyError",
        "exc_value": "conditions",
        "id": "7aba421a-d553-11ee-9b98-005056a2a9c5",
        "local_vars": "(...)",
        "os": "SUSE Linux Enterprise Server 15 SP5",
        "python_paths": [
            "/omd/sites/mytestsite/local/lib/python3",
            "/omd/sites/mytestsite/lib/python3/cloud",
            "/omd/sites/mytestsite/lib/python311.zip",
            "/omd/sites/mytestsite/lib/python3.11",
            "/omd/sites/mytestsite/lib/python3.11/lib-dynload",
            "/omd/sites/mytestsite/lib/python3.11/site-packages",
            "/omd/sites/mytestsite/lib/python3"
        ],
        "python_version": "3.11.2 (main, Jun 29 2023, 23:24:59) [GCC 12.2.0]",
        "time": "2024-02-27T10:35:00.349060",
        "version": "2.2.0p9"
    },
    "status": 500,
    "title": "Internal Server Error"
}

Der Crash könnte jetzt aber an der falschen JSON-Syntax liegen und nicht an dem fehlenden Attribut::

Für JSON muss man doppelte Anführungszeichen verwenden. Da darf man keine einfachen nehmen. Probier nochmal mit

value_raw='{"command_line": "check_miwu_http -U https://google.de ", "has_perfdata": True, "service_description": "check_google"}'

Das Ergebnis ist leider das gleiche. Crash mit Key Error.

Mich wundert, dass da das Attribut conditions (Plural-s) angemeckert wird. Ich kenne bei Regeln sonst nur das Attribut condition. Ich würde jetzt entweder blind mal

"condition": {}

(gerne auch im Plural) zum value_raw hinzufügen.

Oder – und das klingt vielversprechender für mich – eine Regel über die GUI anlegen und dann per API abfragen. Dann sieht man ja, wie sie aussehen soll.

So funktioniert der Aufruf:

http POST "$API_URL/domain-types/rule/collections/all" \
    "Authorization: Bearer $USERNAME $PASSWORD" \
    "Accept: application/json" \
    "Content-Type:application/json" \
    properties:='{"disabled": false}'\
    ruleset='custom_checks'\
    folder='~real_hosts'\
    conditions:='{}'\
    value_raw='{"command_line": "check_miwu_http -U https://google.de", "service_description":"check_google", "has_perfdata": True}'

Ist aber ein wildes gemische der Syntax, da teilweise für Python und teilweise für httpie formatiert werden muss. Man muss bei den Hochkommata aufpassen und bei True/False, die jeweils groß oder klein geschrieben werden müssen.
“conditions” muss einfach leer hinzugefügt werden dann kommt keine Fehlermeldung mehr.

Für mich habe ich gerade gelernt, ich bleibe da lieber bei Python :wink:

4 Likes

Marc, super, vielen Dank.

Das funktioniert perfekt und ich kann in dem Check-Aufruf in der Rule sogar noch Variablen wie $USER5$ mitgeben. Das erleichtert meine Migration sehr und ich kann meine alten Checks sauber in in die neue Rule-Syntax von Check_MK überführen.

Nochmal danke und Gruß
Miwu

2 Likes