docs: New README, two options to choose from right now
All checks were successful
Run Check Script / check (push) Successful in 1m48s
Run Check Script / check (pull_request) Successful in 1m47s

This commit is contained in:
Jean-Gabriel Gill-Couture 2025-06-11 14:26:17 -04:00
parent ef5ec4a131
commit 2dc16ef8e3
2 changed files with 256 additions and 150 deletions

265
README.md
View File

@ -1,171 +1,136 @@
# Harmony : Open Infrastructure Orchestration
# Harmony
## Quick demo
### Open Infrastructure Orchestration for Enterprise
`cargo run -p example-tui`
Harmony is an open-source orchestrator designed to **unify** the **entire software lifecycle** within a **single, coherent codebase**. It seamlessly **integrates project creation, infrastructure provisioning, and application deployment** across all your environments—**from a local mini-cluster to a full-scale production setup.**
This will launch Harmony's minimalist terminal ui which embeds a few demo scores.
Built on the principles of **Infrastructure as Code (IaC)** and **Platform Engineering**, Harmony leverages the **full power** of a real programming language **(Rust)** to provide a robust, type-safe, and unified developer experience.
Usage instructions will be displayed at the bottom of the TUI.
## The Harmony Philosophy
`cargo run --bin example-cli -- --help`
Infrastructure is a requirement for nearly all software, but it isn't your core business. It's ours. Harmony provides an expert-designed foundation for your applications, allowing you to focus on the features that matter to your customers.
This is the harmony CLI, a minimal implementation
### Principle 1: Infrastructure as Resilient Code, Not Fragile Configuration.
The current help text:
- The Problem: Traditional infrastructure is managed with static files (like YAML) and brittle scripts. These are error-prone, hard to test, and don't scale with complexity.
- The Harmony Way: We treat infrastructure with the same seriousness as application code. By using a powerful, type-safe programming language (Rust), we define infrastructure as living code that can be tested, reused, and reasoned about, making it fundamentally more robust.
````
Usage: example-cli [OPTIONS]
### Principle 2: From "Hope It Works" to "Prove It Works".
Options:
-y, --yes Run score(s) or not
-f, --filter <FILTER> Filter query
-i, --interactive Run interactive TUI or not
-a, --all Run all or nth, defaults to all
-n, --number <NUMBER> Run nth matching, zero indexed [default: 0]
-l, --list list scores, will also be affected by run filter
-h, --help Print help
-V, --version Print version```
- The Problem: With conventional tools, you only discover if a deployment plan is valid when you run it—often in a staging or production environment.
- The Harmony Way: We believe correctness should be a guarantee, not a hope. Harmony uses the compiler to prove that your application's needs are compatible with your infrastructure's capabilities before deployment. This eliminates entire classes of configuration errors at the earliest possible stage.
## Core architecture
### Principle 3: A Unified Model for a Unified Reality.
![Harmony Core Architecture](docs/diagrams/Harmony_Core_Architecture.drawio.svg)
````
## Supporting a new field in OPNSense `config.xml`
- The Problem: In reality, software and infrastructure are a single, interdependent system. Yet, we manage them with separate, disjointed tools, creating a gap where errors and inconsistencies thrive.
- The Harmony Way: We model the system as it truly is: a single entity. Harmony creates a unified codebase where application and infrastructure logic live together, enabling deep integration and holistic management of your entire platform, from bare-metal hardware to the final application.
Two steps:
- Supporting the field in `opnsense-config-xml`
- Enabling Harmony to control the field
If you like metaphors, see this one : [cyborg-metaphor](docs/cyborg-metaphor.md)
We'll use the `filename` field in the `dhcpcd` section of the file as an example.
## Quick Start: Deploying a Full LAMP Stack
### Supporting the field
The following example demonstrates how to define and deploy a complete, production-grade LAMP stack. Harmony will handle everything: setting up a local Kubernetes cluster, building a containerized PHP application, deploying a MariaDB database, and configuring monitoring.
As type checking if enforced, every field from `config.xml` must be known by the code. Each subsection of `config.xml` has its `.rs` file. For the `dhcpcd` section, we'll modify `opnsense-config-xml/src/data/dhcpd.rs`.
#### `main.rs`
When a new field appears in the xml file, an error like this will be thrown and Harmony will panic :
```
Running `/home/stremblay/nt/dir/harmony/target/debug/example-nanodc`
Found unauthorized element filename
thread 'main' panicked at opnsense-config-xml/src/data/opnsense.rs:54:14:
OPNSense received invalid string, should be full XML: ()
```
Define the missing field (`filename`) in the `DhcpInterface` struct of `opnsense-config-xml/src/data/dhcpd.rs`:
```
pub struct DhcpInterface {
...
pub filename: Option<String>,
```
Harmony should now be fixed, build and run.
### Controlling the field
Define the `xml field setter` in `opnsense-config/src/modules/dhcpd.rs`.
```
impl<'a> DhcpConfig<'a> {
...
pub fn set_filename(&mut self, filename: &str) {
self.enable_netboot();
self.get_lan_dhcpd().filename = Some(filename.to_string());
}
...
```
Define the `value setter` in the `DhcpServer trait` in `domain/topology/network.rs`
```
#[async_trait]
pub trait DhcpServer: Send + Sync {
...
async fn set_filename(&self, filename: &str) -> Result<(), ExecutorError>;
...
```
Implement the `value setter` in each `DhcpServer` implementation.
`infra/opnsense/dhcp.rs`:
```
#[async_trait]
impl DhcpServer for OPNSenseFirewall {
...
async fn set_filename(&self, filename: &str) -> Result<(), ExecutorError> {
{
let mut writable_opnsense = self.opnsense_config.write().await;
writable_opnsense.dhcp().set_filename(filename);
debug!("OPNsense dhcp server set filename {filename}");
}
Ok(())
}
...
```
`domain/topology/ha_cluster.rs`
```
#[async_trait]
impl DhcpServer for DummyInfra {
...
async fn set_filename(&self, _filename: &str) -> Result<(), ExecutorError> {
unimplemented!("{}", UNIMPLEMENTED_DUMMY_INFRA)
}
...
```
Add the new field to the DhcpScore in `modules/dhcp.rs`
```
pub struct DhcpScore {
...
pub filename: Option<String>,
```
Define it in its implementation in `modules/okd/dhcp.rs`
```
impl OKDDhcpScore {
...
Self {
dhcp_score: DhcpScore {
...
filename: Some("undionly.kpxe".to_string()),
```
Define it in its implementation in `modules/okd/bootstrap_dhcp.rs`
```
impl OKDDhcpScore {
...
Self {
dhcp_score: DhcpScore::new(
...
Some("undionly.kpxe".to_string()),
```
Update the interpret (function called by the `execute` fn of the interpret) so it now updates the `filename` field value in `modules/dhcp.rs`
```
impl DhcpInterpret {
...
let filename_outcome = match &self.score.filename {
Some(filename) => {
let dhcp_server = Arc::new(topology.dhcp_server.clone());
dhcp_server.set_filename(&filename).await?;
Outcome::new(
InterpretStatus::SUCCESS,
format!("Dhcp Interpret Set filename to {filename}"),
)
}
None => Outcome::noop(),
```rust
use harmony::{
data::Version,
inventory::Inventory,
maestro::Maestro,
modules::{
lamp::{LAMPConfig, LAMPScore},
monitoring::monitoring_alerting::MonitoringAlertingStackScore,
},
topology::{K8sAnywhereTopology, Url},
};
if next_server_outcome.status == InterpretStatus::NOOP
&& boot_filename_outcome.status == InterpretStatus::NOOP
&& filename_outcome.status == InterpretStatus::NOOP
#[tokio::main]
async fn main() {
// This here is the whole configuration to:
// - Setup a local K3D cluster (if not already running)
// - Build a docker image with the PHP project and production-grade settings
// - Deploy a MariaDB database using a production-grade Helm chart
// - Deploy the new container using a Kubernetes Deployment
// - Configure networking between the PHP container and the database
// - Provision a public route and an SSL certificate automatically on production environments
//
// Enjoy :)
let lamp_stack = LAMPScore {
name: "harmony-lamp-demo".to_string(),
domain: Url::Url(url::Url::parse("https://lampdemo.harmony.nationtech.io").unwrap()),
php_version: Version::from("8.4.4").unwrap(),
// This config can be extended as needed for more complicated configurations
config: LAMPConfig {
project_root: "./php".into(),
database_size: "4Gi".into(),
..Default::default()
},
};
...
Ok(Outcome::new(
InterpretStatus::SUCCESS,
format!(
"Dhcp Interpret Set next boot to [{:?}], boot_filename to [{:?}], filename to [{:?}]",
self.score.boot_filename, self.score.boot_filename, self.score.filename
// You can choose the type of Topology you want. We suggest starting with the
// K8sAnywhereTopology, as it is the most automatic one. It enables you to easily deploy
// locally, to a development environment from a CI, to staging, and to production
// with settings that automatically adapt to each environment grade.
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
Inventory::autoload(),
K8sAnywhereTopology::from_env(),
)
...
.await
.unwrap();
// Attach additional features like a full monitoring and alerting stack
let mut monitoring_stack_score = MonitoringAlertingStackScore::new();
monitoring_stack_score.namespace = Some(lamp_stack.config.namespace.clone());
maestro.register_all(vec![Box::new(lamp_stack), Box::new(monitoring_stack_score)]);
// Here we bootstrap the CLI, which provides useful interactive features.
harmony_cli::init(maestro, None).await.unwrap();
}
// That's it. The end of your Infrastructure as Code.
```
### Running the Example
To launch the orchestrator, simply run the project:
```bash
cargo run
```
This will start Harmony, which will analyze the code, determine the required state, and apply the necessary changes to match your definition. It will present you with an interactive TUI to review and approve the execution plan.
## Core Concepts
Harmony is built around a few key architectural concepts:
- **Scores**: A `Score` is a declarative, high-level definition of a resource or application you want to exist (e.g., `LAMPScore`, `PostgresClusterScore`). It defines *what* you want, not *how* to achieve it.
- **Interprets**: An `Interpret` contains the imperative logic that brings a `Score` to life. It's the "how" that translates the declarative goal into concrete actions, like running `kubectl` commands or calling a cloud provider API.
- **Topology**: A `Topology` defines *where* your infrastructure runs. It's an abstraction over your target environment, whether it's a local `k3d` cluster, a bare-metal server, or a public cloud provider. `K8sAnywhereTopology` is a powerful default that adapts to any Kubernetes environment.
- **Maestro**: The `Maestro` is the central orchestrator. It loads the inventory, initializes the `Topology`, and executes the `Interprets` for all registered `Scores`.
![Harmony Core Architecture](docs/diagrams/Harmony_Core_Architecture.drawio.svg)
## Contributing & Deeper Dive
Contributions are welcome! Whether it's improving the core, adding a new `Score`, or enhancing the documentation, we'd love to have your help.
For a deeper understanding of our design decisions, please see our **Architectural Decision Records (ADRs)**:
- [ADR-001: Rust as the Primary Language]
- [ADR-003: Infrastructure Abstractions]
- [ADR-006: Secret Management]
- [ADR-011: Multi Tenant Cluster]
- ... and more in the `/adr` directory.
Detailed technical guides, such as **how to extend Harmony to support new hardware (e.g., OPNsense)**, can be found in the `/docs` section of this repository.
## License
This project is licensed under the AGLP License. See the [LICENSE](LICENSE) file for details.
Why AGPL ? Because we believe a strong copyleft license is what enables and empowers all use cases founded in good will, aiming at bringing forward our world towards a better place by leveraging humanity's greatest strenght : collaboration.
We are totally fine with companies forking harmony and beating us at our own game of creating the best infrastructure orchestration tool. But this has been built for the community and must stay open, so we're forcing copyleft terms upon this project to make sure they are not allowed to keep it just for them.

141
README_v2.md Normal file
View File

@ -0,0 +1,141 @@
# Harmony
[![Build](https://git.nationtech.io/NationTech/harmony/actions/workflows/check.yml/badge.svg)](https://git.nationtech.io/nationtech/harmony)
[![License](https://img.shields.io/badge/license-AGPLv3-blue?style=flat-square)](LICENSE)
**Open-source infrastructure orchestration that treats your platform like first-class code.**
Harmony unifies project scaffolding, infrastructure provisioning, application deployment, and day-2 operations in **one strongly-typed Rust codebase**. From a developer laptop to a global production cluster, a single source of truth drives the full software lifecycle.
---
## 1 · The Harmony Philosophy
Infrastructure is essential, but it shouldnt be your core business. Harmony is built on three guiding principles that make modern platforms reliable, repeatable, and easy to reason about.
| Principle | What it means for you |
|-----------|-----------------------|
| **Infrastructure as Resilient Code** | Replace sprawling YAML and bash scripts with type-safe Rust. Test, refactor, and version your platform just like application code. |
| **Prove It Works — Before You Deploy** | Harmony uses the compiler to verify that your applications needs match the target environments capabilities at **compile-time**, eliminating an entire class of runtime outages. |
| **One Unified Model** | Software and infrastructure are a single system. Harmony models them together, enabling deep automation—from bare-metal servers to Kubernetes workloads—with zero context switching. |
These principles surface as simple, ergonomic Rust APIs that let teams focus on their product while trusting the platform underneath.
---
## 2 · Quick Start
The snippet below spins up a complete **production-grade LAMP stack** with monitoring. Swap it for your own scores to deploy anything from microservices to machine-learning pipelines.
```rust
use harmony::{
data::Version,
inventory::Inventory,
maestro::Maestro,
modules::{
lamp::{LAMPConfig, LAMPScore},
monitoring::monitoring_alerting::MonitoringAlertingStackScore,
},
topology::{K8sAnywhereTopology, Url},
};
#[tokio::main]
async fn main() {
// 1. Describe what you want
let lamp_stack = LAMPScore {
name: "harmony-lamp-demo".into(),
domain: Url::Url(url::Url::parse("https://lampdemo.example.com").unwrap()),
php_version: Version::from("8.3.0").unwrap(),
config: LAMPConfig {
project_root: "./php".into(),
database_size: "4Gi".into(),
..Default::default()
},
};
// 2. Pick where it should run
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
Inventory::autoload(), // auto-detect hardware / kube-config
K8sAnywhereTopology::from_env(), // local k3d, CI, staging, prod…
)
.await
.unwrap();
// 3. Enhance with extra scores (monitoring, CI/CD, …)
let mut monitoring = MonitoringAlertingStackScore::new();
monitoring.namespace = Some(lamp_stack.config.namespace.clone());
maestro.register_all(vec![Box::new(lamp_stack), Box::new(monitoring)]);
// 4. Launch an interactive CLI / TUI
harmony_cli::init(maestro, None).await.unwrap();
}
```
Run it:
```bash
cargo run
```
Harmony analyses the code, shows an execution plan in a TUI, and applies it once you confirm. Same code, same binary—every environment.
---
## 3 · Core Concepts
| Term | One-liner |
|------|-----------|
| **Score<T>** | Declarative description of the desired state (e.g., `LAMPScore`). |
| **Interpret<T>** | Imperative logic that realises a `Score` on a specific environment. |
| **Topology** | An environment (local k3d, AWS, bare-metal) exposing verified *Capabilities* (Kubernetes, DNS, …). |
| **Maestro** | Orchestrator that compiles Scores + Topology, ensuring all capabilities line up **at compile-time**. |
| **Inventory** | Optional catalogue of physical assets for bare-metal and edge deployments. |
A visual overview is in the diagram below.
[Harmony Core Architecture](docs/diagrams/Harmony_Core_Architecture.drawio.svg)
---
## 4 · Install
Prerequisites:
* Rust
* Docker (if you deploy locally)
* `kubectl` / `helm` for Kubernetes-based topologies
```bash
git clone https://git.nationtech.io/nationtech/harmony
cd harmony
cargo build --release # builds the CLI, TUI and libraries
```
---
## 5 · Learning More
* **Architectural Decision Records** dive into the rationale
- [ADR-001 · Why Rust](adr/001-rust.md)
- [ADR-003 · Infrastructure Abstractions](adr/003-infrastructure-abstractions.md)
- [ADR-006 · Secret Management](adr/006-secret-management.md)
- [ADR-011 · Multi-Tenant Cluster](adr/011-multi-tenant-cluster.md)
* **Extending Harmony** write new Scores / Interprets, add hardware like OPNsense firewalls, or embed Harmony in your own tooling (`/docs`).
* **Community** discussions and roadmap live in [GitLab issues](https://git.nationtech.io/nationtech/harmony/-/issues). PRs, ideas, and feedback are welcome!
---
## 6 · License
Harmony is released under the **GNU AGPL v3**.
> We choose a strong copyleft license to ensure the project—and every improvement to it—remains open and benefits the entire community. Fork it, enhance it, even out-innovate us; just keep it open.
See [LICENSE](LICENSE) for the full text.
---
*Made with ❤️ & 🦀 by the NationTech and the Harmony community*