Общие сведения о скриптах проверок

Скрипты проверок – это файлы, содержащие пользовательскую логику проверки работоспособности сервиса или узла.

Для создания скрипта проверки используются файлы в формате:

  • .py – для python-скрипта;
  • .sh – для bash-скрипта.

Файлы скриптов проверок располагаются в каталоге /var/lib/tdc/lbscripts/hc/.

Скрипты проверок позволяют выполнять проверки по протоколам:
  • HTTP/HTTPS;
  • TCP.

Параметры проверки передаются скрипту в качестве аргумента командной строки в формате JSON, и обязательно содержат поля:

  • source-ip;
  • target-ip;
  • target-port.

Для каждой выполняемой проверки запускается отдельный процесс с собственной копией скрипта проверки. Большое количество таких процессов может негативно сказаться на производительности системы.

Пример использования python-скрипта (описание полей приведено в таблице):

import requests
import sys
import json

config = json.loads(sys.argv[1])
target_ip = config["target-ip"]
target_port = config["target-port"]

response = requests.get(f"http://{target_ip}:{target_port}", timeout=5)
response.raise_for_status()
sys.exit(0)
BASH
Описание полей python-скрипта проверки

ПолеОписание

import requests

Импортирует модуль requests для выполнения HTTP-запросов

import sys

Импортирует модуль sys для работы с аргументами командной строки

import json

Импортирует модуль json для обработки данных в формате JSON

config = json.loads(sys.argv[1])

Читает первый аргумент командной строки, содержащий строку в формате JSON, и преобразует его в объект Python

target_ip = config["target-ip"]

Извлекает из объекта config значение параметра target-ip

target_port = config["target-port"]

Извлекает из объекта config значение параметра target-port

response = requests.get(f"http://{target_ip}:{target_port}", timeout=5)

Выполняет HTTP-запрос по адресу, составленному из значений параметров target-ip и target-port, с временем ожидания 5 секунд

response.raise_for_status()

Генерирует исключение, если код ответа сервера не входит в диапазон значений 200 – 299

sys.exit(0)

Завершает работу скрипта с кодом 0, если проверка успешна

Проверку с использованием python-скрипта можно упростить, используя логику обработки аргументов командной строки в конфигурационном файле config.py.

Файл config.py должен располагаться в каталоге /var/lib/tdc/lbscripts/hc/.

Пример содержимого файла config.py (описание полей приведено в таблице):

import json

class Config:

    source_ip: str
    target_ip: str
    target_port: str

    def __init__(self, argv):
        if len(argv) != 2:
            raise ValueError(f"List must be the length of two, but has {len(argv)} elements")

        try:
            config = json.loads(argv[1])
            self.source_ip = config.get("source-ip")
            self.target_ip = config.get("target-ip")
            self.target_port = config.get("target-port")
        except json.JSONDecodeError:
            raise TypeError("List's second element must contain valid JSON object")
BASH
Описание полей конфигурационного файла config.py

ПолеОписание

import json

Импортирует модуль json для обработки данных в формате JSON

class Config:

Задает класс Config для хранения параметров проверки

source_ip: str

Атрибут для хранения IP-адреса источника запроса

target_ip: str

Атрибут для хранения IP-адреса назначения

target_port: str

Атрибут для хранения порта назначения

def __init__(self, argv):

Конструктор класса, принимающий список аргументов командной строки

if len(argv) != 2:

Проверяет, что список аргументов содержит ровно два элемента

raise ValueError(...)

Генерирует исключение, если количество аргументов не равно двум

config = json.loads(argv[1])

Читает второй аргумент командной строки, содержащий строку в формате JSON, и преобразует его в объект Python

self.source_ip = config.get("source-ip")

Сохраняет значение поля source-ip в атрибуте source_ip

self.target_ip = config.get("target-ip")

Сохраняет значение поля target-ip в атрибуте target_ip

self.target_port = config.get("target-port")

Сохраняет значение поля target-port в атрибуте target_port

except json.JSONDecodeError:

Обрабатывает ошибку, если второй аргумент не является корректной JSON-строкой

raise TypeError(...)

Генерирует исключение, если аргумент не содержит корректный JSON-объект

Пример python-скрипта с использованием конфигурационного файла config.py (описание полей приведено в таблице):

import sys
import requests
import config # Импорт файла с классом Config

