Skip to content

Azure NetApp Files Create/Read/Update tooling#2454

Open
stumpc wants to merge 6 commits intomicrosoft:mainfrom
stumpc:stumpc/anf-support
Open

Azure NetApp Files Create/Read/Update tooling#2454
stumpc wants to merge 6 commits intomicrosoft:mainfrom
stumpc:stumpc/anf-support

Conversation

@stumpc
Copy link
Copy Markdown

@stumpc stumpc commented Apr 21, 2026

What does this PR do?

  • This PR adds support for Azure NetApp Files into the Azure MCP. It does this by creating tools for Create, Read, and Update operations. This PR deliberately does not add Delete support for Azure NetApp Files.

GitHub issue number?

  • None

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide)
    • Added comprehensive tests for new/modified functionality
    • Created a changelog entry if the change falls among the following: new feature, bug fix, UI/UX update, breaking change, or updated dependencies. Follow the changelog entry guide
  • For MCP tool changes:
    • One tool per PR: This PR adds or modifies only one MCP tool for faster review cycles
    • Updated servers/Azure.Mcp.Server/README.md and/or servers/Fabric.Mcp.Server/README.md documentation
    • Validate README.md changes running the script ./eng/scripts/Process-PackageReadMe.ps1. See Package README
    • For new or modified tool descriptions, ran ToolDescriptionEvaluator and obtained a score of 0.4 or more and a top 3 ranking for all related test prompts
    • For tools with new names, including new tools or renamed tools, update consolidated-tools.json
    • For renamed tools, follow the Tool Rename Checklist and tag the PR with the breaking-change label
    • For new tools associated with Azure services or publicly available tools/APIs/products, add URL to documentation in the PR description
  • Extra steps for Azure MCP Server tool changes:
    • Updated command list in servers/Azure.Mcp.Server/docs/azmcp-commands.md
    • Ran ./eng/scripts/Update-AzCommandsMetadata.ps1 to update tool metadata in azmcp-commands.md (required for CI)
    • Updated test prompts in servers/Azure.Mcp.Server/docs/e2eTestPrompts.md
    • 👉 For Community (non-Microsoft team member) PRs:
      • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
      • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline
stumpc added 6 commits April 10, 2026 11:20
Signed-off-by: Christian Stump <Christian.Stump@netapp.com>
* feat: add create ability for Azure NetApp Files

Signed-off-by: Christian Stump <Christian.Stump@netapp.com>
* feat: add update for AzureNetAppFiles

Signed-off-by: Christian Stump <Christian.Stump@netapp.com>
@github-actions
Copy link
Copy Markdown

Thank you for your contribution @stumpc! We will review the pull request and get back to you soon.

@stumpc
Copy link
Copy Markdown
Author

stumpc commented Apr 21, 2026

@microsoft-github-policy-service agree company="NetApp"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new Azure NetApp Files tool area in the Azure MCP server, adding command implementations and supporting models/options to perform Create / Get / Update operations (intentionally excluding Delete).

Changes:

  • Added NetApp Files command surface (account/pool/volume/snapshot/backup*/volume group + replication status) with JSON-serializable result types.
  • Introduced NetApp Files data/content models and a large INetAppFilesService interface to back the commands.
  • Wired the new area into the Azure MCP server and added e2e test prompts + initial unit tests.

Reviewed changes

