- Stable udev device symlinks (/dev/jmri/nce, /dev/jmri/loconet, /dev/jmri/lcc) - jmri-monitor: polls Leviton Decora Smart switch to start/stop JMRI automatically - Quiet hours 1-10 AM (no polling) - 30s off-delay before shutdown - LCRR config cloned from Gitea (ssh://gitea.mk-labs.cloud:2221/rblundon/LCRR.git) - ~/.jmri symlinked to LCRR repo for GitOps config management - jmri-gui: X11 remote GUI access (PanelPro/DecoderPro) via ssh -X as jmri user - Stops daemon, launches GUI, restarts daemon on exit if layout still on - jmri user gets login shell + SSH key for GUI sessions - Full JRE installed (openjdk-21-jre) for AWT/X11 support
161 lines
5.2 KiB
Markdown
161 lines
5.2 KiB
Markdown
# CouchDB erlangCookie Fix - Implementation Guide
|
|
|
|
## Summary
|
|
|
|
**Problem**: CouchDB deployment fails because `erlangCookie` is missing from the ExternalSecret configuration.
|
|
|
|
**Decision**: Externalize `erlangCookie` to 1Password (pragmatic approach)
|
|
|
|
**Rationale**:
|
|
- ExternalSecret architecture requires ownership of the entire secret
|
|
- Mixing externalized and chart-generated fields in the same secret is not supported
|
|
- Single-node deployment makes erlangCookie rotation unnecessary
|
|
- This is an acceptable deviation from the pure Harbor pattern given the architectural constraints
|
|
|
|
## Implementation Steps
|
|
|
|
### 1. Generate erlangCookie Value
|
|
|
|
```bash
|
|
openssl rand -hex 20
|
|
```
|
|
|
|
Example output: `f4e3c2b1a9d8e7f6c5b4a3d2e1f0a9b8c7d6e5f4`
|
|
|
|
### 2. Add to 1Password
|
|
|
|
- **Vault**: `mk-labs`
|
|
- **Item**: `couchdb`
|
|
- **Field Name**: `erlang-cookie`
|
|
- **Field Type**: password (concealed)
|
|
- **Value**: `<paste generated value from step 1>`
|
|
|
|
### 3. Update ExternalSecret Configuration
|
|
|
|
File: `cluster/applications/couchdb/externalsecret.yaml`
|
|
|
|
```yaml
|
|
apiVersion: external-secrets.io/v1beta1
|
|
kind: ExternalSecret
|
|
metadata:
|
|
name: couchdb-credentials
|
|
namespace: couchdb
|
|
labels:
|
|
app.kubernetes.io/name: couchdb
|
|
app.kubernetes.io/part-of: mk-labs
|
|
spec:
|
|
refreshInterval: 1h
|
|
secretStoreRef:
|
|
kind: ClusterSecretStore
|
|
name: onepassword-connect
|
|
target:
|
|
name: couchdb-admin
|
|
creationPolicy: Owner
|
|
template:
|
|
engineVersion: v2
|
|
data:
|
|
adminUsername: "admin"
|
|
adminPassword: "{{ .adminPassword }}"
|
|
cookieAuthSecret: "{{ .cookieAuthSecret }}"
|
|
erlangCookie: "{{ .erlangCookie }}" # ← ADD THIS LINE
|
|
data:
|
|
- secretKey: adminPassword
|
|
remoteRef:
|
|
key: couchdb
|
|
property: admin-password
|
|
- secretKey: cookieAuthSecret
|
|
remoteRef:
|
|
key: couchdb
|
|
property: cookie-auth-secret
|
|
- secretKey: erlangCookie # ← ADD THIS BLOCK
|
|
remoteRef:
|
|
key: couchdb
|
|
property: erlang-cookie
|
|
```
|
|
|
|
### 4. Update values.yaml Documentation (Optional)
|
|
|
|
File: `cluster/applications/couchdb/values.yaml`
|
|
|
|
Update the comment block at line 9-10:
|
|
|
|
```yaml
|
|
# Admin credentials managed via ExternalSecret
|
|
# See externalsecret.yaml for 1Password integration
|
|
#
|
|
# NOTE: erlangCookie is externalized to 1Password for architectural
|
|
# simplicity (ExternalSecret ownership model). In a pure Harbor pattern,
|
|
# this would be chart-generated, but single-node deployment makes this
|
|
# acceptable. The erlangCookie is treated as an immutable infrastructure
|
|
# secret (generate once, never rotate).
|
|
createAdminSecret: false
|
|
extraSecretName: "couchdb-admin"
|
|
```
|
|
|
|
### 5. Commit and Push
|
|
|
|
```bash
|
|
cd ~/git/homelab
|
|
git add cluster/applications/couchdb/externalsecret.yaml
|
|
git add cluster/applications/couchdb/values.yaml # if modified
|
|
git commit -m "fix(couchdb): add erlangCookie to ExternalSecret from 1Password"
|
|
git push origin main
|
|
```
|
|
|
|
### 6. Verify Deployment
|
|
|
|
```bash
|
|
# Watch ExternalSecret sync
|
|
kubectl get externalsecret -n couchdb couchdb-credentials -w
|
|
# Wait for: SecretSynced
|
|
|
|
# Verify secret created with all four keys
|
|
kubectl get secret -n couchdb couchdb-admin -o yaml
|
|
# Should contain: adminUsername, adminPassword, cookieAuthSecret, erlangCookie
|
|
|
|
# Watch ArgoCD sync
|
|
kubectl get application -n argocd couchdb -w
|
|
# Wait for: Healthy/Synced
|
|
|
|
# Watch pod startup
|
|
kubectl get pods -n couchdb -w
|
|
# Wait for: Running
|
|
|
|
# Test CouchDB access
|
|
kubectl port-forward -n couchdb svc/couchdb-svc-couchdb 5984:5984 &
|
|
curl http://localhost:5984/
|
|
# Expected: {"couchdb":"Welcome","version":"3.5.1"}
|
|
```
|
|
|
|
## Why Not Follow Harbor Pattern Exactly?
|
|
|
|
**Harbor Pattern**: Only user-facing credentials externalized, internal secrets chart-generated.
|
|
|
|
**CouchDB Constraint**: ExternalSecret uses `creationPolicy: Owner`, which takes full ownership of the target secret. This prevents the Helm chart from adding auto-generated fields to the same secret.
|
|
|
|
**Options Considered**:
|
|
1. ✅ **Externalize erlangCookie** (SELECTED) - Works with current architecture
|
|
2. ❌ Chart auto-generation - Conflicts with ExternalSecret ownership
|
|
3. ❌ Dual-secret approach - Requires Helm chart customization
|
|
4. ❌ Disable ExternalSecret - Loses 1Password integration for admin password
|
|
|
|
**Decision**: Pragmatic approach wins. erlangCookie is treated as an infrastructure secret (generate once, never rotate), which is acceptable for a single-node deployment.
|
|
|
|
## Secret Classification
|
|
|
|
| Secret | Type | 1Password? | Rationale |
|
|
|------------------|---------------|------------|------------------------------------|
|
|
| adminUsername | User-facing | No* | Static value, hardcoded in template |
|
|
| adminPassword | User-facing | ✅ YES | User login credential |
|
|
| cookieAuthSecret | Gray area | ✅ YES | Session security, periodic rotation |
|
|
| erlangCookie | Internal | ✅ YES** | Architectural constraint |
|
|
|
|
\* Hardcoded in ExternalSecret template (not fetched from 1Password)
|
|
\*\* Pragmatic deviation from Harbor pattern due to ExternalSecret architecture
|
|
|
|
## References
|
|
|
|
- Full analysis: `/home/hermes/couchdb-erlangcookie-analysis.txt`
|
|
- Harbor pattern: `/home/hermes/harbor-simplification-complete.txt`
|
|
- CouchDB Helm chart: `apache/couchdb` v4.6.3
|