Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .mise.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tools]
actionlint = "1.7.7"
ginkgo = '2.22.2'
ginkgo = '2.23.4'
golang = '1.24'
golangci-lint = "2.1.6"
"go:golang.org/x/tools/cmd/goimports" = "0.33.0"
Expand Down
112 changes: 112 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands

### Prerequisites Setup

```bash
mise trust
mise install # Installs all dependencies including go, docker, kubectl, etc.
```

### Core Development

```bash
make help # Show all available make targets
make build # Build manager binary
make run # Run controller locally
make test # Run unit tests with coverage
make test-e2e # Run end-to-end tests
make watch # Watch tests continuously
make lint # Run golangci-lint and yamllint
make lint-fix # Run linters with auto-fix
```

Once the project has been built at least once, you can also run `ginkgo`
directly to execute individual tests. See the @Makefile for how to run it.

### Code Generation

```bash
make manifests # Generate CRDs, webhooks, ClusterRoles
make generate # Generate DeepCopy methods
make docs # Generate CRD documentation (PrefectServer.md, PrefectWorkPool.md)
```

### Kubernetes Operations

```bash
make install # Install CRDs to cluster
make uninstall # Remove CRDs from cluster
make deploy # Deploy operator via Helm
make undeploy # Remove operator deployment
kubectl apply -k deploy/samples/ # Apply sample resources
```

### Docker Operations

```bash
make docker-build IMG=<registry>/prefect-operator:tag
make docker-push IMG=<registry>/prefect-operator:tag
```

## Architecture

This is a Kubernetes operator built with Kubebuilder that manages Prefect infrastructure components.

### Core Custom Resources

- **PrefectServer**: Manages Prefect server deployments with configurable storage backends (ephemeral, SQLite, PostgreSQL) and optional Redis messaging
- **PrefectWorkPool**: Manages Prefect work pools for different execution environments (Kubernetes, process-based, external)
- **PrefectDeployment**: Manages Prefect deployments (not Kubernetes ones) of Python flows

### Key Components

- **Controllers** (`internal/controller/`): Reconciliation logic for CRDs
- **API Types** (`api/v1/`): CRD definitions and helper methods
- **Utils** (`internal/utils/`): Hash utilities for detecting resource changes
- **Conditions** (`internal/conditions/`): Status condition management
- **Constants** (`internal/constants/`): Shared constants

### Deployment Architecture

- Main controller runs as a deployment in cluster
- Uses controller-runtime for Kubernetes API interactions
- Supports namespace-scoped operation via `WATCH_NAMESPACES` env var
- Health checks on `:8081`, metrics on `:8080`
- Leader election enabled for HA deployments

### Storage Backend Configuration

PrefectServer supports three storage modes:

1. **Ephemeral**: In-memory SQLite (no persistence)
2. **SQLite**: Persistent SQLite with PVC storage
3. **PostgreSQL**: External PostgreSQL database with connection details

Each backend generates appropriate environment variables for the Prefect server container.

### Testing Strategy

- Unit tests use Ginkgo/Gomega with envtest for Kubernetes API simulation
- E2E tests require actual Kubernetes cluster
- Coverage includes API types, controllers, and utilities
- Tests run against Kubernetes v1.29.0 via envtest

The typically manual testing approach is to run a local cluster like `minikube`
and run the `prefect-operator` locally pointing to that cluster. That means
that for many testing scenarios, we can't assume that the operator is running
in the same cluster it is operating on. Use port-forwarding where appropriate
to support these cases.

### Code Generation Workflow

The operator uses controller-gen for:

- CRD generation from Go types → `deploy/charts/prefect-operator/crds/`
- DeepCopy method generation for all API types
- RBAC manifest generation

Always run `make manifests generate` after modifying API types in `api/v1/`.
1 change: 1 addition & 0 deletions CLAUDE.md
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ manifests: tools ## Generate WebhookConfiguration, ClusterRole and CustomResourc
.PHONY: generate
generate: tools ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
@echo "Adding coverage ignore directive to generated files..."
@sed -i '1a\\n//go:coverage ignore' api/v1/zz_generated.deepcopy.go

.PHONY: fmt
fmt: ## Run go fmt against code.
Expand Down Expand Up @@ -139,6 +141,7 @@ run: manifests generate fmt vet ## Run a controller from your host.
docs: tools
crdoc --resources deploy/charts/prefect-operator/crds/prefect.io_prefectservers.yaml --output PrefectServer.md
crdoc --resources deploy/charts/prefect-operator/crds/prefect.io_prefectworkpools.yaml --output PrefectWorkPool.md
crdoc --resources deploy/charts/prefect-operator/crds/prefect.io_prefectdeployments.yaml --output PrefectDeployment.md

# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
Expand Down
Loading