Гайд по миграции инвентаризационных данных в OCS Inventory NG 2.x без декоративных элементов

Гайд и Python-скрипт для миграции инвентаризации в OCS Inventory NG. Конвертация CSV в XML, безопасный импорт через injector, валидация, бэкап и откат.

2026.04.19                  


Гайд по миграции инвентаризационных данных в OCS Inventory NG 2.x без декоративных элементовГайд по миграции инвентаризационных данных в OCS Inventory NG 2.x без декоративных элементов Ниже представлен подробный гайд по миграции инвентаризационных данных в OCS Inventory NG 2.x без декоративных элементов. Гайд построен на официальной практике использования ocsinventory-injector (XML-импорт), так как прямая запись в MySQL/MariaDB нарушает целостность БД и приводит к потере данных при обновлениях.

Важно:

  • Формат источника данных не указан. Гайд использует CSV как универсальный промежуточный формат. Если у вас старая версия OCS, GLPI, Excel или кастомная БД, шаги 1–2 адаптируются под ваш источник, а шаги 3–6 остаются неизменными.

1. Подготовка инфраструктуры

Действие Команда / Описание
Установить OCS Inventory NG apt install ocsinventory-server ocsinventory-reports mysql-server (Debian/Ubuntu)
Включить модуль импорта a2enmod ocsinventory + перезапуск Apache
Проверить работу сервера curl http://<ocs-server>/ocsinventory → должен вернуть OK
Создать бэкап целевой БД mysqldump -u root -p ocsweb > ocsweb_backup_$(date +%F).sql
Соз staging-окружение Рекомендуется разворачивать миграцию на клоне сервера

2. Архитектура данных OCS Inventory NG

OCS хранит данные в нормализованных таблицах.

Основные:

Таблица Назначение Ключевые поля
hardware Основные сведения об устройстве ID, DEVICEID, NAME, USERDOMAIN, OSNAME, OSVERSION, USERID
networks Сетевые интерфейсы HARDWARE_ID, MACADDR, IPADDRESS, IPGATEWAY, IPMASK
softwares Установленное ПО HARDWARE_ID, NAME, VERSION, PUBLISHER
monitors, storages, memories Периферия и компоненты Связь через HARDWARE_ID
accountinfo Кастомные поля HARDWARE_ID, TAG, FIELDS_...

Уникальный идентификатор: DEVICEID (обычно формируется как HOSTNAME-MAC или HOSTNAME-TIMESTAMP). Дубликаты DEVICEID перезаписывают существующие записи.


3. Пошаговый план миграции

  1. Экспорт данных из старой системы в CSV/JSON/SQL.
  2. Сопоставление полей с OCS-схемой (см. таблицу ниже).
  3. Генерация XML в формате, совместимом с ocsinventory-injector.
  4. Валидация XML на синтаксис и обязательные поля.
  5. Импорт порциями (по 50–200 записей).
  6. Проверка в веб-интерфейсе и логах.
  7. Синхронизация агентов (если устройства остаются под управлением).

4. Скрипт миграции (Python 3)

Скрипт читает CSV, генерирует OCS-совместимый XML и сохраняет файлы в указанную директорию.

#!/usr/bin/env python3
"""
ocs_migrate.py – Конвертер инвентаризации в XML для OCS Inventory NG
Требования: pip install pandas lxml
"""

import pandas as pd
import logging
from pathlib import Path
from lxml import etree
import xml.dom.minidom
import argparse

logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")

def create_ocs_xml(row):
    root = etree.Element("REQUEST")
    deviceid = str(row.get("DEVICEID", f"{row.get('HOSTNAME','UNKNOWN')}-{row.get('MAC','00:00:00:00:00:00').replace(':','')}"))
    etree.SubElement(root, "DEVICEID").text = deviceid

    content = etree.SubElement(root, "CONTENT")

    # HARDWARE
    hw = etree.SubElement(content, "HARDWARE")
    for tag, col in [
        ("NAME", "HOSTNAME"),
        ("USERDOMAIN", "DOMAIN"),
        ("OSNAME", "OS"),
        ("OSVERSION", "OS_VERSION"),
        ("OSCOMMENTS", "OS_BUILD"),
        ("USERID", "USER"),
        ("WINCOMPANY", "COMPANY"),
        ("WINOWNER", "OWNER"),
        ("WINPRODUCTID", "PRODUCT_ID"),
        ("WINPRODKEY", "PRODUCT_KEY"),
        ("UUID", "SYSTEM_UUID"),
        ("TYPE", "CHASSIS_TYPE"),
        ("WORKGROUP", "WORKGROUP"),
    ]:
        val = str(row.get(col, "")).strip()
        if val:
            etree.SubElement(hw, tag).text = val

    # NETWORK (один основной интерфейс)
    net = etree.SubElement(content, "NETWORKS")
    net_entry = etree.SubElement(net, "NETWORK")
    for tag, col in [("MACADDR", "MAC"), ("IPADDRESS", "IP"), ("IPGATEWAY", "GATEWAY"), ("IPMASK", "MASK")]:
        val = str(row.get(col, "")).strip()
        if val:
            etree.SubElement(net_entry, tag).text = val

    # SOFTWARE (опционально, если есть список)
    if "SOFTWARES" in row and pd.notna(row["SOFTWARES"]):
        sw_list = etree.SubElement(content, "SOFTWARES")
        for sw in str(row["SOFTWARES"]).split(";"):
            sw_entry = etree.SubElement(sw_list, "SOFTWARE")
            parts = sw.strip().split("|")
            if len(parts) >= 1:
                etree.SubElement(sw_entry, "NAME").text = parts[0]
            if len(parts) >= 2:
                etree.SubElement(sw_entry, "VERSION").text = parts[1]
            if len(parts) >= 3:
                etree.SubElement(sw_entry, "PUBLISHER").text = parts[2]

    return etree.tostring(root, pretty_print=True, encoding="utf-8", xml_declaration=True)

