Основной метод, который вызывается, это ServeDNS
. У него три параметра:
context.Context
;dns.ResponseWriter
, который, по сути, представляет соединение клиента;*dns.Msg
, запрос от клиента.ServeDNS
возвращает два значения: код ответа и ошибку. Если ошибка не равна nil
, CoreDNS
вернет код SERVFAIL
клиенту. Код ответа сообщает CoreDNS, был ли ответ записан цепочкой
плагинов или нет. В последнем случае CoreDNS сам позаботится об этом.
CoreDNS обрабатывает:
как специальные коды и считает, что ничего не было записано клиенту. В остальных случаях предполагается, что что-то было записано клиенту (плагином).
Пример плагина example демонстрирует базовую реализацию, которую можно использовать в качестве отправной точки для вашего плагина. Этот плагин имеет тесты и подробные комментарии в коде.
См. несколько блог-постов о том, как создавать и добавлять плагины в CoreDNS:
plugin/pkg/log
.Этот пакет реализует уровни логирования. Стандартный способ вывода: log.Info
для сообщений
уровня info
. Доступны уровни log.Info
, log.Warning
, log.Error
, log.Debug
. Каждый из
этих уровней также имеет вариацию f
. Имя плагина должно быть включено, используя пакет логирования
следующим образом:~~~ go
import clog "github.com/coredns/coredns/plugin/pkg/log"
var log = clog.NewWithPlugin("whoami")
log.Info("сообщение") // выводит: [INFO] plugin/whoami: сообщение
В общем, логирование должно оставаться на более высоких уровнях, возвращая ошибку. Однако, если
есть причина обрабатывать ошибку и уведомлять пользователя, то логирование в самом плагине может
быть допустимым. Функции `Debug*` выводят что-то только тогда, когда плагин `debug` загружен в
сервер.
## Метрики
При экспорте метрик пространство имен должно быть `plugin.Namespace` (="coredns"), а подпространство
должно быть именем плагина. В README.md для плагина должна быть секция *Metrics*, детализирующая
метрики.
## Готовность
Если плагин поддерживает сигнал о готовности, он должен иметь раздел *Готовность*, описывающий, как это работает, и реализовать интерфейс `ready.Readiness`.
## Открытие сокетов
См. плагин/pkg/reuseport для функций `Listen` и `ListenPacket`. Использование этих функций улучшает обработку событий перезагрузки плагином.
## Контекст
Каждый запрос получает контекст `context.Context`, который предварительно заполнен двумя значениями:
* `Key`: содержит указатель на текущий сервер, что может быть полезно для логирования или метрик. Это значение используется в плагине *metrics* для привязки запроса к конкретному (внутреннему) серверу.
* `LoopKey`: содержит целое число для обнаружения циклов в текущем контексте. Плагин *file* использует это для обнаружения циклов при разрешении CNAME.
## Документация
Каждый плагин должен иметь файл README.md, объясняющий, что делает плагин и как он настраивается. Файл должен иметь следующую структуру:
* Заголовок: используйте имя плагина
* Подраздел с заголовком: "Name"
с *PLUGIN* - однострочной описательной строкой.
* Подраздел с заголовком: "Описание" содержит более подробное описание.
* Подраздел с заголовком: "Синтаксис", синтаксис и поддерживаемые директивы.
* Подраздел с заголовком: "Примеры"
Более разделов, конечно, возможны.
### Стиль
Мы используем стиль страницы Unix-руководства:
* Имя плагина в тексте должно быть курсивом: *plugin*.
* Все заглавные буквы: аргументы, предоставленные пользователем, в тексте ссылки на это используются жирным шрифтом: `**`: **EXAMPLE**.
* Необязательный текст: в блоках цитирования: `[необязательный]`.
* Используйте три точки для указания, что допускается несколько опций: `arg...`.
* Элементы используются в виде литерала: `литерал`.
### Пример доменных имен
Пожалуйста, убедитесь, что вы используете `example.org` или `example.net` в любых примерах и тестах, которые вы предоставляете. Эти доменные имена созданы для этой цели.
## Передача управленияВ идеальном мире следующее должно быть истинным для плагина: "Либо вы отвечаете за зону, либо нет". Если ответ "нет", плагин должен вызвать следующий плагин в цепочке. Если "да", он должен обрабатывать *все* имена, которые находятся в этой зоне и имена ниже — то есть он должен обрабатывать весь домен и все поддомены.~~~ txt
. {
file example.org db.example
}
В этом примере плагин file обрабатывает все имена ниже (и включая) example.org
. Если запрос приходит, который не является поддоменом (или равен) example.org
, вызывается следующий плагин. Теперь мир не идеален, и могут быть причины для "перехода" к следующему плагину,
что означает, что плагин отвечает только за подмножество имен в зоне.
Инструкция fallthrough
должна по желанию принимать список зон. Только запросы на записи
в одной из этих зон должны быть разрешены для перехода. См. plugin/pkg/fallthrough
для реализации.
Используя пользовательский ResponseWriter
, плагин может изменять ответ, когда другой плагин ниже по цепочке записывает ответ клиенту.
Если плагин изменяет ответ, он должен сделать копию всего ответа перед тем, как это сделать. Ответ является указателем на dns.Msg
, и таким образом вы будете манипулировать исходным ответом, который мог быть сгенерирован из хранилища данных. Например, плагин file создаёт ответ, который затем перезаписывается плагином rewrite; не копируя данные, означает, что также изменяется данные хранилища file. Ответ можно скопировать, используя метод Copy()
.
Некоторые общие рекомендации:* время логирования должно быть выполнено в секундах (вызовите метод Seconds()
для любого интервала времени).
parse
.plugin.Error()
для обёртки ошибок, возвращаемых функцией setup
.## Квалификация для основного репозиторияПлагины для CoreDNS могут существовать вне дерева, plugin.cfg
по умолчанию указывает на репозиторий CoreDNS, но другие репозитории работают также хорошо. Так когда мы рассматриваем включение нового плагина в основной репозиторий?
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )