Application hooks are written in Go using the same module-sdk as Deckhouse Kubernetes Platform (DKP) module hooks. The key difference is that Application hooks use ApplicationHookInput instead of HookInput, which adds Application-specific capabilities and enforces namespace isolation.
ApplicationHookInput
ApplicationHookInput exposes all the standard hook input methods plus:
Instance()— returns metadata about the Application instance, including its name and namespace. Use this to scope operations to the correct namespace.ObjectPatcher()— returns a namespace-scoped patcher. Create and patch operations are limited to the namespace of the Application instance. Hooks cannot create or modify cluster-wide resources.
Example: basic hook
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 — name of the Application resource
// instance.Namespace — namespace where the Application is installed
patcher := input.ObjectPatcher()
// patcher only operates within instance.Namespace
return nil
}
Settings validation hook
Applications can include a settings validation hook that runs before DKP applies changes. This is used when OpenAPI schema validation is insufficient — for example, to check business logic constraints across multiple settings fields.
The hook implements a Check function with the signature:
func Check(_ context.Context, input settingscheck.Input) settingscheck.Result
settingscheck.Input provides access to the Application.spec.settings values.
settingscheck.Result is one of:
settingscheck.Allow(warnings...)— settings are valid; optionally attach warning messages.settingscheck.Reject(reason)— settings are invalid; the Application resource will not be applied.
Example:
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...)
}
Namespace isolation guarantee
The ObjectPatcher returned by ApplicationHookInput enforces that:
- All
Create,Patch, andUpdatecalls target the Application’s own namespace. - Calls targeting other namespaces or cluster-wide resources are rejected at runtime.
This is an architectural enforcement, not just a convention. Hooks that need to read (not write) cluster-wide resources can still use d8 k or the Kubernetes API client directly, but writes outside the namespace are blocked.