diff --git a/source/Octopus.Client.Tests/Operations/RegisterKubernetesClusterOperationFixture.cs b/source/Octopus.Client.Tests/Operations/RegisterKubernetesClusterOperationFixture.cs index e2550c16d..c98ea0bfe 100644 --- a/source/Octopus.Client.Tests/Operations/RegisterKubernetesClusterOperationFixture.cs +++ b/source/Octopus.Client.Tests/Operations/RegisterKubernetesClusterOperationFixture.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using FluentAssertions; using NSubstitute; using NUnit.Framework; +using Octopus.Client.Exceptions; using Octopus.Client.Extensibility; using Octopus.Client.Model; using Octopus.Client.Model.Endpoints; @@ -22,6 +24,7 @@ public class RegisterKubernetesClusterOperationFixture ResourceCollection environments; ResourceCollection machines; ResourceCollection machinePolicies; + private ResourceCollection proxies; [SetUp] public void SetUp() @@ -32,6 +35,7 @@ public void SetUp() operation = new RegisterKubernetesClusterOperation(clientFactory); serverEndpoint = new OctopusServerEndpoint("http://octopus", "ABC123"); + proxies = new ResourceCollection(new ProxyResource[0], LinkCollection.Self("/foo")); environments = new ResourceCollection(new EnvironmentResource[0], LinkCollection.Self("/foo")); machines = new ResourceCollection(new MachineResource[0], LinkCollection.Self("/foo")); machinePolicies = new ResourceCollection(new MachinePolicyResource[0], LinkCollection.Self("/foo")); @@ -45,6 +49,7 @@ public void SetUp() .Add("MachinePolicies", "/api/machinepolicies") .Add("CurrentUser", "/api/users/me") .Add("SpaceHome", "/api/spaces") + .Add("Proxies", "/api/proxies") }; client.Get(Arg.Any(), Arg.Any()).Returns(rootDocument); @@ -57,6 +62,8 @@ public void SetUp() .Do(ci => ci.Arg, bool>>()(machines)); client.When(x => x.Paginate(Arg.Any(), Arg.Any(), Arg.Any, bool>>(), Arg.Any())) .Do(ci => ci.Arg, bool>>()(machinePolicies)); + client.When(x => x.Paginate(Arg.Any(), Arg.Any(), Arg.Any, bool>>(), Arg.Any())) + .Do(ci => ci.Arg, bool>>()(proxies)); } [Test] @@ -101,5 +108,147 @@ public async Task ShouldCreateNewPollingKubernetesTentacle() machineResources.Should().ContainSingle().Which.Endpoint.Should().BeOfType().Which.Should().BeEquivalentTo(new KubernetesTentacleEndpointResource(new PollingTentacleEndpointConfigurationResource("ABCDEF", "poll://ckyhfyfkcbmzjl8sfgch/"))); } + + [Test] + public async Task ShouldOnlyUpdateEndpointConnectionConfigurationOnExistingMachine() + { + var updatedMachines = new List(); + await client.Update("/machines/whatever/1", Arg.Do(m => updatedMachines.Add(m)), Arg.Any(), Arg.Any()); + + environments.Items.Add(new EnvironmentResource {Id = "environments-1", Name = "UAT", Links = LinkCollection.Self("/api/environments/environments-1").Add("Machines", "/api/environments/environments-1/machines")}); + environments.Items.Add(new EnvironmentResource {Id = "environments-2", Name = "Production", Links = LinkCollection.Self("/api/environments/environments-2").Add("Machines", "/api/environments/environments-2/machines")}); + + machines.Items.Add(new MachineResource + { + Id = "machines/84", EnvironmentIds = new ReferenceCollection(new[] { "environments-1" }), Name = "Mymachine", Links = LinkCollection.Self("/machines/whatever/1"), + Endpoint = new KubernetesTentacleEndpointResource(new ListeningTentacleEndpointConfigurationResource("123456", "myMachine.test.com") { ProxyId = "proxy-2" }) + }); + + proxies.Items.Add(new ProxyResource { Id = "proxy-1", Name = "MyNewProxy", Links = LinkCollection.Self("/api/proxies/proxy-1") }); + + operation.MachineName = "Mymachine"; + operation.TentaclePort = 10930; + operation.TentacleThumbprint = "ABCDEF"; + operation.TentacleHostname = "my-new-machine.test.com"; + operation.CommunicationStyle = CommunicationStyle.TentaclePassive; + operation.EnvironmentNames = new[] {"Production"}; + operation.ProxyName = "MyNewProxy"; + + await operation.ExecuteAsync(serverEndpoint).ConfigureAwait(false); + + var thing = updatedMachines.Should().ContainSingle().Which; + + thing.Should().BeEquivalentTo(new MachineResource + { + Id = "machines/84", + Name = "Mymachine", + EnvironmentIds = new ReferenceCollection("environments-1"), + Endpoint = new KubernetesTentacleEndpointResource(new ListeningTentacleEndpointConfigurationResource("ABCDEF", "https://my-new-machine.test.com:10930/") {ProxyId = "proxy-1"}), + Links = LinkCollection.Self("/machines/whatever/1") + }, cfg => cfg.RespectingRuntimeTypes()); + } + + [Test] + public async Task ShouldUpdateExistingMachineWhenForceIsEnabled() + { + environments.Items.Add(new EnvironmentResource {Id = "environments-1", Name = "UAT", Links = LinkCollection.Self("/api/environments/environments-1").Add("Machines", "/api/environments/environments-1/machines")}); + environments.Items.Add(new EnvironmentResource {Id = "environments-2", Name = "Production", Links = LinkCollection.Self("/api/environments/environments-2").Add("Machines", "/api/environments/environments-2/machines")}); + + machines.Items.Add(new MachineResource {Id = "machines/84", EnvironmentIds = new ReferenceCollection(new[] {"environments-1"}), Name = "Mymachine", Links = LinkCollection.Self("/machines/whatever/1")}); + + operation.TentacleThumbprint = "ABCDEF"; + operation.TentaclePort = 10930; + operation.MachineName = "Mymachine"; + operation.TentacleHostname = "Mymachine.test.com"; + operation.CommunicationStyle = CommunicationStyle.TentaclePassive; + operation.EnvironmentNames = new[] {"Production"}; + operation.AllowOverwrite = true; + + await operation.ExecuteAsync(serverEndpoint).ConfigureAwait(false); + + await client.Received().Update("/machines/whatever/1", Arg.Is(m => + m.Id == "machines/84" + && m.Name == "Mymachine" + && m.EnvironmentIds.First() == "environments-2"), + Arg.Any(), Arg.Any()).ConfigureAwait(false); + } + + [Test] + public async Task ShouldCreateWhenCantDeserializeMachines() + { + client.When(x => x.Paginate(Arg.Any(), Arg.Any(), Arg.Any, bool>>())) + .Throw(new OctopusDeserializationException(1, "Can not deserialize")); + + environments.Items.Add(new EnvironmentResource { Id = "environments-1", Name = "UAT", Links = LinkCollection.Self("/api/environments/environments-1").Add("Machines", "/api/environments/environments-1/machines") }); + environments.Items.Add(new EnvironmentResource { Id = "environments-2", Name = "Production", Links = LinkCollection.Self("/api/environments/environments-2").Add("Machines", "/api/environments/environments-2/machines") }); + + operation.TentacleThumbprint = "ABCDEF"; + operation.TentaclePort = 10930; + operation.MachineName = "Mymachine"; + operation.TentacleHostname = "Mymachine.test.com"; + operation.CommunicationStyle = CommunicationStyle.TentaclePassive; + operation.EnvironmentNames = new[] { "Production" }; + + await operation.ExecuteAsync(serverEndpoint).ConfigureAwait(false); + + await client.Received().Create("/api/machines", Arg.Is(m => + m.Name == "Mymachine" + && ((KubernetesTentacleEndpointResource)m.Endpoint).TentacleEndpointConfiguration.Uri == "https://mymachine.test.com:10930/" + && m.EnvironmentIds.First() == "environments-2"), + Arg.Any(), Arg.Any()).ConfigureAwait(false); + } + + [Test] + public async Task ShouldNotOverwriteMachinePolicyToNull() + { + environments.Items.Add(new EnvironmentResource { Id = "environments-1", Name = "UAT", Links = LinkCollection.Self("/api/environments/environments-1").Add("Machines", "/api/environments/environments-1/machines") }); + environments.Items.Add(new EnvironmentResource { Id = "environments-2", Name = "Production", Links = LinkCollection.Self("/api/environments/environments-2").Add("Machines", "/api/environments/environments-2/machines") }); + + machines.Items.Add(new MachineResource { Id = "machines/84", MachinePolicyId = "MachinePolicies-1", EnvironmentIds = new ReferenceCollection(new[] { "environments-1" }), Name = "Mymachine", Links = LinkCollection.Self("/machines/whatever/1") }); + + operation.TentacleThumbprint = "ABCDEF"; + operation.TentaclePort = 10930; + operation.MachineName = "Mymachine"; + operation.TentacleHostname = "Mymachine.test.com"; + operation.CommunicationStyle = CommunicationStyle.TentaclePassive; + operation.EnvironmentNames = new[] { "Production" }; + operation.AllowOverwrite = true; + + await operation.ExecuteAsync(serverEndpoint).ConfigureAwait(false); + + await client.Received().Update("/machines/whatever/1", Arg.Is(m => + m.Id == "machines/84" + && m.Name == "Mymachine" + && m.EnvironmentIds.First() == "environments-2" + && m.MachinePolicyId == "MachinePolicies-1"), + Arg.Any(), Arg.Any()).ConfigureAwait(false); + } + + [Test] + public async Task ShouldOverwriteMachinePolicyWhenPassed() + { + environments.Items.Add(new EnvironmentResource { Id = "environments-1", Name = "UAT", Links = LinkCollection.Self("/api/environments/environments-1").Add("Machines", "/api/environments/environments-1/machines") }); + environments.Items.Add(new EnvironmentResource { Id = "environments-2", Name = "Production", Links = LinkCollection.Self("/api/environments/environments-2").Add("Machines", "/api/environments/environments-2/machines") }); + + machines.Items.Add(new MachineResource { Id = "machines/84", MachinePolicyId = "MachinePolicies-1", EnvironmentIds = new ReferenceCollection(new[] { "environments-1" }), Name = "Mymachine", Links = LinkCollection.Self("/machines/whatever/1") }); + machinePolicies.Items.Add(new MachinePolicyResource {Id = "MachinePolicies-2", Name = "Machine Policy 2"}); + operation.TentacleThumbprint = "ABCDEF"; + operation.TentaclePort = 10930; + operation.MachineName = "Mymachine"; + operation.TentacleHostname = "Mymachine.test.com"; + operation.CommunicationStyle = CommunicationStyle.TentaclePassive; + operation.EnvironmentNames = new[] { "Production" }; + operation.AllowOverwrite = true; + operation.MachinePolicy = "Machine Policy 2"; + + await operation.ExecuteAsync(serverEndpoint).ConfigureAwait(false); + + await client.Received().Update("/machines/whatever/1", Arg.Is(m => + m.Id == "machines/84" + && m.Name == "Mymachine" + && m.EnvironmentIds.First() == "environments-2" + && m.MachinePolicyId == "MachinePolicies-2"), + Arg.Any(), Arg.Any()).ConfigureAwait(false); + } } } \ No newline at end of file