@if (!state.initError) { @if (state.loaded) { @if (!state.wizard) {

The location where the edited subnet information is saved depends on the loaded Kea hooks. If libdhcp_cb_cmds is loaded, Stork updates the Config Backend database. If libdhcp_subnet_cmds is loaded, Stork updates subnet data in the Kea JSON configuration file.

If both libdhcp_subnet_cmds and libdhcp_cb_cmds hooks are loaded, Stork updates the subnet configuration in the Config Backend database, and leaves the JSON configuration unchanged. It conforms to the Kea behavior that prioritizes configuration specified in the Config Backend over the configuration sourced from the JSON file.

If some daemons have the libdhcp_cb_cmds hook loaded, they are connected to the same Config Backend database, and share the same server tag, then they cannot be configured individually. In this case, they are grouped into a single position in the server selection list. Such a group is labeled with the server tag and the number of daemons in the group. The configuration changes are applied to all daemons in the group.

@if ( state.group.get('selectedDaemonGroups').invalid && (state.group.get('selectedDaemonGroups').dirty || state.group.get('selectedDaemonGroups').touched) ) { At least one server must be selected. } @if (state.group.get('selectedDaemonGroups')?.disabled) {
Server selection is disabled
When a subnet belongs to a shared network, it is not allowed to change the assignments of the subnet to servers. These assignments can only be controlled in the shared network form, for the entire shared network. The subnet assignments can be directly controlled only when the subnet does not belong to a shared network.
}
} @if ( state.group.get('subnet').invalid && (state.group.get('subnet').dirty || state.group.get('subnet').touched) ) { @if (state.group.get('subnet').hasError('prefixInList')) { A subnet with this prefix already exists. } @if (state.group.get('subnet').hasError('ipPrefix')) { {{ state.group.get('subnet').errors.ipPrefix }} } @if ( !state.group.get('subnet').hasError('prefixInList') && !state.group.get('subnet').hasError('ipPrefix') ) { A valid subnet prefix is required. } } @if (!state.wizard) { } @if (!state.wizard) {
Unlock setting subnet names for individual servers.
@for ( userContext of state.group.get('userContexts.names')?.controls; track userContext; let i = $index ) { @if (i === 0 || state.group.get('userContexts.unlocked')?.value) {
@if (state.group.get('userContexts.unlocked')?.value) {
@if (state.group.get('userContexts.names')?.length > 1) { {{ state.servers[i] }} }
}
} }
@for (pool of state.group.get('pools')?.controls; track pool; let i = $index) {
{{ getPoolHeader(i)[0] }} @if ( pool.invalid && (pool.dirty || pool.touched || pool.get('range')?.hasError('ipRangeOverlaps')) ) { }
}
@if (subnet.includes(':')) { @for (pool of state.group.get('prefixPools')?.controls; track pool; let i = $index) {
{{ getPrefixPoolHeader(i)[0] }} @if ( pool.invalid && (pool.dirty || pool.touched || pool.get('prefixes')?.hasError('ipv6PrefixOverlaps')) ) { }
}
}
Unlock setting DHCP options for individual servers.
@for (optionSet of state.group.get('options.data')?.controls; track optionSet; let i = $index) { @if (i === 0 || state.group.get('options.unlocked')?.value) {
@if (state.group.get('options.unlocked')?.value) {
@if (state.group.get('options.data')?.length > 1) { {{ state.servers[i] }} }
}
} }
}
@if (subnetId) { } @if (!state.wizard) { } @else { }
} @else { } } @else {
In order to apply configuration changes, the server should begin a transaction between the user and the server. The server should also return the current data required, in the form where the subnet information is specified. Unfortunately, starting the new transaction failed with the following error:
{{ state.initError }}
Retrying can help in some cases.
}