-
Notifications
You must be signed in to change notification settings - Fork 536
Migrate AppConfig tools to new tool design #2871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| changes: | ||
| - section: "Breaking Changes" | ||
| description: "Removed unused parameters from AppConfig tools." | ||
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Azure.Mcp.Core.Commands.Subscription; | ||
| using Azure.Mcp.Core.Services.Azure.Subscription; | ||
| using Azure.Mcp.Tools.AppConfig.Options.KeyValue; | ||
| using Azure.Mcp.Tools.AppConfig.Services; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
@@ -24,26 +26,19 @@ Delete a key-value pair from an App Configuration store. This command removes th | |
| ReadOnly = false, | ||
| Secret = false, | ||
| LocalRequired = false)] | ||
| public sealed class KeyValueDeleteCommand(ILogger<KeyValueDeleteCommand> logger, IAppConfigService appConfigService) | ||
| : BaseKeyValueCommand<KeyValueDeleteOptions>() | ||
| public sealed class KeyValueDeleteCommand(ILogger<KeyValueDeleteCommand> logger, IAppConfigService appConfigService, ISubscriptionResolver subscriptionResolver) | ||
| : SubscriptionCommand<KeyValueDeleteOptions, KeyValueDeleteCommand.KeyValueDeleteCommandResult>(subscriptionResolver) | ||
| { | ||
| private readonly ILogger<KeyValueDeleteCommand> _logger = logger; | ||
| private readonly IAppConfigService _appConfigService = appConfigService; | ||
|
|
||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult, CancellationToken cancellationToken) | ||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, KeyValueDeleteOptions options, CancellationToken cancellationToken) | ||
| { | ||
| if (!Validate(parseResult.CommandResult, context.Response).IsValid) | ||
| { | ||
| return context.Response; | ||
| } | ||
|
|
||
| var options = BindOptions(parseResult); | ||
|
|
||
| try | ||
| { | ||
| var existed = await _appConfigService.DeleteKeyValue( | ||
| options.Account!, | ||
| options.Key!, | ||
| options.Account, | ||
| options.Key, | ||
|
Comment on lines
+40
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can these be null now? |
||
| options.Subscription!, | ||
| options.Tenant, | ||
| options.RetryPolicy, | ||
|
|
@@ -65,5 +60,5 @@ public override async Task<CommandResponse> ExecuteAsync(CommandContext context, | |
| return context.Response; | ||
| } | ||
|
|
||
| internal record KeyValueDeleteCommandResult(string? Key, string? Label, bool Existed, string Message); | ||
| public sealed record KeyValueDeleteCommandResult(string? Key, string? Label, bool Existed, string Message); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,14 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Azure.Mcp.Core.Commands.Subscription; | ||
| using Azure.Mcp.Core.Services.Azure.Subscription; | ||
| using Azure.Mcp.Tools.AppConfig.Models; | ||
| using Azure.Mcp.Tools.AppConfig.Options; | ||
| using Azure.Mcp.Tools.AppConfig.Options.KeyValue; | ||
| using Azure.Mcp.Tools.AppConfig.Services; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Mcp.Core.Commands; | ||
| using Microsoft.Mcp.Core.Extensions; | ||
| using Microsoft.Mcp.Core.Models.Command; | ||
| using Microsoft.Mcp.Core.Models.Option; | ||
|
|
||
| namespace Azure.Mcp.Tools.AppConfig.Commands.KeyValue; | ||
|
|
||
|
|
@@ -29,53 +28,31 @@ Gets key-values in an App Configuration store. This command can either retrieve | |
| ReadOnly = true, | ||
| Secret = false, | ||
| LocalRequired = false)] | ||
| public sealed class KeyValueGetCommand(ILogger<KeyValueGetCommand> logger, IAppConfigService appConfigService) | ||
| : BaseAppConfigCommand<KeyValueGetOptions>() | ||
| public sealed class KeyValueGetCommand(ILogger<KeyValueGetCommand> logger, IAppConfigService appConfigService, ISubscriptionResolver subscriptionResolver) | ||
| : SubscriptionCommand<KeyValueGetOptions, KeyValueGetCommand.KeyValueGetCommandResult>(subscriptionResolver) | ||
| { | ||
| private readonly ILogger<KeyValueGetCommand> _logger = logger; | ||
| private readonly IAppConfigService _appConfigService = appConfigService; | ||
|
|
||
| protected override void RegisterOptions(Command command) | ||
| public override void ValidateOptions(KeyValueGetOptions options, ValidationResult validationResult) | ||
| { | ||
| base.RegisterOptions(command); | ||
| command.Options.Add(AppConfigOptionDefinitions.Key.AsOptional()); | ||
| command.Options.Add(AppConfigOptionDefinitions.Label); | ||
| command.Options.Add(AppConfigOptionDefinitions.KeyFilter); | ||
| command.Options.Add(AppConfigOptionDefinitions.LabelFilter); | ||
| command.Validators.Add(result => | ||
| base.ValidateOptions(options, validationResult); | ||
| if (!string.IsNullOrEmpty(options.Key) && !string.IsNullOrEmpty(options.KeyFilter)) | ||
| { | ||
| var key = result.GetValueOrDefault<string>(AppConfigOptionDefinitions.Key.Name); | ||
| var keyFilter = result.GetValueOrDefault(AppConfigOptionDefinitions.KeyFilter); | ||
| if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(keyFilter)) | ||
| { | ||
| result.AddError("Cannot specify both --key and --key-filter options together. Use only one to get a specific key-value or to filter the list of key-values."); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| protected override KeyValueGetOptions BindOptions(ParseResult parseResult) | ||
| { | ||
| var options = base.BindOptions(parseResult); | ||
| options.Key = parseResult.GetValueOrDefault<string>(AppConfigOptionDefinitions.Key.Name); | ||
| options.Label = parseResult.GetValueOrDefault<string>(AppConfigOptionDefinitions.Label.Name); | ||
| options.KeyFilter = parseResult.GetValueOrDefault<string>(AppConfigOptionDefinitions.KeyFilter.Name); | ||
| options.LabelFilter = parseResult.GetValueOrDefault<string>(AppConfigOptionDefinitions.LabelFilter.Name); | ||
| return options; | ||
| } | ||
|
|
||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult, CancellationToken cancellationToken) | ||
| { | ||
| if (!Validate(parseResult.CommandResult, context.Response).IsValid) | ||
| validationResult.Errors.Add("Cannot specify both --key and --key-filter options together. Use only one to get a specific key-value or to filter the list of key-values."); | ||
| } | ||
| if (!string.IsNullOrEmpty(options.Label) && !string.IsNullOrEmpty(options.LabelFilter)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should mention this validation update in the changelog entry either as a bug fix or breaking change. |
||
| { | ||
| return context.Response; | ||
| validationResult.Errors.Add("Cannot specify both --label and --label-filter options together. Use only one to get a specific key-value or to filter the list of key-values."); | ||
| } | ||
| } | ||
|
|
||
| var options = BindOptions(parseResult); | ||
|
|
||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, KeyValueGetOptions options, CancellationToken cancellationToken) | ||
| { | ||
| try | ||
| { | ||
| var settings = await _appConfigService.GetKeyValues( | ||
| options.Account!, | ||
| options.Account, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we not checking for requiredness here anymore because we do so when binding options? |
||
| options.Subscription!, | ||
| options.Key, | ||
| options.Label, | ||
|
|
@@ -96,5 +73,5 @@ public override async Task<CommandResponse> ExecuteAsync(CommandContext context, | |
| return context.Response; | ||
| } | ||
|
|
||
| internal record KeyValueGetCommandResult(List<KeyValueSetting> Settings); | ||
| public sealed record KeyValueGetCommandResult(List<KeyValueSetting> Settings); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,12 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Azure.Mcp.Tools.AppConfig.Options; | ||
| using Azure.Mcp.Core.Commands.Subscription; | ||
| using Azure.Mcp.Core.Services.Azure.Subscription; | ||
| using Azure.Mcp.Tools.AppConfig.Options.KeyValue; | ||
| using Azure.Mcp.Tools.AppConfig.Services; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Mcp.Core.Commands; | ||
| using Microsoft.Mcp.Core.Extensions; | ||
| using Microsoft.Mcp.Core.Models.Command; | ||
|
|
||
| namespace Azure.Mcp.Tools.AppConfig.Commands.KeyValue; | ||
|
|
@@ -27,44 +27,20 @@ Set a key-value setting in an App Configuration store. This command creates or u | |
| ReadOnly = false, | ||
| Secret = false, | ||
| LocalRequired = false)] | ||
| public sealed class KeyValueSetCommand(ILogger<KeyValueSetCommand> logger, IAppConfigService appConfigService) | ||
| : BaseKeyValueCommand<KeyValueSetOptions>() | ||
| public sealed class KeyValueSetCommand(ILogger<KeyValueSetCommand> logger, IAppConfigService appConfigService, ISubscriptionResolver subscriptionResolver) | ||
| : SubscriptionCommand<KeyValueSetOptions, KeyValueSetCommand.KeyValueSetCommandResult>(subscriptionResolver) | ||
| { | ||
| private const string CommandTitle = "Set App Configuration Key-Value Setting"; | ||
| private readonly ILogger<KeyValueSetCommand> _logger = logger; | ||
| private readonly IAppConfigService _appConfigService = appConfigService; | ||
|
|
||
| protected override void RegisterOptions(Command command) | ||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, KeyValueSetOptions options, CancellationToken cancellationToken) | ||
| { | ||
| base.RegisterOptions(command); | ||
| command.Options.Add(AppConfigOptionDefinitions.Value); | ||
| command.Options.Add(AppConfigOptionDefinitions.Tags); | ||
| } | ||
|
|
||
| protected override KeyValueSetOptions BindOptions(ParseResult parseResult) | ||
| { | ||
| var options = base.BindOptions(parseResult); | ||
| options.Value = parseResult.GetValueOrDefault<string>(AppConfigOptionDefinitions.Value.Name); | ||
| options.Tags = parseResult.GetValueOrDefault<string[]>(AppConfigOptionDefinitions.Tags.Name); | ||
| return options; | ||
| } | ||
|
|
||
| [McpServerTool(Destructive = true, ReadOnly = false, Title = CommandTitle)] | ||
| public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult, CancellationToken cancellationToken) | ||
| { | ||
| if (!Validate(parseResult.CommandResult, context.Response).IsValid) | ||
| { | ||
| return context.Response; | ||
| } | ||
|
|
||
| var options = BindOptions(parseResult); | ||
|
|
||
| try | ||
| { | ||
| await _appConfigService.SetKeyValue( | ||
| options.Account!, | ||
| options.Key!, | ||
| options.Value!, | ||
| options.Account, | ||
| options.Key, | ||
| options.Value, | ||
|
Comment on lines
+41
to
+43
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question about requiredness/nullability. |
||
| options.Subscription!, | ||
| options.Tenant, | ||
| options.RetryPolicy, | ||
|
|
@@ -86,5 +62,5 @@ await _appConfigService.SetKeyValue( | |
| return context.Response; | ||
| } | ||
|
|
||
| internal record KeyValueSetCommandResult(string? Key, string? Value, string? Label, string? ContentType = null, string[]? Tags = null); | ||
| public sealed record KeyValueSetCommandResult(string? Key, string? Value, string? Label, string? ContentType = null, string[]? Tags = null); | ||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,22 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Azure.Mcp.Core.Options; | ||
| using Microsoft.Mcp.Core.Options; | ||
|
|
||
| namespace Azure.Mcp.Tools.AppConfig.Options.Account; | ||
|
|
||
| public class AccountListOptions : SubscriptionOptions; | ||
| public sealed class AccountListOptions : ISubscriptionOption | ||
| { | ||
| [Option(OptionDescriptions.Tenant)] | ||
| public string? Tenant { get; set; } | ||
|
|
||
| [Option(OptionDescriptions.Subscription)] | ||
| public string? Subscription { get; set; } | ||
|
|
||
| [Option(OptionDescriptions.ResourceGroup)] | ||
| public string? ResourceGroup { get; set; } | ||
|
|
||
| [Option(Name = "retry")] | ||
| public RetryPolicyOptions? RetryPolicy { get; set; } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.