Development Guide
Prerequisites
Section titled “Prerequisites”| Tool | Version | Notes |
|---|---|---|
| .NET SDK | 10.0+ | Download |
| Docker | Any recent | For building images |
| kubectl | Cluster-matching | Download |
| Helm | 3.14+ | For chart work |
| Bun | 1.3+ | Install — docs site only |
| A Kubernetes cluster | 1.25+ | kind/k3d/Docker Desktop work well |
Optional but useful:
- kind or k3d for a local cluster
- k9s for cluster introspection
- A C# IDE (Rider, Visual Studio, VS Code with C# Dev Kit)
Repository setup
Section titled “Repository setup”git clone https://github.com/danihengeveld/mc-operator.gitcd mc-operator
# Restore .NET tool chaindotnet tool restore
# Restore NuGet packagesdotnet restore mc-operator.slnxRunning tests
Section titled “Running tests”Tests use TUnit and run via dotnet run:
# Run all testsdotnet run --project src/McOperator.Tests/
# Run a specific test classdotnet run --project src/McOperator.Tests/ -- \ --treenode-filter "*/*/ValidationWebhookTests/*"Tests cover:
- Webhook validation logic (
ValidationWebhookTests) - Memory parsing helpers (
MemoryParsingTests) - StatefulSet builder output (
StatefulSetBuilderTests) - Service builder output (
ServiceBuilderTests) - ConfigMap builder output (
ConfigMapBuilderTests)
Running the operator locally
Section titled “Running the operator locally”The operator runs as a standard ASP.NET Core application and uses the active kubeconfig to connect to Kubernetes:
# Apply the CRD to your local clusterkubectl apply -f manifests/crd/minecraftservers.yaml
# Apply RBACkubectl apply -f manifests/rbac/
# Run the operator (watches the current kubeconfig context)dotnet run --project src/McOperator/ -- --environment DevelopmentBuilding the Docker image
Section titled “Building the Docker image”docker build -t ghcr.io/danihengeveld/mc-operator:dev .
# Test the imagedocker run --rm ghcr.io/danihengeveld/mc-operator:dev --helpRegenerating CRDs and manifests
Section titled “Regenerating CRDs and manifests”After changing the CRD entity classes, regenerate the YAML manifests:
# Install KubeOps CLI (if not already installed)dotnet tool restore
# Regenerate all manifestsdotnet kubeops generate operator "mc-operator" \ src/McOperator/McOperator.csproj \ --out manifests/ \ --docker-image "ghcr.io/danihengeveld/mc-operator" \ --docker-image-tag "latest"Always review generated changes before committing — the generator may produce diffs in formatting or ordering that are worth cleaning up.
Project structure
Section titled “Project structure”src/├── McOperator/│ ├── Builders/ # StatefulSetBuilder, ServiceBuilder, ConfigMapBuilder│ ├── Controllers/ # MinecraftServerController (reconciler)│ ├── Entities/ # MinecraftServer, MinecraftServerSpec, MinecraftServerStatus│ ├── Extensions/ # MinecraftServerExtensions (owner reference helper)│ ├── Finalizers/ # MinecraftServerFinalizer (PVC cleanup)│ ├── Webhooks/ # MinecraftServerValidationWebhook, MinecraftServerMutationWebhook│ └── Program.cs # Startup and DI registration└── McOperator.Tests/ ├── ConfigMapBuilderTests.cs ├── MemoryParsingTests.cs ├── ServiceBuilderTests.cs ├── StatefulSetBuilderTests.cs └── ValidationWebhookTests.csCoding conventions
Section titled “Coding conventions”- Language: C# 13 with nullable reference types enabled
- Framework: .NET 10, ASP.NET Core minimal hosting
- Tests: TUnit (
[Test],[Arguments],await Assert.That(...)) - Formatting: Standard C# conventions; see
.editorconfigat the repo root - Packages: All NuGet versions centralized in
Directory.Packages.props - Build props: All shared MSBuild properties in
Directory.Build.props
Adding a new spec field
Section titled “Adding a new spec field”- Add the field to the relevant class in
src/McOperator/Entities/MinecraftServerSpec.cs - If it maps to an environment variable, add it in
StatefulSetBuilder.cs - If it needs validation, add it in
MinecraftServerValidationWebhook.cs - If it has a default, add it in
MinecraftServerMutationWebhook.cs - Add/update tests
- Regenerate CRD YAML
- Update the CRD reference docs
Common tasks
Section titled “Common tasks”Inspect the effective spec after mutation
Section titled “Inspect the effective spec after mutation”kubectl get minecraftserver <name> -n minecraft -o yamlThe mutating webhook runs before the resource is stored, so the stored spec reflects all applied defaults.
Check webhook call logs
Section titled “Check webhook call logs”The operator logs all webhook invocations at Information level. Look for ValidationWebhook or MutationWebhook in the operator pod logs.
Debug reconcile loops
Section titled “Debug reconcile loops”kubectl logs -n mc-operator-system -l app.kubernetes.io/name=mc-operator -fLook for lines containing Reconciling to trace individual reconcile cycles.