Skip to content

Commit d14a95e

Browse files
committed
chore: add running example operator
1 parent 8c080e8 commit d14a95e

File tree

12 files changed

+200
-3
lines changed

12 files changed

+200
-3
lines changed

.config/dotnet-tools.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
"docfx": {
66
"version": "2.71.0",
77
"commands": ["docfx"]
8+
},
9+
"kubeops.cli": {
10+
"version": "8.0.0-pre.16",
11+
"commands": ["kubeops"]
812
}
913
}
1014
}

KubeOps.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubeOps.KubernetesClient",
5353
EndProject
5454
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubeOps.KubernetesClient.Test", "test\KubeOps.KubernetesClient.Test\KubeOps.KubernetesClient.Test.csproj", "{25F767E5-7A74-459B-83CC-39519461F38B}"
5555
EndProject
56+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserConfigOperator", "examples\UserConfigOperator\UserConfigOperator.csproj", "{032A7FE0-EDFD-4959-9618-B3A911B163F0}"
57+
EndProject
5658
Global
5759
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5860
Debug|Any CPU = Debug|Any CPU
@@ -76,6 +78,7 @@ Global
7678
{A793FC08-E76C-448B-BE93-88C137D2C7AB} = {4DB01062-6DC5-4028-BB72-C0619C2F5F2E}
7779
{C2C6FF06-2B9D-4FAC-A039-3DC1E007DE3B} = {4DB01062-6DC5-4028-BB72-C0619C2F5F2E}
7880
{25F767E5-7A74-459B-83CC-39519461F38B} = {C587731F-8191-4A19-8662-B89A60FE79A1}
81+
{032A7FE0-EDFD-4959-9618-B3A911B163F0} = {DC760E69-D0EA-417F-AE38-B12D0B04DE39}
7982
EndGlobalSection
8083
GlobalSection(ProjectConfigurationPlatforms) = postSolution
8184
{E9A0B04E-D90E-4B94-90E0-DD3666B098FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -134,5 +137,9 @@ Global
134137
{25F767E5-7A74-459B-83CC-39519461F38B}.Debug|Any CPU.Build.0 = Debug|Any CPU
135138
{25F767E5-7A74-459B-83CC-39519461F38B}.Release|Any CPU.ActiveCfg = Release|Any CPU
136139
{25F767E5-7A74-459B-83CC-39519461F38B}.Release|Any CPU.Build.0 = Release|Any CPU
140+
{032A7FE0-EDFD-4959-9618-B3A911B163F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
141+
{032A7FE0-EDFD-4959-9618-B3A911B163F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
142+
{032A7FE0-EDFD-4959-9618-B3A911B163F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
143+
{032A7FE0-EDFD-4959-9618-B3A911B163F0}.Release|Any CPU.Build.0 = Release|Any CPU
137144
EndGlobalSection
138145
EndGlobal

examples/Operator/Operator.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<ProjectReference Include="..\..\src\KubeOps.Abstractions\KubeOps.Abstractions.csproj"/>
1413
<ProjectReference Include="..\..\src\KubeOps.Operator\KubeOps.Operator.csproj"/>
1514
<ProjectReference Include="..\..\src\KubeOps.Generator\KubeOps.Generator.csproj"
1615
OutputItemType="Analyzer"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using k8s;
2+
using k8s.Models;
3+
4+
using KubeOps.Abstractions.Controller;
5+
using KubeOps.Abstractions.Rbac;
6+
using KubeOps.KubernetesClient;
7+
8+
using Microsoft.Extensions.Logging;
9+
10+
using UserConfigOperator.Entities;
11+
12+
namespace UserConfigOperator.Controller;
13+
14+
[EntityRbac(typeof(V1UserConfig), typeof(V1ConfigMap), Verbs = RbacVerb.All)]
15+
public class V1UserConfigController : IEntityController<V1UserConfig>
16+
{
17+
private readonly ILogger<V1UserConfigController> _logger;
18+
private readonly IKubernetesClient<V1ConfigMap> _client;
19+
20+
public V1UserConfigController(
21+
ILogger<V1UserConfigController> logger,
22+
IKubernetesClient<V1ConfigMap> client)
23+
{
24+
_logger = logger;
25+
_client = client;
26+
}
27+
28+
public async Task ReconcileAsync(V1UserConfig entity)
29+
{
30+
var config = await _client.GetAsync(entity.Name());
31+
if (config is not null)
32+
{
33+
_logger.LogInformation("Config with name {name} already exists.", entity.Name());
34+
return;
35+
}
36+
37+
var configMap = new V1ConfigMap(metadata: new(name: entity.Name(), namespaceProperty: entity.Namespace()))
38+
.Initialize();
39+
configMap.AddOwnerReference(new(
40+
entity.ApiVersion,
41+
entity.Kind,
42+
entity.Metadata.Name,
43+
entity.Metadata.Uid));
44+
await _client.CreateAsync(configMap);
45+
_logger.LogInformation("Config with name {name} created.", entity.Name());
46+
}
47+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using k8s.Models;
2+
3+
using KubeOps.Abstractions.Entities;
4+
using KubeOps.Abstractions.Entities.Attributes;
5+
6+
namespace UserConfigOperator.Entities;
7+
8+
[KubernetesEntity(Kind = "UserConfig", ApiVersion = "v1", Group = "demo-operators.io")]
9+
public partial class V1UserConfig : CustomKubernetesEntity<V1UserConfig.EntitySpec>
10+
{
11+
public class EntitySpec
12+
{
13+
[Required]
14+
public string Username { get; set; } = string.Empty;
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using k8s.Models;
2+
3+
using KubeOps.Operator;
4+
5+
using Microsoft.Extensions.Hosting;
6+
using Microsoft.Extensions.Logging;
7+
8+
var builder = Host.CreateApplicationBuilder(args);
9+
10+
builder.Logging.SetMinimumLevel(LogLevel.Trace);
11+
12+
builder.Services
13+
.AddKubernetesOperator()
14+
.RegisterComponents()
15+
.AddEntity<V1ConfigMap>(
16+
new(
17+
V1ConfigMap.KubeKind,
18+
V1ConfigMap.KubeApiVersion,
19+
V1ConfigMap.KubeGroup,
20+
V1ConfigMap.KubePluralName));
21+
22+
using var host = builder.Build();
23+
await host.RunAsync();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"UserConfigOperator": {
5+
"commandName": "Project"
6+
}
7+
}
8+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# KubeOps Demo Operator
2+
3+
This is a demo operator for the KubeOps framework. It is a simple operator that
4+
creates a `Config Map` object for each `V1UserConfig` object.
5+
6+
To run the operator, build the project such that the required installer objects
7+
are generated with the dotnet tool. Then, build the docker image and install
8+
the operator on your cluster.
9+
10+
If you use Docker for Desktop with the Kubernetes extension, you
11+
can just build the image and then use "imagePullPolicy: Never".
12+
13+
A running example on Docker for Desktop looks like this:
14+
15+
1. Build the project locally with the dotnet tool `KubeOps.Cli` installed
16+
2. Build the docker image with `docker build -t kubeops-demo-operator:latest .`
17+
3. Add the imagePullPolicy patch to the created `kustomization.yaml` in the config dir
18+
```yaml
19+
patches:
20+
- target:
21+
kind: Deployment
22+
labelSelector: operator-deployment=kubernetes-operator
23+
patch: |-
24+
- op: add
25+
path: /spec/template/spec/containers/0/imagePullPolicy
26+
value: Never
27+
```
28+
4. Set the image correctly in the `kustomization.yaml`
29+
```yaml
30+
images:
31+
- name: operator
32+
newName: kubeops-demo-operator
33+
newTag: latest
34+
```
35+
5. Install the operator locally with `kustomize build config | kubectl apply -f -`
36+
37+
This should install the operator in your cluster. Now when you
38+
apply the test entity (with `kubectl apply -f test_entity.yaml`)
39+
a config map should be created.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<IsPackable>false</IsPackable>
9+
<GenerateDocumentationFile>false</GenerateDocumentationFile>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="KubeOps.Generator" Version="8.0.0-pre.16" />
14+
<PackageReference Include="KubeOps.Operator" Version="8.0.0-pre.16" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: demo-operators.io/v1
2+
kind: UserConfig
3+
metadata:
4+
name: demo-user
5+
spec:
6+
username: my user

0 commit comments

Comments
 (0)