def check_http(target_ip, target_port):
    url = f"http://{target_ip}:{target_port}"
    try:
        response = requests.head(url, timeout=3)
        print("HEAD: OK")
        response = requests.get(url, timeout=3)
        print("GET: OK")
        return True
    except requests.exceptions.RequestException:
        print("NOT OK")
        return False

config = config.Config(sys.argv) # Использование класса
source_ip = config.source_ip # Получение source-ip
target_ip = config.target_ip # Получение target-ip
target_port = config.target_port # Получение target-port

print(f"Config:")
print(f"  Source IP: {source_ip}")
print(f"  Target IP: {target_ip}")
print(f"  Target Port: {target_port}")
print(f"Checking HTTP server at {target_ip}:{target_port}...", end=" ")

if not check_http(target_ip, target_port):
    sys.exit(1)

sys.exit(0)
BASH
Описание полей python-скрипта с использованием файла config.py

ПолеОписание

import requests

Импортирует модуль requests для выполнения HTTP-запросов

import sys

Импортирует модуль sys для работы с аргументами командной строки

import config

Импортирует модуль config, содержащий класс Config для обработки аргументов командной строки

def check_http(target_ip, target_port):

Определяет функцию check_http для выполнения HTTP-проверки работоспособности узла или сервиса

url = f"http://{target_ip}:{target_port}"

Формирует URL-адрес из значений параметров target_ip и target_port

response = requests.head(url, timeout=3)

Выполняет HEAD-запрос по указанному адресу с временем ожидания 3 секунды

print("HEAD: OK")

Выводит сообщение об успешном выполнении HEAD-запроса

response = requests.get(url, timeout=3)

Выполняет GET-запрос по указанному адресу с временем ожидания 3 секунды

print("GET: OK")

Выводит сообщение об успешном выполнении GET-запроса

return True

Возвращает значение True, если оба запроса завершились без ошибок

except requests.exceptions.RequestException:

Перехватывает исключения, возникающие при выполнении HTTP-запросов

print("NOT OK")

Выводит сообщение о неуспешной проверке

return False

Возвращает значение False в случае ошибки при выполнении запросов

config = config.Config(sys.argv)

Создает объект класса Config и передает ему аргументы командной строки

source_ip = config.source_ip

Получает значение параметра source-ip из объекта Config

target_ip = config.target_ip

Получает значение параметра target-ip из объекта Config

target_port = config.target_port

Получает значение параметра target-port из объекта Config

print(f"Config:")

Выводит заголовок конфигурации

print(f" Source IP: {source_ip}")

Выводит IP-адрес источника запроса

print(f" Target IP: {target_ip}")

Выводит IP-адрес назначения

print(f" Target Port: {target_port}")

Выводит порт назначения проверки

print(f"Checking HTTP server at {target_ip}:{target_port}...", end=" ")

Выводит сообщение о начале HTTP-проверки

if not check_http(target_ip, target_port):

Проверяет результат выполнения функции check_http для указанного узла или сервиса

sys.exit(1)

Завершает работу скрипта с кодом ошибки 1, если проверка неуспешна

sys.exit(0)

Завершает работу скрипта с кодом 0, если проверка успешна

Пример использования bash-скрипта (описание полей приведено в таблице):

#!/bin/bash

json_input="$1"
target_ip=$(jq -r '.["target-ip"]' <<< "$json_input")
target_port=$(jq -r '.["target-port"]' <<< "$json_input")

curl -s -o /dev/null "http://${target_ip}:${target_port}"
exit $?
BASH
Описание полей bash-скрипта проверки

ПолеОписание

json_input="$1"

Сохраняет первый аргумент командной строки в переменную json_input

target_ip=$(jq -r '.["target-ip"]' <<< "$json_input")

Извлекает значение параметра target-ip из переменной json_input с использованием утилиты jq

target_port=$(jq -r '.["target-port"]' <<< "$json_input")

Извлекает значение параметра target-port из переменной json_input с использованием утилиты jq

curl -s -o /dev/null "http://${target_ip}:${target_port}"

Выполняет HTTP-запрос с использованием утилиты curl по адресу, составленному из значений параметров target-ip и target-port, без вывода содержимого ответа и информации о процессе выполнения

exit $?

Завершает выполнение скрипта с кодом ответа, который вернула утилита curl