Гайд по миграции инвентаризационных данных в 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. Пошаговый план миграции
- Экспорт данных из старой системы в CSV/JSON/SQL.
- Сопоставление полей с OCS-схемой (см. таблицу ниже).
- Генерация XML в формате, совместимом с
ocsinventory-injector. - Валидация XML на синтаксис и обязательные поля.
- Импорт порциями (по 50–200 записей).
- Проверка в веб-интерфейсе и логах.
- Синхронизация агентов (если устройства остаются под управлением).
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. Рекомендации по эксплуатации после миграции
- Настройте автоочистку дубликатов: OCS умеет объединять записи с одинаковым
UUIDилиMAC. Включите вOCS Inventory NG Server → Configuration → Inventory → Duplicate management. - Регулярный сбор: Убедитесь, что агенты настроены на
--server=https://<ocs-server>/ocsinventoryи--cron=1. - Мониторинг: Добавьте в Zabbix/Prometheus проверку длины очереди импорта и размера
ocsweb.hardware. - Документация: Сохраните маппинг полей и версию CSV-схемы. При обновлениях OCS структура БД меняется редко, но не гарантируется.