crossplane-diff

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2025 License: Apache-2.0

README

crossplane-diff

A standalone tool for visualizing the differences between Crossplane resources in YAML files and their resulting state when applied to a live Kubernetes cluster. Similar to kubectl diff but with specific enhancements for Crossplane resources, particularly Composite Resources (XRs) and their composed resources.

Overview

The crossplane-diff tool helps you:

  • Preview changes before applying Crossplane resources to a cluster
  • Visualize differences at multiple levels: both the XR itself and all downstream composed resources
  • Analyze composition impact showing how composition changes affect existing XRs in the cluster
  • Support complex compositions including functions, requirements, and environment configurations
  • Handle both Crossplane v1 and v2 resource definitions, including namespaced composite resources
  • Detect resources that would be removed by your changes

Installation

Download Pre-built Binary

Download the latest release from the releases page.

Build from Source
git clone https://github.com/crossplane-contrib/crossplane-diff.git
cd crossplane-diff
go build -o crossplane-diff ./cmd/diff

Usage

XR Diff - Preview Changes to Composite Resources
# Show changes that would result from applying an XR from a file
crossplane-diff xr xr.yaml

# Show changes from stdin
cat xr.yaml | crossplane-diff xr -

# Process multiple files
crossplane-diff xr xr1.yaml xr2.yaml xr3.yaml

# Show changes in a compact format with minimal context
crossplane-diff xr xr.yaml --compact

# Disable color output
crossplane-diff xr xr.yaml --no-color
Composition Diff - Analyze Impact of Composition Changes
# Show impact of updated composition on all XRs using it
crossplane-diff comp updated-composition.yaml

# Show impact of multiple composition changes
crossplane-diff comp comp1.yaml comp2.yaml comp3.yaml

# Show impact only on XRs in a specific namespace
crossplane-diff comp updated-composition.yaml -n production

# Include XRs with Manual update policy (pinned revisions)
crossplane-diff comp updated-composition.yaml --include-manual
Command Options
xr - Diff Composite Resources
crossplane-diff xr [<files> ...] [flags]

Arguments:
  [<files> ...]    YAML files containing Crossplane resources to diff.

Flags:
  -h, --help                   Show context-sensitive help.
      --verbose                Print verbose logging statements.
      --no-color               Disable colorized output.
      --compact                Show compact diffs with minimal context.
      --max-nested-depth=10    Maximum depth for nested XR recursion.
      --timeout=1m             How long to run before timing out.
      --qps=0                  Maximum QPS to the API server.
      --burst=0                Maximum burst for throttle.

Note: XR namespaces are read directly from the YAML files being diffed, not from command-line flags.

comp - Diff Composition Impact
crossplane-diff comp [<files> ...] [flags]

Arguments:
  [<files> ...]    YAML files containing updated Composition(s).

Flags:
  -h, --help                   Show context-sensitive help.
      --verbose                Print verbose logging statements.
      --no-color               Disable colorized output.
      --compact                Show compact diffs with minimal context.
      --max-nested-depth=10    Maximum depth for nested XR recursion.
      --timeout=1m             How long to run before timing out.
      --qps=0                  Maximum QPS to the API server.
      --burst=0                Maximum burst for throttle.
  -n, --namespace=""           Namespace to find XRs (empty = all namespaces).
      --include-manual         Include XRs with Manual update policy (default:
                               only Automatic policy XRs)

Note: The diff subcommand is deprecated. Use xr instead.

Prerequisites
  • A running Kubernetes cluster with Crossplane installed
  • kubectl configured to access your cluster
  • Appropriate RBAC permissions (see Required Permissions)

How It Works

The tool performs the following steps:

  1. Load resources from YAML files or stdin
  2. Find matching compositions for each Composite Resource
  3. Render resources using the same composition pipeline as Crossplane
  4. Resolve requirements iteratively (environment configs, external resources)
  5. Propagate namespaces from XRs to managed resources (for Crossplane v2)
  6. Validate resources against their schemas and enforce scope constraints
  7. Calculate diffs by comparing rendered resources against current cluster state
  8. Display formatted output showing what would change

Crossplane v2 Support

This tool fully supports both Crossplane v1 and v2, including:

  • Cluster-scoped XRDs: Traditional cluster-wide resources
  • Namespaced XRDs: Resources confined to specific namespaces for better isolation
  • Automatic scope detection: Determines whether XRDs are cluster or namespace scoped
  • Namespace propagation: Ensures managed resources inherit appropriate namespaces
  • Scope validation: Enforces rules like "namespaced XRs cannot own cluster-scoped managed resources"

Note: Namespace information is read directly from the XR definitions in your YAML files, not from command-line flags.

Required Permissions

The tool requires read access to:

  • Crossplane definitions: XRDs, Compositions, Functions
  • Crossplane runtime resources: XRs, Claims, Managed Resources
  • Crossplane configuration: EnvironmentConfigs
  • Kubernetes resources: CRDs, referenced resources
  • Resource hierarchies: Owner references and relationships

Output Format

