diff --git a/nodejs/routes/api_directory_admin.js b/nodejs/routes/api_directory_admin.js index 60049f7..55ae8b8 100644 --- a/nodejs/routes/api_directory_admin.js +++ b/nodejs/routes/api_directory_admin.js @@ -365,6 +365,25 @@ router.post('/resources', async (req, res, next) => { const ancestorSite = await Resource.findAncestorSiteSlug(r.id); if (r.kind === 'site') { await ensureSiteGroups(r.slug, req.user.dn, r.name, r.id); + // Two previously-unrelated "site slug" concepts: this Resource's own + // slug (the Directory catalog's site container -- what every group + // name and the resource tree actually use) vs. site_config.js's + // siteSlug (the multi-site replication identity shown on the + // Multi-Site modal, sourced only from a separately-set SITE_SLUG env + // var). They coincidentally share the name "site slug" but nothing + // ever kept them in sync -- a real deployment could show "E2E Site" + // in the Directory tree and "site-default" on the Multi-Site modal + // for the exact same node. Sync them here, the moment this node's own + // site Resource is created (bootstrap.js's first call), so there's + // one real identity instead of two that can drift apart. Only for a + // still-default master: never overwrite a real multi-site identity a + // join/promote has already established, and a spoke's replication + // identity is the master's to assign, not this node's own resource + // creation to decide. + const cfg = siteConfig.get(); + if (cfg.isMaster && cfg.siteSlug === 'site-default') { + siteConfig.save({ siteSlug: r.slug }); + } } else if (gKind && ancestorSite) { await ensureSiteGroups(ancestorSite, req.user.dn, r.name); // backfill site tier if missing await provisionResourceGroups(r, gKind, ancestorSite, req.user.dn); diff --git a/test/multisite_join_e2e.js b/test/multisite_join_e2e.js index c3a64b3..f6062f3 100644 --- a/test/multisite_join_e2e.js +++ b/test/multisite_join_e2e.js @@ -172,6 +172,12 @@ async function main() { }); if (siteRes.status !== 200) fail(`seeding pre-join site on master failed: ${siteRes.status} ${JSON.stringify(siteRes.body)}`); + step('Verifying the Directory site Resource\'s slug synced into the multi-site replication identity'); + const { body: masterCfgAfterSite } = await api(MASTER_URL, '/api/site/config', { token: masterToken }); + if (masterCfgAfterSite.config.siteSlug !== 'site_e2e') { + fail(`expected site_config's siteSlug to sync to the new site Resource's slug (site_e2e), got ${JSON.stringify(masterCfgAfterSite.config.siteSlug)}`); + } + const seedRes = await api(MASTER_URL, '/api/directory-admin/resources', { method: 'POST', token: masterToken,