From 751022e49e6306ea6f63259c8144d6612912812e Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Wed, 15 May 2024 14:55:03 +1000 Subject: [PATCH 1/7] Update to Kubernetes SDK 14 and add new test --- .../KubernetesAgentIntegrationTest.cs | 10 +++ .../KubernetesClusterOneTimeSetUp.cs | 4 +- ...ubernetesScriptServiceV1IntegrationTest.cs | 62 ++++++++++++++++++ .../KubernetesTestsGlobalContext.cs | 6 +- .../Setup/KubernetesAgentInstaller.cs | 2 +- .../Setup/Tooling/KubeCtlTool.cs | 63 +++++++++++++++++++ .../Octopus.Tentacle/Octopus.Tentacle.csproj | 11 ++-- 7 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs index 9c92b9263..c2b297d8e 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs @@ -8,6 +8,7 @@ using Octopus.Tentacle.CommonTestUtils; using Octopus.Tentacle.Contracts.Observability; using Octopus.Tentacle.Kubernetes.Tests.Integration.Setup; +using Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling; using Octopus.Tentacle.Tests.Integration.Common.Builders.Decorators; using Octopus.Tentacle.Tests.Integration.Common.Logging; @@ -27,6 +28,7 @@ public abstract class KubernetesAgentIntegrationTest protected CancellationToken CancellationToken { get; private set; } protected TentacleServiceDecoratorBuilder? TentacleServiceDecoratorBuilder { get; set; } + protected KubeCtlTool KubeCtl { get; private set; } [OneTimeSetUp] public async Task OneTimeSetUp() @@ -38,6 +40,13 @@ public async Task OneTimeSetUp() KubernetesTestsGlobalContext.Instance.KubeConfigPath, KubernetesTestsGlobalContext.Instance.Logger); + KubeCtl = new KubeCtlTool( + KubernetesTestsGlobalContext.Instance.TemporaryDirectory, + KubernetesTestsGlobalContext.Instance.KubeCtlExePath, + KubernetesTestsGlobalContext.Instance.KubeConfigPath, + kubernetesAgentInstaller.Namespace, + KubernetesTestsGlobalContext.Instance.Logger); + //create a new server halibut runtime var listeningPort = BuildServerHalibutRuntimeAndListen(); @@ -49,6 +58,7 @@ public async Task OneTimeSetUp() BuildTentacleClient(thumbprint); } + [SetUp] public void SetUp() { diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs index 22f5272e5..23e352258 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs @@ -18,12 +18,12 @@ public async Task OneTimeSetUp() await installer.Install(); //if we are not running in TeamCity, then we need to find the latest local tag and use that if it exists - if (!TeamCityDetection.IsRunningInTeamCity()) + if (!TeamCityDetection.IsRunningInTeamCity() && bool.TryParse(Environment.GetEnvironmentVariable("KubernetesAgentTests_UseLocalImage"), out var useLocal) && useLocal) { var imageLoader = new DockerImageLoader(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, KubernetesTestsGlobalContext.Instance.Logger, kindExePath); KubernetesTestsGlobalContext.Instance.TentacleImageAndTag = imageLoader.LoadMostRecentImageIntoKind(installer.ClusterName); } - else + else if(TeamCityDetection.IsRunningInTeamCity()) { var tag = Environment.GetEnvironmentVariable("KubernetesAgentTests_ImageTag"); KubernetesTestsGlobalContext.Instance.TentacleImageAndTag = $"docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:{tag}"; diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs index a8f4e0eff..217366733 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs @@ -59,4 +59,66 @@ Task ScriptCompleted(CancellationToken ct) return Task.CompletedTask; } } + + [Test] + public async Task TentaclePodIsTerminatedDuringScriptExecution_ShouldRestartAndPickUpPodStatus() + { + // Arrange + var logs = new List(); + var scriptCompleted = false; + var count = 50; + var scriptBody = $@"echo ""Hello World"" +for i in $(seq 1 {50}); +do + echo Count: $i + sleep 0.1 +done +"; + var command = new ExecuteKubernetesScriptCommandBuilder(LoggingUtils.CurrentTestHash()) + .WithScriptBody(scriptBody) + .Build(); + + var commandResult = await KubeCtl.ExecuteNamespacedCommand("get pods -l app.kubernetes.io/name=octopus-agent -o \"Name\""); + var initialPodName = commandResult.StdOut.Single(); + + //act + var scriptTask = TentacleClient.ExecuteScript(command, StatusReceived, ScriptCompleted, new InMemoryLog(), CancellationToken.None); + var killTask = KubeCtl.ExecuteNamespacedCommand("delete pods -l app.kubernetes.io/name=octopus-agent"); + + await Task.WhenAll(scriptTask, killTask); + + var result = scriptTask.Result; + + commandResult = await KubeCtl.ExecuteNamespacedCommand("get pods -l app.kubernetes.io/name=octopus-agent -o \"Name\""); + var finalPodName = commandResult.StdOut.Single(); + + //Assert + logs.Should().Contain(po => po.Source == ProcessOutputSource.StdOut && po.Text == "Hello World"); + + //verify that we are getting all the logs and that the tentacle has been killed + for (var i = 1; i <= count; i++) + { + var i1 = i; + logs.Should().Contain(po => po.Source == ProcessOutputSource.StdOut && po.Text == $"Count: {i1}"); + } + + scriptCompleted.Should().BeTrue(); + result.ExitCode.Should().Be(0); + result.State.Should().Be(ProcessState.Complete); + + finalPodName.Should().NotBe(initialPodName, because: "the tentacle pod should have been killed and restarted"); + + return; + + void StatusReceived(ScriptExecutionStatus status) + { + logs.AddRange(status.Logs); + } + + Task ScriptCompleted(CancellationToken ct) + { + scriptCompleted = true; + return Task.CompletedTask; + } + } } \ No newline at end of file diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs index 9f7dc9e37..133867aee 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs @@ -6,15 +6,15 @@ namespace Octopus.Tentacle.Kubernetes.Tests.Integration; public class KubernetesTestsGlobalContext : IDisposable { public static KubernetesTestsGlobalContext Instance { get; } = new(); - + public TemporaryDirectory TemporaryDirectory { get; } - + public ILogger Logger { get; } public string KubeConfigPath { get; set; } = ""; public string HelmExePath { get; private set; } = null!; - public string KubeCtlExePath { get; private set; }= null!; + public string KubeCtlExePath { get; private set; } = null!; public string? TentacleImageAndTag { get; set; } KubernetesTestsGlobalContext() diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KubernetesAgentInstaller.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KubernetesAgentInstaller.cs index 0f25712c2..175824a51 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KubernetesAgentInstaller.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KubernetesAgentInstaller.cs @@ -35,7 +35,7 @@ public KubernetesAgentInstaller(TemporaryDirectory temporaryDirectory, string he public string AgentName { get; } - string Namespace => $"octopus-agent-{AgentName}"; + public string Namespace => $"octopus-agent-{AgentName}"; public Uri SubscriptionId { get; } = PollingSubscriptionId.Generate(); diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs new file mode 100644 index 000000000..2be3a30d5 --- /dev/null +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs @@ -0,0 +1,63 @@ +using System.Text; +using Octopus.Tentacle.CommonTestUtils; +using Octopus.Tentacle.CommonTestUtils.Logging; +using Octopus.Tentacle.Util; + +namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling; + +public class KubeCtlTool +{ + readonly TemporaryDirectory temporaryDirectory; + readonly string kubeCtlExePath; + readonly string kubeConfigPath; + readonly string ns; + readonly ILogger logger; + + public KubeCtlTool(TemporaryDirectory temporaryDirectory, string kubeCtlExePath, string kubeConfigPath, string ns, ILogger logger) + { + this.temporaryDirectory = temporaryDirectory; + this.kubeCtlExePath = kubeCtlExePath; + this.kubeConfigPath = kubeConfigPath; + this.ns = ns; + this.logger = logger; + } + + public Task ExecuteNamespacedCommand(string command, CancellationToken cancellationToken = default) + { + return Task.Run(() => ExecuteCommand($"{command} --namespace {ns}", cancellationToken), cancellationToken); + } + + KubeCtlCommandResult ExecuteCommand(string command, CancellationToken cancellationToken = default) + { + var sb = new StringBuilder(); + var sprLogger = new LoggerConfiguration() + .WriteTo.Logger(logger) + .WriteTo.StringBuilder(sb) + .MinimumLevel.Debug() + .CreateLogger(); + + var stdOut = new List(); + var stdErr = new List(); + + var exitCode = SilentProcessRunner.ExecuteCommand( + kubeCtlExePath, + $"{command} --kubeconfig=\"{kubeConfigPath}\"", + temporaryDirectory.DirectoryPath, + sprLogger.Debug, + x => + { + sprLogger.Information(x); + stdOut.Add(x); + }, + y => + { + sprLogger.Error(y); + stdErr.Add(y); + }, + cancellationToken); + + return new (exitCode, stdOut, stdErr); + } + + public record KubeCtlCommandResult(int ExitCode, IEnumerable StdOut, IEnumerable StdError); +} \ No newline at end of file diff --git a/source/Octopus.Tentacle/Octopus.Tentacle.csproj b/source/Octopus.Tentacle/Octopus.Tentacle.csproj index 24a4478e2..59ac7e051 100644 --- a/source/Octopus.Tentacle/Octopus.Tentacle.csproj +++ b/source/Octopus.Tentacle/Octopus.Tentacle.csproj @@ -46,10 +46,7 @@ $(DefineConstants);HTTP_CLIENT_SUPPORTS_SSL_OPTIONS;REQUIRES_EXPLICIT_LOG_CONFIG;REQUIRES_CODE_PAGE_PROVIDER;USER_INTERACTIVE_DOES_NOT_WORK;DEFAULT_PROXY_IS_NOT_AVAILABLE;HAS_NULLABLE_REF_TYPES - - - - + @@ -127,4 +124,10 @@ + + + + + + From 3825611857d7455c62dffd5d7e2b955c84f9dc7f Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Thu, 16 May 2024 10:56:01 +1000 Subject: [PATCH 2/7] Minor cleanup based on PR feedback --- .../KubernetesClusterOneTimeSetUp.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs index 23e352258..57f2132f5 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClusterOneTimeSetUp.cs @@ -17,25 +17,32 @@ public async Task OneTimeSetUp() installer = new KubernetesClusterInstaller(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, kindExePath, helmExePath, kubeCtlPath, KubernetesTestsGlobalContext.Instance.Logger); await installer.Install(); - //if we are not running in TeamCity, then we need to find the latest local tag and use that if it exists - if (!TeamCityDetection.IsRunningInTeamCity() && bool.TryParse(Environment.GetEnvironmentVariable("KubernetesAgentTests_UseLocalImage"), out var useLocal) && useLocal) - { - var imageLoader = new DockerImageLoader(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, KubernetesTestsGlobalContext.Instance.Logger, kindExePath); - KubernetesTestsGlobalContext.Instance.TentacleImageAndTag = imageLoader.LoadMostRecentImageIntoKind(installer.ClusterName); - } - else if(TeamCityDetection.IsRunningInTeamCity()) + KubernetesTestsGlobalContext.Instance.TentacleImageAndTag = GetTentacleImageAndTag(kindExePath); + KubernetesTestsGlobalContext.Instance.SetToolExePaths(helmExePath, kubeCtlPath); + KubernetesTestsGlobalContext.Instance.KubeConfigPath = installer.KubeConfigPath; + } + + string? GetTentacleImageAndTag(string kindExePath) + { + //By default, we don't override the values in the helm chart. This is useful if you are just writing new tests and not changing Tentacle code. + string? imageAndTag = null; + if (TeamCityDetection.IsRunningInTeamCity()) { + //In TeamCity, use the tag of the currently building code var tag = Environment.GetEnvironmentVariable("KubernetesAgentTests_ImageTag"); - KubernetesTestsGlobalContext.Instance.TentacleImageAndTag = $"docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:{tag}"; + imageAndTag = $"docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:{tag}"; } - - if (KubernetesTestsGlobalContext.Instance.TentacleImageAndTag is not null) + else if(bool.TryParse(Environment.GetEnvironmentVariable("KubernetesAgentTests_UseLatestLocalImage"), out var useLocal) && useLocal) { - KubernetesTestsGlobalContext.Instance.Logger.Information("Using tentacle image: {ImageAndTag}", KubernetesTestsGlobalContext.Instance.TentacleImageAndTag); + //if we should use the latest locally build image, load the tag from docker and load it into kind + var imageLoader = new DockerImageLoader(KubernetesTestsGlobalContext.Instance.TemporaryDirectory, KubernetesTestsGlobalContext.Instance.Logger, kindExePath); + imageAndTag = imageLoader.LoadMostRecentImageIntoKind(installer.ClusterName); } + + if(imageAndTag is not null) + KubernetesTestsGlobalContext.Instance.Logger.Information("Using tentacle image: {ImageAndTag}", imageAndTag); - KubernetesTestsGlobalContext.Instance.SetToolExePaths(helmExePath, kubeCtlPath); - KubernetesTestsGlobalContext.Instance.KubeConfigPath = installer.KubeConfigPath; + return imageAndTag; } [OneTimeTearDown] From 149a35df56a4435f6f7bc82ccca76c13eee238f9 Mon Sep 17 00:00:00 2001 From: Kevin Tchang Date: Tue, 23 Jul 2024 09:02:05 +1000 Subject: [PATCH 3/7] remove new test as existing test coverage is sufficient --- ...ubernetesScriptServiceV1IntegrationTest.cs | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs index 217366733..a8f4e0eff 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesScriptServiceV1IntegrationTest.cs @@ -59,66 +59,4 @@ Task ScriptCompleted(CancellationToken ct) return Task.CompletedTask; } } - - [Test] - public async Task TentaclePodIsTerminatedDuringScriptExecution_ShouldRestartAndPickUpPodStatus() - { - // Arrange - var logs = new List(); - var scriptCompleted = false; - var count = 50; - var scriptBody = $@"echo ""Hello World"" -for i in $(seq 1 {50}); -do - echo Count: $i - sleep 0.1 -done -"; - var command = new ExecuteKubernetesScriptCommandBuilder(LoggingUtils.CurrentTestHash()) - .WithScriptBody(scriptBody) - .Build(); - - var commandResult = await KubeCtl.ExecuteNamespacedCommand("get pods -l app.kubernetes.io/name=octopus-agent -o \"Name\""); - var initialPodName = commandResult.StdOut.Single(); - - //act - var scriptTask = TentacleClient.ExecuteScript(command, StatusReceived, ScriptCompleted, new InMemoryLog(), CancellationToken.None); - var killTask = KubeCtl.ExecuteNamespacedCommand("delete pods -l app.kubernetes.io/name=octopus-agent"); - - await Task.WhenAll(scriptTask, killTask); - - var result = scriptTask.Result; - - commandResult = await KubeCtl.ExecuteNamespacedCommand("get pods -l app.kubernetes.io/name=octopus-agent -o \"Name\""); - var finalPodName = commandResult.StdOut.Single(); - - //Assert - logs.Should().Contain(po => po.Source == ProcessOutputSource.StdOut && po.Text == "Hello World"); - - //verify that we are getting all the logs and that the tentacle has been killed - for (var i = 1; i <= count; i++) - { - var i1 = i; - logs.Should().Contain(po => po.Source == ProcessOutputSource.StdOut && po.Text == $"Count: {i1}"); - } - - scriptCompleted.Should().BeTrue(); - result.ExitCode.Should().Be(0); - result.State.Should().Be(ProcessState.Complete); - - finalPodName.Should().NotBe(initialPodName, because: "the tentacle pod should have been killed and restarted"); - - return; - - void StatusReceived(ScriptExecutionStatus status) - { - logs.AddRange(status.Logs); - } - - Task ScriptCompleted(CancellationToken ct) - { - scriptCompleted = true; - return Task.CompletedTask; - } - } } \ No newline at end of file From 30ee750d17918a06cb3f79475c6ba05e04e9a60c Mon Sep 17 00:00:00 2001 From: Kevin Tchang Date: Tue, 23 Jul 2024 09:16:32 +1000 Subject: [PATCH 4/7] clean diff --- .../KubernetesAgentIntegrationTest.cs | 4 +- .../KubernetesTestsGlobalContext.cs | 6 +- .../Tooling/KubeCtlTool.cs | 64 ------------------- 3 files changed, 5 insertions(+), 69 deletions(-) delete mode 100644 source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs index 0358d0167..fb7829aed 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs @@ -40,7 +40,7 @@ public async Task OneTimeSetUp() KubernetesTestsGlobalContext.Instance.KubeCtlExePath, KubernetesTestsGlobalContext.Instance.KubeConfigPath, KubernetesTestsGlobalContext.Instance.Logger); - + KubeCtl = new KubeCtlTool( KubernetesTestsGlobalContext.Instance.TemporaryDirectory, KubernetesTestsGlobalContext.Instance.KubeCtlExePath, @@ -87,7 +87,7 @@ public async Task TearDown() } protected virtual TentacleServiceDecoratorBuilder ConfigureTentacleServiceDecoratorBuilder(TentacleServiceDecoratorBuilder builder) => builder; - + void BuildTentacleClient() { var endpoint = new ServiceEndPoint(kubernetesAgentInstaller.SubscriptionId, agentThumbprint, ServerHalibutRuntime.TimeoutsAndLimits); diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs index 133867aee..9f7dc9e37 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesTestsGlobalContext.cs @@ -6,15 +6,15 @@ namespace Octopus.Tentacle.Kubernetes.Tests.Integration; public class KubernetesTestsGlobalContext : IDisposable { public static KubernetesTestsGlobalContext Instance { get; } = new(); - + public TemporaryDirectory TemporaryDirectory { get; } - + public ILogger Logger { get; } public string KubeConfigPath { get; set; } = ""; public string HelmExePath { get; private set; } = null!; - public string KubeCtlExePath { get; private set; } = null!; + public string KubeCtlExePath { get; private set; }= null!; public string? TentacleImageAndTag { get; set; } KubernetesTestsGlobalContext() diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs deleted file mode 100644 index cae324e54..000000000 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Text; -using Octopus.Tentacle.CommonTestUtils; -using Octopus.Tentacle.CommonTestUtils.Logging; -using Octopus.Tentacle.Util; - -namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Tooling; - -public class KubeCtlTool -{ - readonly TemporaryDirectory temporaryDirectory; - readonly string kubeCtlExePath; - readonly string kubeConfigPath; - readonly string ns; - readonly ILogger logger; - - public KubeCtlTool(TemporaryDirectory temporaryDirectory, string kubeCtlExePath, string kubeConfigPath, string ns, ILogger logger) - { - this.temporaryDirectory = temporaryDirectory; - this.kubeCtlExePath = kubeCtlExePath; - this.kubeConfigPath = kubeConfigPath; - this.ns = ns; - this.logger = logger; - } - - public Task ExecuteNamespacedCommand(string command, CancellationToken cancellationToken = default) - { - return Task.Run(() => ExecuteCommand($"{command} --namespace {ns}", cancellationToken), cancellationToken); - } - - KubeCtlCommandResult ExecuteCommand(string command, CancellationToken cancellationToken = default) - { - var sb = new StringBuilder(); - var sprLogger = new LoggerConfiguration() - .WriteTo.Logger(logger) - .WriteTo.StringBuilder(sb) - .MinimumLevel.Debug() - .CreateLogger(); - - var stdOut = new List(); - var stdErr = new List(); - - var exitCode = SilentProcessRunner.ExecuteCommand( - kubeCtlExePath, - $"{command} --kubeconfig=\"{kubeConfigPath}\"", - temporaryDirectory.DirectoryPath, - sprLogger.Debug, - x => - { - sprLogger.Information(x); - stdOut.Add(x); - }, - y => - { - sprLogger.Error(y); - stdErr.Add(y); - }, - cancellationToken); - - return new (exitCode, stdOut, stdErr); - } - - public record KubeCtlCommandResult(int ExitCode, IEnumerable StdOut, IEnumerable StdError); -} \ No newline at end of file From 5ca4c29eb1950ced3031af9f61083c94573b163a Mon Sep 17 00:00:00 2001 From: Kevin Tchang Date: Tue, 23 Jul 2024 09:19:35 +1000 Subject: [PATCH 5/7] revert tool namespace --- .../KubernetesAgentIntegrationTest.cs | 2 +- .../{Setup => }/Tooling/KubeCtlTool.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename source/Octopus.Tentacle.Kubernetes.Tests.Integration/{Setup => }/Tooling/KubeCtlTool.cs (95%) diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs index fb7829aed..5874cdd5a 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesAgentIntegrationTest.cs @@ -8,7 +8,7 @@ using Octopus.Tentacle.CommonTestUtils; using Octopus.Tentacle.Contracts.Observability; using Octopus.Tentacle.Kubernetes.Tests.Integration.Setup; -using Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling; +using Octopus.Tentacle.Kubernetes.Tests.Integration.Tooling; using Octopus.Tentacle.Tests.Integration.Common.Builders.Decorators; using Octopus.Tentacle.Tests.Integration.Common.Logging; diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs similarity index 95% rename from source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs rename to source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs index 2be3a30d5..cae324e54 100644 --- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlTool.cs +++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Tooling/KubeCtlTool.cs @@ -1,9 +1,10 @@ -using System.Text; +using System; +using System.Text; using Octopus.Tentacle.CommonTestUtils; using Octopus.Tentacle.CommonTestUtils.Logging; using Octopus.Tentacle.Util; -namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling; +namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Tooling; public class KubeCtlTool { From feab974da1b708e6a40eb04853fa71073200551f Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Tue, 13 Aug 2024 09:31:51 +1000 Subject: [PATCH 6/7] Update Kubernetes SDK to 14.0.8 --- source/Octopus.Tentacle/Octopus.Tentacle.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Octopus.Tentacle/Octopus.Tentacle.csproj b/source/Octopus.Tentacle/Octopus.Tentacle.csproj index 329150d7b..dbdce1737 100644 --- a/source/Octopus.Tentacle/Octopus.Tentacle.csproj +++ b/source/Octopus.Tentacle/Octopus.Tentacle.csproj @@ -46,7 +46,7 @@ $(DefineConstants);HTTP_CLIENT_SUPPORTS_SSL_OPTIONS;REQUIRES_EXPLICIT_LOG_CONFIG;REQUIRES_CODE_PAGE_PROVIDER;USER_INTERACTIVE_DOES_NOT_WORK;DEFAULT_PROXY_IS_NOT_AVAILABLE;HAS_NULLABLE_REF_TYPES - + @@ -125,9 +125,9 @@ - + - + From 17cadf11d2bc650f42e3d904c12687f6127464c3 Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Fri, 16 Aug 2024 10:43:50 +1000 Subject: [PATCH 7/7] Downgrade to 14.0.2 --- source/Octopus.Tentacle/Octopus.Tentacle.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Octopus.Tentacle/Octopus.Tentacle.csproj b/source/Octopus.Tentacle/Octopus.Tentacle.csproj index dbdce1737..329150d7b 100644 --- a/source/Octopus.Tentacle/Octopus.Tentacle.csproj +++ b/source/Octopus.Tentacle/Octopus.Tentacle.csproj @@ -46,7 +46,7 @@ $(DefineConstants);HTTP_CLIENT_SUPPORTS_SSL_OPTIONS;REQUIRES_EXPLICIT_LOG_CONFIG;REQUIRES_CODE_PAGE_PROVIDER;USER_INTERACTIVE_DOES_NOT_WORK;DEFAULT_PROXY_IS_NOT_AVAILABLE;HAS_NULLABLE_REF_TYPES - + @@ -125,9 +125,9 @@ - + - +