The output follows familiar diff conventions with colorized output (unless disabled):

+++ Resource/new-resource-(generated)
+ apiVersion: nop.crossplane.io/v1alpha1
+ kind: NopResource
+ metadata:
+   name: new-resource
+ spec:
+   forProvider:
+     field: value

---
--- XNopResource/removed-resource
- apiVersion: diff.example.org/v1alpha1
- kind: XNopResource
- spec:
-   coolField: goodbye!

~~~
~~~ Resource/modified-resource
  metadata:
    name: modified-resource
- spec:
-   oldValue: something
+ spec:
+   newValue: something-else
---

Summary: 1 added, 1 modified, 1 removed

Guiding Principles

The tool prioritizes accuracy above all else:

  • Never silently continues in the face of failures
  • Avoids making best-guesses that could compromise accuracy
  • Fails completely rather than emit potentially incorrect partial results
  • Reaches extensively into the cluster for all information needed to produce accurate diffs
  • Caches resources only to avoid API throttling
Caveats

The tool does not take a snapshot of cluster state before processing, so changes made to the cluster during execution may affect results.

Documentation

  • Design Document: Comprehensive technical design and architecture
  • CLAUDE.md: Instructions for Claude. Contains development principles and guidelines for LLMs.

Development

Local Development Setup

Prerequisites:

Setup Steps:

  1. Install required tools:

    go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.20
    setup-envtest use 1.30.3 # or whatever cluster version we're using now
    
  2. Generate test manifests:

    earthly +go-generate --CROSSPLANE_IMAGE_TAG=main
    
  3. Build the project:

    earthly +build
    
Running Tests

Unit and Integration Tests (fast):

cd cmd/diff
go test ./...

Development Checks (linting, tests, generation):

# Run before opening any PR
earthly +reviewable

End-to-End Tests:

# Full test matrix against multiple Crossplane versions (slower)
earthly -P +e2e-matrix

# Single E2E test against specific version
earthly +e2e --CROSSPLANE_IMAGE_TAG=main
Build and Development Commands
# Build binary
earthly +build

# Run linting
earthly +lint

# Generate code/manifests
earthly +generate

# All available targets
earthly --help
Architecture

The tool follows a clean layered architecture:

  • Command Layer: CLI argument parsing and coordination
  • Application Layer: Process orchestration and resource loading
  • Domain Layer: Core diff logic, rendering, and validation
  • Client Layer: Kubernetes and Crossplane API interactions
Testing

The project includes comprehensive testing:

  • Unit tests: Fast, isolated component testing
  • Integration tests: Using envtest for realistic cluster interactions
  • E2E tests: Full end-to-end scenarios across v1, v2-cluster, and v2-namespaced configurations

Contributing

Contributions are welcome! Please see our contributing guidelines for detailed setup instructions and development workflow.

Quick Start for Contributors:

  1. Fork and clone the repository
  2. Run setup: earthly +go-generate --CROSSPLANE_IMAGE_TAG=main
  3. Make your changes
  4. Test your changes: earthly +reviewable && earthly -P +e2e-matrix
  5. Open a pull request

See CONTRIBUTING.md for complete guidelines and CODE_OF_CONDUCT.md for community standards.

License

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

Directories

Path Synopsis
cmd
diff command
Package main implements the crossplane-diff CLI tool for diffing Crossplane resources.
Package main implements the crossplane-diff CLI tool for diffing Crossplane resources.
diff/client/core
Package core contains structs and functions to aggregate built-in kube clients for use elsewhere
Package core contains structs and functions to aggregate built-in kube clients for use elsewhere
diff/client/crossplane
Package crossplane contains interfaces and implementations for clients that talk to Kubernetes about Crossplane primitives, often by consuming clients from the kubernetes package.
Package crossplane contains interfaces and implementations for clients that talk to Kubernetes about Crossplane primitives, often by consuming clients from the kubernetes package.
diff/client/kubernetes
Package kubernetes contains interfaces and implementations for clients that talk directly to Kubernetes
Package kubernetes contains interfaces and implementations for clients that talk directly to Kubernetes
diff/diffprocessor
Package diffprocessor contains the logic to calculate and render diffs.
Package diffprocessor contains the logic to calculate and render diffs.
diff/renderer
Package renderer contains the logic for formatting and displaying diffs.
Package renderer contains the logic for formatting and displaying diffs.
diff/renderer/types
Package types provides types used in the renderer in order to facilitate code reuse in test
Package types provides types used in the renderer in order to facilitate code reuse in test
diff/serial
Package serial provides utilities for serializing render operations.
Package serial provides utilities for serializing render operations.
diff/testutils
Package testutils is for test utilities.
Package testutils is for test utilities.
diff/types
Package types defines shared type definitions and interfaces used across the crossplane-diff application.
Package types defines shared type definitions and interfaces used across the crossplane-diff application.
diff/version
Package version contains version cmd
Package version contains version cmd
internal
version
Package version contains utilities for working with semantic versions.
Package version contains utilities for working with semantic versions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL