Skip to content

Commit 10bfb69

Browse files
committed
Add lift-quarantine subcommand to agents CLI
Introduced a new lift-quarantine subcommand for the agents command, enabling users to lift quarantine mode for an AI agent by agent ID. Updated Vectra.Client.Net to v1.1.0 to support this feature. Added corresponding unit tests and updated command creation tests to cover the new subcommand. #45
1 parent 5d84b30 commit 10bfb69

4 files changed

Lines changed: 60 additions & 1 deletion

File tree

‎src/VectraCtl/Commands/AgentsCommand.cs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static Command Create(IServiceProvider serviceProvider)
1515
command.Subcommands.Add(CreateListCommand(serviceProvider));
1616
command.Subcommands.Add(CreateRegisterCommand(serviceProvider));
1717
command.Subcommands.Add(CreateAssignPolicyCommand(serviceProvider));
18+
command.Subcommands.Add(CreateLiftQuarantineCommand(serviceProvider));
1819
command.Subcommands.Add(CreateDeleteCommand(serviceProvider));
1920

2021
return command;
@@ -45,6 +46,25 @@ private static Command CreateListCommand(IServiceProvider serviceProvider)
4546
return cmd;
4647
}
4748

49+
private static Command CreateLiftQuarantineCommand(IServiceProvider serviceProvider)
50+
{
51+
var agentIdOption = new Option<Guid>("--agent-id") { Description = "Agent ID (GUID)", Required = true };
52+
53+
var cmd = new Command("lift-quarantine", "Lift quarantine mode for an AI agent")
54+
{
55+
agentIdOption
56+
};
57+
58+
cmd.SetAction((parseResult, ct) => CommandHelpers.ExecuteAsync(serviceProvider, async (logger, sp) =>
59+
{
60+
var client = sp.GetRequiredService<IVectraClient>();
61+
await client.Agents.LiftQuarantineAsync(parseResult.GetValue(agentIdOption)!, ct);
62+
logger.Write("Quarantine lifted successfully.");
63+
}));
64+
65+
return cmd;
66+
}
67+
4868
private static Command CreateRegisterCommand(IServiceProvider serviceProvider)
4969
{
5070
var nameOption = new Option<string>("--name") { Description = "Agent name", Required = true };

‎src/VectraCtl/VectraCtl.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<ItemGroup>
3131
<PackageReference Include="Spectre.Console" Version="0.55.2" />
3232
<PackageReference Include="System.CommandLine" Version="2.0.8" />
33-
<PackageReference Include="Vectra.Client.Net" Version="1.0.0" />
33+
<PackageReference Include="Vectra.Client.Net" Version="1.1.0" />
3434
<PackageReference Include="YamlDotNet" Version="17.1.0" />
3535
</ItemGroup>
3636

‎tests/VectraCtl.UnitTests/Commands/ApiCommandActionTests.cs‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,44 @@ public async Task AgentsCommand_Delete_Exception_WritesError()
187187
provider.GetRequiredService<IVectraCtlLogger>().Received().WriteError(Arg.Any<string>());
188188
}
189189

190+
[Fact]
191+
public async Task AgentsCommand_LiftQuarantine_Success_WritesSuccess()
192+
{
193+
var provider = BuildProvider(s =>
194+
{
195+
var client = Substitute.For<IVectraClient>();
196+
var agentClient = Substitute.For<IVectraAgentClient>();
197+
agentClient.LiftQuarantineAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
198+
.Returns(Task.CompletedTask);
199+
client.Agents.Returns(agentClient);
200+
s.AddSingleton(client);
201+
});
202+
203+
var cmd = AgentsCommand.Create(provider);
204+
await InvokeAsync(cmd, ["lift-quarantine", "--agent-id", Guid.NewGuid().ToString()]);
205+
206+
provider.GetRequiredService<IVectraCtlLogger>().Received().Write(Arg.Is<string>(s => s.Contains("Quarantine lifted")));
207+
}
208+
209+
[Fact]
210+
public async Task AgentsCommand_LiftQuarantine_Exception_WritesError()
211+
{
212+
var provider = BuildProvider(s =>
213+
{
214+
var client = Substitute.For<IVectraClient>();
215+
var agentClient = Substitute.For<IVectraAgentClient>();
216+
agentClient.LiftQuarantineAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
217+
.Throws(new Exception("bad request"));
218+
client.Agents.Returns(agentClient);
219+
s.AddSingleton(client);
220+
});
221+
222+
var cmd = AgentsCommand.Create(provider);
223+
await InvokeAsync(cmd, ["lift-quarantine", "--agent-id", Guid.NewGuid().ToString()]);
224+
225+
provider.GetRequiredService<IVectraCtlLogger>().Received().WriteError(Arg.Any<string>());
226+
}
227+
190228
// ── HitlCommand ──────────────────────────────────────────────────────────
191229

192230
[Fact]

‎tests/VectraCtl.UnitTests/Commands/CommandCreationTests.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public void AgentsCommand_Create_ReturnsCommandWithCorrectNameAndSubcommands()
6969
cmd.Subcommands.Should().Contain(s => s.Name == "list");
7070
cmd.Subcommands.Should().Contain(s => s.Name == "register");
7171
cmd.Subcommands.Should().Contain(s => s.Name == "assign-policy");
72+
cmd.Subcommands.Should().Contain(s => s.Name == "lift-quarantine");
7273
cmd.Subcommands.Should().Contain(s => s.Name == "delete");
7374
}
7475

0 commit comments

Comments
 (0)