Copilot reviewed 136 out of 136 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tools/Azure.Mcp.Tools.NetAppFiles/tests/Azure.Mcp.Tools.NetAppFiles.UnitTests/Snapshot/SnapshotGetCommandTests.cs Adds unit tests for snapshot get command behavior/serialization
tools/Azure.Mcp.Tools.NetAppFiles/tests/Azure.Mcp.Tools.NetAppFiles.UnitTests/Azure.Mcp.Tools.NetAppFiles.UnitTests.csproj Introduces unit test project for NetApp Files tool
tools/Azure.Mcp.Tools.NetAppFiles/tests/Azure.Mcp.Tools.NetAppFiles.UnitTests/Account/AccountGetCommandTests.cs Adds unit tests for account get command behavior/error handling
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/VolumeGroupData.cs Adds Resource Graph projection model for volume groups
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/VolumeGroupCreateOrUpdateContent.cs Adds ARM payload model for volume group create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/SnapshotPolicyData.cs Adds Resource Graph projection model for snapshot policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/SnapshotPolicyCreateOrUpdateContent.cs Adds ARM payload model for snapshot policy create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/SnapshotData.cs Adds Resource Graph projection model for snapshots
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/SnapshotCreateOrUpdateContent.cs Adds ARM payload model for snapshot create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/ReplicationStatusData.cs Adds Resource Graph projection model for replication status
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/NetAppVolumeData.cs Adds Resource Graph projection model for volumes
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/NetAppVolumeCreateOrUpdateContent.cs Adds ARM payload model for volume create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/NetAppAccountData.cs Adds Resource Graph projection model for accounts
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/NetAppAccountCreateOrUpdateContent.cs Adds ARM payload model for account create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/CapacityPoolData.cs Adds Resource Graph projection model for capacity pools
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/CapacityPoolCreateOrUpdateContent.cs Adds ARM payload model for capacity pool create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupVaultData.cs Adds Resource Graph projection model for backup vaults
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupVaultCreateOrUpdateContent.cs Adds ARM payload model for backup vault create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupPolicyData.cs Adds Resource Graph projection model for backup policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupPolicyCreateOrUpdateContent.cs Adds ARM payload model for backup policy create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupData.cs Adds Resource Graph projection model for backups
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/Models/BackupCreateOrUpdateContent.cs Adds ARM payload model for backup create/update
tools/Azure.Mcp.Tools.NetAppFiles/src/Services/INetAppFilesService.cs Defines NetApp Files service contract used by commands
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/VolumeGroup/VolumeGroupUpdateOptions.cs Adds CLI/JSON options for volume group update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/VolumeGroup/VolumeGroupGetOptions.cs Adds CLI/JSON options for volume group get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/VolumeGroup/VolumeGroupCreateOptions.cs Adds CLI/JSON options for volume group create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Volume/VolumeUpdateOptions.cs Adds CLI/JSON options for volume update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Volume/VolumeGetOptions.cs Adds CLI/JSON options for volume get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Volume/VolumeCreateOptions.cs Adds CLI/JSON options for volume create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/SnapshotPolicy/SnapshotPolicyUpdateOptions.cs Adds CLI/JSON options for snapshot policy update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/SnapshotPolicy/SnapshotPolicyGetOptions.cs Adds CLI/JSON options for snapshot policy get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/SnapshotPolicy/SnapshotPolicyCreateOptions.cs Adds CLI/JSON options for snapshot policy create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Snapshot/SnapshotUpdateOptions.cs Adds CLI/JSON options for snapshot update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Snapshot/SnapshotGetOptions.cs Adds CLI/JSON options for snapshot get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Snapshot/SnapshotCreateOptions.cs Adds CLI/JSON options for snapshot create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/ReplicationStatus/ReplicationStatusGetOptions.cs Adds CLI/JSON options for replication status get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Pool/PoolUpdateOptions.cs Adds CLI/JSON options for pool update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Pool/PoolGetOptions.cs Adds CLI/JSON options for pool get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Pool/PoolCreateOptions.cs Adds CLI/JSON options for pool create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BaseNetAppFilesOptions.cs Adds shared base options (subscription + account)
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupVault/BackupVaultUpdateOptions.cs Adds CLI/JSON options for backup vault update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupVault/BackupVaultGetOptions.cs Adds CLI/JSON options for backup vault get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupVault/BackupVaultCreateOptions.cs Adds CLI/JSON options for backup vault create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupPolicy/BackupPolicyUpdateOptions.cs Adds CLI/JSON options for backup policy update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupPolicy/BackupPolicyGetOptions.cs Adds CLI/JSON options for backup policy get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/BackupPolicy/BackupPolicyCreateOptions.cs Adds CLI/JSON options for backup policy create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Backup/BackupUpdateOptions.cs Adds CLI/JSON options for backup update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Backup/BackupGetOptions.cs Adds CLI/JSON options for backup get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Backup/BackupCreateOptions.cs Adds CLI/JSON options for backup create
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Account/AccountUpdateOptions.cs Adds CLI/JSON options for account update
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Account/AccountGetOptions.cs Adds CLI/JSON options for account get
tools/Azure.Mcp.Tools.NetAppFiles/src/Options/Account/AccountCreateOptions.cs Adds CLI/JSON options for account create
tools/Azure.Mcp.Tools.NetAppFiles/src/NetAppFilesSetup.cs Registers NetApp Files area commands and DI services
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/VolumeGroupInfo.cs Adds response projection model for volume groups
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/VolumeGroupCreateResult.cs Adds create/update result model for volume groups
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/SnapshotPolicyInfo.cs Adds response projection model for snapshot policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/SnapshotPolicyCreateResult.cs Adds create/update result model for snapshot policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/SnapshotInfo.cs Adds response projection model for snapshots
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/SnapshotCreateResult.cs Adds create/update result model for snapshots
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/ReplicationStatusInfo.cs Adds response projection model for replication status
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/NetAppVolumeInfo.cs Adds response projection model for volumes
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/NetAppVolumeCreateResult.cs Adds create/update result model for volumes
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/NetAppAccountInfo.cs Adds response projection model for accounts
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/NetAppAccountCreateResult.cs Adds create/update result model for accounts
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/CapacityPoolInfo.cs Adds response projection model for capacity pools
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/CapacityPoolCreateResult.cs Adds create/update result model for capacity pools
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupVaultInfo.cs Adds response projection model for backup vaults
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupVaultCreateResult.cs Adds create/update result model for backup vaults
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupPolicyInfo.cs Adds response projection model for backup policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupPolicyCreateResult.cs Adds create/update result model for backup policies
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupInfo.cs Adds response projection model for backups
tools/Azure.Mcp.Tools.NetAppFiles/src/Models/BackupCreateResult.cs Adds create/update result model for backups
tools/Azure.Mcp.Tools.NetAppFiles/src/GlobalUsings.cs Introduces global using for System.CommandLine
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/VolumeGroup/VolumeGroupUpdateCommand.cs Implements volume group update command (tags/description)
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/VolumeGroup/VolumeGroupGetCommand.cs Implements volume group get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/VolumeGroup/VolumeGroupCreateCommand.cs Implements volume group create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Volume/VolumeUpdateCommand.cs Implements volume update command (quota/service level/tags)
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Volume/VolumeGetCommand.cs Implements volume get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Volume/VolumeCreateCommand.cs Implements volume create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/SnapshotPolicy/SnapshotPolicyUpdateCommand.cs Implements snapshot policy update command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/SnapshotPolicy/SnapshotPolicyGetCommand.cs Implements snapshot policy get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/SnapshotPolicy/SnapshotPolicyCreateCommand.cs Implements snapshot policy create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Snapshot/SnapshotUpdateCommand.cs Implements snapshot update command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Snapshot/SnapshotGetCommand.cs Implements snapshot get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Snapshot/SnapshotCreateCommand.cs Implements snapshot create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/ReplicationStatus/ReplicationStatusGetCommand.cs Implements replication status get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Pool/PoolUpdateCommand.cs Implements capacity pool update command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Pool/PoolGetCommand.cs Implements capacity pool get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Pool/PoolCreateCommand.cs Implements capacity pool create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/NetAppFilesJsonContext.cs Adds System.Text.Json source-gen context for AOT-safe serialization
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupVault/BackupVaultUpdateCommand.cs Implements backup vault update command (tags)
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupVault/BackupVaultGetCommand.cs Implements backup vault get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupVault/BackupVaultCreateCommand.cs Implements backup vault create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupPolicy/BackupPolicyUpdateCommand.cs Implements backup policy update command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupPolicy/BackupPolicyGetCommand.cs Implements backup policy get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/BackupPolicy/BackupPolicyCreateCommand.cs Implements backup policy create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Backup/BackupUpdateCommand.cs Implements backup update command (label)
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Backup/BackupGetCommand.cs Implements backup get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Backup/BackupCreateCommand.cs Implements backup create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Account/AccountUpdateCommand.cs Implements account update command (tags)
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Account/AccountGetCommand.cs Implements account get/list command
tools/Azure.Mcp.Tools.NetAppFiles/src/Commands/Account/AccountCreateCommand.cs Implements account create command
tools/Azure.Mcp.Tools.NetAppFiles/src/Azure.Mcp.Tools.NetAppFiles.csproj Adds NetApp Files tool project (AOT-compatible)
tools/Azure.Mcp.Tools.NetAppFiles/src/AssemblyInfo.cs Adds InternalsVisibleTo for unit/live test projects
servers/Azure.Mcp.Server/src/Program.cs Registers the new NetApp Files area in the server
servers/Azure.Mcp.Server/docs/e2eTestPrompts.md Adds e2e prompts for NetApp Files tools
Microsoft.Mcp.slnx Adds NetApp Files tool project to solution structure
Comment on lines +55 to +60
_netAppFilesService.GetAccountDetails(
Arg.Is<string?>(s => string.IsNullOrEmpty(s)),
Arg.Is(subscription),
Arg.Any<string>(),
Arg.Any<RetryPolicyOptions>(),
Arg.Any<CancellationToken>())
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NSubstitute setup uses Arg.Any<string>() for the optional tenant parameter of GetAccountDetails. The command passes options.Tenant, which will be null when --tenant isn’t provided, so this setup won’t match and can make the test fail unexpectedly. Use a nullable matcher for optional parameters (e.g., Arg.Any<string?>() or an Arg.Is<string?>(t => t is null || ...)).

