Kubernetes reconciliation is battle-tested and free. Using it is expensive: a purpose-built operator, Kubernetes expertise, and maintenance for as long as it runs. So developers leave it to platform engineers.
Inrun opens it to anyone who has written a service that takes a request and returns a response.
You bring the decision. Inrun brings the machinery.
A caller sends an intent: a small payload in their own words, with no apiVersion, kind or spec. Inrun turns it into a custom resource, reconciles it, and gives the caller back a view of the result.
intent ──▶ gateway ──▶ custom resource ──▶ runtime ──▶ reconcile ──▶ status ──▶ viewThe reconciler decides. Inrun writes. Inrun runs the informers, queues, retries, leader election, server-side apply, owner references, finalizers, status, events, cleanup and metrics. How a resource is reconciled is up to you:
- Declarative: describe the resources in a Blueprint. No code.
- Remote: any HTTP service, in any language, returns what should exist.
- Existing service: an API that knows nothing about Inrun reconciles as it is. Inrun calls it once per reconcile and maps its answer into status.
- Typed: Go hooks, a full reconciler, or an unchanged controller-runtime
Reconcile.
Declarative, remote and typed reconcilers take the same request and return the same result: status, resources, labels and annotations, a requeue, or a cleanup.
- Operators as data. A Blueprint is the operator. It's versioned and published to an OCI registry, carrying its own simulate and e2e results and the tests that produced them.
inrun inspectshows them before you install anything;inrun e2eruns them again on a kind cluster it brings and tears down, so checking the claim needs nothing but Docker. See examples/registry. - Callers apart from the schema. Callers send intents; the CRD stays an internal detail. When a field moves,
migrate.frombrings stored resources to the new shape with the same mapping the gateway applies; when the CRD itself changes (a new kind, group or scope),migrate.tomoves them to it. Either way, callers never notice. See examples/migration. - Kubernetes as a backend. A reconciler doesn't have to create anything: the custom resource can be a durable state machine, cleaned up when it's done. See examples/reconcilers/remote/existing-service-ids.
brew install intentd/tap/inrun intentd/tap/inrun-console
# or
curl -sSL https://get.inrun.dev | bashTwo commands to your first operator:
inrun init # a hello-website operator in the current directory
inrun # run it on your current cluster; the console opens on :8081No cluster? Add --dev to create a temporary kind cluster (needs Docker). Or check it without one, in memory:
inrun simulateOr start from a published pattern:
inrun inspect postgres:v0.1.0 # version, description, test results
inrun postgres:v0.1.0 --apply-cr --dev # run it - all batteries includedpostgres:v0.1.0 is short for ghcr.io/intentd/registry/patterns/blueprints/postgres:v0.1.0. Patterns can live in any OCI registry: set INRUN_REGISTRY to use your own. The published ones are built from inrun-registry.
Examples come in packs. Copy one into a new project with inrun init --pack:
inrun init --pack declarative # Start here: operators declared in a Blueprint, no code
inrun init --pack remote # A reconciler in any language, called over HTTP, including an existing service
inrun init --pack typed # Go: hooks, a constructor, and a controller-runtime drop-in
inrun init --pack intent # Intent in through the gateway, view out
inrun init --pack migration # Change the CRD under live CRs: move fields, or move CRs to another CRD
inrun init --pack registry # Share operators as patterns: consume one, publish your own, deprecate itinrun init --list shows them all. Each pack is a folder of examples; for any of them:
cd declarative/01-hello-website
inrun # run it
inrun simulate # check it without a cluster
inrun simulate --envtest # the same against a real API server and etcd, still no cluster
inrun e2e # test it end to end on a kind cluster it creates and removesEach example's README is its guide.
Two libraries that came out of Inrun and stand on their own:
- KEL: functions that know Kubernetes, for reading state in templates and Go.
- kubewright: building and writing an owner's child resources.
v0.1.0 is the first release. The API may still change before v1.0; breaking changes are listed in CHANGELOG.md.
Inrun began as Orkestra. Its history is on the archive branch and the orkestra-v0.7.18 tag.
make testSee tests/README.md for the test tiers and docs/contributing for how the code is laid out.
Apache 2.0. See LICENSE.