From e3b88652fb9cd0347597ce2b962aa17ececbc416 Mon Sep 17 00:00:00 2001 From: RobE Date: Fri, 9 Jan 2026 14:18:40 +1000 Subject: [PATCH] Make running K8S Agent locally a little easier --- .../Kubernetes/KubernetesConfig.cs | 2 + ...alMachineKubernetesClientConfigProvider.cs | 43 ++++++++++++------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs index b29218fa1..f3985bf6d 100644 --- a/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs +++ b/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs @@ -10,6 +10,8 @@ public static class KubernetesConfig const string ServerCommsAddressVariableName = "ServerCommsAddress"; const string EnvVarPrefix = "OCTOPUS__K8STENTACLE"; + public static string KubeContextVariableName = $"{EnvVarPrefix}__KUBECONTEXT"; + public static string NamespaceVariableName => $"{EnvVarPrefix}__NAMESPACE"; public static string Namespace => GetRequiredEnvVar(NamespaceVariableName, "Unable to determine Kubernetes namespace."); public static string PodServiceAccountName => GetRequiredEnvVar($"{EnvVarPrefix}__PODSERVICEACCOUNTNAME", "Unable to determine Kubernetes Pod service account name."); diff --git a/source/Octopus.Tentacle/Kubernetes/LocalMachineKubernetesClientConfigProvider.cs b/source/Octopus.Tentacle/Kubernetes/LocalMachineKubernetesClientConfigProvider.cs index 91a475256..2801e272f 100644 --- a/source/Octopus.Tentacle/Kubernetes/LocalMachineKubernetesClientConfigProvider.cs +++ b/source/Octopus.Tentacle/Kubernetes/LocalMachineKubernetesClientConfigProvider.cs @@ -19,27 +19,40 @@ public KubernetesClientConfiguration Get() { return GetTelepresenceConfig(telepresenceRoot); } - var kubeConfigEnvVar = Environment.GetEnvironmentVariable("KUBECONFIG"); - if (kubeConfigEnvVar != null && !Path.IsPathRooted(kubeConfigEnvVar)) + + var kubeConfigEnvVar = GetKubeConfigPath(); + + var contextEnvVar = Environment.GetEnvironmentVariable(KubernetesConfig.KubeContextVariableName); + var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeConfigEnvVar, contextEnvVar); + + var namespaceEnvVar = Environment.GetEnvironmentVariable(KubernetesConfig.NamespaceVariableName); + if (!string.IsNullOrEmpty(namespaceEnvVar)) { - // Path.GetFullPath doesn't work with ~, so we need to expand it manually - if (kubeConfigEnvVar.StartsWith("~")) - { - kubeConfigEnvVar = kubeConfigEnvVar - .Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) - .Replace("//", "/"); - } - else - { - kubeConfigEnvVar = Path.GetFullPath(kubeConfigEnvVar); - } + config.Namespace = namespaceEnvVar; } - return KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeConfigEnvVar); + + return config; #else throw new NotSupportedException("Local machine configuration is only supported when debugging."); #endif } + static string? GetKubeConfigPath() + { + var kubeConfigEnvVar = Environment.GetEnvironmentVariable("KUBECONFIG"); + if (string.IsNullOrEmpty(kubeConfigEnvVar) || Path.IsPathRooted(kubeConfigEnvVar)) return kubeConfigEnvVar; + + // Path.GetFullPath doesn't work with ~, so we need to expand it manually + if (kubeConfigEnvVar.StartsWith("~")) + { + return kubeConfigEnvVar + .Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) + .Replace("//", "/"); + } + + return Path.GetFullPath(kubeConfigEnvVar); + } + KubernetesClientConfiguration GetTelepresenceConfig(string telepresenceRoot) { var serviceAccountPath = @@ -70,7 +83,7 @@ KubernetesClientConfiguration GetTelepresenceConfig(string telepresenceRoot) SslCaCerts = certificates, }; - var namespaceVar = Environment.GetEnvironmentVariable("OCTOPUS__K8STENTACLE__NAMESPACE"); + var namespaceVar = Environment.GetEnvironmentVariable(KubernetesConfig.NamespaceVariableName); if (!string.IsNullOrEmpty(namespaceVar)) {