Skip to content

Commit 8e0b557

Browse files
committed
fix(tunnel-client): resolve module → user domain via cluster/module_domains
NS8 stores consumer-to-domain bindings in the cluster/module_domains hash (written by cluster/bind-user-domains), not on the consumer's environment. fetchModuleDomain was only reading USER_DOMAIN from module/{id}/environment, which is empty for most consumers (webtop, mail, …), so the support session manifest reported no domain mapping and the UI hid the per-module domain credentials. Read the cluster mapping first and fall back to the per-module USER_DOMAIN for the providers that do expose it directly.
1 parent 432c772 commit 8e0b557

1 file changed

Lines changed: 22 additions & 5 deletions

File tree

‎services/support/cmd/tunnel-client/internal/users/configurator.go‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,35 @@ func discoverLocalModulesFromRedis() map[string]*moduleInfo {
288288
return result
289289
}
290290

291-
// fetchModuleDomain reads USER_DOMAIN from Redis for a module instance.
291+
// fetchModuleDomain returns the user domain bound to a module instance.
292+
// NS8 stores consumer-to-domain bindings in the cluster/module_domains hash
293+
// (set by the cluster/bind-user-domains action); some providers also expose
294+
// USER_DOMAIN directly in their own environment, so fall back to that when
295+
// the cluster mapping is missing. When a module is bound to multiple
296+
// domains we pick the first one — the support session only provisions one
297+
// domain user per module today.
292298
func fetchModuleDomain(moduleID string) string {
293-
cmd := exec.Command("redis-cli", "HGET", fmt.Sprintf("module/%s/environment", moduleID), "USER_DOMAIN") //nolint:gosec // redis-cli is trusted
299+
if v := redisOutput("HGET", "cluster/module_domains", moduleID); v != "" {
300+
if fields := strings.Fields(v); len(fields) > 0 {
301+
return fields[0]
302+
}
303+
}
304+
return redisOutput("HGET", fmt.Sprintf("module/%s/environment", moduleID), "USER_DOMAIN")
305+
}
306+
307+
// redisOutput runs `redis-cli <args...>` and returns the trimmed stdout,
308+
// or the empty string when the call fails or the value is nil.
309+
func redisOutput(args ...string) string {
310+
cmd := exec.Command("redis-cli", args...) //nolint:gosec // redis-cli is trusted
294311
output, err := cmd.Output()
295312
if err != nil {
296313
return ""
297314
}
298-
domain := string(bytes.TrimSpace(output))
299-
if domain == "" || domain == "(nil)" {
315+
v := string(bytes.TrimSpace(output))
316+
if v == "" || v == "(nil)" {
300317
return ""
301318
}
302-
return domain
319+
return v
303320
}
304321

305322
// discoverPlugins scans usersDir for valid executable plugin files.

0 commit comments

Comments
 (0)