Python: получение по протоколу snmp данных о разрыве на Ethernet соединении.

Применимо в основном для управляемых свичей Dlink/Orion

Принципиальный код:

def get_cable_port_status(host: str, user_port: int, snmp_ro_comm: str = 'X-Files') -> List:
    """
    Метод проверки статуса порта, витой пары и длины пар
    возвращает список словарей типа {'command_name': 'CABLE_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.4.4', 'result': 8}
    """
    SET_COMMAND = f'1.3.6.1.4.1.171.12.58.1.1.1.12.{user_port}'  # команда для получения статуса порта
    CABLE_STATUS_COMMAND = f'1.3.6.1.4.1.171.12.58.1.1.1.12.{user_port}'  # получение статуса кабеля

    status_dict = [{"command_name": "CABLE_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.4.{user_port}'},
                   # статус кабеля 8 кабель не воткнут, 1 с одной стороны в воздухе
                   {"command_name": "LINK_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.3.{user_port}'},
                   # статус порта 1 - ок, иначе нет
                   {"command_name": "PAIR_1", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.8.{user_port}'},
                   # длина 1 пары
                   {"command_name": "PAIR_2", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.9.{user_port}'},
                   # длина 2 пары
                   {"command_name": "PAIR_3", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.10.{user_port}'},
                   # длина 3 пары
                   {"command_name": "PAIR_4", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.11.{user_port}'},
                   # длина 4 пары
                   {"command_name": "PAIR_1_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.4.{user_port}'},
                   # статус 1 пары
                   {"command_name": "PAIR_2_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.5.{user_port}'},
                   # статус 2 пары
                   {"command_name": "PAIR_3_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.6.{user_port}'},
                   # статус 3 пары
                   {"command_name": "PAIR_4_STATUS", "oid": f'1.3.6.1.4.1.171.12.58.1.1.1.7.{user_port}'},
                   # статус 4 пары
                   ]

    new_value = Integer(1)
    type = ObjectType(ObjectIdentity(SET_COMMAND), new_value)
    g = setCmd(SnmpEngine(), CommunityData(snmp_ro_comm), UdpTransportTarget((host, 161)), ContextData(), type,
               lookupMib=False)
    next(g)

    auth = cmdgen.CommunityData(snmp_ro_comm)
    cmdGen = cmdgen.CommandGenerator()
    errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
        auth,
        cmdgen.UdpTransportTarget((host, 161)),
        *[cmdgen.MibVariable(oid) for oid in [oid["oid"] for oid in status_dict]],
        lookupMib=False,
    )

    if errorIndication:
        return False

    for oid, val in varBinds:
        for result in status_dict:
            if str(result["oid"]) == str(oid):
                result["result"] = int(val)

    return status_dict

Вывод в консоли будет вида:

[{'command_name': 'CABLE_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.4.4', 'result': 8}, {'command_name': 'LINK_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.3.4', 'result': 1}, {'command_name': 'PAIR_1', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.8.4', 'result': 0}, {'command_name': 'PAIR_2', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.9.4', 'result': 46}, {'command_name': 'PAIR_3', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.10.4', 'result': 46}, {'command_name': 'PAIR_4', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.11.4', 'result': 0}, {'command_name': 'PAIR_1_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.4.4', 'result': 8}, {'command_name': 'PAIR_2_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.5.4', 'result': 0}, {'command_name': 'PAIR_3_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.6.4', 'result': 0}, {'command_name': 'PAIR_4_STATUS', 'oid': '1.3.6.1.4.1.171.12.58.1.1.1.7.4', 'result': 8}]

Код не мой, предоставлен postcoder для «истории» 😉

MySQL: выборка последних значений таблицы с группировкой по колонке

Задача: выбрать последние по дате значения в таблице для каждого значения в колонке source

Решение: запрос получается с соединением. Т.е. в соединении мы делаем запрос максимальных дат с группировкой по source, а затем соединяем по дате и значению source

SELECT 
m_data.* 
from 
m_data 
inner JOIN (
    SELECT MAX(m_data.dt) as dt,m_data.source from m_data where m_data.source in (SELECT id FROM sources where device IN (1,2)) GROUP by m_data.source
) as maximum
on (maximum.source=m_data.source and maximum.dt=m_data.dt)

postgresql: выполнение запроса из командной строки

Задача: периодически необходимо подрезать логи

Решение: самое простое подготовить скрипт на bash и разместить ссылку на его выполнение в crontab:

#!/bin/bash
PGPASSWORD="Zewkkjfoeir" psql -U eee_pg -d eee -c "delete from log where dt<now() - INTERVAL '90 DAYS'"

Insert или Update если не уникальная запись

Маленькая напоминалка . Синтаксис pgsql чуть отличается от mysql.

Задача: если запись не уникальна в таблице, то просто обновить дату последнего обновления.

MySQL:

INSERT INTO users_sessions(user_id, ssid) VALUES(10, "1") ON DUPLICATE KEY UPDATE last_updated=now()

PostgreeSQL:

insert into users_sessions (user_id,ssid) values (10,'1') on conflict(ssid) do update set last_updated=now();

Уникальным должен быть объявлен столбец ssid

Ошибка обновления Ubuntu с 20.04 до 22.04

При попытке выполнить do-release-upgrade, получаем ошибку:

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts-development.

Решение:

В моём случае в логах проскочило:

esult of meta-release download: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:841)

Так-же можно проверить «тухлость» сертификата при помощи:

wget https://changelogs.ubuntu.com/meta-release-lts-development

Рекомендация обновить корневые сертификаты не помогла. Одно из решений — отключить проверку сертификатов при обновлении вообще. Для этого нужно отредактировать файл /usr/lib/python3/dist-packages/UpdateManager/Core/MetaRelease.py, добавив в него строки:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

После чего обновление прошло штатно.

1 8 9 10 11 12 59