def main():
    parser = argparse.ArgumentParser(description="Миграция инвентаризации в OCS NG XML")
    parser.add_argument("-i", "--input", required=True, help="Путь к CSV файлу")
    parser.add_argument("-o", "--output", required=True, help="Директория для XML")
    parser.add_argument("-e", "--encoding", default="utf-8")
    args = parser.parse_args()

    out_dir = Path(args.output)
    out_dir.mkdir(parents=True, exist_ok=True)

    df = pd.read_csv(args.input, encoding=args.encoding)
    logging.info(f"Загружено {len(df)} записей. Генерация XML...")

    for idx, row in df.iterrows():
        xml_data = create_ocs_xml(row)
        filename = out_dir / f"device_{idx:04d}.xml"
        filename.write_bytes(xml_data)

    logging.info(f"Готово. Файлы сохранены в {out_dir}")
    logging.info("Для импорта выполните: cat *.xml | ocsinventory-injector")

if __name__ == "__main__":
    main()

Пример inventory.csv

HOSTNAME,DOMAIN,OS,OS_VERSION,USER,MAC,IP,GATEWAY,MASK,SOFTWARES
WS-FINANCE-01,corp.local,Windows 10 Pro,22H2,ivanov,00:1A:2B:3C:4D:5E,192.168.10.15,192.168.10.1,255.255.255.0,Microsoft Office 2021|16.0.14326|Microsoft;7-Zip|22.01|Igor Pavlov

5. Импорт в OCS Inventory NG

# 1. Установите утилиту инъектора (обычно идёт с пакетом ocsinventory-reports)
apt install ocsinventory-reports

# 2. Импортируйте пакетно (рекомендуется по 100 файлов за раз)
cd /path/to/xml_output
head -n 100 *.xml | ocsinventory-injector

# 3. Проверьте логи сервера
tail -f /var/log/apache2/ocsinventory_server.log
tail -f /var/log/apache2/ocsinventory_activity.log

ocsinventory-injector отправляет XML на http://<ocs-server>/ocsinventory. Убедитесь, что сервер доступен с машины импорта.


6. Альтернативные способы импорта

Метод Плюсы Минусы Когда использовать
ocsinventory-injector (XML) Официальный, безопасный, сохраняет целостность БД Требует генерации XML Основной рекомендуемый путь
OCS REST API (/ocsinventory/rest) Поддержка авторизации, JSON Доступен в OCS 2.10+, требует настройки Автоматизация, CI/CD
Прямой SQL INSERT Быстро Ломает связи, не обновляет индексы, опасно при апгрейдах Не рекомендуется
Плагин ocsinventory-import GUI, маппинг CSV Устарел, плохо документирован Только если XML не подходит

7. Валидация и отладка

-- Проверка количества импортированных устройств
SELECT COUNT(*) FROM hardware;

-- Поиск устройств без IP
SELECT NAME, DEVICEID FROM hardware 
LEFT JOIN networks ON hardware.ID = networks.HARDWARE_ID 
WHERE IPADDRESS IS NULL;

-- Дубликаты DEVICEID
SELECT DEVICEID, COUNT(*) c FROM hardware GROUP BY DEVICEID HAVING c > 1;

-- ПО без привязки к устройству
SELECT COUNT(*) FROM softwares WHERE HARDWARE_ID = 0;

Чек-лист перед вводом в prod:

  • [ ] Импорт на staging с 5% данных
  • [ ] Проверка веб-интерфейса: устройства отображаются, поля не пустые
  • [ ] Логи ocsinventory_server.log без ERROR
  • [ ] Агенты на тестовых машинах успешно отправляют инвентарь
  • [ ] Бэкап БД сделан до начала импорта

8. Резервное копирование и план отката

# Бэкап перед миграцией
mysqldump -u root -p ocsweb > ocsweb_pre_migration.sql
gzip ocsweb_pre_migration.sql

# Откат (если что-то пошло не так)
mysql -u root -p ocsweb < ocsweb_pre_migration.sql
service apache2 restart

Совет:

  • Используйте SET FOREIGN_KEY_CHECKS=0; только в крайних случаях и сразу возвращайте 1. OCS строго зависит от связей hardware.ID ↔ networks.HARDWARE_ID.

9. Рекомендации по эксплуатации после миграции

  1. Настройте автоочистку дубликатов: OCS умеет объединять записи с одинаковым UUID или MAC. Включите в OCS Inventory NG Server → Configuration → Inventory → Duplicate management.
  2. Регулярный сбор: Убедитесь, что агенты настроены на --server=https://<ocs-server>/ocsinventory и --cron=1.
  3. Мониторинг: Добавьте в Zabbix/Prometheus проверку длины очереди импорта и размера ocsweb.hardware.
  4. Документация: Сохраните маппинг полей и версию CSV-схемы. При обновлениях OCS структура БД меняется редко, но не гарантируется.