Skip to content

Commit

Permalink
Adds new runbook run endpoint
Browse files Browse the repository at this point in the history
* Adds new endpoints for creating Runbook Runs

* Adds version awareness to runbook run methods

* Adjust version tolerance to ensure integration tests are happy and to support pre-release canary customers


Co-authored-by: Andrew Best <[email protected]>
  • Loading branch information
paulegradie and andrewabest authored Jun 24, 2020
1 parent 771e969 commit 92ba6a1
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4312,6 +4312,28 @@ Octopus.Client.Model
Int32 QuantityToKeep { get; set; }
Boolean ShouldKeepForever { get; set; }
}
class RunbookRunParameters
{
.ctor()
String EnvironmentId { get; set; }
String[] EnvironmentIds { get; set; }
String[] ExcludedMachineIds { get; set; }
Boolean ForcePackageDownload { get; set; }
Dictionary<String, String> FormValues { get; set; }
String ProjectId { get; set; }
Nullable<DateTimeOffset> QueueTime { get; set; }
Nullable<DateTimeOffset> QueueTimeExpiry { get; set; }
String RunbookId { get; set; }
String RunbookSnapshotNameOrId { get; set; }
String[] SkipActions { get; set; }
String[] SpecificMachineIds { get; set; }
String TenantId { get; set; }
String[] TenantIds { get; set; }
String[] TenantTagNames { get; set; }
Boolean UseDefaultSnapshot { get; set; }
Nullable<Boolean> UseGuidedFailure { get; set; }
static Octopus.Client.Model.RunbookRunParameters MapFrom(Octopus.Client.Model.RunbookRunResource)
}
class RunbookRunPreviewResource
Octopus.Client.Extensibility.IResource
Octopus.Client.Model.IAuditedResource
Expand Down Expand Up @@ -6892,6 +6914,7 @@ Octopus.Client.Repositories
Octopus.Client.Model.RunbookRunTemplateResource GetRunbookRunTemplate(Octopus.Client.Model.RunbookResource)
Octopus.Client.Model.RunbookSnapshotTemplateResource GetRunbookSnapshotTemplate(Octopus.Client.Model.RunbookResource)
Octopus.Client.Model.RunbookRunResource Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunResource)
Octopus.Client.Model.RunbookRunResource[] Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunParameters)
}
interface IRunbookRunRepository
Octopus.Client.Repositories.IGet<RunbookRunResource>
Expand Down Expand Up @@ -7581,6 +7604,7 @@ Octopus.Client.Repositories.Async
Task<RunbookRunTemplateResource> GetRunbookRunTemplate(Octopus.Client.Model.RunbookResource)
Task<RunbookSnapshotTemplateResource> GetRunbookSnapshotTemplate(Octopus.Client.Model.RunbookResource)
Task<RunbookRunResource> Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunResource)
Task<RunbookRunResource[]> Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunParameters)
}
interface IRunbookRunRepository
Octopus.Client.Repositories.Async.IGet<RunbookRunResource>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4331,6 +4331,28 @@ Octopus.Client.Model
Int32 QuantityToKeep { get; set; }
Boolean ShouldKeepForever { get; set; }
}
class RunbookRunParameters
{
.ctor()
String EnvironmentId { get; set; }
String[] EnvironmentIds { get; set; }
String[] ExcludedMachineIds { get; set; }
Boolean ForcePackageDownload { get; set; }
Dictionary<String, String> FormValues { get; set; }
String ProjectId { get; set; }
Nullable<DateTimeOffset> QueueTime { get; set; }
Nullable<DateTimeOffset> QueueTimeExpiry { get; set; }
String RunbookId { get; set; }
String RunbookSnapshotNameOrId { get; set; }
String[] SkipActions { get; set; }
String[] SpecificMachineIds { get; set; }
String TenantId { get; set; }
String[] TenantIds { get; set; }
String[] TenantTagNames { get; set; }
Boolean UseDefaultSnapshot { get; set; }
Nullable<Boolean> UseGuidedFailure { get; set; }
static Octopus.Client.Model.RunbookRunParameters MapFrom(Octopus.Client.Model.RunbookRunResource)
}
class RunbookRunPreviewResource
Octopus.Client.Extensibility.IResource
Octopus.Client.Model.IAuditedResource
Expand Down Expand Up @@ -6917,6 +6939,7 @@ Octopus.Client.Repositories
Octopus.Client.Model.RunbookRunTemplateResource GetRunbookRunTemplate(Octopus.Client.Model.RunbookResource)
Octopus.Client.Model.RunbookSnapshotTemplateResource GetRunbookSnapshotTemplate(Octopus.Client.Model.RunbookResource)
Octopus.Client.Model.RunbookRunResource Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunResource)
Octopus.Client.Model.RunbookRunResource[] Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunParameters)
}
interface IRunbookRunRepository
Octopus.Client.Repositories.IGet<RunbookRunResource>
Expand Down Expand Up @@ -7606,6 +7629,7 @@ Octopus.Client.Repositories.Async
Task<RunbookRunTemplateResource> GetRunbookRunTemplate(Octopus.Client.Model.RunbookResource)
Task<RunbookSnapshotTemplateResource> GetRunbookSnapshotTemplate(Octopus.Client.Model.RunbookResource)
Task<RunbookRunResource> Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunResource)
Task<RunbookRunResource[]> Run(Octopus.Client.Model.RunbookResource, Octopus.Client.Model.RunbookRunParameters)
}
interface IRunbookRunRepository
Octopus.Client.Repositories.Async.IGet<RunbookRunResource>
Expand Down
63 changes: 63 additions & 0 deletions source/Octopus.Client/Model/RunbookRunParameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Octopus.Client.Model
{
public class RunbookRunParameters
{
/// <summary>
/// Parameter class for marshalling params between OctopusCLI and Octopus Server
/// This class is used to facilitate backwards compatibility while extending /runbooks/{id}/run"
/// </summary>
public RunbookRunParameters()
{
FormValues = new Dictionary<string, string>();
SpecificMachineIds = new string[0];
ExcludedMachineIds = new string[0];
EnvironmentIds = new string[0];
TenantTagNames = new string[0];
TenantIds = new string[0];
SkipActions = new string[0];
}

public bool UseDefaultSnapshot { get; set; } = true;

public string RunbookId { get; set; }
public string ProjectId { get; set; }
public string RunbookSnapshotNameOrId { get; set; }
public string EnvironmentId { get; set; }
public string[] EnvironmentIds { get; set; }
public bool ForcePackageDownload { get; set; }
public bool? UseGuidedFailure { get; set; }
public string[] SpecificMachineIds { get; set; }
public string[] ExcludedMachineIds { get; set; }
public string TenantId { get; set; }
public string[] TenantIds { get; set; }
public string[] TenantTagNames { get; set; }
public string[] SkipActions { get; set; }
public DateTimeOffset? QueueTime { get; set; }
public DateTimeOffset? QueueTimeExpiry { get; set; }
public Dictionary<string, string> FormValues { get; set; }

public static RunbookRunParameters MapFrom(RunbookRunResource runbookRun)
{
return new RunbookRunParameters
{
UseDefaultSnapshot = true,
RunbookId = runbookRun.RunbookId,
ProjectId = runbookRun.ProjectId,
EnvironmentId = runbookRun.EnvironmentId,
ForcePackageDownload = runbookRun.ForcePackageDownload,
UseGuidedFailure = runbookRun.UseGuidedFailure,
SpecificMachineIds = runbookRun.SpecificMachineIds != null ? runbookRun.SpecificMachineIds.ToArray() : new string[0],
ExcludedMachineIds = runbookRun.ExcludedMachineIds != null ? runbookRun.ExcludedMachineIds.ToArray() : new string[0],
TenantId = runbookRun.TenantId,
SkipActions = runbookRun.SkipActions != null ? runbookRun.SkipActions.ToArray() : new string[0],
QueueTime = runbookRun.QueueTime,
QueueTimeExpiry = runbookRun.QueueTimeExpiry,
FormValues = runbookRun.FormValues ?? new Dictionary<string, string>()
};
}
}
}
38 changes: 35 additions & 3 deletions source/Octopus.Client/Repositories/Async/RunbookRepository.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Threading.Tasks;
using System.Linq;
using System.Threading.Tasks;
using Octopus.Client.Editors.Async;
using Octopus.Client.Exceptions;
using Octopus.Client.Model;