Copilot uses AI. Check for mistakes.
Comment on lines +159 to +162
_netAppFilesService.GetAccountDetails(
Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(expectedAccount));
}
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this theory setup, the substitute uses Arg.Any<string>() for parameters that are optional in the command (account and tenant). For cases like --subscription sub123 where account/tenant are omitted, the command will pass null and the call won’t match this setup. Update the matchers for optional parameters to accept null (e.g., Arg.Any<string?>()).

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +63
_netAppFilesService.GetSnapshotDetails(
Arg.Any<string?>(),
Arg.Any<string?>(),
Arg.Any<string?>(),
Arg.Any<string?>(),
Arg.Is(subscription),
Arg.Any<string>(),
Arg.Any<RetryPolicyOptions>(),
Arg.Any<CancellationToken>())
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NSubstitute setup uses Arg.Any<string>() for the optional tenant parameter of GetSnapshotDetails. options.Tenant will be null when --tenant isn’t provided, so this setup won’t match and can cause the test to fail. Use a nullable matcher for optional parameters (e.g., Arg.Any<string?>()).

Copilot uses AI. Check for mistakes.
Comment on lines +171 to +173
_netAppFilesService.GetSnapshotDetails(
Arg.Any<string?>(), Arg.Any<string?>(), Arg.Any<string?>(), Arg.Any<string?>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(expectedSnapshots));
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this theory setup, the substitute uses non-nullable matchers (Arg.Any<string>()) for parameters that the command may pass as null (e.g., tenant, and potentially account/pool/volume/snapshot depending on the input). This can prevent the setup from matching and make the test flaky/fail. Use nullable matchers (Arg.Any<string?>()) for optional parameters in GetSnapshotDetails.

