Skip to content

Commit 4e5b1d1

Browse files
committed
azurebackup: fix mojibake chars (em dash/en dash/arrow -> ASCII) and restore DiskProtection recording
- Replace 90 Unicode characters (U+2014 em dash, U+2013 en dash, U+2192 right arrow) with ASCII equivalents across 22 .cs files per Jon's review feedback. - Fix ProtectedItemProtect_DppVault_DiskProtection_Succeeds_E2E: add daily-retention-days parameter required by the new PolicyCreateValidator. - Restore ProtectedItemProtect and VaultCreate_CreatesDppVault recordings from upstream tag (accidentally deleted/overwritten during previous asset push). - Push corrected recordings as new asset tag.
1 parent 595a9ab commit 4e5b1d1

18 files changed

Lines changed: 93 additions & 92 deletions

‎tools/Azure.Mcp.Tools.AzureBackup/src/AzureBackupSetup.cs‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,53 +59,53 @@ public CommandGroup RegisterCommands(IServiceProvider serviceProvider)
5959
{
6060
var azureBackup = new CommandGroup(Name,
6161
"""
62-
Azure Backup operations Unified commands to manage backup across Recovery Services vaults (RSV)
62+
Azure Backup operations - Unified commands to manage backup across Recovery Services vaults (RSV)
6363
and Backup vaults (DPP/Data Protection). Supports vault management, protected item operations,
6464
policy management, job monitoring, recovery point browsing, governance, and disaster recovery.
6565
Use --vault-type to specify vault type or let the system auto-detect.
6666
""",
6767
Title);
6868

69-
var vault = new CommandGroup("vault", "Backup vault operations Get vault details or list all vaults, create, and update vaults.");
69+
var vault = new CommandGroup("vault", "Backup vault operations - Get vault details or list all vaults, create, and update vaults.");
7070
azureBackup.AddSubGroup(vault);
7171
RegisterCommand<VaultGetCommand>(serviceProvider, vault);
7272
RegisterCommand<VaultCreateCommand>(serviceProvider, vault);
7373
RegisterCommand<VaultUpdateCommand>(serviceProvider, vault);
7474

75-
var policy = new CommandGroup("policy", "Backup policy operations Get policy details or list all policies, and create policies.");
75+
var policy = new CommandGroup("policy", "Backup policy operations - Get policy details or list all policies, and create policies.");
7676
azureBackup.AddSubGroup(policy);
7777
RegisterCommand<PolicyGetCommand>(serviceProvider, policy);
7878
RegisterCommand<PolicyCreateCommand>(serviceProvider, policy);
7979

80-
var protectedItem = new CommandGroup("protecteditem", "Protected item operations Get protected item details or list all, enable backup protection, and undelete soft-deleted items.");
80+
var protectedItem = new CommandGroup("protecteditem", "Protected item operations - Get protected item details or list all, enable backup protection, and undelete soft-deleted items.");
8181
azureBackup.AddSubGroup(protectedItem);
8282
RegisterCommand<ProtectedItemGetCommand>(serviceProvider, protectedItem);
8383
RegisterCommand<ProtectedItemProtectCommand>(serviceProvider, protectedItem);
8484
RegisterCommand<ProtectedItemUndeleteCommand>(serviceProvider, protectedItem);
8585

86-
var protectableItem = new CommandGroup("protectableitem", "Protectable item operations List discovered databases available for protection.");
86+
var protectableItem = new CommandGroup("protectableitem", "Protectable item operations - List discovered databases available for protection.");
8787
azureBackup.AddSubGroup(protectableItem);
8888
RegisterCommand<ProtectableItemListCommand>(serviceProvider, protectableItem);
8989

90-
var backup = new CommandGroup("backup", "Backup operations Check backup status for a datasource.");
90+
var backup = new CommandGroup("backup", "Backup operations - Check backup status for a datasource.");
9191
azureBackup.AddSubGroup(backup);
9292
RegisterCommand<BackupStatusCommand>(serviceProvider, backup);
9393

94-
var job = new CommandGroup("job", "Backup job operations Get job details or list all jobs in a vault.");
94+
var job = new CommandGroup("job", "Backup job operations - Get job details or list all jobs in a vault.");
9595
azureBackup.AddSubGroup(job);
9696
RegisterCommand<JobGetCommand>(serviceProvider, job);
9797

98-
var recoveryPoint = new CommandGroup("recoverypoint", "Recovery point operations Get recovery point details or list all for a protected item.");
98+
var recoveryPoint = new CommandGroup("recoverypoint", "Recovery point operations - Get recovery point details or list all for a protected item.");
9999
azureBackup.AddSubGroup(recoveryPoint);
100100
RegisterCommand<RecoveryPointGetCommand>(serviceProvider, recoveryPoint);
101101

102-
var governance = new CommandGroup("governance", "Governance operations Find unprotected resources, configure immutability and soft delete.");
102+
var governance = new CommandGroup("governance", "Governance operations - Find unprotected resources, configure immutability and soft delete.");
103103
azureBackup.AddSubGroup(governance);
104104
RegisterCommand<GovernanceFindUnprotectedCommand>(serviceProvider, governance);
105105
RegisterCommand<GovernanceImmutabilityCommand>(serviceProvider, governance);
106106
RegisterCommand<GovernanceSoftDeleteCommand>(serviceProvider, governance);
107107

108-
var disasterrecovery = new CommandGroup("disasterrecovery", "Disaster recovery operations Enable Cross-Region Restore on a GRS vault.");
108+
var disasterrecovery = new CommandGroup("disasterrecovery", "Disaster recovery operations - Enable Cross-Region Restore on a GRS vault.");
109109
azureBackup.AddSubGroup(disasterrecovery);
110110
RegisterCommand<DisasterRecoveryEnableCrrCommand>(serviceProvider, disasterrecovery);
111111

‎tools/Azure.Mcp.Tools.AzureBackup/src/Models/ProtectResult.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ namespace Azure.Mcp.Tools.AzureBackup.Models;
2020
/// </param>
2121
/// <param name="JobId">
2222
/// RSV ConfigureBackup job id (use with <c>azurebackup job get</c>). Always
23-
/// <c>null</c> for DPP DPP protection is not surfaced as a job; verify with
23+
/// <c>null</c> for DPP - DPP protection is not surfaced as a job; verify with
2424
/// <c>azurebackup protecteditem get</c> or <c>list</c>.
2525
/// </param>
2626
/// <param name="Message">Human-readable summary of the outcome.</param>
2727
/// <param name="ProtectionStatus">
28-
/// DPP only actual <c>protectionStatus.status</c> read back from the backup
28+
/// DPP only - actual <c>protectionStatus.status</c> read back from the backup
2929
/// instance after the operation (e.g. <c>ProtectionConfigured</c>,
3030
/// <c>ConfiguringProtection</c>, <c>ProtectionError</c>).
3131
/// </param>

‎tools/Azure.Mcp.Tools.AzureBackup/src/Options/AzureBackupOptionDefinitions.cs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static class AzureBackupOptionDefinitions
2929
public const string ResourceTypeFilterName = "resource-type-filter";
3030
public const string TagFilterName = "tag-filter";
3131

32-
// Policy create common schedule flags (new in policy create overhaul)
32+
// Policy create - common schedule flags (new in policy create overhaul)
3333
public const string TimeZoneName = "time-zone";
3434
public const string ScheduleFrequencyName = "schedule-frequency";
3535
public const string ScheduleTimesName = "schedule-times";
@@ -38,7 +38,7 @@ public static class AzureBackupOptionDefinitions
3838
public const string HourlyWindowStartTimeName = "hourly-window-start-time";
3939
public const string HourlyWindowDurationHoursName = "hourly-window-duration-hours";
4040

41-
// Policy create retention flags (new in policy create overhaul)
41+
// Policy create - retention flags (new in policy create overhaul)
4242
public const string WeeklyRetentionWeeksName = "weekly-retention-weeks";
4343
public const string WeeklyRetentionDaysOfWeekName = "weekly-retention-days-of-week";
4444
public const string MonthlyRetentionMonthsName = "monthly-retention-months";
@@ -53,13 +53,13 @@ public static class AzureBackupOptionDefinitions
5353
public const string ArchiveTierAfterDaysName = "archive-tier-after-days";
5454
public const string ArchiveTierModeName = "archive-tier-mode";
5555

56-
// Policy create RSV-VM only flags
56+
// Policy create - RSV-VM only flags
5757
public const string PolicySubTypeName = "policy-sub-type";
5858
public const string InstantRpRetentionDaysName = "instant-rp-retention-days";
5959
public const string InstantRpResourceGroupName = "instant-rp-resource-group";
6060
public const string SnapshotConsistencyName = "snapshot-consistency";
6161

62-
// Policy create RSV-VmWorkload (SQL / SAPHANA / SAPASE) flags
62+
// Policy create - RSV-VmWorkload (SQL / SAPHANA / SAPASE) flags
6363
public const string FullScheduleFrequencyName = "full-schedule-frequency";
6464
public const string FullScheduleDaysOfWeekName = "full-schedule-days-of-week";
6565
public const string DifferentialScheduleDaysOfWeekName = "differential-schedule-days-of-week";
@@ -71,7 +71,7 @@ public static class AzureBackupOptionDefinitions
7171
public const string IsCompressionName = "is-compression";
7272
public const string IsSqlCompressionName = "is-sql-compression";
7373

74-
// Policy create Stage 2 expansion flags
74+
// Policy create - Stage 2 expansion flags
7575
// RSV VM Smart Tier (ML-based archive recommendation)
7676
public const string SmartTierName = "smart-tier";
7777
// RSV SAPHANA snapshot/instance backups
@@ -441,7 +441,7 @@ public static class AzureBackupOptionDefinitions
441441

442442
public static readonly Option<string> SmartTier = new($"--{SmartTierName}")
443443
{
444-
Description = "Enable smart-tiering (ML-based archive recommendation): 'true' or 'false'. RSV VM only equivalent to TieringMode=TierRecommended.",
444+
Description = "Enable smart-tiering (ML-based archive recommendation): 'true' or 'false'. RSV VM only - equivalent to TieringMode=TierRecommended.",
445445
Required = false
446446
};
447447

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/AzureBackupService.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,12 +671,12 @@ private static async Task<T> AutoDetectAndExecuteAsync<T>(
671671
}
672672
catch (RequestFailedException ex) when (ex.Status is 401 or 403)
673673
{
674-
// RSV auth failure try DPP before giving up
674+
// RSV auth failure - try DPP before giving up
675675
rsvAuthFailed = true;
676676
}
677677
catch (RequestFailedException ex) when (ex.Status is 404)
678678
{
679-
// RSV not found try DPP
679+
// RSV not found - try DPP
680680
}
681681

682682
try

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/DppBackupOperations.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public sealed class DppBackupOperations(ITenantService tenantService) : BaseAzur
1919

2020
/// <summary>
2121
/// Resolves the DPP datasource profile from a user-supplied or auto-detected type string.
22-
/// Handles auto-detection (e.g. "Microsoft.Storage/storageAccounts" Blob profile)
23-
/// and friendly name mapping (e.g. "aks" AKS profile).
22+
/// Handles auto-detection (e.g. "Microsoft.Storage/storageAccounts" -> Blob profile)
23+
/// and friendly name mapping (e.g. "aks" -> AKS profile).
2424
/// </summary>
2525
internal static DppDatasourceProfile ResolveProfile(string datasourceTypeOrArm)
2626
{
@@ -280,7 +280,7 @@ public async Task<ProtectedItemInfo> GetProtectedItemAsync(
280280
}
281281
catch (RequestFailedException ex) when (ex.Status == 404)
282282
{
283-
// Direct lookup failed search by friendly/datasource name
283+
// Direct lookup failed - search by friendly/datasource name
284284
}
285285

286286
// Fall back to listing all items and searching by friendly name

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/DppDatasourceProfile.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public enum DppDataSourceSetMode
1414
/// <summary>DataSourceSetInfo points to the datasource itself (AKS).</summary>
1515
Self,
1616

17-
/// <summary>DataSourceSetInfo points to the parent resource (ESAN volume group parent ESAN).</summary>
17+
/// <summary>DataSourceSetInfo points to the parent resource (ESAN volume group -> parent ESAN).</summary>
1818
Parent,
1919
}
2020

@@ -63,7 +63,7 @@ public enum DppBackupParametersMode
6363
/// Each property drives a specific dimension of protect, policy-create, and restore operations.
6464
/// </summary>
6565
/// <remarks>
66-
/// AOT-safe: no reflection, no Func delegates pure data record with enum-driven dispatch.
66+
/// AOT-safe: no reflection, no Func delegates - pure data record with enum-driven dispatch.
6767
///
6868
/// === Policy Create - Staged Implementation Plan ===
6969
///
@@ -104,7 +104,7 @@ public sealed record DppDatasourceProfile
104104
public bool UsesOperationalStore { get; init; }
105105

106106

107-
/// <summary>True for continuous backup (Blob, ADLS) no scheduled backup rule created.</summary>
107+
/// <summary>True for continuous backup (Blob, ADLS) - no scheduled backup rule created.</summary>
108108
public bool IsContinuousBackup { get; init; }
109109

110110
/// <summary>ISO 8601 schedule interval (e.g. "PT4H", "P1D"). Ignored when <see cref="IsContinuousBackup"/> is true.</summary>
@@ -140,7 +140,7 @@ public sealed record DppDatasourceProfile
140140
/// <summary>
141141
/// If non-null, when the user's resource ID matches this base ARM type (e.g. "Microsoft.Storage/storageAccounts"),
142142
/// automatically re-map to this profile's <see cref="ArmResourceType"/>.
143-
/// Used for Blob (storage account blobServices) auto-detection.
143+
/// Used for Blob (storage account -> blobServices) auto-detection.
144144
/// </summary>
145145
public string? AutoDetectFromBaseResourceType { get; init; }
146146

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/DppDatasourceRegistry.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Azure.Mcp.Tools.AzureBackup.Services;
1313
/// To add a new DPP datasource type:
1414
/// 1. Add a static DppDatasourceProfile instance below
1515
/// 2. Register it in the AllProfiles array
16-
/// No other code changes needed in DppBackupOperations.
16+
/// - No other code changes needed in DppBackupOperations.
1717
/// </summary>
1818
public static class DppDatasourceRegistry
1919
{
@@ -193,7 +193,7 @@ public static DppDatasourceProfile Resolve(string workloadTypeOrArmType)
193193
/// <summary>
194194
/// Tries to auto-detect a profile when the user supplies a base resource type
195195
/// (e.g. "Microsoft.Storage/storageAccounts") that needs re-mapping to a child type
196-
/// (e.g. Blob "Microsoft.Storage/storageAccounts/blobServices").
196+
/// (e.g. Blob -> "Microsoft.Storage/storageAccounts/blobServices").
197197
/// </summary>
198198
public static DppDatasourceProfile? TryAutoDetect(string armResourceType)
199199
{
@@ -212,7 +212,7 @@ public static DppDatasourceProfile Resolve(string workloadTypeOrArmType)
212212
}
213213

214214
/// <summary>
215-
/// Derives the parent resource ID from a child resource ID (e.g. ESAN volume group parent ESAN).
215+
/// Derives the parent resource ID from a child resource ID (e.g. ESAN volume group -> parent ESAN).
216216
/// Generic logic that strips the last two path segments (/childType/childName).
217217
/// </summary>
218218
public static ResourceIdentifier GetParentResourceId(ResourceIdentifier childResourceId)

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/Policy/DppPolicyBuilder.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Azure.Mcp.Tools.AzureBackup.Services.Policy;
1212
/// </summary>
1313
/// <remarks>
1414
/// AOT-safe: no reflection, no dynamic dispatch.
15-
/// All inputs are nullable strings when a flag is omitted the builder falls back
15+
/// All inputs are nullable strings - when a flag is omitted the builder falls back
1616
/// to the long-standing default behavior so existing minimal-flag invocations keep
1717
/// working unchanged.
1818
/// Multi-tier retention is opt-in: when <c>--weekly-retention-weeks</c>,
@@ -38,7 +38,7 @@ public static RuleBasedBackupPolicy Build(PolicyCreateRequest request, DppDataso
3838
var isContinuous = profile.IsContinuousBackup && !isVaultedMode;
3939

4040
// For vaulted storage workloads (Blob/ADLS Vaulted mode), the policy is driven entirely
41-
// by VaultStore retention rules no AzureBackupRule (the trigger is implicit, managed by
41+
// by VaultStore retention rules - no AzureBackupRule (the trigger is implicit, managed by
4242
// the storage platform). This matches the Az CLI shape and is what the DPP service accepts.
4343
var isVaultedStorage = isVaultedMode && profile.IsContinuousBackup;
4444

@@ -62,7 +62,7 @@ public static RuleBasedBackupPolicy Build(PolicyCreateRequest request, DppDataso
6262

6363
// Per-tier retention rules (opt-in via positive weeks/months/years).
6464
// When vault-tier copy is enabled on an operational-store workload (e.g. AzureDisk), the
65-
// per-tier rules MUST source from VaultStore the operational (snapshot) tier on AzureDisk
65+
// per-tier rules MUST source from VaultStore - the operational (snapshot) tier on AzureDisk
6666
// does not accept multi-tier (weekly/monthly/yearly) retention rules. The matching tagging
6767
// criteria on the AzureBackupRule lifecycle direct the service to copy tagged RPs to vault.
6868
var tierStore = vaultTierEnabled ? DataStoreType.VaultStore : dataStoreType;

‎tools/Azure.Mcp.Tools.AzureBackup/src/Services/Policy/PolicyCreateRequest.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Azure.Mcp.Tools.AzureBackup.Services.Policy;
1010
/// passed as separate parameters to the service methods.
1111
/// </summary>
1212
/// <remarks>
13-
/// All fields are nullable strings the service layer is responsible for parsing,
13+
/// All fields are nullable strings - the service layer is responsible for parsing,
1414
/// validating, and translating them into SDK objects via the policy builders.
1515
/// This decoupling keeps the System.CommandLine option-binding concerns out of the
1616
/// service layer and makes builder unit tests easy to write.

0 commit comments

Comments
 (0)