- Add MariaDB (REL) IPL validation — master required, secondary non-fatal
- Add RelNodeConfig / RelInstanceConfig structs with master/secondary pattern
- Add rel_services section to beds.toml and test fixture
- Add detailed topology commentary to beds.toml covering standalone,
master/replica, Galera cluster, and multi-DB-per-node configurations
- Add developer wiki (wiki/) covering:
- Origin story — PHP Namaste history, production record, why Rust
- Architecture overview — full system diagram, all layers explained
- The four nodes — appServer, admin, segundo, tercero with real-world context
- IPL sequence — every step documented with rationale for ordering
- Configuration system — layering, env selection, adding new sections
- Queue topology — exchanges, routing keys, broker bindings, vhost isolation
- Template system — REC/REL, TLA convention, cache map, warehousing
- Event lineage — compound event IDs, parent/child tracking, msLogs schema
- Glossary
- Update README with wiki index and MariaDB status
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
171 lines
5.8 KiB
Markdown
171 lines
5.8 KiB
Markdown
# Configuration System
|
|
|
|
## Design Philosophy
|
|
|
|
BEDS configuration follows two rules:
|
|
|
|
1. **The base file is always safe to commit.** It contains structure and production-safe defaults. No real passwords, no real hostnames. It is the documentation of what the config looks like.
|
|
|
|
2. **The env file is never committed.** It contains the real values for a specific environment. It lives on the server and is gitignored. If the env file is lost, you rebuild it — you never recover it from git history.
|
|
|
|
This is the same pattern used in the PHP Namaste framework from day one. The `namaste.xml` base file was committed. The `env.xml` override was not. The habit was intentional: committing credentials to source control, even a private repo, is a category of mistake that ends careers.
|
|
|
|
## File Locations
|
|
|
|
```
|
|
config/
|
|
├── beds.toml ← committed — base config, safe defaults
|
|
├── env_dev.toml ← gitignored — development overrides
|
|
├── env_qa.toml ← gitignored — QA / staging overrides
|
|
└── env_prod.toml ← gitignored — production overrides
|
|
```
|
|
|
|
## Environment Selection
|
|
|
|
The `BEDS_ENV` environment variable selects which override file to load:
|
|
|
|
```bash
|
|
BEDS_ENV=dev cargo run # loads env_dev.toml (default if unset)
|
|
BEDS_ENV=qa ./rustybeds # loads env_qa.toml
|
|
BEDS_ENV=prod ./rustybeds # loads env_prod.toml
|
|
```
|
|
|
|
If `BEDS_ENV` is unset, `dev` is assumed. This means a freshly cloned repo with no env file runs in dev mode — which is the correct safe default.
|
|
|
|
## How Layering Works
|
|
|
|
The `config` crate performs a deep merge. Only keys present in the env file override the base. Everything else inherits from `beds.toml`.
|
|
|
|
Example — overriding only the broker password and env name:
|
|
|
|
```toml
|
|
# env_dev.toml — only what differs from beds.toml
|
|
[id]
|
|
env_name = "development"
|
|
|
|
[broker_services.app_server]
|
|
pass = "my-dev-rabbitmq-password"
|
|
```
|
|
|
|
Every other value — host, port, vhost, instance counts — is inherited from `beds.toml`. You do not need to repeat the full config in the env file.
|
|
|
|
## Configuration Sections
|
|
|
|
### Root Flags
|
|
|
|
```toml
|
|
debug = false # debug-level log output
|
|
syslog = true # route logs to journald
|
|
syslog_mirror_console = true # also echo to console when syslog=true
|
|
audit_on = false # global auditing master switch
|
|
journal_on = false # global journaling master switch
|
|
```
|
|
|
|
### `[id]` — Node Identity
|
|
|
|
```toml
|
|
[id]
|
|
env_name = "production" # development | qa | production
|
|
version = "1.0" # match your git release tag
|
|
wbid = "ms" # 2-char corporate identifier — prefixed to all collection names
|
|
```
|
|
|
|
The `wbid` is permanent. Once your MongoDB collections are created with a given `wbid`, changing it means renaming every collection and updating every template. Choose carefully.
|
|
|
|
### `[broker_services]` — RabbitMQ
|
|
|
|
```toml
|
|
[broker_services]
|
|
queue_tag = "prod_" # prefixed to every queue name — isolates envs
|
|
vhost = "prod" # RabbitMQ virtual host
|
|
timer_violation = 3000 # ms before a broker round-trip is a slow query warning
|
|
records_per_xfer = 5000 # max records per broker response — circuit breaker
|
|
keepalive = true # TCP keepalive — always true in production
|
|
heartbeat = 60 # AMQP heartbeat interval in seconds
|
|
use_ssl = false # TLS for broker connections
|
|
cert_path = "/etc/rabbitmq"
|
|
```
|
|
|
|
Per-node broker config:
|
|
|
|
```toml
|
|
[broker_services.app_server]
|
|
host = "localhost"
|
|
port = 5672
|
|
api_port = 15672 # management UI
|
|
user = "beds"
|
|
pass = "changeme"
|
|
rpi = 50 # records per interval — broker fetch throttle
|
|
|
|
[broker_services.app_server.instances]
|
|
r_broker = 2 # read brokers
|
|
w_broker = 2 # write brokers
|
|
m_broker = 0 # migration brokers (0 = disabled)
|
|
```
|
|
|
|
### `[rec_services]` — MongoDB
|
|
|
|
One entry per BEDS service role that needs MongoDB. Key is the service name (`app_server`, `admin`, `segundo`, `tercero`):
|
|
|
|
```toml
|
|
[rec_services.app_server]
|
|
host = "localhost"
|
|
port = 27017
|
|
user = "beds"
|
|
pass = "changeme"
|
|
database = "beds_app"
|
|
use_ssl = false
|
|
```
|
|
|
|
See `beds.toml` for topology examples (standalone, replica set, sharded cluster).
|
|
|
|
### `[rel_services]` — MariaDB
|
|
|
|
One entry per service role, with master (required) and secondary (optional):
|
|
|
|
```toml
|
|
[rel_services.app_server.master]
|
|
host = "localhost"
|
|
port = 3306
|
|
user = "beds"
|
|
pass = "changeme"
|
|
database = "beds_app"
|
|
|
|
[rel_services.app_server.secondary] # optional read replica
|
|
host = "replica.internal"
|
|
port = 3306
|
|
user = "beds_readonly"
|
|
pass = "changeme"
|
|
database = "beds_app"
|
|
```
|
|
|
|
Secondary failure is always non-fatal — BEDS logs a warning and operates master-only.
|
|
|
|
## The Test Fixture
|
|
|
|
All tests load from `tests/fixtures/beds_test.toml` instead of the live config. This file is committed — it contains only localhost addresses and placeholder credentials. Tests never read `config/beds.toml`.
|
|
|
|
The fixture is loaded via `config::load_from()`:
|
|
|
|
```rust
|
|
// in unit tests (inside source files)
|
|
fn test_cfg() -> BedsConfig {
|
|
load_from("tests/fixtures/beds_test.toml", "")
|
|
.expect("test fixture failed to load")
|
|
}
|
|
|
|
// in integration tests (under tests/)
|
|
let cfg = common::load_test_config();
|
|
```
|
|
|
|
If a test needs a different value, mutate the loaded struct — do not create a separate fixture file for every test variation. The fixture is the baseline; tests modify what they need.
|
|
|
|
## Adding a New Config Section
|
|
|
|
1. Add the TOML section to `beds.toml` with safe defaults and full commentary
|
|
2. Add the same section to `tests/fixtures/beds_test.toml` with test-safe values
|
|
3. Add the corresponding struct(s) to `src/config/structs.rs`
|
|
4. Export the new type from `src/config/mod.rs`
|
|
5. Add the field to `BedsConfig`
|
|
6. Update this wiki page
|