The composer leaves out each resource whose `if-config` holds none of its conditions against the module's config values (with defaults), and drops the key from the rest, as the node-engine parses strictly. A resource that leaves is removed by the existing orphan removal. One table test replaces the two tests of setting_into_test.go. Builds: design 42 zfs-owns-zfs §2, A-21 (declaration side), A-22
81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
package resolution
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// withoutUnconfigured drops each resource whose `if-config` holds none of its conditions against the module's config
|
|
// values (design 42 zfs-owns-zfs §2, ADR 0679 §16 (b)), and the key itself from every resource that keeps it: the
|
|
// node-engine parses strictly and knows no such key. What leaves the declaration this way is removed as any resource
|
|
// that leaves it (ADR 0269 §2), by the node-engine's own orphan removal.
|
|
func withoutUnconfigured(resources []map[string]any, layers []mcat.Layer) []map[string]any {
|
|
out := make([]map[string]any, 0, len(resources))
|
|
for _, r := range resources {
|
|
conditions, has := r[mcat.IfConfigField]
|
|
if !has {
|
|
out = append(out, r)
|
|
continue
|
|
}
|
|
if !ifConfigHolds(conditions, layers) {
|
|
continue
|
|
}
|
|
kept := make(map[string]any, len(r))
|
|
for k, v := range r {
|
|
if k != mcat.IfConfigField {
|
|
kept[k] = v
|
|
}
|
|
}
|
|
out = append(out, kept)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// ifConfigHolds is whether any condition of a list holds: `<key>` when the config value is set and is neither false,
|
|
// off, none, empty nor an empty list; `<key>=<value>` when the value equals it, or a list value holds it as an entry.
|
|
func ifConfigHolds(conditions any, layers []mcat.Layer) bool {
|
|
list, _ := conditions.([]any)
|
|
for _, c := range list {
|
|
key, want, equals := strings.Cut(fmt.Sprint(c), "=")
|
|
value, set := settingValue(layers, key)
|
|
if !set {
|
|
continue
|
|
}
|
|
if !equals {
|
|
if !isOff(value) {
|
|
return true
|
|
}
|
|
continue
|
|
}
|
|
if entries, isList := value.([]any); isList {
|
|
for _, e := range entries {
|
|
if plainly(e) == want {
|
|
return true
|
|
}
|
|
}
|
|
} else if plainly(value) == want {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// isOff is a config value that says "not here": false, off, none, an empty text or an empty list.
|
|
func isOff(value any) bool {
|
|
switch v := value.(type) {
|
|
case bool:
|
|
return !v
|
|
case []any:
|
|
return len(v) == 0
|
|
case nil:
|
|
return true
|
|
}
|
|
switch plainly(value) {
|
|
case "", "false", "off", "none":
|
|
return true
|
|
}
|
|
return false
|
|
}
|