Skip to content

Commit 65fe4b5

Browse files
Codex Automationkimpenhaus
andcommitted
feat: add Aspire integration for KubeOps operators
Add Aspire service defaults, AppHost hosting integration, Kubernetes run/publish support, examples, tests, and docs for local, Azure, and standalone publish scenarios. Co-authored-by: Marcus Kimpenhaus <kimpenhaus@devil-engineering.de>
1 parent cbaaac5 commit 65fe4b5

32 files changed

Lines changed: 2507 additions & 8 deletions

KubeOps.slnx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<Solution>
22
<Folder Name="/examples/">
3+
<Project Path="examples\AspireAppHost\AspireAppHost.csproj" />
4+
<Project Path="examples\AspireOperator\AspireOperator.csproj" />
35
<Project Path="examples\ConversionWebhookOperator\ConversionWebhookOperator.csproj" />
46
<Project Path="examples\Operator\Operator.csproj" />
57
<Project Path="examples\WebhookOperator\WebhookOperator.csproj" />
@@ -29,6 +31,8 @@
2931
</Folder>
3032
<Folder Name="/src/">
3133
<Project Path="src\KubeOps.Abstractions\KubeOps.Abstractions.csproj" />
34+
<Project Path="src\KubeOps.Aspire.Hosting\KubeOps.Aspire.Hosting.csproj" />
35+
<Project Path="src\KubeOps.Aspire\KubeOps.Aspire.csproj" />
3236
<Project Path="src\KubeOps.Cli\KubeOps.Cli.csproj" />
3337
<Project Path="src\KubeOps.Generator\KubeOps.Generator.csproj" />
3438
<Project Path="src\KubeOps.KubernetesClient\KubeOps.KubernetesClient.csproj" />
@@ -41,6 +45,8 @@
4145
<Folder Name="/test/">
4246
<Project Path="test/KubeOps.Generator.Test.Entities/KubeOps.Generator.Test.Entities.csproj" />
4347
<Project Path="test\KubeOps.Abstractions.Test\KubeOps.Abstractions.Test.csproj" />
48+
<Project Path="test\KubeOps.Aspire.Hosting.Test\KubeOps.Aspire.Hosting.Test.csproj" />
49+
<Project Path="test\KubeOps.Aspire.Test\KubeOps.Aspire.Test.csproj" />
4450
<Project Path="test\KubeOps.Cli.Test\KubeOps.Cli.Test.csproj" />
4551
<Project Path="test\KubeOps.Generator.Test\KubeOps.Generator.Test.csproj" />
4652
<Project Path="test\KubeOps.KubernetesClient.Test\KubeOps.KubernetesClient.Test.csproj" />
@@ -49,4 +55,4 @@
4955
<Project Path="test\KubeOps.Transpiler.Test\KubeOps.Transpiler.Test.csproj" />
5056
<File Path="test\Directory.Build.props" />
5157
</Folder>
52-
</Solution>
58+
</Solution>

README.md

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,115 @@ There are two ways to start building an operator with KubeOps:
4848
cd MyOperator
4949
```
5050

51-
The template approach (`dotnet new operator`) scaffolds a basic operator structure with a sample custom resource, controller, and finalizer, so it is the quickest way to get started. The plain console approach gives you an empty project that you build up manually by adding the `KubeOps.Operator` package. In either case, the [`kubeops` CLI tool](./src/KubeOps.Cli/README.md) provides additional commands for generating CRDs, RBAC rules, and more.
51+
Both methods generate a basic operator structure with a sample custom resource, controller, and finalizer. The template approach is simpler and more direct, while the CLI provides additional commands for generating CRDs, RBAC rules, and more.
5252

5353
For detailed tutorials and guides, visit the [KubeOps Documentation Site](https://dotnet.github.io/dotnet-operator-sdk/).
5454

55+
## Aspire Quickstart
56+
57+
KubeOps can be used as a first-class resource in a [.NET Aspire](https://learn.microsoft.com/dotnet/aspire/) AppHost. Add `KubeOps.Aspire.Hosting` to the AppHost and `KubeOps.Aspire` to the operator project.
58+
59+
The repository keeps this in a dedicated `examples/AspireOperator` project so the plain `examples/Operator` sample remains a non-Aspire KubeOps operator.
60+
61+
In the operator project, register the service defaults after the operator:
62+
63+
```csharp
64+
using KubeOps.Aspire;
65+
using KubeOps.Operator;
66+
67+
var builder = Host.CreateApplicationBuilder(args);
68+
69+
builder.Services
70+
.AddKubernetesOperator()
71+
.RegisterComponents();
72+
73+
builder.AddKubeOpsServiceDefaults();
74+
75+
await builder.Build().RunAsync();
76+
```
77+
78+
In the AppHost, add the operator and choose whether it should run locally, publish to Kubernetes, or both:
79+
80+
```csharp
81+
var builder = DistributedApplication.CreateBuilder(args);
82+
83+
var k8s = builder.AddKubernetesEnvironment("k8s")
84+
.WithHelm(helm =>
85+
{
86+
helm.WithChartName("my-operator");
87+
helm.WithReleaseName("my-operator");
88+
helm.WithNamespace("operator-system");
89+
});
90+
91+
builder.AddKubeOps<Projects.AspireOperator>("operator")
92+
.RunWithKubernetes(k8s)
93+
.PublishAsKubernetesOperator(k8s);
94+
95+
builder.Build().Run();
96+
```
97+
98+
Run and publish with the Aspire CLI:
99+
100+
```bash
101+
aspire run --project src/MyApp.AppHost/MyApp.AppHost.csproj
102+
aspire publish --project src/MyApp.AppHost/MyApp.AppHost.csproj --output-path ./artifacts/k8s
103+
```
104+
105+
Common AppHost shapes:
106+
107+
Local development only:
108+
109+
```csharp
110+
var dev = builder.AddKubernetesEnvironment("dev");
111+
112+
builder.AddKubeOps<Projects.AspireOperator>("operator")
113+
.RunWithKubernetes(dev, run => run.WithPersistentCrds());
114+
```
115+
116+
Azure publish/deploy only:
117+
118+
```csharp
119+
var aks = builder.AddAzureKubernetesEnvironment("aks");
120+
121+
builder.AddKubeOps<Projects.AspireOperator>("operator")
122+
.PublishAsKubernetesOperator(aks, publish => publish.WithServiceAccount("operator"));
123+
```
124+
125+
Local run and Azure deploy:
126+
127+
```csharp
128+
var dev = builder.AddKubernetesEnvironment("dev");
129+
var aks = builder.AddAzureKubernetesEnvironment("aks");
130+
131+
builder.AddKubeOps<Projects.AspireOperator>("operator")
132+
.RunWithKubernetes(dev)
133+
.PublishAsKubernetesOperator(aks);
134+
```
135+
136+
Publish only without an Aspire Kubernetes environment:
137+
138+
```csharp
139+
builder.AddKubeOps<Projects.AspireOperator>("operator")
140+
.PublishAsKubernetesOperator(publish =>
141+
{
142+
publish.Namespace = "operator-system";
143+
publish.WithServiceAccount("operator");
144+
});
145+
```
146+
147+
Without `RunWithKubernetes(...)`, `AddKubeOps<TProject>(...)` keeps the operator in explicit-start mode for local Aspire runs. Standalone manifest publish does not require `AddKubernetesEnvironment(...)`, Helm, or a live cluster; publishing with a Kubernetes environment generates an Aspire Helm chart, while `aspire deploy` installs that chart into the selected environment.
148+
55149
## Packages
56150
57-
The runtime libraries target [.NET 8.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview), [.NET 9.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/overview), and [.NET 10.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview), leveraging modern C# features. The build-time packages (`KubeOps.Generator` and `KubeOps.Templates`) target [.NET Standard 2.0](https://learn.microsoft.com/en-us/dotnet/standard/net-standard) for broad tooling compatibility. The underlying Kubernetes client library (`KubernetesClient`) is referenced for interacting with the Kubernetes API.
151+
All packages target [.NET 8.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8/overview) and [.NET 9.0](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/overview), leveraging modern C# features. The underlying Kubernetes client library (`KubernetesClient.Official`) also follows this versioning strategy.
58152
59153
The SDK is designed to be modular. You can include only the packages you need:
60154
61155
| Package | Description |
62156
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63157
| [KubeOps.Abstractions](./src/KubeOps.Abstractions/README.md) | Defines core interfaces, attributes (like `[KubernetesEntity]`), and base classes used across the SDK. Essential for defining your custom resources and controllers. |
158+
| [KubeOps.Aspire](./src/KubeOps.Aspire/README.md) | [.NET Aspire](https://learn.microsoft.com/dotnet/aspire/) service defaults for an operator: a single `AddKubeOpsServiceDefaults()` call wiring up OpenTelemetry, service discovery, HTTP resilience, and health checks. |
159+
| [KubeOps.Aspire.Hosting](./src/KubeOps.Aspire.Hosting/README.md) | [.NET Aspire](https://learn.microsoft.com/dotnet/aspire/) hosting integration. Adds `AddKubeOps<TProject>(...)` so a KubeOps operator can be orchestrated as a resource inside an Aspire AppHost. |
64160
| [KubeOps.Cli](./src/KubeOps.Cli/README.md) | A [.NET Tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools) providing commands for scaffolding projects, generating [Custom Resource Definitions (CRDs)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/), and more. |
65161
| [KubeOps.Generator](./src/KubeOps.Generator/README.md) | Contains [Roslyn Source Generators](https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) to automate boilerplate code generation for CRDs and controllers based on your definitions. |
66162
| [KubeOps.KubernetesClient](./src/KubeOps.KubernetesClient/README.md) | Provides an enhanced client for interacting with the [Kubernetes API](https://kubernetes.io/docs/reference/kubernetes-api/), built on top of the official `KubernetesClient` library. Offers convenience methods for common operator tasks. |
@@ -71,11 +167,7 @@ The SDK is designed to be modular. You can include only the packages you need:
71167
72168
## Examples
73169
74-
You can find various example operators demonstrating different features in the [`examples/`](https://github.com/dotnet/dotnet-operator-sdk/tree/main/examples/) directory of this repository:
75-
76-
- [`Operator`](./examples/Operator) - A minimal operator with an entity, controller, and finalizer.
77-
- [`WebhookOperator`](./examples/WebhookOperator) - Demonstrates validating and mutating admission webhooks.
78-
- [`ConversionWebhookOperator`](./examples/ConversionWebhookOperator) - Demonstrates converting between entity versions with a conversion webhook.
170+
You can find various example operators demonstrating different features in the [`examples/`](https://github.com/dotnet/dotnet-operator-sdk/tree/main/examples/) directory of this repository.
79171
80172
## License
81173

0 commit comments

Comments
 (0)