Skip to content

seryl/amalgam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

56 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ”ง Amalgam

Crates.io License

Generate type-safe Nickel configurations from any schema source

Amalgam transforms Kubernetes CRDs, OpenAPI schemas, and other type definitions into strongly-typed Nickel configuration language, enabling type-safe infrastructure as code with automatic validation and completion.

๐ŸŽฏ Why Nickel?

Nickel is a powerful configuration language that offers:

  • Gradual Typing - Mix static types with dynamic code as needed
  • Contracts - Runtime validation with custom predicates
  • Merging - Powerful record merging and extension
  • Functions - First-class functions for abstraction
  • Correctness - Designed to prevent configuration errors

Amalgam bridges the gap between existing schemas (K8s CRDs, OpenAPI) and Nickel's type system, giving you the best of both worlds: auto-generated types from authoritative sources with Nickel's powerful configuration capabilities.

โœจ Features

  • ๐Ÿ“ฆ Import Kubernetes CRDs - Convert CRDs to strongly-typed Nickel configurations
  • ๐Ÿ” Smart Import Resolution - Automatically resolves cross-package type references with proper imports
  • ๐Ÿ“ Package Generation - Creates organized package structures from multiple schemas
  • ๐Ÿ”Œ Generic Architecture - Universal resolver that works with any schema source
  • ๐Ÿ™ GitHub Integration - Fetch schemas directly from GitHub repositories

๐Ÿ“ฅ Installation

# Clone the repository
git clone https://github.com/seryl/amalgam
cd amalgam

# Build with Cargo
cargo build --release

# Install locally
cargo install --path crates/amalgam-cli

๐Ÿš€ Quick Start

Import a Single CRD

# Import from a local file
amalgam import crd --file my-crd.yaml --output my-crd.ncl

# Import from a URL
amalgam import url --url https://raw.githubusercontent.com/example/repo/main/crd.yaml --output output/

Import Crossplane CRDs

# Fetch all Crossplane CRDs and generate a Nickel package
amalgam import url \
  --url https://github.com/crossplane/crossplane/tree/main/cluster/crds \
  --output crossplane-types/

This generates a structured Nickel package:

crossplane-types/
โ”œโ”€โ”€ mod.ncl                                    # Main module
โ”œโ”€โ”€ apiextensions.crossplane.io/
โ”‚   โ”œโ”€โ”€ mod.ncl                               # Group module
โ”‚   โ”œโ”€โ”€ v1/
โ”‚   โ”‚   โ”œโ”€โ”€ mod.ncl                           # Version module
โ”‚   โ”‚   โ”œโ”€โ”€ composition.ncl                   # Type definitions
โ”‚   โ”‚   โ””โ”€โ”€ compositeresourcedefinition.ncl
โ”‚   โ””โ”€โ”€ v1beta1/
โ”‚       โ””โ”€โ”€ ...
โ””โ”€โ”€ pkg.crossplane.io/
    โ””โ”€โ”€ ...

๐Ÿ“ Generated Nickel Output Example

Amalgam automatically resolves Kubernetes type references and generates clean Nickel code:

# Module: composition.apiextensions.crossplane.io

let k8s_io_v1 = import "../../k8s_io/v1/objectmeta.ncl" in

{
  Composition = {
    apiVersion | optional | String,
    kind | optional | String,
    metadata | optional | k8s_io_v1.ObjectMeta,
    spec | optional | {
      compositeTypeRef | {
        apiVersion | String,
        kind | String,
      },
      # ... more fields
    },
  },
}

๐ŸŽฏ Key Features Explained

Import Resolution

The tool intelligently detects and resolves Kubernetes type references:

  • Detects: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
  • Generates Import: let k8s_io_v1 = import "../../k8s_io/v1/objectmeta.ncl" in
  • Resolves Reference: k8s_io_v1.ObjectMeta

Generic Resolver System

The resolver system uses a simple, generic pattern-matching approach that works for any schema source:

pub struct TypeResolver {
    cache: HashMap<String, Resolution>,
    type_registry: HashMap<String, String>,
}

Key features:

  • Universal Pattern Matching - Works with any schema format (Kubernetes, OpenAPI, Protobuf, etc.)
  • Smart Import Detection - Automatically identifies when imports are needed based on namespace patterns
  • Type Registry - Maintains a registry of all known types for accurate resolution
  • Cache-based Performance - Caches resolutions to avoid repeated lookups
  • No Special-casing - Generic implementation that doesn't favor any particular schema source

๐Ÿ’ป CLI Commands

Main Commands

  • import - Import types from various sources

    • crd - Import from a CRD file
    • url - Import from URL (GitHub, raw files)
    • open-api - Import from OpenAPI spec
    • k8s - Import from Kubernetes cluster (planned)
  • generate - Generate code from IR

  • convert - Convert between formats

  • vendor - Manage vendored packages