Copilot uses AI. Check for mistakes.
Comment on lines +704 to +705
| azmcp-netappfiles-volume-get | List all NetApp Files volumes in my subscription <subscription_name> |
| azmcp-netappfiles-volume-get | Get details of volume <volume_name> in pool <pool_name> for NetApp Files account <account_name> in subscription <subscription_name> |
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new NetApp Files section includes duplicated tool prompt rows for azmcp-netappfiles-volume-get (the same two prompts are listed twice). This can create noise and potentially duplicate test coverage. Remove the duplicate rows so each tool/prompt combination appears once.

Suggested change
| azmcp-netappfiles-volume-get | List all NetApp Files volumes in my subscription <subscription_name> |
| azmcp-netappfiles-volume-get | Get details of volume <volume_name> in pool <pool_name> for NetApp Files account <account_name> in subscription <subscription_name> |
Copilot uses AI. Check for mistakes.
Comment thread Microsoft.Mcp.slnx
<Folder Name="/tools/Azure.Mcp.Tools.NetAppFiles/" />
<Folder Name="/tools/Azure.Mcp.Tools.NetAppFiles/src/">
<Project Path="tools/Azure.Mcp.Tools.NetAppFiles/src/Azure.Mcp.Tools.NetAppFiles.csproj" />
</Folder>
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The solution file adds the NetAppFiles src project but doesn’t include the new unit test project under /tools/Azure.Mcp.Tools.NetAppFiles/tests/. Other tools list their unit test projects here, so omitting it can mean the tests aren’t built/run as part of the solution. Add the NetAppFiles unit test project entry (and tests folder) to the .slnx.

