diff --git a/source/Calamari.Contracts/ArgoCD/FileHash.cs b/source/Calamari.Contracts/ArgoCD/FileHash.cs new file mode 100644 index 0000000000..3d37e4f5ec --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/FileHash.cs @@ -0,0 +1,5 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record FileHash(string FilePath, string Hash); \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs b/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs new file mode 100644 index 0000000000..1b5e418483 --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/FileJsonPatch.cs @@ -0,0 +1,5 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record FileJsonPatch(string FilePath, string JsonPatch); \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs b/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs new file mode 100644 index 0000000000..794a4f2d4b --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/ServiceMessages.cs @@ -0,0 +1,18 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public static class ServiceMessages +{ + public static class ArgoCDFilesUpdated + { + public const string Name = "argocd-files-updated"; + + public static class Attributes + { + public const string GatewayId = "gatewayId"; + public const string ApplicationName = "applicationName"; + public const string Sources = "sources"; + } + } +} \ No newline at end of file diff --git a/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs b/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs new file mode 100644 index 0000000000..21adb0062d --- /dev/null +++ b/source/Calamari.Contracts/ArgoCD/SourceFileChanges.cs @@ -0,0 +1,10 @@ +using System; + +namespace Octopus.Calamari.Contracts.ArgoCD; + +public record SourceFileChanges( + string? CommitSha, + DateTimeOffset? CommitTimestamp, + int SourceIndex, + List ReplacedFiles, + List PatchedFiles); \ No newline at end of file diff --git a/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs b/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs index 5805e1bab3..4cc5d0ba37 100644 --- a/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs +++ b/source/Calamari.Tests/ArgoCD/ArgoCDFilesUpdatedReporterTests.cs @@ -8,6 +8,7 @@ using Calamari.Testing.Helpers; using FluentAssertions; using NUnit.Framework; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.Tests.ArgoCD { diff --git a/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs b/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs index 3d4593717f..5d559298fc 100644 --- a/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs +++ b/source/Calamari.Tests/ArgoCD/Git/AuthenticatingRepositoryFactoryTests.cs @@ -81,6 +81,8 @@ public void AnonymousCloneWhenNoCredentialsMatch() public class SshUrlTests : AuthenticatingRepositoryFactoryTestBase { [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void SshCredentialBranch_IsSelectedAndDispatchesSshKeyGitConnection() { // Use an ssh:// URL so the new strict validation allows it, and mock the factory @@ -108,6 +110,8 @@ public void HttpsCredentialTakesPriorityOverSshWhenBothMatchAnSshUrl() } [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void KnownHostsFromDtoAreCarriedOntoSshKeyGitConnection() { const string sshUrl = "ssh://git@github.com/org/repo.git"; diff --git a/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs b/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs index d9103a5460..f52231a15f 100644 --- a/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs +++ b/source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs @@ -96,6 +96,8 @@ public void CanCloneAnExistingRepositoryAtHEADAndAssociatedFiles() } [Test] + // SSH not currently functional on Windows + [Category(TestCategory.CompatibleOS.OnlyNixOrMac)] public void CloningSshKeyGitConnectionDoesNotResolveAPullRequestClientAndLogsVerboseMessage() { var filename = "sshTest.txt"; diff --git a/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs b/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs index ebf06cdc9c..bf9a513b45 100644 --- a/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs +++ b/source/Calamari/ArgoCD/ArgoCDFilesUpdatedReporter.cs @@ -7,7 +7,8 @@ using Calamari.Common.Plumbing.Logging; using Calamari.Common.Plumbing.ServiceMessages; using Calamari.Kubernetes; -using ArgoCDFilesUpdatedAttributes = Calamari.Kubernetes.SpecialVariables.ServiceMessages.ArgoCDFilesUpdated.Attributes; +using Octopus.Calamari.Contracts.ArgoCD; +using ArgoCDFilesUpdatedAttributes = Octopus.Calamari.Contracts.ArgoCD.ServiceMessages.ArgoCDFilesUpdated.Attributes; namespace Calamari.ArgoCD { @@ -34,33 +35,32 @@ public void ReportFilesUpdated(GitCommitParameters gitCommitParameters, IReadOnl { { ArgoCDFilesUpdatedAttributes.GatewayId, appResult.GatewayId }, { ArgoCDFilesUpdatedAttributes.ApplicationName, appResult.ApplicationName.Value }, - { ArgoCDFilesUpdatedAttributes.Sources, JsonSerializer.Serialize(ConvertPathsToPosix(appResult.TrackedSourceDetails)) } + { ArgoCDFilesUpdatedAttributes.Sources, JsonSerializer.Serialize(appResult.TrackedSourceDetails.Select(MapSource).ToList()) } }; var message = new ServiceMessage( - SpecialVariables.ServiceMessages.ArgoCDFilesUpdated.Name, + ServiceMessages.ArgoCDFilesUpdated.Name, parameters); log.WriteServiceMessage(message); } } - List ConvertPathsToPosix(List inputs) + static SourceFileChanges MapSource(TrackedSourceDetail trackedSourceDetail) { - return inputs.Select(usd => usd with - { - ReplacedFiles = usd.ReplacedFiles.Select(rf => rf with - { - FilePath = rf.FilePath.EnsurePosixDirectorySeparator() - }) - .ToList(), - PatchedFiles = usd.PatchedFiles.Select(pf => pf with - { - FilePath = pf.FilePath.EnsurePosixDirectorySeparator() - }) - .ToList() - }) - .ToList(); + return new SourceFileChanges( + trackedSourceDetail.CommitSha, + trackedSourceDetail.CommitTimestamp, + trackedSourceDetail.SourceIndex, + trackedSourceDetail.ReplacedFiles.Select(f => f with + { + FilePath = f.FilePath.EnsurePosixDirectorySeparator() + }).ToList(), + trackedSourceDetail.PatchedFiles.Select(f => f with + { + FilePath = f.FilePath.EnsurePosixDirectorySeparator() + }).ToList() + ); } } } \ No newline at end of file diff --git a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs index f061a422f5..42c876a2a1 100644 --- a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/CopyTemplatesSourceUpdater.cs @@ -6,6 +6,7 @@ using Calamari.Common.Plumbing.Extensions; using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; +using Octopus.Calamari.Contracts.ArgoCD; using Octopus.CoreUtilities.Extensions; namespace Calamari.ArgoCD.Conventions.ManifestTemplating; diff --git a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs index e9c05e5887..508436fd5e 100644 --- a/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/ManifestTemplating/ManifestUpdateResult.cs @@ -1,6 +1,7 @@ #nullable enable using System; using System.Collections.Generic; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.ManifestTemplating; diff --git a/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs index 89667949a2..06b38eff9e 100644 --- a/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/SourceUpdateResult.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Calamari.ArgoCD.Git; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs index c19af78bee..dfca12fec3 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/AbstractHelmUpdater.cs @@ -9,6 +9,7 @@ using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; using Calamari.Kubernetes.Patching.JsonPatch; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs index 0ccdb023fd..d621437803 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/BaseUpdater.cs @@ -11,6 +11,7 @@ using Calamari.Common.Plumbing.Logging; using Calamari.Kubernetes.Patching; using Calamari.Kubernetes.Patching.JsonPatch; +using Octopus.Calamari.Contracts.ArgoCD; using YamlDotNet.RepresentationModel; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs index 400265eff1..80a49f09f6 100644 --- a/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs +++ b/source/Calamari/ArgoCD/Conventions/UpdateImageTag/FileUpdateResult.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD.Conventions.UpdateImageTag; diff --git a/source/Calamari/ArgoCD/Git/RepositoryFactory.cs b/source/Calamari/ArgoCD/Git/RepositoryFactory.cs index 6b70ec16bf..771c9b83b0 100644 --- a/source/Calamari/ArgoCD/Git/RepositoryFactory.cs +++ b/source/Calamari/ArgoCD/Git/RepositoryFactory.cs @@ -1,10 +1,10 @@ using System; using System.IO; using System.Linq; -using System.Text; using System.Threading; using Calamari.ArgoCD.Git.PullRequests; using Calamari.Common.Commands; +using Calamari.Common.Plumbing; using Calamari.Common.Plumbing.Extensions; using Calamari.Common.Plumbing.FileSystem; using Calamari.Common.Plumbing.Logging; @@ -48,6 +48,8 @@ public RepositoryFactory(ILog log, ICalamariFileSystem fileSystem, string reposi public RepositoryWrapper CloneRepository(string repositoryName, IGitConnection gitConnection) { + WindowsSshKeys.AssertSupported(gitConnection); + var repositoryPath = Path.Combine(repositoryParentDirectory, repositoryName); fileSystem.CreateDirectory(repositoryPath); diff --git a/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs b/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs new file mode 100644 index 0000000000..e84bb52081 --- /dev/null +++ b/source/Calamari/ArgoCD/Git/WindowsSshKeys.cs @@ -0,0 +1,20 @@ +using System; +using Calamari.Common.Plumbing; +using NuGet.Commands; + +namespace Calamari.ArgoCD.Git; + +// Our fork LibGit2Sharp uses WinCNG for it's SSH support, and WinCNG does not support some keys. +// This first implementation blocks on all as we want to get the feature out for Linux first and +// we'll come back to attempt to handle it more gracefully at a later date. +public class WindowsSshKeys +{ + public static void AssertSupported(IGitConnection? connection) + { + if (!CalamariEnvironment.IsRunningOnWindows) return; + if (connection is not SshKeyGitConnection) return; + + throw new CommandException( + "SSH credentials are not currently supported for Git operations running on Windows. Use HTTPS credentials (username + password or PAT) instead or run the deployment on a Linux worker."); + } +} \ No newline at end of file diff --git a/source/Calamari/ArgoCD/ProcessApplicationResult.cs b/source/Calamari/ArgoCD/ProcessApplicationResult.cs index abad5c14ed..f185e88f51 100644 --- a/source/Calamari/ArgoCD/ProcessApplicationResult.cs +++ b/source/Calamari/ArgoCD/ProcessApplicationResult.cs @@ -3,13 +3,10 @@ using System.Collections.Generic; using System.Linq; using Calamari.ArgoCD.Models; +using Octopus.Calamari.Contracts.ArgoCD; namespace Calamari.ArgoCD { - public record FileHash(string FilePath, string Hash); - - public record FileJsonPatch(string FilePath, string JsonPatch); - public record TrackedSourceDetail( string? CommitSha, DateTimeOffset? CommitTimestamp, diff --git a/source/Calamari/Kubernetes/SpecialVariables.cs b/source/Calamari/Kubernetes/SpecialVariables.cs index 86cddcf04b..78ebf30226 100644 --- a/source/Calamari/Kubernetes/SpecialVariables.cs +++ b/source/Calamari/Kubernetes/SpecialVariables.cs @@ -174,18 +174,6 @@ public static class ManifestApplied public const string ManifestAttribute = "manifest"; public const string NamespaceAttribute = "ns"; } - - public static class ArgoCDFilesUpdated - { - public const string Name = "argocd-files-updated"; - - public static class Attributes - { - public const string GatewayId = "gatewayId"; - public const string ApplicationName = "applicationName"; - public const string Sources = "sources"; - } - } } } } \ No newline at end of file