provisioning-platform/prov-ecosystem/crates/gitops
2026-07-09 22:04:43 +01:00
..
src platform: clean-start baseline — Rust workspace: binaries/daemon (constellation materialization) 2026-07-09 22:04:43 +01:00
ARCHITECTURE.md platform: clean-start baseline — Rust workspace: binaries/daemon (constellation materialization) 2026-07-09 22:04:43 +01:00
Cargo.toml platform: clean-start baseline — Rust workspace: binaries/daemon (constellation materialization) 2026-07-09 22:04:43 +01:00
README.md platform: clean-start baseline — Rust workspace: binaries/daemon (constellation materialization) 2026-07-09 22:04:43 +01:00
WOODPECKER_FORGEJO.md platform: clean-start baseline — Rust workspace: binaries/daemon (constellation materialization) 2026-07-09 22:04:43 +01:00

gitops - Event-Driven GitOps Orchestration

A declarative GitOps automation framework that bridges rules (WHAT you want) with environment capabilities (HOW it happens).

Core Principle

RULES (static) + ENVIRONMENT (dynamic) = FLOW (adaptive)

You declare intents, the engine resolves implementations based on available tools.

Key Features

  • Declarative Rules: Define events, conditions, and actions in YAML/TOML/KCL
  • Event-Driven: React to Git pushes, alerts, health checks, schedules, webhooks
  • Adaptive Execution: Automatically chooses the best implementation based on available tools
  • Multi-Target Support: ArgoCD, Flux, Kubernetes, Docker, systemd, n8n
  • Dynamic Environment Detection: Continuously detects available capabilities
  • Fallback Chain: Automatic fallback if primary executor unavailable
  • Multi-Provider Support: GitHub, GitLab, Gitea with unified abstraction

How It Works

1. Declare Rules (WHAT you want)

# gitops-rules.yaml
rules:
  - name: deploy-on-merge
    when:
      event: pr_merged
      branch: main
    then:
      action: deploy
      environment: staging

The rule doesn't say HOW to deploy - that's adaptive.

2. Engine Detects Environment (Available tools)

The engine automatically detects what's available:

Environment detected:
   Docker
   Kubernetes
   ArgoCD
   Flux
   systemd
   n8n

3. Flow Resolution (HOW it happens)

When an event matches the rule, the engine resolves HOW to execute:

Event (pr_merged on main)
    ↓
Match Rule (deploy-on-merge)
    ↓
Resolve Flow with environment
    ├─ ArgoCD available? → Apply Application CRD
    └─ If ArgoCD fails → Try Kubernetes API
      └─ If K8s fails → Try Docker
        └─ Fallback → Execute script
    ↓
Execute Action (Deploy to staging)

Adaptive Workflow Example

Day 1: Local Development with Docker

# Rules stay the same
rules:
  - name: deploy-on-push
    when: { event: push, branch: main }
    then: { action: deploy, environment: staging }

Engine detects: Docker available → Uses docker-compose up

Day 30: Migrate to Kubernetes

Engine detects: Kubernetes available (Docker still there) → Automatically uses kubectl apply Rules unchanged!

Day 60: Adopt ArgoCD

Engine detects: ArgoCD available → Automatically generates Application CRD Rules still unchanged!

Rule Format

rules:
  # Basic deployment rule
  - name: deploy-on-merge
    when:
      event: pr_merged
      branch: main
    then:
      - action: deploy
        environment: staging
      - action: notify
        target: slack

  # Automatic rollback on metrics
  - name: auto-rollback
    when:
      event: alert
      alert: HighErrorRate
      severity: critical
    then:
      - action: rollback
        environment: prod
      - action: notify
        message: "Rollback triggered"
        severity: critical

  # Scheduled backup
  - name: nightly-backup
    when:
      schedule: "0 2 * * *"
    then:
      - action: backup
        retention: 30d

  # Promotion with approval
  - name: promote-to-prod
    when:
      event: workflow_completed
      workflow: "staging-tests-passed"
    then:
      - action: deploy
        environment: prod
        require_approval: true

Architecture

gitops/
├── rule/            # Declarative rules (YAML/TOML/KCL)
├── event/           # Event sources (git, alerts, webhooks, etc)
├── environment/     # Detects available capabilities
├── flow/            # Resolves HOW to execute
├── executor/        # Implements with detected tools
├── provider/        # Git provider abstractions
├── generator/       # Generates configs for external tools
└── integration/     # Integrations with ecosystem crates

Capabilities Detected

Capability Usage
ArgoCD Deploy via Application CRDs
Flux CD Deploy via GitRepository + Kustomization CRDs
Kubernetes Deploy via kubectl directly
Docker Deploy via runtime crate
Podman Deploy via runtime crate
systemd Deploy as service via init-servs crate
n8n Notification and orchestration
Prometheus Metrics-driven actions

Event Sources

  • git: Push, PR, tag events (GitHub, GitLab, Gitea)
  • alert: Prometheus/Alertmanager webhooks
  • schedule: Cron expressions
  • health: observability crate health events
  • n8n: n8n workflow completions
  • manual: CLI/API triggers
  • webhook: Generic HTTP webhooks

Integration with Ecosystem

Crate Integration
observability Health events trigger rules, expose metrics
valida Validation rules in pipeline stages
encrypt Secrets for actions
runtime Container-based deployments
init-servs systemd/launchd deployments
backup Backup actions pre/post deploy
n8n Workflow orchestration + notifications

Quick Start

1. Create rules file

# gitops.yaml
rules:
  - name: deploy-staging
    when:
      event: push
      branch: main
    then:
      - action: deploy
        environment: staging

2. Use in Rust

use gitops::engine::GitOpsEngine;
use gitops::rule::RuleRegistry;
use std::path::Path;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load rules
    let rules = RuleRegistry::from_yaml(Path::new("gitops.yaml"))?;

    // Create engine (auto-detects environment)
    let engine = GitOpsEngine::new(rules).await?;

    // Run the engine
    engine.run().await?;

    Ok(())
}

3. Environment Auto-Detects

Detected capabilities:
  ✓ Kubernetes
  ✓ Docker
  ✓ ArgoCD
  ✓ Prometheus
  ✓ n8n

The engine automatically chooses the best implementation path for each action.

Testing

cargo test -p gitops
# All 15 tests pass ✓

License

MIT