113 lines
5.0 KiB
Markdown
113 lines
5.0 KiB
Markdown
# Phase 2: Migrate Workspace to `harmony_config`
|
|
|
|
## Goal
|
|
|
|
Replace every direct `harmony_secret::SecretManager` call with `harmony_config` equivalents. After this phase, modules and examples depend only on `harmony_config`. `harmony_secret` becomes an internal implementation detail behind `StoreSource`.
|
|
|
|
## Current State
|
|
|
|
19 call sites use `SecretManager::get_or_prompt::<T>()` across:
|
|
|
|
| Location | Secret Types | Call Sites |
|
|
|----------|-------------|------------|
|
|
| `harmony/src/modules/brocade/brocade_snmp.rs` | `BrocadeSnmpAuth`, `BrocadeSwitchAuth` | 2 |
|
|
| `harmony/src/modules/nats/score_nats_k8s.rs` | `NatsAdmin` | 1 |
|
|
| `harmony/src/modules/okd/bootstrap_02_bootstrap.rs` | `RedhatSecret`, `SshKeyPair` | 2 |
|
|
| `harmony/src/modules/application/features/monitoring.rs` | `NtfyAuth` | 1 |
|
|
| `brocade/examples/main.rs` | `BrocadeSwitchAuth` | 1 |
|
|
| `examples/okd_installation/src/main.rs` + `topology.rs` | `SshKeyPair`, `BrocadeSwitchAuth`, `OPNSenseFirewallConfig` | 3 |
|
|
| `examples/okd_pxe/src/main.rs` + `topology.rs` | `SshKeyPair`, `BrocadeSwitchAuth`, `OPNSenseFirewallCredentials` | 3 |
|
|
| `examples/opnsense/src/main.rs` | `OPNSenseFirewallCredentials` | 1 |
|
|
| `examples/sttest/src/main.rs` + `topology.rs` | `SshKeyPair`, `OPNSenseFirewallConfig` | 2 |
|
|
| `examples/opnsense_node_exporter/` | (has dep but unclear usage) | ~1 |
|
|
| `examples/okd_cluster_alerts/` | (has dep but unclear usage) | ~1 |
|
|
| `examples/brocade_snmp_server/` | (has dep but unclear usage) | ~1 |
|
|
|
|
## Tasks
|
|
|
|
### 2.1 Bootstrap `harmony_config` in CLI and TUI entry points
|
|
|
|
Add `harmony_config::init()` as the first thing that happens in `harmony_cli::run()` and `harmony_tui::run()`.
|
|
|
|
```rust
|
|
// harmony_cli/src/lib.rs — inside run()
|
|
pub async fn run<T: Topology + Send + Sync + 'static>(
|
|
inventory: Inventory,
|
|
topology: T,
|
|
scores: Vec<Box<dyn Score<T>>>,
|
|
args_struct: Option<Args>,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
// Initialize config system with default source chain
|
|
let sqlite = Arc::new(SqliteSource::default().await?);
|
|
let env = Arc::new(EnvSource);
|
|
harmony_config::init(vec![env, sqlite]).await;
|
|
|
|
// ... rest of run()
|
|
}
|
|
```
|
|
|
|
This replaces the implicit `SecretManager` lazy initialization that currently happens on first `get_or_prompt` call.
|
|
|
|
### 2.2 Migrate each secret type from `Secret` to `Config`
|
|
|
|
For each secret struct, change:
|
|
|
|
```rust
|
|
// Before
|
|
use harmony_secret::Secret;
|
|
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, InteractiveParse, Secret)]
|
|
struct BrocadeSwitchAuth { ... }
|
|
|
|
// After
|
|
use harmony_config::Config;
|
|
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, InteractiveParse, Config)]
|
|
struct BrocadeSwitchAuth { ... }
|
|
```
|
|
|
|
At each call site, change:
|
|
|
|
```rust
|
|
// Before
|
|
let config = SecretManager::get_or_prompt::<BrocadeSwitchAuth>().await.unwrap();
|
|
|
|
// After
|
|
let config = harmony_config::get_or_prompt::<BrocadeSwitchAuth>().await.unwrap();
|
|
```
|
|
|
|
### 2.3 Migration order (low risk to high risk)
|
|
|
|
1. **`brocade/examples/main.rs`** — 1 call site, isolated example, easy to test manually
|
|
2. **`examples/opnsense/src/main.rs`** — 1 call site, isolated
|
|
3. **`harmony/src/modules/brocade/brocade_snmp.rs`** — 2 call sites, core module but straightforward
|
|
4. **`harmony/src/modules/nats/score_nats_k8s.rs`** — 1 call site
|
|
5. **`harmony/src/modules/application/features/monitoring.rs`** — 1 call site
|
|
6. **`examples/sttest/`** — 2 call sites, has both main.rs and topology.rs patterns
|
|
7. **`examples/okd_installation/`** — 3 call sites, complex topology setup
|
|
8. **`examples/okd_pxe/`** — 3 call sites, similar to okd_installation
|
|
9. **`harmony/src/modules/okd/bootstrap_02_bootstrap.rs`** — 2 call sites, critical OKD bootstrap path
|
|
|
|
### 2.4 Remove `harmony_secret` from direct dependencies
|
|
|
|
After all call sites are migrated:
|
|
|
|
1. Remove `harmony_secret` from `Cargo.toml` of: `harmony`, `brocade`, and all examples that had it
|
|
2. `harmony_config` keeps `harmony_secret` as a dependency (for `StoreSource`)
|
|
3. The `Secret` trait and `SecretManager` remain in `harmony_secret` but are not used directly anymore
|
|
|
|
### 2.5 Backward compatibility for existing local secrets
|
|
|
|
Users who already have secrets stored via `LocalFileSecretStore` (JSON files in `~/.local/share/harmony/secrets/`) need a migration path:
|
|
|
|
- On first run after upgrade, if SQLite has no entry for a key but the old JSON file exists, read from JSON and write to SQLite
|
|
- Or: add `LocalFileSource` as a fallback source at the end of the chain (read-only) for one release cycle
|
|
- Log a deprecation warning when reading from old JSON files
|
|
|
|
## Deliverables
|
|
|
|
- [ ] `harmony_config::init()` called in `harmony_cli::run()` and `harmony_tui::run()`
|
|
- [ ] All 19 call sites migrated from `SecretManager` to `harmony_config`
|
|
- [ ] `harmony_secret` removed from direct dependencies of `harmony`, `brocade`, and all examples
|
|
- [ ] Backward compatibility for existing local JSON secrets
|
|
- [ ] All existing unit tests still pass
|
|
- [ ] Manual verification: one migrated example works end-to-end (prompt → persist → read)
|