namespace Octopus.Client.Repositories.Async
Expand All @@ -12,13 +14,19 @@ public interface IRunbookRepository : IFindByName<RunbookResource>, IGet<Runbook
Task<RunbookRunTemplateResource> GetRunbookRunTemplate(RunbookResource runbook);
Task<RunbookRunPreviewResource> GetPreview(DeploymentPromotionTarget promotionTarget);
Task<RunbookRunResource> Run(RunbookResource runbook, RunbookRunResource runbookRun);
Task<RunbookRunResource[]> Run(RunbookResource runbook, RunbookRunParameters runbookRunParameters);
}

class RunbookRepository : BasicRepository<RunbookResource>, IRunbookRepository
{
private readonly SemanticVersion integrationTestVersion;
private readonly SemanticVersion versionAfterWhichRunbookRunParametersAreAvailable;

public RunbookRepository(IOctopusAsyncRepository repository)
: base(repository, "Runbooks")
{
integrationTestVersion = SemanticVersion.Parse("0.0.0-local");
versionAfterWhichRunbookRunParametersAreAvailable = SemanticVersion.Parse("2020.2.99999");
}

public Task<RunbookResource> FindByName(ProjectResource project, string name)
Expand Down Expand Up @@ -46,9 +54,33 @@ public Task<RunbookRunPreviewResource> GetPreview(DeploymentPromotionTarget prom
return Client.Get<RunbookRunPreviewResource>(promotionTarget.Link("RunbookRunPreview"));
}

public Task<RunbookRunResource> Run(RunbookResource runbook, RunbookRunResource runbookRun)
private bool ServerSupportsRunbookRunParameters(string version)
{
var serverVersion = SemanticVersion.Parse(version);

return serverVersion >= versionAfterWhichRunbookRunParametersAreAvailable ||
serverVersion == integrationTestVersion;
}

public async Task<RunbookRunResource> Run(RunbookResource runbook, RunbookRunResource runbookRun)
{
return Client.Post<object, RunbookRunResource>(runbook.Link("CreateRunbookRun"), runbookRun);
var serverSupportsRunbookRunParameters = ServerSupportsRunbookRunParameters((await Repository.LoadRootDocument()).Version);

return serverSupportsRunbookRunParameters
? (await Run(runbook, RunbookRunParameters.MapFrom(runbookRun))).FirstOrDefault()
: await Client.Post<object, RunbookRunResource>(runbook.Link("CreateRunbookRun"), runbookRun);
}

public async Task<RunbookRunResource[]> Run(RunbookResource runbook, RunbookRunParameters runbookRunParameters)
{
var serverVersion = (await Repository.LoadRootDocument()).Version;
var serverSupportsRunbookRunParameters = ServerSupportsRunbookRunParameters(serverVersion);

if (serverSupportsRunbookRunParameters == false)
throw new UnsupportedApiVersionException($"This Octopus Deploy server is an older version ({serverVersion}) that does not yet support RunbookRunParameters. " +
$"Please update your Octopus Deploy server to 2020.3.* or newer to access this feature.");

return await Client.Post<object, RunbookRunResource[]>(runbook.Link("CreateRunbookRun"), runbookRunParameters);
}
}
}
36 changes: 34 additions & 2 deletions source/Octopus.Client/Repositories/RunbookRepository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Linq;
using Octopus.Client.Editors;
using Octopus.Client.Exceptions;
using Octopus.Client.Model;

