Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Commit

Permalink
Add support for ignoring objects having specified tag(s) when reading…
Browse files Browse the repository at this point in the history
… from Kong
  • Loading branch information
shaynevanasperen committed Nov 12, 2019
1 parent f7e3a9b commit 76c96ef
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 14 deletions.
5 changes: 5 additions & 0 deletions src/Kongverge/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public class KongvergeCommand : CommandBase
[Option("-p|--password=<Password>", "Optional. Basic Auth protected Kong Admin API Password (can be passed via redirected stdin)", CommandOptionType.SingleOrNoValue)]
public Password BasicAuthPassword { get; }

[Option("-i|--ignore=<Tag>", "Optional. A tag to be ignored when reading from Kong. Can be specified multiple times.", CommandOptionType.MultipleValue)]
public string[] IgnoreTags { get; }

protected ValidationResult OnValidate(ValidationContext validationContext, CommandLineContext commandLineContext)
{
if (!string.IsNullOrWhiteSpace(BasicAuthUser) && string.IsNullOrWhiteSpace(BasicAuthPassword.Value))
Expand Down Expand Up @@ -100,6 +103,7 @@ public override void Initialize(CommandLineApplication app)
{
Parent.Initialize(app);
app.GetRequiredService<KongvergeWorkflowArguments>().InputFolder = InputFolder;
app.GetRequiredService<KongvergeWorkflowArguments>().IgnoreTags = Parent.IgnoreTags;
}

public Task<int> OnExecuteAsync(CommandLineApplication app)
Expand All @@ -120,6 +124,7 @@ public Task<int> OnExecuteAsync(CommandLineApplication app)
{
Parent.Initialize(app);
app.GetRequiredService<ExportWorkflowArguments>().OutputFolder = OutputFolder;
app.GetRequiredService<ExportWorkflowArguments>().IgnoreTags = Parent.IgnoreTags;
return app.GetRequiredService<ExportWorkflow>().Execute();
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Kongverge/DTOs/ExportWorkflowArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ namespace Kongverge.DTOs
public class ExportWorkflowArguments
{
public string OutputFolder { get; set; }
public string[] IgnoreTags { get; set; }
}
}
1 change: 1 addition & 0 deletions src/Kongverge/DTOs/KongvergeWorkflowArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace Kongverge.DTOs
public class KongvergeWorkflowArguments
{
public string InputFolder { get; set; }
public string[] IgnoreTags { get; set; }
public bool DryRun { get; set; } = false;
}
}
18 changes: 13 additions & 5 deletions src/Kongverge/Services/ConfigBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -8,21 +9,23 @@ namespace Kongverge.Services
{
public class ConfigBuilder
{
public virtual async Task<KongvergeConfiguration> FromKong(IKongAdminReader kongReader)
public virtual async Task<KongvergeConfiguration> FromKong(IKongAdminReader kongReader, IReadOnlyCollection<string> ignoreTags)
{
ignoreTags ??= Array.Empty<string>();

Log.Information("Reading configuration from Kong");

Log.Verbose("Getting consumers from Kong");
var consumers = await kongReader.GetConsumers();
var consumers = IgnoreByTag(ignoreTags, await kongReader.GetConsumers());

Log.Verbose("Getting plugins from Kong");
var plugins = await kongReader.GetPlugins();
var plugins = IgnoreByTag(ignoreTags, await kongReader.GetPlugins());

Log.Verbose("Getting services from Kong");
var services = await kongReader.GetServices();
var services = IgnoreByTag(ignoreTags, await kongReader.GetServices());

Log.Verbose("Getting routes from Kong");
var routes = await kongReader.GetRoutes();
var routes = IgnoreByTag(ignoreTags, await kongReader.GetRoutes());

foreach (var consumer in consumers)
{
Expand All @@ -48,6 +51,11 @@ public virtual async Task<KongvergeConfiguration> FromKong(IKongAdminReader kong
return configuration;
}

private static IReadOnlyCollection<T> IgnoreByTag<T>(IReadOnlyCollection<string> tags, IEnumerable<T> objects) where T : KongObject
{
return objects.Where(x => !tags.Any() || x.Tags?.Any(tags.Contains) != true).ToArray();
}

private static void PopulateServiceTree(KongService service, IReadOnlyCollection<KongRoute> routes, IReadOnlyCollection<KongPlugin> plugins)
{
service.Plugins = plugins.Where(x => x.Service?.Id == service.Id).ToArray();
Expand Down
2 changes: 1 addition & 1 deletion src/Kongverge/Workflow/ExportWorkflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ExportWorkflow(

public override async Task<int> DoExecute()
{
var existingConfiguration = await _configBuilder.FromKong(KongReader);
var existingConfiguration = await _configBuilder.FromKong(KongReader, _arguments.IgnoreTags);

await _configWriter.WriteConfiguration(existingConfiguration, _arguments.OutputFolder);

Expand Down
4 changes: 2 additions & 2 deletions src/Kongverge/Workflow/KongvergeWorkflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public override async Task<int> DoExecute()
return ExitWithCode.Return(ExitCode.InvalidConfigurationFiles, ex.Message);
}

var existingConfiguration = await _configBuilder.FromKong(KongReader);
var existingConfiguration = await _configBuilder.FromKong(KongReader, _arguments.IgnoreTags);

try
{
Expand All @@ -61,7 +61,7 @@ public override async Task<int> DoExecute()
catch (KongException e) when (e.StatusCode == HttpStatusCode.BadRequest)
{
Log.Error(e, $"Error converging target configuration: {e}");
var currentConfiguration = await _configBuilder.FromKong(KongReader);
var currentConfiguration = await _configBuilder.FromKong(KongReader, _arguments.IgnoreTags);
Log.Information($"Attempting rollback to previous configuration: {existingConfiguration}");
await ConvergeConfiguration(currentConfiguration, existingConfiguration);
return ExitWithCode.Return(ExitCode.UnspecifiedError, "An error occurred while attempting to converge target configuration. Rollback was successful.");
Expand Down
27 changes: 27 additions & 0 deletions test/Kongverge.IntegrationTests/FolderIgnored/global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"plugins": [
{
"tags": [ "kongverge-ignore" ],
"name": "key-auth",
"config": {}
}
],
"consumers": [
{
"tags": [ "kongverge-ignore" ],
"username": "ignored",
"custom_id": "ignored_user",
"id": "65c5e2d4-8a05-4c99-bea8-665a41b33ace",
"plugins": [
{
"name": "request-termination",
"config": {
"status_code": 401,
"content_type": "application/json; charset=utf-8",
"body": "{ \"error\": \"Authentication required\" }"
}
}
]
}
]
}
34 changes: 34 additions & 0 deletions test/Kongverge.IntegrationTests/FolderIgnored/service.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"tags": [ "kongverge-ignore" ],
"name": "service",
"host": "www.service1.com",
"port": 80,
"path": "/resource",
"protocol": "http",
"retries": 1,
"connect_timeout": 10000,
"read_timeout": 10000,
"write_timeout": 10000,
"plugins": [
{
"name": "request-termination",
"config": {
"message": "request-terminated",
"status_code": 403
}
}
],
"routes": [
{
"paths": [
"/resource1"
],
"protocols": [
"http",
"https"
],
"regex_priority": 40,
"strip_path": true
}
]
}
19 changes: 18 additions & 1 deletion test/Kongverge.IntegrationTests/ProgramSteps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ namespace Kongverge.IntegrationTests
public abstract class ProgramSteps
{
public const string Host = "localhost";
public const string Ignore = "kongverge-ignore";
public const int Port = 8001;

protected const string And = "_";
protected const string NonExistent = nameof(NonExistent);
protected const string InvalidData = nameof(InvalidData);
protected const string Ignored = nameof(Ignored);
protected const string A = nameof(A);
protected const string B = nameof(B);
protected const string Output = nameof(Output);
Expand Down Expand Up @@ -55,9 +57,17 @@ protected void InvokingMain()
ExitCode = (ExitCode)Program.Main(arguments);
}

protected void InvokingMainAgainForExport()
protected void InvokingMainAgainForExport() => InvokingMainAgainForExport(false);

protected void InvokingMainAgainForExportWithIgnoreTags() => InvokingMainAgainForExport(true);

protected void InvokingMainAgainForExport(bool ignoreTags)
{
AValidHost();
if (ignoreTags)
{
IgnoreTags();
}
TheExportCommand();
OutputFolderIs(Output);
InvokingMain();
Expand All @@ -69,6 +79,8 @@ protected void NoArguments() { }

protected void AValidHost() => Arguments.AddPair("--host", Host);

protected void IgnoreTags() => Arguments.AddPair("--ignore", Ignore);

protected void TheRunCommand() => Arguments.Add("run");

protected void TheDryRunCommand() => Arguments.Add("dry-run");
Expand Down Expand Up @@ -127,6 +139,11 @@ protected void KongIsBlank()
KongMatchesInputFolder(folderPath);
}

protected void KongMatchesIgnored()
{
KongMatchesInputFolder(Ignored);
}

protected void KongMatchesInputFolder(string folder)
{
AValidHost();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ public void Scenario1() =>
.TearDownWith(s => KongIsBlank())
.BDDfy();

[BddfyFact(DisplayName = nameof(KongIsBlank) + And + nameof(AValidHost) + And + nameof(TheRunCommand) + And + nameof(InputFolderIs) + B)]
[BddfyFact(DisplayName = nameof(KongMatchesIgnored) + And + nameof(AValidHost) + And + nameof(TheRunCommand) + And + nameof(InputFolderIs) + B)]
public void Scenario2() =>
this.Given(x => x.KongIsBlank())
this.Given(x => x.KongMatchesIgnored())
.And(x => x.AValidHost())
.And(x => x.IgnoreTags())
.And(x => x.TheRunCommand())
.And(x => x.InputFolderIs(B))
.When(x => x.InvokingMain())
.And(x => x.TheExitCodeIs(ExitCode.Success))
.And(x => x.InvokingMainAgainForExport())
.And(x => x.InvokingMainAgainForExportWithIgnoreTags())
.Then(x => x.TheExitCodeIs(ExitCode.Success))
.And(x => x.OutputFolderContentsMatchInputFolderContents())
.TearDownWith(s => KongIsBlank())
Expand Down
4 changes: 2 additions & 2 deletions test/Kongverge.Tests/Workflow/WorkflowSteps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public abstract class WorkflowSteps<T> : ScenarioFor<T> where T : Kongverge.Work

protected WorkflowSteps()
{
GetMock<ConfigBuilder>().Setup(x => x.FromKong(Get<IKongAdminReader>())).ReturnsAsync(Existing);
GetMock<ConfigBuilder>().Setup(x => x.FromKong(Get<IKongAdminReader>(), It.IsAny<IReadOnlyCollection<string>>())).ReturnsAsync(Existing);
GetMock<IKongAdminReader>().Setup(x => x.GetSchema(It.IsAny<string>())).ReturnsAsync(new KongSchema());
}

Expand All @@ -40,6 +40,6 @@ protected void KongIsReachable(string version) => GetMock<IKongAdminReader>()

protected void TheExitCodeIs(ExitCode exitCode) => ExitCode.Should().Be(exitCode);

protected void TheConfigurationIsRetrievedFromKong() => GetMock<ConfigBuilder>().Verify(x => x.FromKong(Get<IKongAdminReader>()));
protected void TheConfigurationIsRetrievedFromKong() => GetMock<ConfigBuilder>().Verify(x => x.FromKong(Get<IKongAdminReader>(), It.IsAny<IReadOnlyCollection<string>>()));
}
}

0 comments on commit 76c96ef

Please sign in to comment.