diff --git a/K8sOperator.NET.slnx b/K8sOperator.NET.slnx
index e172296..1ceea1e 100644
--- a/K8sOperator.NET.slnx
+++ b/K8sOperator.NET.slnx
@@ -3,6 +3,7 @@
+
diff --git a/examples/SimpleOperator/Program.cs b/examples/SimpleOperator/Program.cs
index 6d80422..c57ba4e 100644
--- a/examples/SimpleOperator/Program.cs
+++ b/examples/SimpleOperator/Program.cs
@@ -6,8 +6,7 @@
builder.Services.AddOperator(x =>
{
- //x.WithLeaderElection();
-
+ x.WithLeaderElection();
});
var app = builder.Build();
diff --git a/examples/SimpleOperator/Properties/launchSettings.json b/examples/SimpleOperator/Properties/launchSettings.json
index bda3e33..cdcab8f 100644
--- a/examples/SimpleOperator/Properties/launchSettings.json
+++ b/examples/SimpleOperator/Properties/launchSettings.json
@@ -1,24 +1,16 @@
{
"profiles": {
- "Help": {
+ "Operator": {
"commandName": "Project",
- "commandLineArgs": "help",
+ "commandLineArgs": "operator",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
- "Operator": {
- "commandName": "Project",
- "commandLineArgs": "operator",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "dotnetRunMessages": true
- },
"Install": {
"commandName": "Project",
- "commandLineArgs": "install",
+ "commandLineArgs": "install > install.yaml",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
@@ -32,30 +24,14 @@
},
"dotnetRunMessages": true
},
- "Create": {
- "commandName": "Project",
- "commandLineArgs": "create",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "dotnetRunMessages": true
- },
- "GenerateLaunchsettings": {
- "commandName": "Project",
- "commandLineArgs": "generate-launchsettings",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "dotnetRunMessages": true
- },
- "GenerateDockerfile": {
+ "Help": {
"commandName": "Project",
- "commandLineArgs": "generate-dockerfile",
+ "commandLineArgs": "help",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
}
},
- "schema": "http://json.schemastore.org/launchsettings.json"
+ "$schema": "http://json.schemastore.org/launchsettings.json"
}
diff --git a/examples/SimpleOperator/SimpleOperator.csproj b/examples/SimpleOperator/SimpleOperator.csproj
index 712f7b1..2bea637 100644
--- a/examples/SimpleOperator/SimpleOperator.csproj
+++ b/examples/SimpleOperator/SimpleOperator.csproj
@@ -16,10 +16,10 @@
simple-operator
simple-system
-
+
alpha
diff --git a/src/K8sOperator.NET.BuildTasks/GenerateDockerfileTask.cs b/src/K8sOperator.NET.BuildTasks/GenerateDockerfileTask.cs
new file mode 100644
index 0000000..0afc061
--- /dev/null
+++ b/src/K8sOperator.NET.BuildTasks/GenerateDockerfileTask.cs
@@ -0,0 +1,110 @@
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.IO;
+using System.Text.RegularExpressions;
+
+namespace K8sOperator.NET.BuildTasks;
+
+public class GenerateDockerfileTask : Task
+{
+ [Required]
+ public string ProjectDirectory { get; set; } = string.Empty;
+
+ [Required]
+ public string ProjectName { get; set; } = string.Empty;
+
+ [Required]
+ public string TargetFramework { get; set; } = string.Empty;
+
+ [Required]
+ public string OperatorName { get; set; } = string.Empty;
+
+ [Required]
+ public string ContainerRegistry { get; set; } = string.Empty;
+
+ [Required]
+ public string ContainerRepository { get; set; } = string.Empty;
+
+ [Required]
+ public string ContainerTag { get; set; } = string.Empty;
+
+ public override bool Execute()
+ {
+ try
+ {
+ var dockerfilePath = Path.Combine(ProjectDirectory, "Dockerfile");
+ var dockerignorePath = Path.Combine(ProjectDirectory, ".dockerignore");
+
+ // Extract .NET version from TargetFramework
+ var dotnetVersion = ExtractDotNetVersion(TargetFramework);
+
+ // Read templates from embedded resources
+ var dockerfileContent = ReadEmbeddedResource("Dockerfile.template");
+ var dockerignoreContent = ReadEmbeddedResource(".dockerignore.template");
+
+ // Replace placeholders
+ dockerfileContent = dockerfileContent
+ .Replace("{PROJECT_NAME}", ProjectName)
+ .Replace("{DOTNET_VERSION}", dotnetVersion);
+
+ if (!File.Exists(dockerfilePath))
+ {
+ File.WriteAllText(dockerfilePath, dockerfileContent);
+
+ Log.LogMessage(MessageImportance.High, $"Generated Dockerfile at: {dockerfilePath}");
+
+ }
+
+ if (!File.Exists(dockerignorePath))
+ {
+ File.WriteAllText(dockerignorePath, dockerignoreContent);
+
+ Log.LogMessage(MessageImportance.High, $"Generated .dockerignore at: {dockerignorePath}");
+ }
+
+ // Log success
+ Log.LogMessage(MessageImportance.High, $"Operator: {OperatorName}");
+ Log.LogMessage(MessageImportance.High, $" .NET Version: {dotnetVersion}");
+ Log.LogMessage(MessageImportance.High, $" Image: {ContainerRegistry}/{ContainerRepository}:{ContainerTag}");
+ Log.LogMessage(MessageImportance.High, "");
+ Log.LogMessage(MessageImportance.High, "To build the image:");
+ Log.LogMessage(MessageImportance.High, $" docker build -t {ContainerRegistry}/{ContainerRepository}:{ContainerTag} .");
+ Log.LogMessage(MessageImportance.High, "");
+ Log.LogMessage(MessageImportance.High, "To push the image:");
+ Log.LogMessage(MessageImportance.High, $" docker push {ContainerRegistry}/{ContainerRepository}:{ContainerTag}");
+ Log.LogMessage(MessageImportance.High, "");
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.LogError($"Failed to generate Dockerfile: {ex.Message}");
+ return false;
+ }
+ }
+
+ private static string ExtractDotNetVersion(string targetFramework)
+ {
+ // Handle formats like "net10.0", "net8.0", "netcoreapp3.1"
+ var match = Regex.Match(targetFramework, @"net(?:coreapp)?(\d+\.\d+)");
+ if (match.Success)
+ {
+ return match.Groups[1].Value;
+ }
+
+ // Fallback
+ return "10.0";
+ }
+
+ private static string ReadEmbeddedResource(string resourceName)
+ {
+ var assembly = typeof(GenerateDockerfileTask).Assembly;
+ var fullResourceName = $"K8sOperator.NET.BuildTasks.Templates.{resourceName}";
+
+ using var stream = assembly.GetManifestResourceStream(fullResourceName)
+ ?? throw new InvalidOperationException($"Could not find embedded resource: {fullResourceName}");
+ using var reader = new StreamReader(stream);
+ return reader.ReadToEnd();
+ }
+}
diff --git a/src/K8sOperator.NET.BuildTasks/GenerateLaunchSettingsTask.cs b/src/K8sOperator.NET.BuildTasks/GenerateLaunchSettingsTask.cs
new file mode 100644
index 0000000..536310f
--- /dev/null
+++ b/src/K8sOperator.NET.BuildTasks/GenerateLaunchSettingsTask.cs
@@ -0,0 +1,62 @@
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.IO;
+
+namespace K8sOperator.NET.BuildTasks;
+
+public class GenerateLaunchSettingsTask : Task
+{
+ [Required]
+ public string ProjectDirectory { get; set; } = string.Empty;
+
+ public override bool Execute()
+ {
+ try
+ {
+ var propertiesDir = Path.Combine(ProjectDirectory, "Properties");
+ var launchSettingsPath = Path.Combine(propertiesDir, "launchSettings.json");
+
+ if (File.Exists(launchSettingsPath))
+ {
+ Log.LogMessage(MessageImportance.Normal, $"launchSettings.json already exists at {launchSettingsPath}, skipping generation");
+ return true;
+ }
+
+ // Read template from embedded resources
+ var launchSettingsContent = ReadEmbeddedResource("launchSettings.json.template");
+
+ // Create Properties directory if needed
+ Directory.CreateDirectory(propertiesDir);
+
+ // Write launchSettings.json
+ File.WriteAllText(launchSettingsPath, launchSettingsContent);
+
+ // Log success
+ Log.LogMessage(MessageImportance.High, "");
+ Log.LogMessage(MessageImportance.High, $"Generated launchSettings.json at: {launchSettingsPath}");
+ Log.LogMessage(MessageImportance.High, $" Profiles: Operator, Install, Version, Help");
+ Log.LogMessage(MessageImportance.High, "");
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.LogError($"Failed to generate launchSettings.json: {ex.Message}");
+ return false;
+ }
+ }
+
+ private static string ReadEmbeddedResource(string resourceName)
+ {
+ var assembly = typeof(GenerateLaunchSettingsTask).Assembly;
+ var fullResourceName = $"K8sOperator.NET.BuildTasks.Templates.{resourceName}";
+
+ using var stream = assembly.GetManifestResourceStream(fullResourceName)
+ ?? throw new InvalidOperationException($"Could not find embedded resource: {fullResourceName}");
+ using var reader = new StreamReader(stream);
+ return reader.ReadToEnd();
+ }
+}
+
+
diff --git a/src/K8sOperator.NET.BuildTasks/K8sOperator.NET.BuildTasks.csproj b/src/K8sOperator.NET.BuildTasks/K8sOperator.NET.BuildTasks.csproj
new file mode 100644
index 0000000..8f501c7
--- /dev/null
+++ b/src/K8sOperator.NET.BuildTasks/K8sOperator.NET.BuildTasks.csproj
@@ -0,0 +1,24 @@
+
+
+
+ netstandard2.0
+ latest
+ enable
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/K8sOperator.NET/Templates/.dockerignore.template b/src/K8sOperator.NET.BuildTasks/Templates/.dockerignore.template
similarity index 100%
rename from src/K8sOperator.NET/Templates/.dockerignore.template
rename to src/K8sOperator.NET.BuildTasks/Templates/.dockerignore.template
diff --git a/src/K8sOperator.NET/Templates/Dockerfile.template b/src/K8sOperator.NET.BuildTasks/Templates/Dockerfile.template
similarity index 100%
rename from src/K8sOperator.NET/Templates/Dockerfile.template
rename to src/K8sOperator.NET.BuildTasks/Templates/Dockerfile.template
diff --git a/src/K8sOperator.NET.BuildTasks/Templates/launchSettings.json.template b/src/K8sOperator.NET.BuildTasks/Templates/launchSettings.json.template
new file mode 100644
index 0000000..cdcab8f
--- /dev/null
+++ b/src/K8sOperator.NET.BuildTasks/Templates/launchSettings.json.template
@@ -0,0 +1,37 @@
+{
+ "profiles": {
+ "Operator": {
+ "commandName": "Project",
+ "commandLineArgs": "operator",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true
+ },
+ "Install": {
+ "commandName": "Project",
+ "commandLineArgs": "install > install.yaml",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true
+ },
+ "Version": {
+ "commandName": "Project",
+ "commandLineArgs": "version",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true
+ },
+ "Help": {
+ "commandName": "Project",
+ "commandLineArgs": "help",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json"
+}
diff --git a/src/K8sOperator.NET/Builder/ControllerBuilder.cs b/src/K8sOperator.NET/Builder/ControllerBuilder.cs
index 4c04173..e5a6b3d 100644
--- a/src/K8sOperator.NET/Builder/ControllerBuilder.cs
+++ b/src/K8sOperator.NET/Builder/ControllerBuilder.cs
@@ -1,20 +1,22 @@
-using Microsoft.Extensions.DependencyInjection;
+using K8sOperator.NET.Configuration;
+using Microsoft.Extensions.DependencyInjection;
namespace K8sOperator.NET.Builder;
public class ControllerBuilder
{
- private ControllerBuilder(IServiceProvider serviceProvider, Type controllerType, List