namespace Octopus.Client.Repositories
Expand All @@ -11,13 +13,19 @@ public interface IRunbookRepository : IFindByName<RunbookResource>, IGet<Runbook
RunbookRunTemplateResource GetRunbookRunTemplate(RunbookResource runbook);
RunbookRunPreviewResource GetPreview(DeploymentPromotionTarget promotionTarget);
RunbookRunResource Run(RunbookResource runbook, RunbookRunResource runbookRun);
RunbookRunResource[] Run(RunbookResource runbook, RunbookRunParameters runbookRunParameters);
}

class RunbookRepository : BasicRepository<RunbookResource>, IRunbookRepository
{
private readonly SemanticVersion versionAfterWhichRunbookRunParametersAreAvailable;
private readonly SemanticVersion integrationTestVersion;

public RunbookRepository(IOctopusRepository repository)
: base(repository, "Runbooks")
{
integrationTestVersion = SemanticVersion.Parse("0.0.0-local");
versionAfterWhichRunbookRunParametersAreAvailable = SemanticVersion.Parse("2020.2.99999");
}

public RunbookResource FindByName(ProjectResource project, string name)
Expand Down Expand Up @@ -45,9 +53,33 @@ public RunbookRunPreviewResource GetPreview(DeploymentPromotionTarget promotionT
return Client.Get<RunbookRunPreviewResource>(promotionTarget.Link("RunbookRunPreview"));
}

private bool ServerSupportsRunbookRunParameters(string version)
{
var serverVersion = SemanticVersion.Parse(version);

return serverVersion >= versionAfterWhichRunbookRunParametersAreAvailable ||
serverVersion == integrationTestVersion;
}

public RunbookRunResource Run(RunbookResource runbook, RunbookRunResource runbookRun)
{
return Client.Post<object, RunbookRunResource>(runbook.Link("CreateRunbookRun"), runbookRun);
var serverSupportsRunbookRunParameters = ServerSupportsRunbookRunParameters(Repository.LoadRootDocument().Version);

return serverSupportsRunbookRunParameters
? Run(runbook, RunbookRunParameters.MapFrom(runbookRun)).FirstOrDefault()
: Client.Post<object, RunbookRunResource>(runbook.Link("CreateRunbookRun"), runbookRun);
}

public RunbookRunResource[] Run(RunbookResource runbook, RunbookRunParameters runbookRunParameters)
{
var serverVersion = Repository.LoadRootDocument().Version;
var serverSupportsRunbookRunParameters = ServerSupportsRunbookRunParameters(serverVersion);

if (serverSupportsRunbookRunParameters == false)
throw new UnsupportedApiVersionException($"This Octopus Deploy server is an older version ({serverVersion}) that does not yet support RunbookRunParameters. " +
"Please update your Octopus Deploy server to 2020.3.* or newer to access this feature.");

return Client.Post<object, RunbookRunResource[]>(runbook.Link("CreateRunbookRun"), runbookRunParameters);
}
}
}

0 comments on commit 92ba6a1

Please sign in to comment.