... | ... | @@ -28,6 +28,7 @@ The `LibraryManager` manages a single hook. It is responsible for calling the ma |
|
|
The hooks are independent of the main Kea codebase. There is a single common module. It contains some constants, signatures of primary functions, and `CalloutHandle` class.
|
|
|
|
|
|
The hook locations are specified in the Kea DHCPv4 daemon configuration and in the Kea Control Agent configuration.
|
|
|
|
|
|
### Strengths and weaknesses
|
|
|
|
|
|
The main advantage of the Kea design is a separation between the main codebase and hooks. It allows writing hook code without knowledge about the Kea itself. Kea also separates the log messages that making any troubleshooting easier. Another beneficial feature is the easy and bidirectional data exchange between core and hook.
|
... | ... | @@ -215,7 +216,7 @@ The `SetupSettings` function accepts settings registry [`SettingsRegistry`]. Thi |
|
|
|
|
|
The `Load` function accepts the observer of settings [`SettingsObserver`]. It may be used to register on settings notifications. The given function will be called on change of the specific setting.
|
|
|
|
|
|
The hook creator must pick one or more callout interfaces and implement them in a single structure [`FooImpl`/`BarBazImpl`]. The structure must provide the `Close` function. It will be called during a graceful shutdown. The structure instance must be created by the top-level `Load` function. The creator also must implement the top-level `Version` function using the current version [`CurrentVersion'] constant provided by the hook module.
|
|
|
The hook creator must pick one or more callout interfaces and implement them in a single structure [`FooImpl`/`BarBazImpl`]. The structure must provide the `Close` function. It will be called during a graceful shutdown. The structure instance must be created by the top-level `Load` function. The creator also must implement the top-level `Version` function using the current version [`CurrentVersion`] constant provided by the hook module.
|
|
|
|
|
|
The core needs to provide the hook manager [`AgentHookManager`/`ServerHookManager`] as a facade for the hooks. It is responsible for calling the callout points. The hook manager implements all supported callout points and defers calls to the executor [`HookExecutor`]. Executor contains all callout implementations from hooks and provides methods for calling them. The callouts can be called sequentially "one-by-one," to first success, to first fail, etc. The calling order is defined by the hook manager depending on the characteristics of the callout point. The construction of the executor has two phases. First, the hook manager creates an instance and registers all support callouts' types (interfaces). Next, the hook loader [`HookLoader`] retrieves the callout point objects and registers them in the executor. Now, the executor contains the mapping between a callout type (interface) and its implementations.
|
|
|
|
... | ... | @@ -236,6 +237,7 @@ The proposed solutions: |
|
|
- Using the settings table in the database
|
|
|
- Using API
|
|
|
- Integration with existing configuration
|
|
|
|
|
|
### Using environment variables
|
|
|
|
|
|
In this scenario, the configuration parameters are passed using the environment variables. The hooks should use the unique prefix to avoid collisions. The valid parameters must be described by the hook documentation and validated during the hook loading. The hook can read the Stork core variables too.
|
... | ... | @@ -405,6 +407,7 @@ There should also be statistics collected per callout to monitor performance acr |
|
|
func (c *Callouts) Foo(x int) int {
|
|
|
return 42
|
|
|
}
|
|
|
```
|
|
|
|
|
|
5. Prepare top-level version function using the constants from the shared module
|
|
|
|
... | ... | |