Если вы читали мою прошлую статью про FluxCast (тот самый лучший Miracast-клиент =] ), то там мелькал некрасивый сабдомен моего лендинга. Но недавно все изменилось. Я зарегистрировал нормальный домен fluxcast.dev и так бы он и лежал в интернете, а потом я понял, что домену этому реально нужен только один апекс, остальное простаивает без дела.
Тогда я вспомнил проект is-a.dev на который натыкался и раньше. Механика простая: форкаешь репозиторий, кидаешь JSON-файл со своими DNS-записями, открываешь PR, тебе выдают бесплатный поддомен. Идея понравилась настолько, что решил сделать так же у себя, только код написать самому и на Python, а не на JS и Go с DNSControl, как у них.
Звучало как вечер работы. Оказалось не совсем.
Валидация
Первым делом написал проверки для входящих файлов, примерно те же, что у is-a.dev, только на pytest. Приватные IP отсекаются через ipaddress, а дублирующиеся ключи в JSON пришлось ловить отдельно руками. Оказывается, json.loads в Python молча схлопывает повторяющиеся ключи объекта и оставляет только последний. Если бы я это не проверил, кто-то мог бы подсунуть в PR второй набор DNS-записей, спрятанный под задублированным ключом, и я бы этого не заметил при ревью.
Продакшен есть продакшен
На fluxcast.dev уже жил боевой лендинг, и всю миграцию на Cloudflare я боялся, что скрипт случайно снесёт его записи. Решил просто: каждая запись, которую создаёт мой синк, помечается комментарием managed-by:fluxcast-domains, и при каждом запуске скрипт видит в Cloudflare только записи с этой меткой. Остальное для него не существует.
Потом перепутал Zone ID с Account ID в дашборде Cloudflare… ну с кем не бывает, они рядом и выглядят одинаково. Синк справедливо отказался работать с ошибкой “zone not found”, минут десять искал, где накосячил. Разобрался, запустил публикацию по-настоящему — прилетело TypeError: Missing required argument: 'ttl'. В новой версии Cloudflare SDK для Python этот параметр стал обязательным, хотя в документации я этого не заметил. Починил одной строчкой.
Гит не прощает
Пока разбирался, как устроен is-a.dev, склонировал их репо в соседнюю папку для референса и забыл про это. Папка вместе со своим .git внутри попала в коммит не как файлы, а как ссылка на чужой коммит. На GitHub это выглядело как битая директория. Обычный git rm тут не годится, запись уже сидит в истории, пришлось пересобирать всё дерево в один чистый коммит и форсить его поверх старой ветки.
И напоследок сюрприз от собственного домена
Когда всё было готово, запустил публикацию вручную и минут пять смотрел на статус “в очереди”, хотя должно было выполниться за секунды. Совпало два фактора: у GitHub в тот день был лёгкий сбой Actions, а мой репозиторий был приватным, а приватным раннеры выдаются в последнюю очередь. Сделал репозиторий публичным, очередь исчезла.
А ещё, когда поднял публичный API реестра на отдельном поддомене через GitHub Pages, зашёл проверить в браузере и получил во весь экран предупреждение про небезопасное соединение с несовпадающим сертификатом. Секунд десять реально думал, что домен перехватили. Разгадка банальная: сертификат для нового поддомена ещё не успел выпуститься, а зона .dev в HSTS-preload листе, поэтому браузер не даёт исключение и жёстко ругается. Через пару минут всё встало на место само.
Что в итоге
Получился рабочий реестр: форкаешь репозиторий, добавляешь один JSON
// пример{ "owner": { "username": "your-github-username", "email": "you@example.com" }, "records": { "CNAME": "your-github-username.github.io" }}
с DNS-записями, открываешь PR. Проверки гоняют файл через валидацию и следят, что ты правишь только свой файл. Проходит — мёржу, через пару минут поддомен резолвится.
Отдельно решил не повторять чужую бюрократию: сам не раз упирался в сервисы, где твой проект придирчиво проверяют “достаточно ли он про разработку” и заворачивают, если сайт кажется недостаточно готовым. У меня правило одно: сайт должен быть законным, а тема любая, хоть личная страница, хоть коммерция. Режу только реальный вред.
Реестр совсем свежий. Если хотите поддомен, гайд лежит на sub.fluxcast.dev. Найдёте баг в проверках — открывайте issue, я читаю все каждый день 24/7 =]
-
Страница проекта: https://sub.fluxcast.dev
-
Исходный код: https://github.com/IlyaP358/fluxcast-domains
-
Публичный API: https://raw.fluxcast.dev/v2.json
-
Основной проект: https://github.com/IlyaP358/fluxcast
ссылка на оригинал статьи https://habr.com/ru/articles/1062462/