contributes: a module's grant carries no value where it contributed several times
ContributionsFrom settled to whichever of a module's several contributions to one requirement sorted first, arbitrarily — the grant minted for it then carried that contribution's label and port under a credential the OTHER contribution's consumer never sees, and collided with that same contribution's own entry from contributions() besides. Confirmed live: minio's two route contributions (files-api, files) produced three entries in route-adapter's received file — files-api twice, once credentialed and once not, files not credentialed at all. Every single-contribution module (gitea, keycloak, umami) already mints an unused credential for `route` too — route never needs one, by its own documentation — but with exactly one contribution to match there was nothing to collide with, so it never surfaced. Where a module contributes more than once, there is no single value to settle on. The module still asks, still gets its one credential — a pair credential is not a place for a label or a port anyway — and each named contribution reaches the provider on its own, unchanged. No cleanup needed for the secret already minted live for minio+route: the sealed blob is a random pair credential unrelated to Values, which is recomputed fresh on every plan/push regardless.
This commit is contained in:
@@ -1120,17 +1120,34 @@ func boundFile(n Needed, path, as string) (map[string]any, error) {
|
||||
// arrangement refused is the ordinary one. A node running eight services against one database is
|
||||
// not an edge case; it is what a machine looks like. Now each consumer has its own credential and
|
||||
// there is nothing left to refuse.
|
||||
//
|
||||
// **One credential, even where a module contributes several times.** A module may answer one
|
||||
// requirement more than once (ADR 0094's sibling for `contributes`) — an object store's data API
|
||||
// and its console are two different names, not one. There is still only one `Needed` for it, one
|
||||
// credential minted, one grant to settle: a pair credential is not a place to put a label or a
|
||||
// port. So where several of this module's contributions reach the same requirement, none of them
|
||||
// is "the" value — settling to the first, arbitrarily, would hand the grant one contribution's
|
||||
// values under a credential the OTHER contribution's consumer never sees, and would collide with
|
||||
// that contribution's own entry from contributions() besides. Empty values, still granted: the
|
||||
// module asked, gets its credential, and each named contribution reaches the provider on its own.
|
||||
func (r Resolution) ContributionsFrom(requirement, module string, settings SettingsBy) (
|
||||
map[string]any, bool, error) {
|
||||
all, err := r.contributions(settings, nil, nil)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
var mine []map[string]any
|
||||
for _, g := range all[requirement] {
|
||||
if g.From == module {
|
||||
return g.Values, true, nil
|
||||
mine = append(mine, g.Values)
|
||||
}
|
||||
}
|
||||
if len(mine) == 1 {
|
||||
return mine[0], true, nil
|
||||
}
|
||||
if len(mine) > 1 {
|
||||
return map[string]any{}, true, nil
|
||||
}
|
||||
// It contributes no payload — but a require-only consumer of a parameterless provision (one whose
|
||||
// `serves` names no consumer-supplied key: `redis-cache`, `amqp`) still ASKS for it and must be
|
||||
// granted a credential. Keying "asks" on contributions alone marked those grants withdrawn
|
||||
|
||||
Reference in New Issue
Block a user