Options

  • -v, --verbose - Enable verbose output
  • -d, --debug - Enable debug output with detailed tracing

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        amalgam CLI                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                        Schema Pipeline                      โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚   โ”‚   CRD    โ”‚  โ”‚ OpenAPI  โ”‚  โ”‚    Go    โ”‚  โ”‚ Protobuf โ”‚    โ”‚
โ”‚   โ”‚  Parser  โ”‚  โ”‚  Parser  โ”‚  โ”‚   AST    โ”‚  โ”‚  Parser  โ”‚    โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚               Intermediate Representation (IR)              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚         Unified Type System (Algebraic Types)        โ”‚   โ”‚
โ”‚  โ”‚    - Sum Types (Enums/Unions)                        โ”‚   โ”‚
โ”‚  โ”‚    - Product Types (Structs/Records)                 โ”‚   โ”‚
โ”‚  โ”‚    - Contracts & Refinement Types                    โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                       Code Generation                       โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚   โ”‚  Nickel  โ”‚  โ”‚    Go    โ”‚  โ”‚   CUE    โ”‚  โ”‚   JSON   โ”‚    โ”‚
โ”‚   โ”‚Generator โ”‚  โ”‚Generator โ”‚  โ”‚Generator โ”‚  โ”‚ Exporter โ”‚    โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“‚ Project Structure

amalgam/
โ”œโ”€โ”€ Cargo.toml                 # Workspace definition
โ”œโ”€โ”€ flake.nix                  # Nix development environment
โ”œโ”€โ”€ crates/
โ”‚   โ”œโ”€โ”€ amalgam-core/          # Core IR and type system
โ”‚   โ”œโ”€โ”€ amalgam-parser/        # Schema parsers (CRD, OpenAPI)
โ”‚   โ”œโ”€โ”€ amalgam-codegen/       # Code generators with generic resolver
โ”‚   โ”œโ”€โ”€ amalgam-daemon/        # Runtime daemon for watching changes
โ”‚   โ””โ”€โ”€ amalgam-cli/           # Command-line interface
โ”œโ”€โ”€ examples/                  # Example configurations
โ”œโ”€โ”€ tests/                     # Integration tests
โ””โ”€โ”€ docs/                      # Architecture documentation

๐Ÿ’ก Use Cases

Kubernetes Configuration Management

Generate type-safe Nickel configurations from your CRDs:

# Import your custom CRDs
amalgam import crd --file my-operator-crd.yaml --output types/

# Use in Nickel configurations
let types = import "types/my-operator.ncl" in
let config = {
  apiVersion = "example.io/v1",
  kind = "MyResource",
  metadata = {
    name = "example",
  },
  spec = types.MyResourceSpec & {
    # Type-safe configuration with auto-completion
    replicas = 3,
    # ...
  }
}

CrossPlane Composition

Type-safe CrossPlane compositions in Nickel with full IDE support:

let crossplane = import "crossplane-types/mod.ncl" in
let composition = crossplane.apiextensions.v1.Composition & {
  metadata.name = "my-composition",
  spec = {
    compositeTypeRef = {
      apiVersion = "example.io/v1",
      kind = "XDatabase",
    },
    # Full type checking and validation
  }
}

๐Ÿ› ๏ธ Development

Building

# Build all crates
cargo build --workspace

# Run tests
cargo test --workspace

# Run with debug logging
cargo run -- --debug import crd --file test.yaml

Testing

The project includes comprehensive test coverage:

  • Unit tests for type resolution and parsing
  • Integration tests with real CRDs
  • Snapshot tests for generated output
  • Property-based tests for round-trip conversions
# Run all tests
cargo test

# Run specific test suite
cargo test --package amalgam-parser

# Run with coverage (requires cargo-tarpaulin)
cargo tarpaulin --out Html --output-dir coverage

# Run benchmarks (requires cargo-criterion)
cargo criterion

# Update snapshot tests (requires cargo-insta)
cargo insta review

# Run tests with all features
cargo test --all-features

# Run doctests only
cargo test --doc

# Run a specific test
cargo test test_kubernetes_resolver

Code Quality

# Format code
cargo fmt

# Run linter
cargo clippy -- -D warnings

# Check for security vulnerabilities
cargo audit

# Check for outdated dependencies
cargo outdated

# Generate documentation
cargo doc --no-deps --open

# Check licenses
cargo license

๐Ÿค Contributing

Contributions are welcome! Areas of interest:

  • Additional schema parsers (Protobuf, GraphQL)
  • More code generators (TypeScript, Python)
  • Kubernetes cluster integration
  • Enhanced type inference
  • IDE plugins for generated types

๐Ÿ“œ License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Why Apache 2.0?

  • โœ… Enterprise-friendly - Widely accepted in corporate environments
  • โœ… Patent protection - Includes express patent grants
  • โœ… Commercial-ready - Allows building proprietary products and services
  • โœ… Contribution clarity - Clear terms for contributions

๐Ÿ™ Acknowledgments

  • Generates code for Nickel - A powerful configuration language with contracts and gradual typing
  • Inspired by CUE and its approach to configuration
  • Uses patterns from dhall-kubernetes

About

Generate type-safe [Nickel](https://nickel-lang.org) configurations from any schema source

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors