# mcimport — массовое создание ящиков mailcow из CSV Однобинарный инструмент (stdlib-only Go, embedded веб-морда) для провижининга почтовых ящиков mailcow через API. Импорт файла → предпросмотр с валидацией → потоковый журнал создания. ![Интерфейс mcimport: подключение к API и предпросмотр импорта](pic1.png) ## Возможности - **Проверка подключения** к API (домены/ящики читаются, чтобы подтвердить ключ и allow-list). - **Выбор домена**: после проверки подключения можно выбрать домен из списка mailcow — тогда в CSV достаточно логина без `@домена` (email собирается как `логин@выбранный_домен`). - **Предпросмотр**: разбор CSV, структурная валидация (email, пароль, дубликаты), плюс — если задан ключ — сверка с живым mailcow: пропуск существующих ящиков и отсев несуществующих доменов. - **Импорт** с потоковым (NDJSON) журналом в реальном времени: по строке на ящик, разбор ответа mailcow (`success`/`danger`), счётчики, выгрузка лога в CSV. ## Формат CSV Заголовок обязателен. Разделитель — точка с запятой (`;`); также распознаются `,` и таб. BOM снимается, кодировка — UTF-8. Готовый образец можно скачать в UI (ссылка «Скачать пример CSV») или по `GET /api/example`. С выбранным в UI доменом достаточно логина: ```csv login;password;name ivanov;S3cretPass!;Иван Иванов petrov;An0therPass!;Пётр Петров ``` Без выбора домена — полный email в каждой строке: ```csv email;password;name ivanov@bildme.ru;S3cretPass!;Иван Иванов petrov@amega.kz;An0therPass!;Пётр Петров ``` Колонки (регистр/пробелы/подчёркивания не важны, есть RU-алиасы): | колонка | обяз. | примечание | |----------------------|-------|--------------------------------------------------------| | `email` / `login` | да* | при выбранном домене — логин без `@`; иначе полный email или пара `localpart` + `domain` | | `password` | да | <8 символов → предупреждение | | `name` | нет | ФИО; по умолчанию = localpart | | `quota` | нет | МиБ; иначе «квота по умолчанию» | | `active` | нет | `1`/`0`, по умолчанию `1` | ## Запуск ### Бинарь ```bash CGO_ENABLED=0 go build -ldflags="-s -w" -o mcimport . MAILCOW_URL=https://mail.dom.ru ./mcimport # открыть http://localhost:8080 ``` ### Docker ```bash docker compose up -d --build # морда на 127.0.0.1:8080 — ходите через SSH-туннель: # ssh -L 8080:127.0.0.1:8080 user@host ``` ## Переменные окружения | переменная | по умолчанию | назначение | |------------------------|-------------------------|---------------------------------------------------| | `MAILCOW_URL` | — | базовый URL (можно ввести в UI) | | `MAILCOW_API_KEY` | — | Read-Write ключ; если задан — не вводится в UI | | `DEFAULT_QUOTA` | `10240` | квота по умолчанию, МиБ | | `LISTEN` | `:8080` | адрес прослушивания | | `INSECURE_SKIP_VERIFY` | `false` | отключить проверку TLS (внутренний CA) | ## Что нужно на стороне mailcow 1. UI → `Configuration → Access → Edit administrator details → API`: создать ключ с правами **Read-Write**. 2. В `API_ALLOW_FROM` добавить IP, с которого mcimport ходит в API (egress-IP контейнера/хоста). Иначе — отказ доступа. 3. Убедиться, что лимит «Максимум почтовых ящиков» у домена и квоты домена покрывают импортируемую пачку. ## Общая квота домена (частая ошибка `mailbox_quota_left_exceeded`) mailcow не даст создать ящик, если `Σ выделенных квот ящиков домена` превысит **Domain quota** (общую квоту домена). Это не про квоту одного ящика — ставить её в `0` (безлимит) не нужно. Предпросмотр (при заданном ключе) заранее считает нехватку и **останавливает** импорт с подсказкой, до какого значения поднять Domain quota. Поднять квоту домена: mailcow UI → домен → «Domain quota», либо один вызов API: ```bash curl -sk -X POST https://mail.dom.ru/api/v1/edit/domain \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"items":["a27.kz"],"attr":{"quota":"307200"}}' # 300 ГБ (МиБ) ``` После правки — в UI кнопка **«Повторить проверку»** (перепроверить без загрузки файла) или **«Повторить неудавшиеся»** в журнале (досоздать только упавшие ящики). ## Замечания по безопасности - Инструмент **stateless**: ключ и пароли нигде не пишутся на диск и не логируются. Пароли из CSV во время предпросмотра проходят через браузер (внутренний тул) — запускайте только в доверенной сети / за туннелем, не публикуйте наружу. - Публикация порта в примере — только на `127.0.0.1`. - Слабые пароли mailcow отклонит по политике; такие строки видны в предпросмотре как предупреждение и в журнале как `danger: password_complexity`.