Suggested change
</Folder>
</Folder>
<Folder Name="/tools/Azure.Mcp.Tools.NetAppFiles/tests/">
<Project Path="tools/Azure.Mcp.Tools.NetAppFiles/tests/Azure.Mcp.Tools.NetAppFiles.UnitTests/Azure.Mcp.Tools.NetAppFiles.UnitTests.csproj" />
</Folder>
Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@jongio jongio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New Azure NetApp Files toolset with CRU operations across 9 resource types. The structure follows repo conventions, and the commands/options/models are well-organized. A few issues worth addressing before this lands:

Exception wrapping breaks command-level error handling

NetAppFilesService wraps all exceptions in new Exception(msg, ex) (19 occurrences). The commands override GetErrorMessage to pattern-match on RequestFailedException (checking for 404, 403, 409, etc.), but they'll never see that type because the service swallows it. The command error handlers are effectively dead code for all create/update operations.

Compare with StorageService which throws specific exception types (KeyNotFoundException, ArgumentException) or lets ARM SDK exceptions propagate. Either let the original exceptions bubble up (use throw; instead of throw new Exception(...)) or update the command error handlers to inspect ex.InnerException.

Inconsistent GetStatusCode overrides

Only AccountUpdateCommand, BackupVaultUpdateCommand, PoolUpdateCommand, SnapshotCreateCommand, and SnapshotUpdateCommand override GetStatusCode. The other ~25 commands with GetErrorMessage overrides don't, so they'll return HTTP 500 for all errors regardless of the actual status. Either add GetStatusCode to all commands with error handling, or (better) fix the service exception wrapping so the base class handlers work correctly.

Missing PR checklist items

  • consolidated-tools.json isn't updated (required for new tool names per checklist)
  • No changelog entry
  • No live test infrastructure (test-resources.bicep, test-resources-post.ps1, LiveTests project, assets.json) - expected for Azure service toolsets
  • Unit test project isn't in the solution file (the Copilot bot flagged this too)

Test gaps

  • None of the unit tests call TestEnvironment.ClearAzureSubscriptionId(). If AZURE_SUBSCRIPTION_ID is set in the environment, subscription-required validation tests can silently pass even when they shouldn't.
  • No BindOptions_BindsOptionsCorrectly test method in any test file. This is a standard pattern in other toolsets.

Overall this is a solid foundation. The exception handling fix is the most impactful change needed since it affects error messages users will see.

}
catch (Exception ex)
{
throw new Exception($"Error retrieving NetApp Files account details for '{account}': {ex.Message}", ex);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch/throw new Exception pattern is repeated 19 times across the service. It wraps the original RequestFailedException in a generic Exception, which means the command-level GetErrorMessage overrides (that match on RequestFailedException) will never fire. The original HTTP status code, error code, and exception type are all lost to downstream handlers.

Consider using throw; here to let the original exception propagate. The commands already have HandleException with proper error matching. If you want to add context to the message, you could use a custom exception type that preserves the original, or log the context and rethrow.

return context.Response;
}

protected override string GetErrorMessage(Exception ex) => ex switch
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This GetErrorMessage override matches RequestFailedException patterns (409 Conflict, 403 Forbidden, 404 NotFound). But AccountCreateCommand.ExecuteAsync calls the service's CreateAccount method, which catches any exception and wraps it in new Exception(..., ex). So by the time the exception reaches this handler, it's a plain Exception, not a RequestFailedException - none of these branches will execute.

This applies to all Create/Update commands in this toolset that have GetErrorMessage overrides.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment