Skip to content

[core] Add explicit database name settings - #8097

Merged
Cookiezaurs merged 3 commits into
masterfrom
claude/database-names-config
Oct 8, 2026
Merged

Cookiezaurs merged 3 commits into
masterfrom
claude/database-names-config

Conversation

@Cookiezaurs

Copy link
Copy Markdown
Contributor

Problem

Since 25.03.39 (#7381) replaceDatabaseString always replaces the database name in a MongoDB connection string with countly, countly_drill, countly_out or countly_fs. Combined with the API always passing explicit names to dbConnection (so mongodb.db in object form config was only used by the dashboard and job handler), there was no working way to run Countly on databases with other names.

Installs upgrading from 25.03.38 or older whose data is in databases not named exactly countly* (custom name in the connection string path, or names the old string parsing produced) end up on new, empty databases after the upgrade, and the dashboard shows the setup screen.

Change

New databases config, one env var per database:

COUNTLY_CONFIG__DATABASES_COUNTLY
COUNTLY_CONFIG__DATABASES_COUNTLY_DRILL
COUNTLY_CONFIG__DATABASES_COUNTLY_OUT
COUNTLY_CONFIG__DATABASES_COUNTLY_FS

Names are used as is, never parsed from or inserted into the connection string, so any valid MongoDB database name works.

Order of precedence per database (highest first):

main drill / out / fs
1 COUNTLY_CONFIG__DATABASES_COUNTLY COUNTLY_CONFIG__DATABASES_COUNTLY_DRILL / _OUT / _FS
2 databases.countly in config.js databases.countly_drill / ...
3 db in object form mongodb config db in the database's own config file (plugins/drill/config.js, api/configs/config.db_out.js, config.db_fs.js)
4 countly countly_drill / countly_out / countly_fs

The resolved name is used by every connection: named connections (dbConnection("countly_drill") etc., also used by enterprise plugin scripts), the dashboard connection, the job handler (singleDefaultConnection), shared_connection, and getDbConnectionParams (exports, countly mongo).

Other changes:

  • configextender: override sections missing from config.js are now created with lower case keys. Before, COUNTLY_CONFIG__COOKIE_SAMESITE without a cookie section produced an unused COOKIE key; without this fix the new env vars would always land in an unused DATABASES key, as databases is commented out in the samples.
  • When a name is configured, MongoDB appname shows the internal label (countly_drill) instead of the database name.
  • Number-like env values (COUNTLY_CONFIG__DATABASES_COUNTLY=2024, parsed to numbers by configextender) are accepted.
  • Config samples: document databases and the order of precedence; URL example without /countly path (database names are not taken from the URL) and with an authSource hint, since the path db is the default auth database.

Behaviour changes

  • Nothing set: identical to current behaviour (verified for object form, connection strings with and without path, empty values).
  • Object form config with a custom mongodb.db (e.g. countly_base): previously the dashboard and job handler used countly_base while the API used countly. Now all connections use countly_base. Data the API wrote to countly in such installs stays there.

Not changed

  • A database path in a connection string (main or COUNTLY_CONFIG_PLUGINDRILL_MONGODB) is still ignored.
  • With a string COUNTLY_CONFIG__MONGODB, any COUNTLY_CONFIG__MONGODB_* env var still replaces the string (existing configextender behaviour), hence the DATABASES_ prefix.
  • countly backup (bin/commands/countly.sh) still dumps --db countly.

Testing

  • test/unit-tests/plugins.pluginManager.database-names.js (22 tests): env var mapping, precedence, every connection type, fallback when nothing is set, prototype keys, number-like names, drill config file level. Connections are checked without a server by stubbing MongoClient.connect.
  • 23 setup combinations (object/string config, path/no path, file/env, drill config file, empty and wrong env vars) run through the real pluginManager before and after the change; only the intended rows changed.
  • End to end against MongoDB 8.0 with auth: all connections opened and read existing databases configured only through env vars.

🤖 Generated with Claude Code

Since 25.03.39 the database name in a MongoDB connection string is
replaced with countly, countly_drill, countly_out or countly_fs, and
the API always ignored mongodb.db, so there was no working way to run
Countly on databases with other names.

Add a "databases" config with one env var per database:
COUNTLY_CONFIG__DATABASES_COUNTLY, ..._COUNTLY_DRILL, ..._COUNTLY_OUT,
..._COUNTLY_FS. Names are used as is and never parsed from or put into
the connection string. Order of precedence per database: env var,
databases.* in config.js, db in object form mongodb config (main
database) or in the database's own config file (drill/out/fs), default.

The name is applied to every connection: named connections, dashboard
connection, job handler, shared connection and command line/export
params, so API and dashboard always use the same main database.

configextender now creates missing override sections with lower case
keys, without it the new env vars landed in an unused DATABASES key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Cookiezaurs
Cookiezaurs force-pushed the claude/database-names-config branch from c13b11b to 0acf0de Compare October 7, 2026 13:56
@kanwarujjaval

Copy link
Copy Markdown
Member

Critical review

Reviewed commit 0acf0de301be0fdec95bfd4a8d79b42abc5b0aed. I recommend addressing the following before merging. These findings also apply to the companion PR.

1. [P1] Backup/restore ignores the configured databases

With databases.countly = "analytics", the application uses analytics, but countly backup still dumps countly; restore also targets the original names. If the old databases remain, a backup can succeed while omitting current production data. The PR description acknowledges this omission, but it remains a release blocker for supporting custom names.

Resolve each database through the shared configuration and verify a backup/restore round trip, including the other three database names.

Source: bin/commands/countly.sh.

2. [P1] User-data exports write into the wrong database

export_safely() still uses $merge into countly.exports, whereas download and cleanup use common.db.collection("exports"). With a renamed main database, exported records land elsewhere: downloads miss them, cleanup misses them, and credentials restricted to the configured database can cause the merge to fail.

Use the resolved main database as the merge destination and cover export, download, and cleanup with a custom-name test.

Source: api/parts/mgmt/app_users.js.

3. [P2] Explicit config objects lose their database selection

The new resolver reads global useConfig, even when the caller supplies a different config object. A before/after probe reproduced the regression: with global mongodb.db = "countly", passing {mongodb: {host: "localhost", port: 27017, db: "explicit_db"}} previously opened explicit_db; this PR opens countly. getDbConnectionParams() has the same problem. A supplied databases.countly override is also ignored.

Resolve names from the supplied object when that overload is used. The current config-object test passes the same global object, so it does not expose this regression.

Source: plugins/pluginManager.js.

4. [P2] CLI exports can authenticate against a different database from the application

For mongodb://review_user:dummy@localhost:27017/countly, no explicit authSource, and databases.countly = "analytics", the probe showed the driver selecting analytics while authenticating against countly. Generated CLI parameters instead contain --db analytics without --authenticationDatabase. MongoDB documents that mongoexport then authenticates against the export database, so credentials that work in the application can fail for exports.

Preserve the effective authentication database when replacing ob.db.

Sources: getDbConnectionParams, MongoDB authenticationDatabase documentation.

5. [P2] Some valid environment-variable names silently select the fallback database

COUNTLY_CONFIG__DATABASES_COUNTLY=false and ...=true become booleans through configextender, then the resolver rejects them. Both probes selected countly rather than the literal requested name. This contradicts the “used as is” contract and can redirect writes.

Preserve database-name environment values as strings and test boolean-like names through the actual environment override path.

Source: getConfiguredDatabaseName.

Validation and limits

  • The added suite passed in isolation: 22/22, with MongoClient.connect and build-info calls stubbed.
  • Additional local probes reproduced the config-object regression, environment-value fallback, and driver/CLI authentication-parameter mismatch.
  • Backup/restore and export destination findings were established by tracing the code; no live database writes or backup/restore operations were performed.
  • The reviewed head’s core CI job fails four of the new database-name tests: three report Unable to parse mongodb:undefined with URL, and one expects analytics but receives countly. The isolated pass does not establish compatibility with the full suite.

kanwarujjaval and others added 2 commits October 8, 2026 12:56
CI sets COUNTLY_CONFIG__MONGODB_HOST. Env overrides are applied again
for drill/out/fs connections, so with the connection string these
tests use, the env var replaced it with {host: "mongodb"} and the
connections failed. Run the connection tests without COUNTLY_CONFIG*
env vars and restore config in finally blocks so one failure does not
cascade into the following tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Cookiezaurs
Cookiezaurs merged commit 4bffdd4 into master Oct 8, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants