diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs index e3cb7027cbbd..affbbee24c75 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs @@ -190,7 +190,7 @@ public static PolicyBase GetPolicyModelForAzureSql(ServiceClientModel.Protection ServiceClientModel.SimpleRetentionPolicy azureSqlRetentionPolicy = (ServiceClientModel.SimpleRetentionPolicy)azureSqlPolicy.RetentionPolicy; sqlPolicyModel.RetentionPolicy = - PolicyHelpers.GetPSSimpleRetentionPolicy(azureSqlRetentionPolicy, null); + PolicyHelpers.GetPSSimpleRetentionPolicy(azureSqlRetentionPolicy, null, "AzureSql"); return policyModel; } @@ -236,6 +236,85 @@ public static PolicyBase GetPolicyModelForAzureFileShare(ServiceClientModel.Prot return policyModel; } + public static PolicyBase GetPolicyModelForAzureVmWorkload(ServiceClientModel.ProtectionPolicyResource serviceClientResponse, + PolicyBase policyModel) + { + ServiceClientModel.AzureVmWorkloadProtectionPolicy azureVmWorkloadPolicy = + (ServiceClientModel.AzureVmWorkloadProtectionPolicy)serviceClientResponse.Properties; + + foreach (var policy in azureVmWorkloadPolicy.SubProtectionPolicy) + { + if (string.Compare(policy.PolicyType, "Full") == 0) + { + if (policy.SchedulePolicy.GetType() != + typeof(ServiceClientModel.SimpleSchedulePolicy)) + { + Logger.Instance.WriteDebug("Unknown Schedule object received: " + + policy.SchedulePolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + if (policy.RetentionPolicy.GetType() != + typeof(ServiceClientModel.LongTermRetentionPolicy)) + { + Logger.Instance.WriteDebug("Unknown RetentionPolicy object received: " + + policy.RetentionPolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + } + else if (string.Compare(policy.PolicyType, "Differential") == 0) + { + if (policy.SchedulePolicy.GetType() != + typeof(ServiceClientModel.SimpleSchedulePolicy)) + { + Logger.Instance.WriteDebug("Unknown Schedule object received: " + + policy.SchedulePolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + if (policy.RetentionPolicy.GetType() != + typeof(ServiceClientModel.SimpleRetentionPolicy)) + { + Logger.Instance.WriteDebug("Unknown RetentionPolicy object received: " + + policy.RetentionPolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + } + else if (string.Compare(policy.PolicyType, "Log") == 0) + { + if (policy.SchedulePolicy.GetType() != + typeof(ServiceClientModel.LogSchedulePolicy)) + { + Logger.Instance.WriteDebug("Unknown Schedule object received: " + + policy.SchedulePolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + if (policy.RetentionPolicy.GetType() != + typeof(ServiceClientModel.SimpleRetentionPolicy)) + { + Logger.Instance.WriteDebug("Unknown RetentionPolicy object received: " + + policy.RetentionPolicy.GetType()); + Logger.Instance.WriteWarning(Resources.UpdateToNewAzurePowershellWarning); + return null; + } + } + } + + policyModel = new AzureVmWorkloadPolicy(); + AzureVmWorkloadPolicy azureVmWorkloadPolicyModel = policyModel as AzureVmWorkloadPolicy; + azureVmWorkloadPolicyModel.WorkloadType = WorkloadType.MSSQL; + azureVmWorkloadPolicyModel.BackupManagementType = BackupManagementType.AzureWorkload; + azureVmWorkloadPolicyModel.IsCompression = + ((ServiceClientModel.AzureVmWorkloadProtectionPolicy)serviceClientResponse.Properties).Settings.IsCompression; + GetPSSubProtectionPolicy(azureVmWorkloadPolicyModel, serviceClientResponse, + ((ServiceClientModel.AzureVmWorkloadProtectionPolicy)serviceClientResponse.Properties).Settings.TimeZone); + + return policyModel; + } + /// /// Helper function to convert ps backup policy model from service response. /// @@ -263,6 +342,11 @@ public static PolicyBase GetPolicyModel(ServiceClientModel.ProtectionPolicyResou { policyModel = GetPolicyModelForAzureFileShare(serviceClientResponse, policyModel); } + else if (serviceClientResponse.Properties.GetType() == + typeof(ServiceClientModel.AzureVmWorkloadProtectionPolicy)) + { + policyModel = GetPolicyModelForAzureVmWorkload(serviceClientResponse, policyModel); + } else { // we will enter this case when service supports new workload and customer @@ -431,6 +515,53 @@ public static List GetItemModelList(IEnumerable weeklyLimit)) || + (simplePolicy.RetentionDurationType == RetentionDurationType.Months && + (simplePolicy.RetentionCount <= 0 || simplePolicy.RetentionCount > monthlyLimit)) || + (simplePolicy.RetentionDurationType == RetentionDurationType.Years && + (simplePolicy.RetentionCount <= 0 || simplePolicy.RetentionCount > yearlyLimit))) + { + throw new ArgumentException(Resources.AllowedSqlRetentionRange); + } + } + return simplePolicy; } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SchedulePolicyConversions.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SchedulePolicyConversions.cs index 1aae1875a9fe..65332628f675 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SchedulePolicyConversions.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SchedulePolicyConversions.cs @@ -54,6 +54,26 @@ public static SimpleSchedulePolicy GetPSSimpleSchedulePolicy( return psPolicy; } + // + /// Helper function to convert ps log schedule policy from service response. + /// + public static LogSchedulePolicy GetPSLogSchedulePolicy( + ServiceClientModel.LogSchedulePolicy serviceClientPolicy, string timeZone) + { + if (serviceClientPolicy == null) + { + return null; + } + + LogSchedulePolicy psPolicy = new LogSchedulePolicy(); + psPolicy.ScheduleFrequencyInMins = serviceClientPolicy.ScheduleFrequencyInMins; + + // safe side validation + psPolicy.Validate(); + + return psPolicy; + } + #endregion #region PStoServiceClientObject conversions @@ -117,6 +137,19 @@ public static ServiceClientModel.SimpleSchedulePolicy GetServiceClientSimpleSche return serviceClientPolicy; } + public static ServiceClientModel.LogSchedulePolicy GetServiceClientLogSchedulePolicy( + LogSchedulePolicy psPolicy) + { + if (psPolicy == null) + { + return null; + } + + ServiceClientModel.LogSchedulePolicy serviceClientPolicy = new ServiceClientModel.LogSchedulePolicy(); + serviceClientPolicy.ScheduleFrequencyInMins = psPolicy.ScheduleFrequencyInMins; + return serviceClientPolicy; + } + // /// Helper function to get nullable date time list from date time list. /// diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SubPolicyConversions.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SubPolicyConversions.cs new file mode 100644 index 000000000000..c158b40aff0d --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/SubPolicyConversions.cs @@ -0,0 +1,90 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// 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 Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; +using System.Collections.Generic; +using ServiceClientModel = Microsoft.Azure.Management.RecoveryServices.Backup.Models; +using CmdletModel = Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers +{ + /// + /// Backup policy conversion helper + /// + public partial class PolicyHelpers + { + public static List GetServiceClientSubProtectionPolicy( + SQLRetentionPolicy retentionPolicy, + SQLSchedulePolicy schedulePolicy) + { + List subProtectionPolicy = + new List(); + if (schedulePolicy.FullBackupSchedulePolicy != null && + retentionPolicy.FullBackupRetentionPolicy != null) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Full", + GetServiceClientSimpleSchedulePolicy(schedulePolicy.FullBackupSchedulePolicy), + GetServiceClientLongTermRetentionPolicy(retentionPolicy.FullBackupRetentionPolicy))); + } + if (schedulePolicy.DifferentialBackupSchedulePolicy != null && + retentionPolicy.DifferentialBackupRetentionPolicy != null && + schedulePolicy.IsDifferentialBackupEnabled) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Differential", + GetServiceClientSimpleSchedulePolicy(schedulePolicy.DifferentialBackupSchedulePolicy), + GetServiceClientSimpleRetentionPolicy(retentionPolicy.DifferentialBackupRetentionPolicy))); + } + if (schedulePolicy.LogBackupSchedulePolicy != null && + retentionPolicy.LogBackupRetentionPolicy != null && + schedulePolicy.IsLogBackupEnabled) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Log", + GetServiceClientLogSchedulePolicy(schedulePolicy.LogBackupSchedulePolicy), + GetServiceClientSimpleRetentionPolicy(retentionPolicy.LogBackupRetentionPolicy))); + } + return subProtectionPolicy; + } + + public static List GetServiceClientSubProtectionPolicy( + AzureVmWorkloadPolicy policy) + { + List subProtectionPolicy = + new List(); + if (policy.FullBackupSchedulePolicy != null && + policy.FullBackupRetentionPolicy != null) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Full", + GetServiceClientSimpleSchedulePolicy((SimpleSchedulePolicy)policy.FullBackupSchedulePolicy), + GetServiceClientLongTermRetentionPolicy((LongTermRetentionPolicy)policy.FullBackupRetentionPolicy))); + } + if (policy.DifferentialBackupSchedulePolicy != null && + policy.DifferentialBackupRetentionPolicy != null && + policy.IsDifferentialBackupEnabled) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Differential", + GetServiceClientSimpleSchedulePolicy((SimpleSchedulePolicy)policy.DifferentialBackupSchedulePolicy), + GetServiceClientSimpleRetentionPolicy((SimpleRetentionPolicy)policy.DifferentialBackupRetentionPolicy))); + } + if (policy.LogBackupSchedulePolicy != null && + policy.LogBackupRetentionPolicy != null && + policy.IsLogBackupEnabled) + { + subProtectionPolicy.Add(new ServiceClientModel.SubProtectionPolicy("Log", + GetServiceClientLogSchedulePolicy((LogSchedulePolicy)policy.LogBackupSchedulePolicy), + GetServiceClientSimpleRetentionPolicy((SimpleRetentionPolicy)policy.LogBackupRetentionPolicy))); + } + return subProtectionPolicy; + } + } +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Validations/PolicyValidations.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Validations/PolicyValidations.cs index 013fedb0ca6e..760881a77c99 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Validations/PolicyValidations.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Validations/PolicyValidations.cs @@ -118,6 +118,111 @@ public static void ValidateLongTermRetentionPolicyWithSimpleRetentionPolicy( } } + public static void ValidateLongTermRetentionPolicyWithSimpleRetentionPolicy( + SQLRetentionPolicy ltrPolicy, + SQLSchedulePolicy schPolicy) + { + // for daily schedule, daily retention policy is required + if (schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Daily && + (ltrPolicy.FullBackupRetentionPolicy.DailySchedule == null || + ltrPolicy.FullBackupRetentionPolicy.IsDailyScheduleEnabled == false)) + { + throw new ArgumentException(Resources.DailyRetentionScheduleNullException); + } + + // for weekly schedule, daily retention policy should be NULL + // AND weekly retention policy is required + if (schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly && + (ltrPolicy.FullBackupRetentionPolicy.IsDailyScheduleEnabled != false || + ltrPolicy.FullBackupRetentionPolicy.WeeklySchedule == null || + (ltrPolicy.FullBackupRetentionPolicy.IsWeeklyScheduleEnabled == false))) + { + throw new ArgumentException(Resources.WeeklyRetentionScheduleNullException); + } + + // validate daily retention schedule with schPolicy + if (ltrPolicy.FullBackupRetentionPolicy.DailySchedule != null && + ltrPolicy.FullBackupRetentionPolicy.IsDailyScheduleEnabled == true) + { + ValidateRetentionAndBackupTimes(schPolicy.FullBackupSchedulePolicy.ScheduleRunTimes, + ltrPolicy.FullBackupRetentionPolicy.DailySchedule.RetentionTimes); + } + + // validate weekly retention schedule with schPolicy + if (ltrPolicy.FullBackupRetentionPolicy.WeeklySchedule != null && + ltrPolicy.FullBackupRetentionPolicy.IsWeeklyScheduleEnabled == true) + { + ValidateRetentionAndBackupTimes(schPolicy.FullBackupSchedulePolicy.ScheduleRunTimes, + ltrPolicy.FullBackupRetentionPolicy.WeeklySchedule.RetentionTimes); + + if (schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly) + { + // count of daysOfWeek should match for weekly schedule + if (ltrPolicy.FullBackupRetentionPolicy.WeeklySchedule.DaysOfTheWeek.Count != + schPolicy.FullBackupSchedulePolicy.ScheduleRunDays.Count) + { + throw new ArgumentException(Resources.DaysofTheWeekInWeeklyRetentionException); + } + + // validate days of week + ValidateRetentionAndScheduleDaysOfWeek(schPolicy.FullBackupSchedulePolicy.ScheduleRunDays, + ltrPolicy.FullBackupRetentionPolicy.WeeklySchedule.DaysOfTheWeek); + } + } + + // validate monthly retention schedule with schPolicy + if (ltrPolicy.FullBackupRetentionPolicy.MonthlySchedule != null && + ltrPolicy.FullBackupRetentionPolicy.IsMonthlyScheduleEnabled == true) + { + ValidateRetentionAndBackupTimes(schPolicy.FullBackupSchedulePolicy.ScheduleRunTimes, + ltrPolicy.FullBackupRetentionPolicy.MonthlySchedule.RetentionTimes); + + // if backupSchedule is weekly, then user cannot choose 'Daily Retention format' + if (schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly && + ltrPolicy.FullBackupRetentionPolicy.MonthlySchedule.RetentionScheduleFormatType + == RetentionScheduleFormat.Daily) + { + throw new ArgumentException(Resources.MonthlyYearlyInvalidDailyRetentionFormatTypeException); + } + + // for monthly and weeklyFormat, validate days of week + if (ltrPolicy.FullBackupRetentionPolicy.MonthlySchedule.RetentionScheduleFormatType + == RetentionScheduleFormat.Weekly && + schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly) + { + ValidateRetentionAndScheduleDaysOfWeek(schPolicy.FullBackupSchedulePolicy.ScheduleRunDays, + ltrPolicy.FullBackupRetentionPolicy.MonthlySchedule. + RetentionScheduleWeekly.DaysOfTheWeek); + } + } + + // validate yearly retention schedule with schPolicy + if (ltrPolicy.FullBackupRetentionPolicy.YearlySchedule != null && + ltrPolicy.FullBackupRetentionPolicy.IsYearlyScheduleEnabled == true) + { + ValidateRetentionAndBackupTimes(schPolicy.FullBackupSchedulePolicy.ScheduleRunTimes, + ltrPolicy.FullBackupRetentionPolicy.YearlySchedule.RetentionTimes); + + // if backupSchedule is weekly, then user cannot choose 'Daily Retention format' + if (schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly && + ltrPolicy.FullBackupRetentionPolicy.YearlySchedule.RetentionScheduleFormatType + == RetentionScheduleFormat.Daily) + { + throw new ArgumentException(Resources.MonthlyYearlyInvalidDailyRetentionFormatTypeException); + } + + // for yearly and weeklyFormat, validate days of week + if (ltrPolicy.FullBackupRetentionPolicy.YearlySchedule.RetentionScheduleFormatType + == RetentionScheduleFormat.Weekly && + schPolicy.FullBackupSchedulePolicy.ScheduleRunFrequency == ScheduleRunType.Weekly) + { + ValidateRetentionAndScheduleDaysOfWeek(schPolicy.FullBackupSchedulePolicy.ScheduleRunDays, + ltrPolicy.FullBackupRetentionPolicy.YearlySchedule. + RetentionScheduleWeekly.DaysOfTheWeek); + } + } + } + #region private private static void ValidateRetentionAndBackupTimes(List schPolicyTimes, List retPolicyTimes) diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureDbModels/AzureDbPolicy.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureDbModels/AzureDbPolicy.cs new file mode 100644 index 000000000000..1d75427d9a54 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureDbModels/AzureDbPolicy.cs @@ -0,0 +1,93 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// 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. +// ---------------------------------------------------------------------------------- + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models +{ + /// + /// Azure Db Workload specific backup policy class. + /// + public class AzureDbPolicy : PolicyBase + { + /// + /// Is compression enabled + /// + public bool? IsCompression { get; set; } + + /// + /// Object defining is differential backup is enabled. + /// + public bool IsDifferentialBackupEnabled { get; set; } + + /// + /// Object defining if log backup is enabled. + /// + public bool IsLogBackupEnabled { get; set; } + + /// + /// Object defining the schedule associated with full backup policy. + /// + public SchedulePolicyBase FullBackupSchedulePolicy { get; set; } + + /// + /// Object defining the schedule associated with differential backup policy. + /// + public SchedulePolicyBase DifferentialBackupSchedulePolicy { get; set; } + + /// + /// Object defining the schedule associated with Log backup policy. + /// + public SchedulePolicyBase LogBackupSchedulePolicy { get; set; } + + /// + /// Object defining the retention behavior of full backup policy. + /// + public RetentionPolicyBase FullBackupRetentionPolicy { get; set; } + + /// + /// Object defining the retention behavior of differential backup policy. + /// + public RetentionPolicyBase DifferentialBackupRetentionPolicy { get; set; } + + /// + /// Object defining the retention behavior of log backup policy. + /// + public RetentionPolicyBase LogBackupRetentionPolicy { get; set; } + + public override void Validate() + { + base.Validate(); + + FullBackupSchedulePolicy.Validate(); + if (DifferentialBackupSchedulePolicy != null) + { + DifferentialBackupSchedulePolicy.Validate(); + } + if (LogBackupSchedulePolicy != null) + { + LogBackupSchedulePolicy.Validate(); + } + + FullBackupRetentionPolicy.Validate(); + if (DifferentialBackupRetentionPolicy != null) + { + DifferentialBackupRetentionPolicy.Validate(); + } + if (LogBackupRetentionPolicy != null) + { + LogBackupRetentionPolicy.Validate(); + } + } + } + +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureSqlModels/AzureSqlPolicy.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureSqlModels/AzureSqlPolicy.cs index 317655824be2..9ff0fb88c0d9 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureSqlModels/AzureSqlPolicy.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureSqlModels/AzureSqlPolicy.cs @@ -27,7 +27,6 @@ public class AzureSqlPolicy : PolicyBase public override void Validate() { base.Validate(); - RetentionPolicy.Validate(); } } } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureVmWorkloadModels/AzureVmWorkloadPolicy.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureVmWorkloadModels/AzureVmWorkloadPolicy.cs new file mode 100644 index 000000000000..aba72d92e240 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureVmWorkloadModels/AzureVmWorkloadPolicy.cs @@ -0,0 +1,25 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// 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.Collections.Generic; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models +{ + /// + /// Azure VM workload specific backup policy class. + /// + public class AzureVmWorkloadPolicy : AzureDbPolicy + { + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs index 0eb39736cf24..f710b00c9787 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs @@ -291,6 +291,27 @@ public class SchedulePolicyBase : ObjectBase { } + /// + /// Base class for azure workload policy settings. + /// + public class SettingsBase : ObjectBase + { + /// + /// Is compression enabled + /// + public bool? IsCompression { get; set; } + + /// + /// Is sql compression enabled + /// + public bool? Issqlcompression { get; set; } + + /// + /// TimeZone property + /// + public string TimeZone { get; set; } + } + /// /// Base class for backup job. /// diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/Commands.RecoveryServices.Backup.Models.csproj b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/Commands.RecoveryServices.Backup.Models.csproj new file mode 100644 index 000000000000..1a7d10e4e648 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/Commands.RecoveryServices.Backup.Models.csproj @@ -0,0 +1,109 @@ + + + + + + Debug + AnyCPU + {30B92759-50B3-494E-B9F0-EC9A2CE9D57B} + Library + Properties + Microsoft.Azure.Commands.RecoveryServices.Backup + Microsoft.Azure.Commands.RecoveryServices.Backup.Models + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + prompt + 4 + TRACE;SIGN + true + MSSharedLibKey.snk + true + false + + + + False + ..\..\..\packages\Microsoft.Azure.Management.RecoveryServices.Backup.3.0.1-preview\lib\net452\Microsoft.Azure.Management.RecoveryServices.Backup.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Resources.resx + True + True + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + + {142d7b0b-388a-4ceb-a228-7f6d423c5c2e} + Commands.Profile + + + + + + + + + \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyRetentionObjects.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyRetentionObjects.cs index 82fc3ece465c..a4c76fa816d6 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyRetentionObjects.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyRetentionObjects.cs @@ -38,21 +38,6 @@ public override string ToString() public override void Validate() { base.Validate(); - - int weeklyLimit = PolicyConstants.MaxAllowedRetentionDurationCountWeeklySql; - int monthlyLimit = PolicyConstants.MaxAllowedRetentionDurationCountMonthlySql; - int yearlyLimit = PolicyConstants.MaxAllowedRetentionDurationCountYearlySql; - - if ((RetentionDurationType == RetentionDurationType.Days) || - (RetentionDurationType == RetentionDurationType.Weeks && - (RetentionCount <= 0 || RetentionCount > weeklyLimit)) || - (RetentionDurationType == RetentionDurationType.Months && - (RetentionCount <= 0 || RetentionCount > monthlyLimit)) || - (RetentionDurationType == RetentionDurationType.Years && - (RetentionCount <= 0 || RetentionCount > yearlyLimit))) - { - throw new ArgumentException(Resources.AllowedSqlRetentionRange); - } } } @@ -185,6 +170,28 @@ public override string ToString() } } + public class SQLRetentionPolicy : RetentionPolicyBase + { + /// + /// Full backup retention policy object + /// + public LongTermRetentionPolicy FullBackupRetentionPolicy { get; set; } + + /// + /// Differential backup retention policy object + /// + public SimpleRetentionPolicy DifferentialBackupRetentionPolicy { get; set; } + + /// + /// Log backup retention policy object + /// + public SimpleRetentionPolicy LogBackupRetentionPolicy { get; set; } + + public SQLRetentionPolicy() + { + } + } + /// /// Base class for retention schedule. /// diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyScheduleObjects.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyScheduleObjects.cs index 3d3912a843a1..e89a703b4270 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyScheduleObjects.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/PolicyScheduleObjects.cs @@ -74,4 +74,46 @@ public override string ToString() TraceUtils.GetString(ScheduleRunTimes)); } } + + public class LogSchedulePolicy : SchedulePolicyBase + { + public int? ScheduleFrequencyInMins { get; set; } + } + + public class SQLSchedulePolicy : SchedulePolicyBase + { + /// + /// Is compression enabled + /// + public bool? IsCompression { get; set; } + + /// + /// Is differential backup enabled bool object + /// + public bool IsDifferentialBackupEnabled { get; set; } + + /// + /// Is log backup enabled bool object + /// + public bool IsLogBackupEnabled { get; set; } + + /// + /// Full backup schedule policy object + /// + public SimpleSchedulePolicy FullBackupSchedulePolicy { get; set; } + + /// + /// Differential backup schedule policy object + /// + public SimpleSchedulePolicy DifferentialBackupSchedulePolicy { get; set; } + + /// + /// Log backup schedule policy object + /// + public LogSchedulePolicy LogBackupSchedulePolicy { get; set; } + + public SQLSchedulePolicy() + { + } + } } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs index b7fb5f2a1bd8..d586719a91b8 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs @@ -236,6 +236,18 @@ public void ValidateSimpleSchedulePolicy(CmdletModel.SchedulePolicyBase policy) policy.Validate(); } + public void ValidateSQLSchedulePolicy(CmdletModel.SchedulePolicyBase policy) + { + if (policy == null || policy.GetType() != typeof(CmdletModel.SQLSchedulePolicy)) + { + throw new ArgumentException(string.Format(Resources.InvalidSchedulePolicyException, + typeof(CmdletModel.SQLSchedulePolicy).ToString())); + } + + // call validation + policy.Validate(); + } + public void ValidateLongTermRetentionPolicy(CmdletModel.RetentionPolicyBase policy) { if (policy == null || policy.GetType() != typeof(CmdletModel.LongTermRetentionPolicy)) @@ -250,6 +262,20 @@ public void ValidateLongTermRetentionPolicy(CmdletModel.RetentionPolicyBase poli policy.Validate(); } + public void ValidateSQLRetentionPolicy(CmdletModel.RetentionPolicyBase policy) + { + if (policy == null || policy.GetType() != typeof(CmdletModel.SQLRetentionPolicy)) + { + throw new ArgumentException( + string.Format( + Resources.InvalidRetentionPolicyException, + typeof(CmdletModel.SQLRetentionPolicy).ToString())); + } + + // perform validation + policy.Validate(); + } + public DateTime GenerateRandomScheduleTime() { //Schedule time will be random to avoid the load in service (same is in portal as well) @@ -352,5 +378,46 @@ public CmdletModel.RecoveryPointBase GetRecoveryPointDetails(Dictionary(); + CmdletModel.Day dayBasedRetention = new CmdletModel.Day(); + dayBasedRetention.IsLast = false; + dayBasedRetention.Date = 1; + dailyRetention.DaysOfTheMonth.Add(dayBasedRetention); + return dailyRetention; + } + + public static CmdletModel.WeeklyRetentionFormat GetWeeklyRetentionFormat() + { + CmdletModel.WeeklyRetentionFormat weeklyRetention = + new CmdletModel.WeeklyRetentionFormat(); + weeklyRetention.DaysOfTheWeek = new List(); + weeklyRetention.DaysOfTheWeek.Add(System.DayOfWeek.Sunday); + + weeklyRetention.WeeksOfTheMonth = new List(); + weeklyRetention.WeeksOfTheMonth.Add(CmdletModel.WeekOfMonth.First); + return weeklyRetention; + } + + public void GetUpdatedSchedulePolicy(CmdletModel.PolicyBase policy, CmdletModel.SQLSchedulePolicy schPolicy) + { + ((CmdletModel.AzureVmWorkloadPolicy)policy).FullBackupSchedulePolicy = schPolicy.FullBackupSchedulePolicy; + ((CmdletModel.AzureVmWorkloadPolicy)policy).DifferentialBackupSchedulePolicy = schPolicy.DifferentialBackupSchedulePolicy; + ((CmdletModel.AzureVmWorkloadPolicy)policy).LogBackupSchedulePolicy = schPolicy.LogBackupSchedulePolicy; + ((CmdletModel.AzureVmWorkloadPolicy)policy).IsLogBackupEnabled = schPolicy.IsLogBackupEnabled; + ((CmdletModel.AzureVmWorkloadPolicy)policy).IsDifferentialBackupEnabled = schPolicy.IsDifferentialBackupEnabled; + ((CmdletModel.AzureVmWorkloadPolicy)policy).IsCompression = schPolicy.IsCompression; + } + + public void GetUpdatedRetentionPolicy(CmdletModel.PolicyBase policy, CmdletModel.SQLRetentionPolicy retPolicy) + { + ((CmdletModel.AzureVmWorkloadPolicy)policy).FullBackupRetentionPolicy = retPolicy.FullBackupRetentionPolicy; + ((CmdletModel.AzureVmWorkloadPolicy)policy).DifferentialBackupRetentionPolicy = retPolicy.DifferentialBackupRetentionPolicy; + ((CmdletModel.AzureVmWorkloadPolicy)policy).LogBackupRetentionPolicy = retPolicy.LogBackupRetentionPolicy; + } } } \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureSqlPsBackupProvider.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureSqlPsBackupProvider.cs index 29a4979f2013..ea4d1db5a974 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureSqlPsBackupProvider.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureSqlPsBackupProvider.cs @@ -524,7 +524,6 @@ private void ValidateAzureSqlRetentionPolicy(RetentionPolicyBase policy) typeof(CmdletModel.SimpleRetentionPolicy).ToString())); } - // call validation policy.Validate(); } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs index 8a2dbc27f142..0bcb58c64d90 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs @@ -57,7 +57,7 @@ public ResourceBackupStatus CheckBackupStatus() public ProtectionPolicyResource CreatePolicy() { - throw new NotImplementedException(); + return CreateorModifyPolicy().Body; } public RestAzureNS.AzureOperationResponse DisableProtection() @@ -72,12 +72,101 @@ public RestAzureNS.AzureOperationResponse EnableProtection() public RetentionPolicyBase GetDefaultRetentionPolicyObject() { - throw new NotImplementedException(); + SQLRetentionPolicy defaultRetention = new SQLRetentionPolicy(); + DateTime retentionTime = AzureWorkloadProviderHelper.GenerateRandomScheduleTime(); + + defaultRetention.FullBackupRetentionPolicy = new CmdletModel.LongTermRetentionPolicy(); + defaultRetention.DifferentialBackupRetentionPolicy = new CmdletModel.SimpleRetentionPolicy(); + defaultRetention.LogBackupRetentionPolicy = new CmdletModel.SimpleRetentionPolicy(); + + //Setup FullBackupRetentionPolicy + //Daily Retention policy + defaultRetention.FullBackupRetentionPolicy.IsDailyScheduleEnabled = true; + defaultRetention.FullBackupRetentionPolicy.DailySchedule = new CmdletModel.DailyRetentionSchedule(); + defaultRetention.FullBackupRetentionPolicy.DailySchedule.RetentionTimes = new List(); + defaultRetention.FullBackupRetentionPolicy.DailySchedule.RetentionTimes.Add(retentionTime); + defaultRetention.FullBackupRetentionPolicy.DailySchedule.DurationCountInDays = 180; //TBD make it const + + //Weekly Retention policy + defaultRetention.FullBackupRetentionPolicy.IsWeeklyScheduleEnabled = true; + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule = new CmdletModel.WeeklyRetentionSchedule(); + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule.DaysOfTheWeek = new List(); + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule.DaysOfTheWeek.Add(System.DayOfWeek.Sunday); + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule.DurationCountInWeeks = 104; //TBD make it const + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule.RetentionTimes = new List(); + defaultRetention.FullBackupRetentionPolicy.WeeklySchedule.RetentionTimes.Add(retentionTime); + + //Monthly retention policy + defaultRetention.FullBackupRetentionPolicy.IsMonthlyScheduleEnabled = true; + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule = new CmdletModel.MonthlyRetentionSchedule(); + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.DurationCountInMonths = 60; //tbd: make it const + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.RetentionTimes = new List(); + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.RetentionTimes.Add(retentionTime); + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.RetentionScheduleFormatType = + CmdletModel.RetentionScheduleFormat.Weekly; + + //Initialize day based schedule + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.RetentionScheduleDaily = AzureWorkloadProviderHelper.GetDailyRetentionFormat(); + + //Initialize Week based schedule + defaultRetention.FullBackupRetentionPolicy.MonthlySchedule.RetentionScheduleWeekly = AzureWorkloadProviderHelper.GetWeeklyRetentionFormat(); + + //Yearly retention policy + defaultRetention.FullBackupRetentionPolicy.IsYearlyScheduleEnabled = true; + defaultRetention.FullBackupRetentionPolicy.YearlySchedule = new CmdletModel.YearlyRetentionSchedule(); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.DurationCountInYears = 10; + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.RetentionTimes = new List(); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.RetentionTimes.Add(retentionTime); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.RetentionScheduleFormatType = + CmdletModel.RetentionScheduleFormat.Weekly; + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.MonthsOfYear = new List(); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.MonthsOfYear.Add(Month.January); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.RetentionScheduleDaily = AzureWorkloadProviderHelper.GetDailyRetentionFormat(); + defaultRetention.FullBackupRetentionPolicy.YearlySchedule.RetentionScheduleWeekly = AzureWorkloadProviderHelper.GetWeeklyRetentionFormat(); + + //Setup DifferentialBackupRetentionPolicy + defaultRetention.DifferentialBackupRetentionPolicy.RetentionDurationType = CmdletModel.RetentionDurationType.Days; + defaultRetention.DifferentialBackupRetentionPolicy.RetentionCount = 30; + + //Setup LogBackupRetentionPolicy + defaultRetention.LogBackupRetentionPolicy.RetentionDurationType = CmdletModel.RetentionDurationType.Days; + defaultRetention.LogBackupRetentionPolicy.RetentionCount = 15; + + return defaultRetention; } public SchedulePolicyBase GetDefaultSchedulePolicyObject() { - throw new NotImplementedException(); + SQLSchedulePolicy defaultSchedule = new SQLSchedulePolicy(); + + defaultSchedule.FullBackupSchedulePolicy = new CmdletModel.SimpleSchedulePolicy(); + defaultSchedule.DifferentialBackupSchedulePolicy = new CmdletModel.SimpleSchedulePolicy(); + defaultSchedule.LogBackupSchedulePolicy = new CmdletModel.LogSchedulePolicy(); + defaultSchedule.IsDifferentialBackupEnabled = false; + defaultSchedule.IsLogBackupEnabled = true; + defaultSchedule.IsCompression = false; + + //Setup FullBackupSchedulePolicy + defaultSchedule.FullBackupSchedulePolicy.ScheduleRunFrequency = CmdletModel.ScheduleRunType.Daily; + DateTime scheduleTime = AzureWorkloadProviderHelper.GenerateRandomScheduleTime(); + defaultSchedule.FullBackupSchedulePolicy.ScheduleRunTimes = new List(); + defaultSchedule.FullBackupSchedulePolicy.ScheduleRunTimes.Add(scheduleTime); + + defaultSchedule.FullBackupSchedulePolicy.ScheduleRunDays = new List(); + defaultSchedule.FullBackupSchedulePolicy.ScheduleRunDays.Add(System.DayOfWeek.Sunday); + + //Setup DifferentialBackupSchedulePolicy + defaultSchedule.DifferentialBackupSchedulePolicy.ScheduleRunFrequency = CmdletModel.ScheduleRunType.Weekly; + defaultSchedule.DifferentialBackupSchedulePolicy.ScheduleRunTimes = new List(); + defaultSchedule.DifferentialBackupSchedulePolicy.ScheduleRunTimes.Add(scheduleTime); + + defaultSchedule.DifferentialBackupSchedulePolicy.ScheduleRunDays = new List(); + defaultSchedule.DifferentialBackupSchedulePolicy.ScheduleRunDays.Add(System.DayOfWeek.Monday); + + //Setup LogBackupSchedulePolicy + defaultSchedule.LogBackupSchedulePolicy.ScheduleFrequencyInMins = 120; + + return defaultSchedule; } public ProtectedItemResource GetProtectedItem() @@ -112,7 +201,120 @@ public List ListRecoveryPoints() public RestAzureNS.AzureOperationResponse ModifyPolicy() { - throw new NotImplementedException(); + return CreateorModifyPolicy(); + } + + private RestAzureNS.AzureOperationResponse CreateorModifyPolicy() + { + string vaultName = (string)ProviderData[VaultParams.VaultName]; + string resourceGroupName = (string)ProviderData[VaultParams.ResourceGroupName]; + string policyName = ProviderData.ContainsKey(PolicyParams.PolicyName) ? + (string)ProviderData[PolicyParams.PolicyName] : null; + RetentionPolicyBase retentionPolicy = + ProviderData.ContainsKey(PolicyParams.RetentionPolicy) ? + (RetentionPolicyBase)ProviderData[PolicyParams.RetentionPolicy] : + null; + SchedulePolicyBase schedulePolicy = + ProviderData.ContainsKey(PolicyParams.SchedulePolicy) ? + (SchedulePolicyBase)ProviderData[PolicyParams.SchedulePolicy] : + null; + PolicyBase policy = + ProviderData.ContainsKey(PolicyParams.ProtectionPolicy) ? + (PolicyBase)ProviderData[PolicyParams.ProtectionPolicy] : + null; + ProtectionPolicyResource serviceClientRequest = new ProtectionPolicyResource(); + + if (policy != null) + { + // do validations + ValidateAzureWorkloadProtectionPolicy(policy); + Logger.Instance.WriteDebug("Validation of Protection Policy is successful"); + + // RetentionPolicy and SchedulePolicy both should not be empty + if (retentionPolicy == null && schedulePolicy == null) + { + throw new ArgumentException(Resources.BothRetentionAndSchedulePoliciesEmpty); + } + + // validate RetentionPolicy and SchedulePolicy + if (schedulePolicy != null) + { + AzureWorkloadProviderHelper.ValidateSQLSchedulePolicy(schedulePolicy); + AzureWorkloadProviderHelper.GetUpdatedSchedulePolicy(policy, (SQLSchedulePolicy)schedulePolicy); + Logger.Instance.WriteDebug("Validation of Schedule policy is successful"); + } + if (retentionPolicy != null) + { + AzureWorkloadProviderHelper.ValidateSQLRetentionPolicy(retentionPolicy); + AzureWorkloadProviderHelper.GetUpdatedRetentionPolicy(policy, (SQLRetentionPolicy)retentionPolicy); + Logger.Instance.WriteDebug("Validation of Retention policy is successful"); + } + + // copy the backupSchedule time to retentionPolicy after converting to UTC + AzureWorkloadProviderHelper.CopyScheduleTimeToRetentionTimes( + (CmdletModel.LongTermRetentionPolicy)((AzureVmWorkloadPolicy)policy).FullBackupRetentionPolicy, + (CmdletModel.SimpleSchedulePolicy)((AzureVmWorkloadPolicy)policy).FullBackupSchedulePolicy); + Logger.Instance.WriteDebug("Copy of RetentionTime from with SchedulePolicy to RetentionPolicy is successful"); + + // Now validate both RetentionPolicy and SchedulePolicy matches or not + PolicyHelpers.ValidateLongTermRetentionPolicyWithSimpleRetentionPolicy( + (CmdletModel.LongTermRetentionPolicy)((AzureVmWorkloadPolicy)policy).FullBackupRetentionPolicy, + (CmdletModel.SimpleSchedulePolicy)((AzureVmWorkloadPolicy)policy).FullBackupSchedulePolicy); + Logger.Instance.WriteDebug("Validation of Retention policy with Schedule policy is successful"); + + // construct Service Client policy request + AzureVmWorkloadProtectionPolicy azureVmWorkloadProtectionPolicy = new AzureVmWorkloadProtectionPolicy(); + azureVmWorkloadProtectionPolicy.Settings = new Settings("UTC", + ((AzureVmWorkloadPolicy)policy).IsCompression, + ((AzureVmWorkloadPolicy)policy).IsCompression); + azureVmWorkloadProtectionPolicy.WorkLoadType = ConversionUtils.GetServiceClientWorkloadType(policy.WorkloadType.ToString()); + azureVmWorkloadProtectionPolicy.SubProtectionPolicy = new List(); + azureVmWorkloadProtectionPolicy.SubProtectionPolicy = PolicyHelpers.GetServiceClientSubProtectionPolicy((AzureVmWorkloadPolicy)policy); + serviceClientRequest.Properties = azureVmWorkloadProtectionPolicy; + } + else + { + CmdletModel.WorkloadType workloadType = + (CmdletModel.WorkloadType)ProviderData[PolicyParams.WorkloadType]; + + // do validations + ValidateAzureWorkloadWorkloadType(workloadType); + AzureWorkloadProviderHelper.ValidateSQLSchedulePolicy(schedulePolicy); + Logger.Instance.WriteDebug("Validation of Schedule policy is successful"); + + // validate RetentionPolicy + AzureWorkloadProviderHelper.ValidateSQLRetentionPolicy(retentionPolicy); + Logger.Instance.WriteDebug("Validation of Retention policy is successful"); + + // update the retention times from backupSchedule to retentionPolicy after converting to UTC + AzureWorkloadProviderHelper.CopyScheduleTimeToRetentionTimes(((SQLRetentionPolicy)retentionPolicy).FullBackupRetentionPolicy, + ((SQLSchedulePolicy)schedulePolicy).FullBackupSchedulePolicy); + Logger.Instance.WriteDebug("Copy of RetentionTime from with SchedulePolicy to RetentionPolicy is successful"); + + // Now validate both RetentionPolicy and SchedulePolicy together + PolicyHelpers.ValidateLongTermRetentionPolicyWithSimpleRetentionPolicy( + (SQLRetentionPolicy)retentionPolicy, + (SQLSchedulePolicy)schedulePolicy); + Logger.Instance.WriteDebug("Validation of Retention policy with Schedule policy is successful"); + + // construct Service Client policy request + AzureVmWorkloadProtectionPolicy azureVmWorkloadProtectionPolicy = new AzureVmWorkloadProtectionPolicy(); + azureVmWorkloadProtectionPolicy.Settings = new Settings("UTC", + ((SQLSchedulePolicy)schedulePolicy).IsCompression, + ((SQLSchedulePolicy)schedulePolicy).IsCompression); + azureVmWorkloadProtectionPolicy.WorkLoadType = ConversionUtils.GetServiceClientWorkloadType(workloadType.ToString()); + azureVmWorkloadProtectionPolicy.SubProtectionPolicy = new List(); + azureVmWorkloadProtectionPolicy.SubProtectionPolicy = PolicyHelpers.GetServiceClientSubProtectionPolicy( + (SQLRetentionPolicy)retentionPolicy, + (SQLSchedulePolicy)schedulePolicy); + serviceClientRequest.Properties = azureVmWorkloadProtectionPolicy; + } + + return ServiceClientAdapter.CreateOrUpdateProtectionPolicy( + policyName = policyName ?? policy.Name, + serviceClientRequest, + vaultName: vaultName, + resourceGroupName: resourceGroupName); } public RPMountScriptDetails ProvisionItemLevelRecoveryAccess() @@ -134,5 +336,29 @@ public RestAzureNS.AzureOperationResponse TriggerRestore() { throw new NotImplementedException(); } + + private void ValidateAzureWorkloadProtectionPolicy(PolicyBase policy) + { + if (policy == null || policy.GetType() != typeof(AzureVmWorkloadPolicy)) + { + throw new ArgumentException(string.Format(Resources.InvalidProtectionPolicyException, + typeof(AzureVmWorkloadPolicy).ToString())); + } + + ValidateAzureWorkloadWorkloadType(policy.WorkloadType); + + // call validation + policy.Validate(); + } + + private void ValidateAzureWorkloadWorkloadType(CmdletModel.WorkloadType type) + { + if (type != CmdletModel.WorkloadType.MSSQL) + { + throw new ArgumentException(string.Format(Resources.UnExpectedWorkLoadTypeException, + CmdletModel.WorkloadType.MSSQL.ToString(), + type.ToString())); + } + } } } \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs index 979ce2eca53b..b17dc3235d3a 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs @@ -792,10 +792,10 @@ public RetentionPolicyBase GetDefaultRetentionPolicyObject() CmdletModel.RetentionScheduleFormat.Weekly; //Initialize day based schedule - defaultRetention.MonthlySchedule.RetentionScheduleDaily = GetDailyRetentionFormat(); + defaultRetention.MonthlySchedule.RetentionScheduleDaily = AzureWorkloadProviderHelper.GetDailyRetentionFormat(); //Initialize Week based schedule - defaultRetention.MonthlySchedule.RetentionScheduleWeekly = GetWeeklyRetentionFormat(); + defaultRetention.MonthlySchedule.RetentionScheduleWeekly = AzureWorkloadProviderHelper.GetWeeklyRetentionFormat(); //Yearly retention policy defaultRetention.IsYearlyScheduleEnabled = true; @@ -807,8 +807,8 @@ public RetentionPolicyBase GetDefaultRetentionPolicyObject() CmdletModel.RetentionScheduleFormat.Weekly; defaultRetention.YearlySchedule.MonthsOfYear = new List(); defaultRetention.YearlySchedule.MonthsOfYear.Add(Month.January); - defaultRetention.YearlySchedule.RetentionScheduleDaily = GetDailyRetentionFormat(); - defaultRetention.YearlySchedule.RetentionScheduleWeekly = GetWeeklyRetentionFormat(); + defaultRetention.YearlySchedule.RetentionScheduleDaily = AzureWorkloadProviderHelper.GetDailyRetentionFormat(); + defaultRetention.YearlySchedule.RetentionScheduleWeekly = AzureWorkloadProviderHelper.GetWeeklyRetentionFormat(); return defaultRetention; } @@ -816,30 +816,6 @@ public RetentionPolicyBase GetDefaultRetentionPolicyObject() #region private - private static CmdletModel.DailyRetentionFormat GetDailyRetentionFormat() - { - CmdletModel.DailyRetentionFormat dailyRetention = - new CmdletModel.DailyRetentionFormat(); - dailyRetention.DaysOfTheMonth = new List(); - CmdletModel.Day dayBasedRetention = new CmdletModel.Day(); - dayBasedRetention.IsLast = false; - dayBasedRetention.Date = 1; - dailyRetention.DaysOfTheMonth.Add(dayBasedRetention); - return dailyRetention; - } - - private static CmdletModel.WeeklyRetentionFormat GetWeeklyRetentionFormat() - { - CmdletModel.WeeklyRetentionFormat weeklyRetention = - new CmdletModel.WeeklyRetentionFormat(); - weeklyRetention.DaysOfTheWeek = new List(); - weeklyRetention.DaysOfTheWeek.Add(System.DayOfWeek.Sunday); - - weeklyRetention.WeeksOfTheMonth = new List(); - weeklyRetention.WeeksOfTheMonth.Add(CmdletModel.WeekOfMonth.First); - return weeklyRetention; - } - private void ValidateAzureVMWorkloadType(CmdletModel.WorkloadType type) { if (type != CmdletModel.WorkloadType.AzureVM) diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.csproj b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.csproj new file mode 100644 index 000000000000..cfd489ad1ff9 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.csproj @@ -0,0 +1,277 @@ + + + + + + Debug + AnyCPU + {65E15D74-1E24-4600-8671-D0B420524B17} + Library + Properties + Microsoft.Azure.Commands.RecoveryServices.Backup.Test + Microsoft.Azure.Commands.RecoveryServices.Backup.Test + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\packages\Microsoft.Azure.Management.Compute.23.2.0\lib\net452\Microsoft.Azure.Management.Compute.dll + True + + + ..\..\..\packages\Microsoft.Azure.Management.Network.19.6.0-preview\lib\net452\Microsoft.Azure.Management.Network.dll + + + False + ..\..\..\packages\Microsoft.Azure.Management.RecoveryServices.4.2.1-preview\lib\net452\Microsoft.Azure.Management.RecoveryServices.dll + + + False + ..\..\..\packages\Microsoft.Azure.Management.RecoveryServices.Backup.3.0.1-preview\lib\net452\Microsoft.Azure.Management.RecoveryServices.Backup.dll + + + ..\..\..\packages\Microsoft.Azure.Management.Storage.4.1.0-preview\lib\net45\Microsoft.Azure.Management.Storage.dll + + + + + + + + + + + + + + Designer + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + + + {08cf7da7-0392-4a19-b79b-e1ff67cdb81a} + Commands.Storage + + + {52643bd5-6378-49bd-9f6e-dac9dd8a867b} + Commands.Compute + + + {98cfd96b-a6bc-4f15-ae2c-603fc2b58981} + Commands.Network + + + {604260dc-b392-4cf4-81ec-34b14591e2d2} + Commands.RecoveryServices + + + {e1f5201d-6067-430e-b303-4e367652991b} + Commands.Resources + + + {30b92759-50b3-494e-b9f0-ec9a2ce9d57b} + Commands.RecoveryServices.Backup.Models + + + {3b3e879a-f856-46bf-aff9-8ad6760cf7b9} + Commands.RecoveryServices.Backup.Cmdlets + + + + + + + + + + \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.cs new file mode 100644 index 000000000000..7d396f0344b6 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.cs @@ -0,0 +1,33 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// 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 Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; +using Microsoft.WindowsAzure.Commands.ScenarioTest; +using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; +using Xunit; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Test.ScenarioTests +{ + public partial class PolicyTests : RMTestBase + { + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(TestConstants.Workload, TestConstants.AzureVmWorkload)] + public void TestAzureVmWorkloadPolicy() + { + TestController.NewInstance.RunPsTest( + _logger, PsBackupProviderTypes.AzureWorkload, "Test-AzureVmWorkloadPolicy"); + } + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.ps1 b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.ps1 new file mode 100644 index 000000000000..5e72e7008144 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/PolicyTests.ps1 @@ -0,0 +1,80 @@ +# ---------------------------------------------------------------------------------- +# +# Copyright Microsoft Corporation +# 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. +# ---------------------------------------------------------------------------------- + +$location = "westus" +$resourceGroupName = "sisi-RSV" +$vaultName = "sisi-RSV-29-6" +$newPolicyName = "newSqlPolicy" + +function Test-AzureVmWorkloadPolicy +{ + $vault = Get-AzureRmRecoveryServicesVault -ResourceGroupName $resourceGroupName -Name $vaultName + + # Get default policy objects + $schedulePolicy = Get-AzureRmRecoveryServicesBackupSchedulePolicyObject -WorkloadType MSSQL + Assert-NotNull $schedulePolicy + $retentionPolicy = Get-AzureRmRecoveryServicesBackupRetentionPolicyObject -WorkloadType MSSQL + Assert-NotNull $retentionPolicy + + # Create policy + $policy = New-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -Name $newPolicyName ` + -WorkloadType MSSQL ` + -RetentionPolicy $retentionPolicy ` + -SchedulePolicy $schedulePolicy + Assert-NotNull $policy + Assert-AreEqual $policy.Name $newPolicyName + + # Get policy + $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -Name $newPolicyName + Assert-NotNull $policy + Assert-AreEqual $policy.Name $newPolicyName + + # Get default policy objects (this data is generated partially at random. So, running this again gives different values) + $schedulePolicy = Get-AzureRmRecoveryServicesBackupSchedulePolicyObject -WorkloadType MSSQL + $schedulePolicy.FullBackupSchedulePolicy.ScheduleRunFrequency = "Weekly" + $schedulePolicy.IsDifferentialBackupEnabled = $true + $schedulePolicy.IsCompression = $true + Assert-NotNull $schedulePolicy + + $retentionPolicy = Get-AzureRmRecoveryServicesBackupRetentionPolicyObject -WorkloadType MSSQL + $retentionPolicy.FullBackupRetentionPolicy.IsDailyScheduleEnabled = $false + $retentionPolicy.DifferentialBackupRetentionPolicy.RetentionCount = 31 + Assert-NotNull $retentionPolicy + + # Update policy + Set-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -RetentionPolicy $retentionPolicy ` + -SchedulePolicy $schedulePolicy ` + -Policy $policy + $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -Name $newPolicyName + Assert-AreEqual $policy.DifferentialBackupRetentionPolicy.RetentionCount $retentionPolicy.DifferentialBackupRetentionPolicy.RetentionCount + Assert-AreEqual $policy.IsCompression $schedulePolicy.IsCompression + + # Delete policy + Remove-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -Policy $policy ` + -Force + $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy ` + -VaultId $vault.ID ` + -WorkloadType MSSQL + Assert-False { $policy.Name -contains $newPolicyName } +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/TestConstants.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/TestConstants.cs index ed14871dd2d9..4dc07218666f 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/TestConstants.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/TestConstants.cs @@ -30,5 +30,7 @@ public class TestConstants public const string MAB = "MAB"; public const string AzureFS = "AzureFS"; + + public const string AzureVmWorkload = "AzureVmWorkload"; } } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/ProtectionPolicy/GetAzureRmRecoveryServicesBackupProtectionPolicy.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/ProtectionPolicy/GetAzureRmRecoveryServicesBackupProtectionPolicy.cs index fd0d6d16313c..35394c2719df 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/ProtectionPolicy/GetAzureRmRecoveryServicesBackupProtectionPolicy.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/ProtectionPolicy/GetAzureRmRecoveryServicesBackupProtectionPolicy.cs @@ -28,7 +28,7 @@ namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets /// Gets the list of protection policies associated with this recovery services vault /// according to the filters passed via the cmdlet parameters. /// - [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesBackupProtectionPolicy", DefaultParameterSetName = NoParamSet),OutputType(typeof(PolicyBase))] + [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesBackupProtectionPolicy", DefaultParameterSetName = NoParamSet), OutputType(typeof(PolicyBase))] public class GetAzureRmRecoveryServicesBackupProtectionPolicy : RSBackupVaultCmdletBase { protected const string PolicyNameParamSet = "PolicyNameParamSet"; @@ -121,48 +121,74 @@ public override void ExecuteCmdlet() { serviceClientProviderType = ServiceClientHelpers.GetServiceClientProviderType(Models.WorkloadType.AzureFiles); } + else if (WorkloadType == Models.WorkloadType.MSSQL) + { + serviceClientProviderType = ServiceClientHelpers.GetServiceClientProviderType(Models.WorkloadType.MSSQL); + } break; case WorkloadBackupMangementTypeParamSet: - if (WorkloadType == Models.WorkloadType.AzureVM) + if( WorkloadType == Models.WorkloadType.AzureVM ) + { + if( BackupManagementType != Models.BackupManagementType.AzureVM ) { - if (BackupManagementType != Models.BackupManagementType.AzureVM) - { - throw new ArgumentException( - Resources.AzureVMUnsupportedBackupManagementTypeException); - } - serviceClientProviderType = ServiceClientHelpers. - GetServiceClientProviderType(Models.WorkloadType.AzureVM); + throw new ArgumentException( + Resources.AzureVMUnsupportedBackupManagementTypeException ); } - else if (WorkloadType == Models.WorkloadType.AzureSQLDatabase) + serviceClientProviderType = ServiceClientHelpers. + GetServiceClientProviderType( Models.WorkloadType.AzureVM ); + } + else if( WorkloadType == Models.WorkloadType.AzureSQLDatabase ) + { + if( BackupManagementType != Models.BackupManagementType.AzureSQL ) { - if (BackupManagementType != Models.BackupManagementType.AzureSQL) - { - throw new ArgumentException( - Resources.AzureSqlUnsupportedBackupManagementTypeException); - } - serviceClientProviderType = - ServiceClientHelpers.GetServiceClientProviderType( - Models.WorkloadType.AzureSQLDatabase); + throw new ArgumentException( + Resources.AzureSqlUnsupportedBackupManagementTypeException ); } - else if (WorkloadType == Models.WorkloadType.AzureFiles) + serviceClientProviderType = + ServiceClientHelpers.GetServiceClientProviderType( + Models.WorkloadType.AzureSQLDatabase ); + } + else if( WorkloadType == Models.WorkloadType.AzureFiles ) + { + if( BackupManagementType != Models.BackupManagementType.AzureStorage ) { - if (BackupManagementType != Models.BackupManagementType.AzureStorage) - { - throw new ArgumentException( - Resources.AzureFileUnsupportedBackupManagementTypeException); - } - serviceClientProviderType = - ServiceClientHelpers.GetServiceClientProviderType( - Models.WorkloadType.AzureFiles); + throw new ArgumentException( + Resources.AzureFileUnsupportedBackupManagementTypeException ); + } + serviceClientProviderType = + ServiceClientHelpers.GetServiceClientProviderType( + Models.WorkloadType.AzureFiles ); + } + else if( WorkloadType == Models.WorkloadType.AzureFiles ) + { + if( BackupManagementType != Models.BackupManagementType.AzureStorage ) + { + throw new ArgumentException( + Resources.AzureFileUnsupportedBackupManagementTypeException ); } - else + serviceClientProviderType = + ServiceClientHelpers.GetServiceClientProviderType( + Models.WorkloadType.AzureFiles ); + } + else if( WorkloadType == Models.WorkloadType.MSSQL ) + { + if( BackupManagementType != Models.BackupManagementType.AzureWorkload ) { - throw new ArgumentException(string.Format( - Resources.UnsupportedWorkloadBackupManagementTypeException, - WorkloadType.ToString(), - BackupManagementType.ToString())); + throw new ArgumentException( + Resources.AzureFileUnsupportedBackupManagementTypeException ); } + serviceClientProviderType = + ServiceClientHelpers.GetServiceClientProviderType( + Models.WorkloadType.MSSQL ); + } + else + { + throw new ArgumentException( string.Format( + Resources.UnsupportedWorkloadBackupManagementTypeException, + WorkloadType.ToString(), + BackupManagementType.ToString() ) ); + } break; default: