Skip to content
This repository has been archived by the owner on Mar 23, 2018. It is now read-only.

Commit

Permalink
feat: deploy, install, register, unregister commands
Browse files Browse the repository at this point in the history
  • Loading branch information
cruikshj committed Apr 3, 2016
1 parent 97ed0ff commit afb10ae
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
bin
obj
.vscode

project.lock.json
17 changes: 10 additions & 7 deletions nautilus/CommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
namespace Nautilus
{
public abstract class CommandBase
{
[Option("server", Required = true, HelpText = "Octopus server address (e.g. http://your-octopus-server/).")]
{
[Option('s', "server", Required = true, HelpText = "Octopus server address (e.g. http://your-octopus-server/).")]
public string OctopusServerAddress { get; set; }

[Option("apiKey", Required = true, HelpText = "Octopus API key.")]
[Option('k', "apikey", Required = true, HelpText = "Octopus API key.")]
public string OctopusApiKey { get; set; }

public int Run()
{
var octopus = new OctopusProxy(OctopusServerAddress, OctopusApiKey);
return Run(octopus);
}

[Option("machine", Required = false, HelpText = "The target machine name.")]
public string MachineName { get; set; }

public abstract int Run();
protected abstract int Run(OctopusProxy octopus);
}
}
38 changes: 29 additions & 9 deletions nautilus/DeployCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,40 @@
using System.Collections.Generic;
using System.Linq;
using CommandLine;
using Octopus.Client.Model;

namespace Nautilus
{
[Verb("deploy", HelpText = "Creates deployments for the latest release of all projects related to the target machine by role and environment.")]
public class DeployCommand : CommandBase
{
public override int Run()
{
var octopus = new OctopusProxy(OctopusServerAddress, OctopusApiKey);

[Option('n', "name", Required = false, HelpText = "The target machine name.")]
public string MachineName { get; set; }

protected override int Run(OctopusProxy octopus)
{
var machineName = MachineName ?? Environment.MachineName;

Console.WriteLine($"Preparing to deploy to target machine ({machineName})...");
Console.WriteLine($"Preparing to deploy to target machine ({machineName})");

var machine = octopus.GetMachine(machineName);
if (machine == null)
{
Console.WriteLine($"Error: The target machine ({machineName}) is not registered with Octopus ({OctopusServerAddress}).");
Console.WriteLine($"Error: The target machine ({machineName}) is not registered with Octopus ({OctopusServerAddress})");
return 1;
}

Console.WriteLine($"{machine.Id} {machine.Name} {String.Join(",", machine.Roles)} {String.Join(",", machine.EnvironmentIds)}");

Console.WriteLine($"Finding projects with the target roles ({String.Join(",", machine.Roles)})...");
Console.WriteLine($"Finding projects with the target roles ({String.Join(",", machine.Roles)})");

var projectIds = new List<string>();
var projects = octopus.GetProjects();
foreach(var project in projects)
{
var deploymentProcess = octopus.GetDeploymentProcess(project.DeploymentProcessId);

if (deploymentProcess.HasAnyRole(machine.Roles))
if (HasAnyRole(deploymentProcess, machine.Roles))
{
projectIds.Add(project.Id);
Console.WriteLine($"{project.Id} {project.Name}");
Expand All @@ -48,7 +50,7 @@ public override int Run()

var dashboard = octopus.GetDynamicDashboard(projectIds, machine.EnvironmentIds);

Console.WriteLine($"Creating deployments for target environments ({String.Join(",", machine.EnvironmentIds)})...");
Console.WriteLine($"Creating deployments for target environments ({String.Join(",", machine.EnvironmentIds)})");

foreach(var item in dashboard.Items)
{
Expand All @@ -61,5 +63,23 @@ public override int Run()

return 0;
}

private static bool HasAnyRole(DeploymentProcessResource deploymentProcess, IEnumerable<string> roles)
{
foreach (var step in deploymentProcess.Steps)
{
PropertyValueResource targetRolesProperty;
if (step.Properties.TryGetValue("Octopus.Action.TargetRoles", out targetRolesProperty))
{
var targetRoles = targetRolesProperty.Value.Split(',');
if (roles.Intersect(targetRoles).Any())
{
return true;
}
}
}

return false;
}
}
}
27 changes: 0 additions & 27 deletions nautilus/Helpers.cs

This file was deleted.

66 changes: 63 additions & 3 deletions nautilus/InstallCommand.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,72 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using CommandLine;

namespace Nautilus
{
[Verb("install", HelpText = "Installs an Octopus tenticle on the target machine.")]
[Verb("install", HelpText = "Installs an Octopus tenticle on the local machine.")]
public class InstallCommand : CommandBase
{
public override int Run()
{
protected override int Run(OctopusProxy octopus)
{
var systemInfo = octopus.GetSystemInfo();
var downloadVersion = systemInfo.Version;
if (Environment.Is64BitOperatingSystem)
{
downloadVersion += "-x64";
}
var downloadUrl = $"http://download.octopusdeploy.com/octopus/Octopus.Tentacle.{downloadVersion}.msi";
var filePath = $"{Path.GetTempPath()}Octopus.Tentacle.{downloadVersion}.msi";

Console.WriteLine($"Downloading installer from {downloadUrl} to {filePath}");
using (var webClient = new WebClient())
{
webClient.DownloadFile(downloadUrl, filePath);
}

Console.WriteLine($"Installing tentacle from {filePath}");
var processStartInfo = new ProcessStartInfo
{
FileName = "msiexec",
Arguments = $"/i \"{filePath}\" /quiet",
UseShellExecute = true
};
using (var process = Process.Start(processStartInfo))
{
var timeout = 120000;
if (!process.WaitForExit(timeout))
{
Console.WriteLine($"Error: Operation timed out ({timeout} milliseconds) while waiting for tentacle installation to complete");
return 1;
}

if (process.ExitCode != 0)
{
Console.WriteLine($"Tentacle installation failed and exited with code {process.ExitCode}");
return 1;
}
}

Console.WriteLine("Tentacle installation completed successfully");

Console.WriteLine("Configuring tentacle");

//todo: configure

// cd "C:\Program Files\Octopus Deploy\Tentacle"


// Tentacle.exe create-instance --instance "Tentacle" --config "C:\Octopus\Tentacle.config" --console
// Tentacle.exe new-certificate --instance "Tentacle" --if-blank --console
// Tentacle.exe configure --instance "Tentacle" --reset-trust --console
// Tentacle.exe configure --instance "Tentacle" --home "C:\Octopus" --app "C:\Octopus\Applications" --port "10933" --console
// Tentacle.exe configure --instance "Tentacle" --trust "YOUR_OCTOPUS_THUMBPRINT" --console
// "netsh" advfirewall firewall add rule "name=Octopus Deploy Tentacle" dir=in action=allow protocol=TCP localport=10933
// Tentacle.exe register-with --instance "Tentacle" --server "http://YOUR_OCTOPUS" --apiKey="API-YOUR_API_KEY" --role "web-server" --environment "Staging" --comms-style TentaclePassive --console
// Tentacle.exe service --instance "Tentacle" --install --start --console

return 0;
}
}
Expand Down
44 changes: 43 additions & 1 deletion nautilus/OctopusProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using Octopus.Client;
using Octopus.Client.Model;
using Octopus.Client.Model.Endpoints;

namespace Nautilus
{
Expand All @@ -15,10 +16,51 @@ public OctopusProxy(string serverAddress, string apiKey)

_repository = new OctopusRepository(new OctopusServerEndpoint(serverAddress, apiKey));
}

public SystemInfoResource GetSystemInfo()
{
var serverStatus = _repository.ServerStatus.GetServerStatus();
return _repository.ServerStatus.GetSystemInfo(serverStatus);
}

public CertificateResource GetGlobalCertificate()
{
return _repository.Certificates.Get("certificate-global");
}

public MachineResource GetMachine(string name)
{
return _repository.Machines.FindOne(m => m.Name == name);
return _repository.Machines.FindByName(name);
}

public MachineResource CreateMachine(string name, string thumbprint, string hostname, int port, IEnumerable<string> environmentNames, IEnumerable<string> roles)
{
var machine = new MachineResource();

machine.Name = name;

var environments = _repository.Environments.FindByNames(environmentNames);
foreach (var environment in environments)
{
machine.EnvironmentIds.Add(environment.Id);
}

foreach (var role in roles)
{
machine.Roles.Add(role);
}

var endpoint = new ListeningTentacleEndpointResource();
endpoint.Uri = $"https://{hostname}:{port}";
endpoint.Thumbprint = thumbprint;
machine.Endpoint = endpoint;

return _repository.Machines.Create(machine);
}

public void DeleteMachine(MachineResource machine)
{
_repository.Machines.Delete(machine);
}

public IEnumerable<ProjectResource> GetProjects()
Expand Down
12 changes: 10 additions & 2 deletions nautilus/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using CommandLine;
using System.Net;
using CommandLine;

namespace Nautilus
{
public class Program
{
public static int Main(string[] args)
{
{
// Enable TLS 1.2
ServicePointManager.SecurityProtocol =
SecurityProtocolType.Ssl3
| SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12;

return CommandLine.Parser.Default.ParseArguments<DeployCommand, InstallCommand, RegisterCommand, UnregisterCommand>(args)
.MapResult(
(DeployCommand command) => command.Run(),
Expand Down
47 changes: 45 additions & 2 deletions nautilus/RegisterCommand.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,55 @@
using System;
using System.Collections.Generic;
using CommandLine;

namespace Nautilus
{
[Verb("register", HelpText = "Registers the target machine with Octopus.")]
public class RegisterCommand : CommandBase
{
public override int Run()
{
[Option('n', "name", Required = false, HelpText = "The target machine name.")]
public string MachineName { get; set; }

[Option('t', "thumbprint", Required = false, HelpText = "The Octopus server certificate thumbprint. Defaults to global certificate.")]
public string Thumbprint { get; set; }

[Option('h', "host", Required = false, HelpText = "The target machine tentacle host name.")]
public string HostName { get; set; }

[Option('p', "port", Required = false, HelpText = "The target machine tentacle port.")]
public int? Port { get; set; }

[Option('e', "environments", Required = true, HelpText = "The environment names of the target machine.")]
public IList<string> Environments { get; set; }

[Option('r', "roles", Required = true, HelpText = "The roles of the target machine.")]
public IList<string> Roles { get; set; }

protected override int Run(OctopusProxy octopus)
{
var machineName = MachineName ?? Environment.MachineName;

var machine = octopus.GetMachine(machineName);
if (machine != null)
{
Console.WriteLine($"The target machine ({machineName}) is already registered with Octopus ({OctopusServerAddress})");
return 0;
}

var hostName = HostName ?? Environment.MachineName;
var port = Port ?? 10933;

var thumbprint = Thumbprint;
if (thumbprint == null)
{
var certicate = octopus.GetGlobalCertificate();
thumbprint = certicate.Thumbprint;
}

machine = octopus.CreateMachine(machineName, thumbprint, hostName, port, Environments, Roles);

Console.WriteLine($"Target machine ({machine.Name}) registered successfully");

return 0;
}
}
Expand Down
19 changes: 18 additions & 1 deletion nautilus/UnregisterCommand.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
using System;
using CommandLine;

namespace Nautilus
{
[Verb("unregister", HelpText = "Unregisters the target machine from Octopus.")]
public class UnregisterCommand : CommandBase
{
public override int Run()
[Option('n', "name", Required = false, HelpText = "The target machine name.")]
public string MachineName { get; set; }

protected override int Run(OctopusProxy octopus)
{
var machineName = MachineName ?? Environment.MachineName;

var machine = octopus.GetMachine(machineName);
if (machine == null)
{
Console.WriteLine($"The target machine ({machineName}) is not registered with Octopus ({OctopusServerAddress})");
return 0;
}

octopus.DeleteMachine(machine);

Console.WriteLine($"Target machine ({machine.Name}) unregistered successfully");

return 0;
}
}
Expand Down

0 comments on commit afb10ae

Please sign in to comment.