A contribution's unset required value is refused in its module's own form's words, as a file's is (issue 1126, seed-8: de-spiegel in the config form was told ${setting:…} and settings set)
This commit is contained in:
@@ -445,6 +445,19 @@ func TestAnUnsetRequiredValueIsRefusedInTheConfigFormsWords(t *testing.T) {
|
||||
t.Fatalf("not typed as a value nobody gave: %v", err)
|
||||
}
|
||||
|
||||
// A contribution's value too (issue 1126, seed-8: de-spiegel's route names were refused with ${setting:…}).
|
||||
withRoute := inConfigForm()
|
||||
withRoute["contributes"] = map[string]any{"route": map[string]any{"site": map[string]any{"name": "${config:sender}", "port": 80}}}
|
||||
routed, err := parseRaw(t, withRoute)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = Resolution{}.composed(routed, "route", routed.ContributesMany["route"]["site"], nil, "notifier contributing site to route")
|
||||
if !errors.As(err, &unset) || unset.Module != "notifier" || !strings.Contains(err.Error(),
|
||||
`notifier has a contribution site to route, in "name", that says ${config:sender}`) || strings.Contains(err.Error(), "${setting:") {
|
||||
t.Fatalf("a contribution's unset value is not said in the config form's words: %v", err)
|
||||
}
|
||||
|
||||
settingsForm := notifier()
|
||||
settingsForm.Resources[0]["content"] = "from = ${setting:domain}\n"
|
||||
err = unsetInConfigWords(settingInto(settingsForm.Resources[0], nil, "notifier"), settingsForm)
|
||||
|
||||
@@ -10,6 +10,7 @@ package catalogue
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -1832,7 +1833,14 @@ func (r Resolution) composed(m Manifest, to string, raw map[string]any, layers [
|
||||
// module's files is no part of it (novox/hq 04-ISSUES/173).
|
||||
values, err := overridden(raw, WithDefaults(m, layers), what)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", what, err)
|
||||
// A required value nothing sets is said in the words of the module's form, as a file's, a unit's and an owner's
|
||||
// are (issue 1126, seed-8: de-spiegel in the config form was refused with ${setting:…} and `settings set`).
|
||||
var unset *UnsetSettingError
|
||||
if errors.As(err, &unset) && unset.Module == "" {
|
||||
unset.Module = m.Module
|
||||
unset.where = fmt.Sprintf("a contribution%s, in %q,", strings.TrimPrefix(what, m.Module+" contributing"), unset.field)
|
||||
}
|
||||
return nil, unsetInConfigWords(fmt.Errorf("%s: %w", what, err), m)
|
||||
}
|
||||
reaches, err := Reaches(m, layers)
|
||||
if err != nil {
|
||||
|
||||
@@ -51,6 +51,8 @@ type UnsetSettingError struct {
|
||||
// where says what asks for it — "a file", "a service whose unit", "a directory <id> whose owner" — and
|
||||
// setToday which of the module's keys a layer sets, for saying it again in the config form's words.
|
||||
where, setToday string
|
||||
// field is the key of a contribution whose value asks for it, where the contribution's words are made by its caller.
|
||||
field string
|
||||
}
|
||||
|
||||
func (e *UnsetSettingError) Error() string { return e.said }
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
@@ -129,7 +130,12 @@ func ApplySettings(resource map[string]any, layers []Layer) (map[string]any, err
|
||||
// contract. Until issue 696, a layer replaced any served key it named; influxdb on ace was the one
|
||||
// layer relying on it, and serves `${setting:org}` and `${setting:bucket}` since.
|
||||
func Settle(base map[string]any, layers []Layer) (map[string]any, error) {
|
||||
return filledFromSettings(deepCopy(base), layers, "what is served")
|
||||
out, err := filledFromSettings(deepCopy(base), layers, "what is served")
|
||||
if err != nil {
|
||||
// Said as it was, untyped: what is served names no module here to type it by.
|
||||
return nil, errors.New(err.Error())
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ServedSettings is every key a module's served values and its zone's name fill from its settings (`${setting:<key>}`
|
||||
@@ -193,10 +199,12 @@ func filledFromSettings(merged map[string]any, layers []Layer, what string) (map
|
||||
for _, asked := range settingsUsed(s) {
|
||||
v, set := settingValue(layers, asked)
|
||||
if !set {
|
||||
return nil, fmt.Errorf(
|
||||
// Typed, its module and where left to the caller that knows them (Resolution.composed), so a module in
|
||||
// the config form is refused in its own words (unsetInConfigWords; issue 1126, seed-8).
|
||||
return nil, &UnsetSettingError{Setting: asked, field: key, setToday: orNoSettings(layers), said: fmt.Sprintf(
|
||||
"%s says ${setting:%s} for %q, and nothing sets %q — an operator's value is the "+
|
||||
"assignment's, never the definition's (novox/hq ADR 0112)%s",
|
||||
what, asked, key, asked, orNoSettings(layers))
|
||||
what, asked, key, asked, orNoSettings(layers))}
|
||||
}
|
||||
s = strings.ReplaceAll(s, "${setting:"+asked+"}", plainly(v))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user