From 63f414aadea41b068dfd79d01bd7bd3736dfdaff Mon Sep 17 00:00:00 2001 From: Liam McLennan Date: Fri, 19 Apr 2024 16:00:56 +1000 Subject: [PATCH 1/7] stubbed index commands --- global.json | 2 +- src/SeqCli/Cli/Commands/Index/ListCommand.cs | 55 +++++++++++++++++ .../Cli/Commands/Index/SuppressCommand.cs | 59 +++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/SeqCli/Cli/Commands/Index/ListCommand.cs create mode 100644 src/SeqCli/Cli/Commands/Index/SuppressCommand.cs diff --git a/global.json b/global.json index 1ee82c37..1658e451 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.203" + "version": "8.0.204" } } diff --git a/src/SeqCli/Cli/Commands/Index/ListCommand.cs b/src/SeqCli/Cli/Commands/Index/ListCommand.cs new file mode 100644 index 00000000..a3eacb61 --- /dev/null +++ b/src/SeqCli/Cli/Commands/Index/ListCommand.cs @@ -0,0 +1,55 @@ +// Copyright 2018 Datalust Pty Ltd and Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Linq; +using System.Threading.Tasks; +using SeqCli.Cli.Features; +using SeqCli.Config; +using SeqCli.Connection; + +namespace SeqCli.Cli.Commands.Index; + +[Command("index", "list", "List indexes", Example="seqcli index list")] +class ListCommand : Command +{ + readonly SeqConnectionFactory _connectionFactory; + + readonly ConnectionFeature _connection; + readonly OutputFormatFeature _output; + + public ListCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) + { + if (config == null) throw new ArgumentNullException(nameof(config)); + _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + _output = Enable(new OutputFormatFeature(config.Output)); + _connection = Enable(); + } + + protected override async Task Run() + { + var connection = _connectionFactory.Connect(_connection); + + // var list = _userIdentity.Id != null ? + // new[] { await connection.Users.FindAsync(_userIdentity.Id) } : + // (await connection.Users.ListAsync()) + // .Where(u => _userIdentity.Name == null || _userIdentity.Name == u.Username); + // + // _output.ListEntities(list); + + await Task.Delay(1); + return 0; + } +} \ No newline at end of file diff --git a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs new file mode 100644 index 00000000..0b390791 --- /dev/null +++ b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs @@ -0,0 +1,59 @@ +// Copyright 2018 Datalust Pty Ltd and Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Threading.Tasks; +using SeqCli.Cli.Features; +using SeqCli.Config; +using SeqCli.Connection; +using Serilog; + +namespace SeqCli.Cli.Commands.Index; + +[Command("index", "suppress", "Suppress index", Example="seqcli index suppress -i signal-6543")] +class SuppressCommand : Command +{ + readonly SeqConnectionFactory _connectionFactory; + readonly ConnectionFeature _connection; + string? _id; + + public SuppressCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) + { + if (config == null) throw new ArgumentNullException(nameof(config)); + _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + Options.Add( + "i=|id=", + "The id of an entity with an index to suppress", + id => _id = id); + + _connection = Enable(); + } + + protected override async Task Run() + { + if (_id == null) + { + Log.Error("An `id` must be specified"); + return 1; + } + + // var connection = _connectionFactory.Connect(_connection); + // var toRemove = await connection.RetentionPolicies.FindAsync(_id); + // await connection.RetentionPolicies.RemoveAsync(toRemove); + + await Task.Delay(1); + return 0; + } +} \ No newline at end of file From 1b26754d7f328f5f6af1409e1ad9663c4dab47b3 Mon Sep 17 00:00:00 2001 From: Liam McLennan Date: Mon, 22 Apr 2024 16:01:04 +1000 Subject: [PATCH 2/7] Adding index commands --- .../Commands/ExpressionIndex/ListCommand.cs | 33 +++++++++++++++++++ src/SeqCli/Cli/Commands/Index/ListCommand.cs | 9 ++--- .../Cli/Commands/Index/SuppressCommand.cs | 14 +++++--- src/SeqCli/SeqCli.csproj | 2 +- .../Index/IndexBasicsTestCase.cs | 22 +++++++++++++ 5 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs create mode 100644 test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs diff --git a/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs b/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs new file mode 100644 index 00000000..172cb04a --- /dev/null +++ b/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using SeqCli.Cli.Features; +using SeqCli.Config; +using SeqCli.Connection; + +namespace SeqCli.Cli.Commands.ExpressionIndex; + +[Command("expressionindex", "list", "List expression indexes", Example="seqcli expressionindex list")] +class ListCommand : Command +{ + readonly SeqConnectionFactory _connectionFactory; + + readonly ConnectionFeature _connection; + readonly OutputFormatFeature _output; + + public ListCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) + { + if (config == null) throw new ArgumentNullException(nameof(config)); + _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + _output = Enable(new OutputFormatFeature(config.Output)); + _connection = Enable(); + } + + protected override async Task Run() + { + var connection = _connectionFactory.Connect(_connection); + var list = await connection.ExpressionIndexes.ListAsync(); + _output.ListEntities(list); + return 0; + } +} \ No newline at end of file diff --git a/src/SeqCli/Cli/Commands/Index/ListCommand.cs b/src/SeqCli/Cli/Commands/Index/ListCommand.cs index a3eacb61..6780f17a 100644 --- a/src/SeqCli/Cli/Commands/Index/ListCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/ListCommand.cs @@ -42,12 +42,9 @@ protected override async Task Run() { var connection = _connectionFactory.Connect(_connection); - // var list = _userIdentity.Id != null ? - // new[] { await connection.Users.FindAsync(_userIdentity.Id) } : - // (await connection.Users.ListAsync()) - // .Where(u => _userIdentity.Name == null || _userIdentity.Name == u.Username); - // - // _output.ListEntities(list); + var list = await connection.Indexes.ListAsync(); + + _output.ListEntities(list); await Task.Delay(1); return 0; diff --git a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs index 0b390791..a24c6b5c 100644 --- a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs @@ -14,6 +14,7 @@ using System; using System.Threading.Tasks; +using Seq.Api.Model.Indexes; using SeqCli.Cli.Features; using SeqCli.Config; using SeqCli.Connection; @@ -35,7 +36,7 @@ public SuppressCommand(SeqConnectionFactory connectionFactory, SeqCliConfig conf Options.Add( "i=|id=", - "The id of an entity with an index to suppress", + "The id of a signal index to suppress", id => _id = id); _connection = Enable(); @@ -49,9 +50,14 @@ protected override async Task Run() return 1; } - // var connection = _connectionFactory.Connect(_connection); - // var toRemove = await connection.RetentionPolicies.FindAsync(_id); - // await connection.RetentionPolicies.RemoveAsync(toRemove); + var connection = _connectionFactory.Connect(_connection); + var toSuppress = await connection.Indexes.FindAsync(_id); + if (toSuppress.IndexedEntityType != IndexedEntityType.Signal) + { + Log.Error("Only Signal indexes may be suppressed; to delete an expression index or an alert index remove the expression index or alert"); + return 1; + } + await connection.Indexes.SuppressAsync(toSuppress); await Task.Delay(1); return 0; diff --git a/src/SeqCli/SeqCli.csproj b/src/SeqCli/SeqCli.csproj index 69b925f7..52507e05 100644 --- a/src/SeqCli/SeqCli.csproj +++ b/src/SeqCli/SeqCli.csproj @@ -28,6 +28,7 @@ + @@ -38,7 +39,6 @@ - diff --git a/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs b/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs new file mode 100644 index 00000000..5969524c --- /dev/null +++ b/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Seq.Api; +using SeqCli.EndToEnd.Support; +using Serilog; +using Xunit; + +namespace SeqCli.EndToEnd.Index; + +public class IndexBasicsTestCase : ICliTestCase +{ + public Task ExecuteAsync( + SeqConnection connection, + ILogger logger, + CliCommandRunner runner) + { + var exit = runner.Exec("index list", ""); + Assert.Equal(0, exit); + var output = runner.LastRunProcess?.Output; + Assert.Equal("list output goes here", output?.Trim()); + return Task.CompletedTask; + } +} \ No newline at end of file From 0e985ff38125bbcaee3a50b22a50357d1addd835 Mon Sep 17 00:00:00 2001 From: Liam McLennan Date: Tue, 23 Apr 2024 13:57:52 +1000 Subject: [PATCH 3/7] Complete index and expression index commands --- .../Commands/ExpressionIndex/CreateCommand.cs | 70 +++++++++++++++++++ .../Commands/ExpressionIndex/ListCommand.cs | 10 ++- .../Commands/ExpressionIndex/RemoveCommand.cs | 59 ++++++++++++++++ src/SeqCli/Cli/Commands/Index/ListCommand.cs | 12 +++- .../Cli/Commands/Index/SuppressCommand.cs | 4 +- src/SeqCli/SeqCli.csproj | 2 +- src/SeqCli/Templates/Export/EntityName.cs | 5 ++ .../Templates/Export/TemplateSetExporter.cs | 8 +++ .../Templates/Import/TemplateSetImporter.cs | 2 +- 9 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs create mode 100644 src/SeqCli/Cli/Commands/ExpressionIndex/RemoveCommand.cs diff --git a/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs b/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs new file mode 100644 index 00000000..e72199b5 --- /dev/null +++ b/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs @@ -0,0 +1,70 @@ +// Copyright © Datalust Pty Ltd and Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Threading.Tasks; +using Seq.Api.Model.Signals; +using SeqCli.Cli.Features; +using SeqCli.Config; +using SeqCli.Connection; +using SeqCli.Signals; +using SeqCli.Syntax; +using SeqCli.Util; +using Serilog; + +namespace SeqCli.Cli.Commands.ExpressionIndex; + +[Command("expressionindex", "create", "Create an expression index", + Example = "seqcli expressionindex create --expression \"ServerName\"")] +class CreateCommand : Command +{ + readonly SeqConnectionFactory _connectionFactory; + + readonly ConnectionFeature _connection; + readonly OutputFormatFeature _output; + + string? _expression; + + public CreateCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) + { + _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + Options.Add( + "expression=", + "The expression to index", + v => _expression = ArgumentString.Normalize(v)); + + _connection = Enable(); + _output = Enable(new OutputFormatFeature(config.Output)); + } + + protected override async Task Run() + { + var connection = _connectionFactory.Connect(_connection); + + if (string.IsNullOrEmpty(_expression)) + { + Log.Error("An `expression` must be specified"); + return 1; + } + + var index = await connection.ExpressionIndexes.TemplateAsync(); + index.Expression = _expression; + index = await connection.ExpressionIndexes.AddAsync(index); + + _output.WriteEntity(index); + + return 0; + } +} \ No newline at end of file diff --git a/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs b/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs index 172cb04a..6836d3f1 100644 --- a/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs +++ b/src/SeqCli/Cli/Commands/ExpressionIndex/ListCommand.cs @@ -13,12 +13,18 @@ class ListCommand : Command readonly ConnectionFeature _connection; readonly OutputFormatFeature _output; + string? _id; public ListCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) { if (config == null) throw new ArgumentNullException(nameof(config)); _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + Options.Add( + "i=|id=", + "The id of a single expression index to list", + id => _id = id); + _output = Enable(new OutputFormatFeature(config.Output)); _connection = Enable(); } @@ -26,7 +32,9 @@ public ListCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) protected override async Task Run() { var connection = _connectionFactory.Connect(_connection); - var list = await connection.ExpressionIndexes.ListAsync(); + var list = _id is not null + ? [await connection.ExpressionIndexes.FindAsync(_id)] + : await connection.ExpressionIndexes.ListAsync(); _output.ListEntities(list); return 0; } diff --git a/src/SeqCli/Cli/Commands/ExpressionIndex/RemoveCommand.cs b/src/SeqCli/Cli/Commands/ExpressionIndex/RemoveCommand.cs new file mode 100644 index 00000000..c7ebee37 --- /dev/null +++ b/src/SeqCli/Cli/Commands/ExpressionIndex/RemoveCommand.cs @@ -0,0 +1,59 @@ +// Copyright 2018 Datalust Pty Ltd and Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Linq; +using System.Threading.Tasks; +using SeqCli.Cli.Features; +using SeqCli.Connection; +using Serilog; + +namespace SeqCli.Cli.Commands.ExpressionIndex; + +[Command("expressionindex", "remove", "Remove an expression index from the server", + Example = "seqcli expressionindex -i expressionindex-2529")] +class RemoveCommand : Command +{ + readonly SeqConnectionFactory _connectionFactory; + + readonly ConnectionFeature _connection; + string? _id; + + public RemoveCommand(SeqConnectionFactory connectionFactory) + { + _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + Options.Add( + "i=|id=", + "The id of an expression index to remove", + id => _id = id); + + _connection = Enable(); + } + + protected override async Task Run() + { + if (_id == null) + { + Log.Error("An `id` must be specified"); + return 1; + } + + var connection = _connectionFactory.Connect(_connection); + var toRemove = await connection.ExpressionIndexes.FindAsync(_id); + await connection.ExpressionIndexes.RemoveAsync(toRemove); + + return 0; + } +} \ No newline at end of file diff --git a/src/SeqCli/Cli/Commands/Index/ListCommand.cs b/src/SeqCli/Cli/Commands/Index/ListCommand.cs index 6780f17a..ec8dc446 100644 --- a/src/SeqCli/Cli/Commands/Index/ListCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/ListCommand.cs @@ -13,8 +13,10 @@ // limitations under the License. using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Seq.Api.Model.Indexes; using SeqCli.Cli.Features; using SeqCli.Config; using SeqCli.Connection; @@ -28,11 +30,17 @@ class ListCommand : Command readonly ConnectionFeature _connection; readonly OutputFormatFeature _output; + string? _id; public ListCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config) { if (config == null) throw new ArgumentNullException(nameof(config)); _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); + + Options.Add( + "i=|id=", + "The id of a single index to list", + id => _id = id); _output = Enable(new OutputFormatFeature(config.Output)); _connection = Enable(); @@ -42,7 +50,9 @@ protected override async Task Run() { var connection = _connectionFactory.Connect(_connection); - var list = await connection.Indexes.ListAsync(); + var list = _id is not null + ? [await connection.Indexes.FindAsync(_id)] + : await connection.Indexes.ListAsync(); _output.ListEntities(list); diff --git a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs index a24c6b5c..4dd760db 100644 --- a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs @@ -22,7 +22,7 @@ namespace SeqCli.Cli.Commands.Index; -[Command("index", "suppress", "Suppress index", Example="seqcli index suppress -i signal-6543")] +[Command("index", "suppress", "Suppress index", Example="seqcli index suppress -i index-2191448f1d9b4f22bd32c6edef752748")] class SuppressCommand : Command { readonly SeqConnectionFactory _connectionFactory; @@ -36,7 +36,7 @@ public SuppressCommand(SeqConnectionFactory connectionFactory, SeqCliConfig conf Options.Add( "i=|id=", - "The id of a signal index to suppress", + "The id of an index of a signal to suppress", id => _id = id); _connection = Enable(); diff --git a/src/SeqCli/SeqCli.csproj b/src/SeqCli/SeqCli.csproj index 52507e05..983bf911 100644 --- a/src/SeqCli/SeqCli.csproj +++ b/src/SeqCli/SeqCli.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/SeqCli/Templates/Export/EntityName.cs b/src/SeqCli/Templates/Export/EntityName.cs index 34512914..cad514d3 100644 --- a/src/SeqCli/Templates/Export/EntityName.cs +++ b/src/SeqCli/Templates/Export/EntityName.cs @@ -15,6 +15,11 @@ public static string FromEntityType(Type entityType) public static string ToResourceGroup(string resource) { + if (resource.Equals("expressionindex")) + { + return "expressionindexes"; + } + if (!resource.EndsWith("y")) return resource + "s"; diff --git a/src/SeqCli/Templates/Export/TemplateSetExporter.cs b/src/SeqCli/Templates/Export/TemplateSetExporter.cs index 051a3cda..0bfa38c5 100644 --- a/src/SeqCli/Templates/Export/TemplateSetExporter.cs +++ b/src/SeqCli/Templates/Export/TemplateSetExporter.cs @@ -8,6 +8,7 @@ using Seq.Api.Model; using Seq.Api.Model.Alerting; using Seq.Api.Model.Dashboarding; +using Seq.Api.Model.Indexing; using Seq.Api.Model.Retention; using Seq.Api.Model.Signals; using Seq.Api.Model.SqlQueries; @@ -78,6 +79,13 @@ await ExportTemplates( () => _connection.RetentionPolicies.ListAsync(), retentionPolicy => retentionPolicy.Id.Replace("retentionpolicy-", ""), templateValueMap); + + await ExportTemplates( + id => _connection.ExpressionIndexes.FindAsync(id), + () => _connection.ExpressionIndexes.ListAsync(), + expressionIndex => expressionIndex.Id.Replace("expressionindex-", ""), + templateValueMap); + } async Task ExportTemplates( diff --git a/src/SeqCli/Templates/Import/TemplateSetImporter.cs b/src/SeqCli/Templates/Import/TemplateSetImporter.cs index 8ac069c8..dd04ce6d 100644 --- a/src/SeqCli/Templates/Import/TemplateSetImporter.cs +++ b/src/SeqCli/Templates/Import/TemplateSetImporter.cs @@ -39,7 +39,7 @@ static class TemplateSetImporter bool merge) { var ordering = new[] {"users", "signals", "apps", "appinstances", - "dashboards", "sqlqueries", "workspaces", "retentionpolicies", "alerts"}.ToList(); + "dashboards", "sqlqueries", "workspaces", "retentionpolicies", "alerts", "expressionindexes"}.ToList(); var sorted = templates.OrderBy(t => ordering.IndexOf(t.ResourceGroup)); From 494999a16ff2ea4ba96a3bb162c87ba3dcce69e9 Mon Sep 17 00:00:00 2001 From: Liam McLennan Date: Tue, 23 Apr 2024 13:59:48 +1000 Subject: [PATCH 4/7] Delete test --- .../Index/IndexBasicsTestCase.cs | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs diff --git a/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs b/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs deleted file mode 100644 index 5969524c..00000000 --- a/test/SeqCli.EndToEnd/Index/IndexBasicsTestCase.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using Seq.Api; -using SeqCli.EndToEnd.Support; -using Serilog; -using Xunit; - -namespace SeqCli.EndToEnd.Index; - -public class IndexBasicsTestCase : ICliTestCase -{ - public Task ExecuteAsync( - SeqConnection connection, - ILogger logger, - CliCommandRunner runner) - { - var exit = runner.Exec("index list", ""); - Assert.Equal(0, exit); - var output = runner.LastRunProcess?.Output; - Assert.Equal("list output goes here", output?.Trim()); - return Task.CompletedTask; - } -} \ No newline at end of file From 917cf128bdb0863028cf4ad8999409eca015b0d4 Mon Sep 17 00:00:00 2001 From: Liam McLennan Date: Tue, 23 Apr 2024 16:30:38 +1000 Subject: [PATCH 5/7] PR feedback --- .../Cli/Commands/ExpressionIndex/CreateCommand.cs | 2 +- src/SeqCli/Cli/Commands/Index/ListCommand.cs | 1 - src/SeqCli/Cli/Commands/Index/SuppressCommand.cs | 8 +------- src/SeqCli/Templates/Export/EntityName.cs | 14 ++++++++------ src/SeqCli/Templates/Export/TemplateSetExporter.cs | 7 ++++--- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs b/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs index e72199b5..5fc39086 100644 --- a/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs +++ b/src/SeqCli/Cli/Commands/ExpressionIndex/CreateCommand.cs @@ -41,7 +41,7 @@ public CreateCommand(SeqConnectionFactory connectionFactory, SeqCliConfig config _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory)); Options.Add( - "expression=", + "e=|expression=", "The expression to index", v => _expression = ArgumentString.Normalize(v)); diff --git a/src/SeqCli/Cli/Commands/Index/ListCommand.cs b/src/SeqCli/Cli/Commands/Index/ListCommand.cs index ec8dc446..958451b5 100644 --- a/src/SeqCli/Cli/Commands/Index/ListCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/ListCommand.cs @@ -56,7 +56,6 @@ protected override async Task Run() _output.ListEntities(list); - await Task.Delay(1); return 0; } } \ No newline at end of file diff --git a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs index 4dd760db..84f5d628 100644 --- a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs @@ -36,7 +36,7 @@ public SuppressCommand(SeqConnectionFactory connectionFactory, SeqCliConfig conf Options.Add( "i=|id=", - "The id of an index of a signal to suppress", + "The id of an index to suppress", id => _id = id); _connection = Enable(); @@ -52,14 +52,8 @@ protected override async Task Run() var connection = _connectionFactory.Connect(_connection); var toSuppress = await connection.Indexes.FindAsync(_id); - if (toSuppress.IndexedEntityType != IndexedEntityType.Signal) - { - Log.Error("Only Signal indexes may be suppressed; to delete an expression index or an alert index remove the expression index or alert"); - return 1; - } await connection.Indexes.SuppressAsync(toSuppress); - await Task.Delay(1); return 0; } } \ No newline at end of file diff --git a/src/SeqCli/Templates/Export/EntityName.cs b/src/SeqCli/Templates/Export/EntityName.cs index cad514d3..c4bd5c40 100644 --- a/src/SeqCli/Templates/Export/EntityName.cs +++ b/src/SeqCli/Templates/Export/EntityName.cs @@ -15,14 +15,16 @@ public static string FromEntityType(Type entityType) public static string ToResourceGroup(string resource) { - if (resource.Equals("expressionindex")) + if (resource.EndsWith('y')) { - return "expressionindexes"; + return resource.TrimEnd('y') + "ies"; } - - if (!resource.EndsWith("y")) - return resource + "s"; - return resource.TrimEnd('y') + "ies"; + if (resource.EndsWith('x')) + { + return resource + "es"; + } + + return resource + "s"; } } \ No newline at end of file diff --git a/src/SeqCli/Templates/Export/TemplateSetExporter.cs b/src/SeqCli/Templates/Export/TemplateSetExporter.cs index 0bfa38c5..57d8d059 100644 --- a/src/SeqCli/Templates/Export/TemplateSetExporter.cs +++ b/src/SeqCli/Templates/Export/TemplateSetExporter.cs @@ -83,11 +83,12 @@ await ExportTemplates( await ExportTemplates( id => _connection.ExpressionIndexes.FindAsync(id), () => _connection.ExpressionIndexes.ListAsync(), - expressionIndex => expressionIndex.Id.Replace("expressionindex-", ""), + expressionIndex => expressionIndex.Expression.All(char.IsLetterOrDigit) + ? expressionIndex.Expression + : expressionIndex.Id.Replace("expressionindex-", ""), templateValueMap); - } - + async Task ExportTemplates( Func> findEntity, Func>> listEntities, From fed611a4db9238ba93d7f9255dad733a33952524 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Wed, 24 Apr 2024 09:21:02 +1000 Subject: [PATCH 6/7] Mark template export test case with min API version --- test/SeqCli.EndToEnd/Templates/TemplateExportImportTestCase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SeqCli.EndToEnd/Templates/TemplateExportImportTestCase.cs b/test/SeqCli.EndToEnd/Templates/TemplateExportImportTestCase.cs index f97b7fdb..1286d37c 100644 --- a/test/SeqCli.EndToEnd/Templates/TemplateExportImportTestCase.cs +++ b/test/SeqCli.EndToEnd/Templates/TemplateExportImportTestCase.cs @@ -8,7 +8,7 @@ namespace SeqCli.EndToEnd.Templates; -[CliTestCase(MinimumApiVersion = "2021.3.6336")] +[CliTestCase(MinimumApiVersion = "2024.3.0")] public class TemplateExportImportTestCase : ICliTestCase { readonly TestDataFolder _testDataFolder; From e95cc7b62522f061a3dca66772ad79ac52feb2a3 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Wed, 24 Apr 2024 09:36:49 +1000 Subject: [PATCH 7/7] Version-gated end-to-end tests for new index-related commands --- .../Cli/Commands/Index/SuppressCommand.cs | 2 +- .../Indexes/ExpressionIndexBasicsTestCase.cs | 36 +++++++++++++++++++ .../Indexes/IndexesTestCase.cs | 34 ++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 test/SeqCli.EndToEnd/Indexes/ExpressionIndexBasicsTestCase.cs create mode 100644 test/SeqCli.EndToEnd/Indexes/IndexesTestCase.cs diff --git a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs index 84f5d628..5aa495bd 100644 --- a/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs +++ b/src/SeqCli/Cli/Commands/Index/SuppressCommand.cs @@ -22,7 +22,7 @@ namespace SeqCli.Cli.Commands.Index; -[Command("index", "suppress", "Suppress index", Example="seqcli index suppress -i index-2191448f1d9b4f22bd32c6edef752748")] +[Command("index", "suppress", "Suppress an index", Example="seqcli index suppress -i index-2191448f1d9b4f22bd32c6edef752748")] class SuppressCommand : Command { readonly SeqConnectionFactory _connectionFactory; diff --git a/test/SeqCli.EndToEnd/Indexes/ExpressionIndexBasicsTestCase.cs b/test/SeqCli.EndToEnd/Indexes/ExpressionIndexBasicsTestCase.cs new file mode 100644 index 00000000..4e7497d4 --- /dev/null +++ b/test/SeqCli.EndToEnd/Indexes/ExpressionIndexBasicsTestCase.cs @@ -0,0 +1,36 @@ +using System.Linq; +using System.Threading.Tasks; +using Seq.Api; +using SeqCli.EndToEnd.Support; +using Serilog; +using Xunit; + +namespace SeqCli.EndToEnd.Indexes; + +[CliTestCase(MinimumApiVersion = "2024.3.0")] +public class ExpressionIndexBasicsTestCase: ICliTestCase +{ + public async Task ExecuteAsync(SeqConnection connection, ILogger logger, CliCommandRunner runner) + { + const string expr = "@Resource.service.name"; + var exit = runner.Exec("expressionindex create", $"-e {expr}"); + Assert.Equal(0, exit); + + var entity = (await connection.ExpressionIndexes.ListAsync()).Single(e => e.Expression == expr); + Assert.Equal(expr, entity.Expression); + + exit = runner.Exec("expressionindex list"); + Assert.Equal(0, exit); + + Assert.Contains(expr, runner.LastRunProcess!.Output); + Assert.Contains(entity.Id, runner.LastRunProcess.Output); + + exit = runner.Exec("expressionindex remove", $"-i {entity.Id}"); + Assert.Equal(0, exit); + + exit = runner.Exec("expressionindex list"); + Assert.Equal(0, exit); + + Assert.DoesNotContain(entity.Id, runner.LastRunProcess.Output); + } +} \ No newline at end of file diff --git a/test/SeqCli.EndToEnd/Indexes/IndexesTestCase.cs b/test/SeqCli.EndToEnd/Indexes/IndexesTestCase.cs new file mode 100644 index 00000000..84b82f03 --- /dev/null +++ b/test/SeqCli.EndToEnd/Indexes/IndexesTestCase.cs @@ -0,0 +1,34 @@ +using System.Linq; +using System.Threading.Tasks; +using Seq.Api; +using SeqCli.EndToEnd.Support; +using Serilog; +using Xunit; + +namespace SeqCli.EndToEnd.Indexes; + +[CliTestCase(MinimumApiVersion = "2024.3.0")] +public class IndexesTestCase: ICliTestCase +{ + public async Task ExecuteAsync(SeqConnection connection, ILogger logger, CliCommandRunner runner) + { + const string expr = "Magic123"; + var exit = runner.Exec("expressionindex create", $"-e {expr}"); + Assert.Equal(0, exit); + + var expressionIndex = (await connection.ExpressionIndexes.ListAsync()).Single(e => e.Expression == expr); + var signal = (await connection.Signals.ListAsync()).First(s => !s.IsIndexSuppressed); + var indexForSignal = (await connection.Indexes.ListAsync()).First(i => i.IndexedEntityId == signal.Id); + + exit = runner.Exec("index list"); + Assert.Equal(0, exit); + Assert.Contains(expressionIndex.Id, runner.LastRunProcess!.Output); + Assert.Contains(signal.Id, runner.LastRunProcess!.Output); + + exit = runner.Exec($"index suppress -i {indexForSignal.Id}"); + Assert.Equal(0, exit); + + signal = await connection.Signals.FindAsync(signal.Id); + Assert.True(signal.IsIndexSuppressed); + } +}