Хуки Application пишутся на Go с использованием того же module-sdk, что и хуки модулей Deckhouse Kubernetes Platform (DKP). Ключевое отличие в том, что хуки Application используют ApplicationHookInput вместо HookInput — это добавляет возможности, специфичные для Application, и обеспечивает изоляцию неймспейса.
ApplicationHookInput
ApplicationHookInput предоставляет все стандартные методы hook input, а также:
Instance()— возвращает метаданные об экземпляре Application, включая его имя и неймспейс. Используйте для ограничения операций нужным неймспейсом.ObjectPatcher()— возвращает ObjectPatcher, ограниченный неймспейсом. Операции создания и патча ограничены неймспейсом экземпляра Application. Хуки не могут создавать или изменять cluster-wide ресурсы.
Пример: базовый хук
package main
import (
"context"
"github.com/deckhouse/module-sdk/pkg"
applicationhook "github.com/deckhouse/module-sdk/pkg/app-hook"
)
func main() {
applicationhook.Run(onSync)
}
func onSync(ctx context.Context, input applicationhook.ApplicationHookInput) error {
instance := input.Instance()
// instance.Name — имя ресурса Application
// instance.Namespace — неймспейс, в котором установлен Application
patcher := input.ObjectPatcher()
// patcher работает только внутри instance.Namespace
return nil
}
Хук валидации настроек
Application может содержать хук валидации настроек, выполняющийся до того, как DKP применяет изменения. Используется когда валидации через OpenAPI-схему недостаточно — например, для проверки бизнес-логики между несколькими полями настроек.
Хук реализует функцию Check с сигнатурой:
func Check(_ context.Context, input settingscheck.Input) settingscheck.Result
settingscheck.Input предоставляет доступ к значениям Application.spec.settings.
settingscheck.Result — одно из:
settingscheck.Allow(warnings...)— настройки валидны; опционально можно добавить предупреждения.settingscheck.Reject(reason)— настройки невалидны; ресурс Application не будет применён.
Пример:
func Check(_ context.Context, input settingscheck.Input) settingscheck.Result {
replicas := input.Settings.Get("replicas").Int()
if replicas == 0 {
return settingscheck.Reject("replicas cannot be 0")
}
var warnings []string
if replicas == 2 {
warnings = append(warnings, "an even number of replicas may cause split-brain in some configurations")
}
if replicas > 3 {
return settingscheck.Reject("replicas cannot be greater than 3")
}
return settingscheck.Allow(warnings...)
}
Гарантия изоляции неймспейса
ObjectPatcher, возвращаемый ApplicationHookInput, обеспечивает, что:
- Все операции
Create,PatchиUpdateнаправлены в неймспейс самого Application. - Обращения к другим неймспейсам или cluster-wide ресурсам отклоняются в рантайме.
Это архитектурное ограничение, а не просто соглашение. Хуки, которым нужно читать (но не писать) cluster-wide ресурсы, могут по-прежнему использовать d8 k или Kubernetes API-клиент напрямую, но запись за пределами неймспейса заблокирована.