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..a301c0617e62 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/Conversions/ConversionHelpers.cs @@ -12,10 +12,10 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System; -using System.Collections.Generic; using Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; +using System; +using System.Collections.Generic; using ServiceClientModel = Microsoft.Azure.Management.RecoveryServices.Backup.Models; namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers @@ -322,6 +322,7 @@ public static ItemBase GetItemModel(ServiceClientModel.ProtectedItemResource pro if (protectedItem != null && protectedItem.Properties != null) { + string z = protectedItem.Properties.GetType().ToString(); if (protectedItem.Properties.GetType().IsSubclassOf(typeof(ServiceClientModel.AzureIaaSVMProtectedItem))) { itemModel = GetAzureVmItemModel(protectedItem); @@ -338,8 +339,38 @@ public static ItemBase GetItemModel(ServiceClientModel.ProtectedItemResource pro { itemModel = GetAzureFileShareItemModel(protectedItem); } + + if (protectedItem.Properties.GetType() == + typeof(ServiceClientModel.AzureVmWorkloadSQLDatabaseProtectedItem)) + { + itemModel = GetAzureVmWorkloadItemModel(protectedItem); + } + } + + return itemModel; + } + + private static ItemBase GetAzureVmWorkloadItemModel(ServiceClientModel.ProtectedItemResource protectedItem) + { + ItemBase itemModel; + string policyName = null; + string policyId = ((ServiceClientModel.AzureVmWorkloadSQLDatabaseProtectedItem)protectedItem.Properties).PolicyId; + if (!string.IsNullOrEmpty(policyId)) + { + Dictionary keyValueDict = + HelperUtils.ParseUri(policyId); + policyName = HelperUtils.GetPolicyNameFromPolicyId(keyValueDict, policyId); } + string containerUri = HelperUtils.GetContainerUri( + HelperUtils.ParseUri(protectedItem.Id), + protectedItem.Id); + + itemModel = new AzureWorkloadSQLDatabaseProtectedItem( + protectedItem, + IdUtils.GetNameFromUri(containerUri), + ContainerType.AzureWorkload, + policyName); return itemModel; } @@ -418,7 +449,42 @@ private static ItemBase GetAzureVmItemModel(ServiceClientModel.ProtectedItemReso } /// - /// Helper function to convert ps backup policy item list from service response. + /// Helper function to convert ps protectable item from service response. + /// + public static ProtectableItemBase GetProtectableItemModel(ServiceClientModel.WorkloadProtectableItemResource protectableItem) + { + ProtectableItemBase itemModel = null; + + if (protectableItem != null && + protectableItem.Properties != null) + { + if (protectableItem.Properties.GetType().IsSubclassOf(typeof(ServiceClientModel.AzureVmWorkloadProtectableItem))) + { + itemModel = GetAzureWorkloadProtectableItemModel(protectableItem); + } + } + + return itemModel; + } + + private static ProtectableItemBase GetAzureWorkloadProtectableItemModel(ServiceClientModel.WorkloadProtectableItemResource protectableItem) + { + ProtectableItemBase itemModel; + + string containerUri = HelperUtils.GetContainerUri( + HelperUtils.ParseUri(protectableItem.Id), + protectableItem.Id); + + itemModel = new AzureWorkloadProtectableItem( + protectableItem, + IdUtils.GetNameFromUri(containerUri), + ContainerType.AzureWorkload); + + return itemModel; + } + + /// + /// Helper function to convert ps item list from service response. /// public static List GetItemModelList(IEnumerable protectedItems) { @@ -431,6 +497,21 @@ public static List GetItemModelList(IEnumerable + /// Helper function to convert ps protectable item list from service response. + /// + public static List GetProtectableItemModelList(IEnumerable protectableItems) + { + List itemModels = new List(); + + foreach (var protectableItem in protectableItems) + { + itemModels.Add(GetProtectableItemModel(protectableItem)); + } + + return itemModels; + } #endregion } } diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/ServiceClientHelpers.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/ServiceClientHelpers.cs index 07acea7e5bbf..b6ab24a37197 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/ServiceClientHelpers.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Helpers/ServiceClientHelpers.cs @@ -76,6 +76,9 @@ public static string GetServiceClientProviderType(CmdletModel.WorkloadType workl case CmdletModel.WorkloadType.AzureFiles: providerType = ServiceClientModel.BackupManagementType.AzureStorage.ToString(); break; + case CmdletModel.WorkloadType.MSSQL: + providerType = ServiceClientModel.BackupManagementType.AzureWorkload.ToString(); + break; default: break; } @@ -353,4 +356,4 @@ public static string GetServiceClientWorkloadType(CmdletModel.WorkloadType workl return serviceClientWorkloadType; } } -} +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadProtectableItem.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadProtectableItem.cs new file mode 100644 index 000000000000..bc9f900592df --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadProtectableItem.cs @@ -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. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Management.RecoveryServices.Backup.Models; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models +{ + /// + /// Azure workload protectable item Class + /// + public class AzureWorkloadProtectableItem : ProtectableItemBase + { + /// + /// name for instance or AG + /// + public string ParentName { get; set; } + + /// + /// Name of the Parent Only Applicable for data bases where the parent would be either + /// Instance or a SQL AG. + /// + public string ParentUniqueName { get; set; } + + /// + /// host/Cluster Name for instance or AG + /// + public string ServerName { get; set; } + + /// + /// indicates if protectable item is auto-protectable + /// + public bool? IsAutoProtectable { get; set; } + + /// + /// for instance or AG, indicates number of DB's present + /// + public int? Subinquireditemcount { get; set; } + + /// + /// for instance or AG, indicates number of DB's to be protected + /// + public int? Subprotectableitemcount { get; set; } + + /// + /// pre-backup validation for protectable objects + /// + public PreBackupValidation Prebackupvalidation { get; set; } + + /// + /// Constructor. Takes the service client object representing the protected item + /// and converts it in to the PS protected item model + /// + /// Service client object representing the protected item resource + /// Name of the container associated with this protected item + /// Type of the container associated with this protected item + public AzureWorkloadProtectableItem(WorkloadProtectableItemResource workloadProtectableItemResource, + string containerName, ContainerType containerType) + : base(workloadProtectableItemResource, containerName, containerType) + { + AzureVmWorkloadProtectableItem protectedItem = (AzureVmWorkloadProtectableItem)workloadProtectableItemResource.Properties; + ParentName = protectedItem.ParentName; + ParentUniqueName = protectedItem.ParentUniqueName; + ServerName = protectedItem.ServerName; + IsAutoProtectable = protectedItem.IsAutoProtectable; + Subinquireditemcount = protectedItem.Subinquireditemcount; + Subprotectableitemcount = protectedItem.Subprotectableitemcount; + } + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadSQLDatabaseProtectedItem.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadSQLDatabaseProtectedItem.cs new file mode 100644 index 000000000000..5aab74d361e0 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/AzureWorkloadModels/AzureWorkloadSQLDatabaseProtectedItem.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. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Management.RecoveryServices.Backup.Models; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models +{ + /// + /// Azure sql database workload Item Class + /// + public class AzureWorkloadSQLDatabaseProtectedItem : AzureItem + { + /// + /// friendly name of the DB represented by this backup item. + /// + public string FriendlyName { get; set; } + + /// + /// host/Cluster Name for instance or AG. + /// + public string ServerName { get; set; } + + /// + /// parent name of the DB such as Instance or Availability Group. + /// + public string ParentName { get; set; } + + /// + /// protected item, example: for a DB, standalone server + /// or distributed. + /// + public string ParentType { get; set; } + + /// + /// error details in last backup + /// + public ErrorDetail LastBackupErrorDetail { get; set; } + + /// + ///ID of the protected item. + /// + public string ProtectedItemDataSourceId { get; set; } + + /// + /// health status of the backup item + /// + public string ProtectedItemHealthStatus { get; set; } + + /// + /// Constructor. Takes the service client object representing the protected item + /// and converts it in to the PS protected item model + /// + /// Service client object representing the protected item resource + /// Name of the container associated with this protected item + /// Type of the container associated with this protected item + /// Name of the protection policy associated with this protected item + public AzureWorkloadSQLDatabaseProtectedItem(ProtectedItemResource protectedItemResource, + string containerName, ContainerType containerType, string policyName) + : base(protectedItemResource, containerName, containerType, policyName) + { + AzureVmWorkloadSQLDatabaseProtectedItem protectedItem = (AzureVmWorkloadSQLDatabaseProtectedItem)protectedItemResource.Properties; + FriendlyName = protectedItem.FriendlyName; + ServerName = protectedItem.ServerName; + ParentName = protectedItem.ParentName; + ParentType = protectedItem.ParentType; + LastBackupErrorDetail = protectedItem.LastBackupErrorDetail; + ProtectedItemDataSourceId = protectedItem.ProtectedItemDataSourceId; + ProtectedItemHealthStatus = protectedItem.ProtectedItemHealthStatus; + LastBackupStatus = protectedItem.LastBackupStatus; + LastBackupTime = protectedItem.LastBackupTime; + ProtectionState = + EnumUtils.GetEnum(protectedItem.ProtectionState.ToString()); + ProtectionStatus = EnumUtils.GetEnum(protectedItem.ProtectionStatus); + } + } + + /// + /// Azure Workload Item ExtendedInfo Class + /// + public class AzureWorkloadSQLDatabaseProtectedItemExtendedInfo : AzureItemExtendedInfo + { } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs index 0eb39736cf24..5189eb88d86d 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/BaseObjects.cs @@ -12,9 +12,9 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; using System; using System.Collections.Generic; -using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; using ServiceClientModel = Microsoft.Azure.Management.RecoveryServices.Backup.Models; namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models @@ -160,6 +160,37 @@ public ItemContext(ServiceClientModel.ProtectedItem protectedItem, } } + /// + /// Represents Azure Backup Item Context Class + /// + public class ProtectableItemContext : ContainerContext + { + /// + /// Workload Type of Item + /// + public WorkloadType WorkloadType { get; set; } + + /// + /// Unique name of the Container + /// + public string ContainerName { get; set; } + + public ProtectableItemContext() + : base() + { + + } + + public ProtectableItemContext(ServiceClientModel.WorkloadProtectableItem protectableItem, + string containerName, ContainerType containerType) + : base(containerType, protectableItem.BackupManagementType) + { + WorkloadType = ConversionUtils.GetPsWorkloadType( + protectableItem.WorkloadType.ToString()); + ContainerName = containerName; + } + } + /// /// Represents Azure Backup Item Base Class /// @@ -197,6 +228,31 @@ public ItemBase(ServiceClientModel.ProtectedItemResource protectedItemResource, } } + /// + /// Represents Azure Backup Protectable Item Base Class + /// + public class ProtectableItemBase : ProtectableItemContext + { + /// + /// Name of the item + /// + public string Name { get; set; } + + /// + /// Id of the item + /// + public string Id { get; set; } + + public ProtectableItemBase(ServiceClientModel.WorkloadProtectableItemResource workloadProtectableItemResource, + string containerName, ContainerType containerType) + : base(workloadProtectableItemResource.Properties, containerName, containerType) + { + ServiceClientModel.WorkloadProtectableItem protectableItem = workloadProtectableItemResource.Properties; + Name = workloadProtectableItemResource.Name; + Id = workloadProtectableItemResource.Id; + } + } + /// /// Represents Azure Backup Item ExtendedInfo Base Class /// diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CmdletParamEnums.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CmdletParamEnums.cs index 8c7821e52dea..a64a7994fc61 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CmdletParamEnums.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CmdletParamEnums.cs @@ -90,6 +90,7 @@ public enum ItemParams WorkloadType, Policy, Item, + ProtectableItem, ParameterSetName, Container, ProtectionStatus, diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Enums.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Enums.cs index 1ac388827f41..b8ab8fa5d328 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Enums.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Enums.cs @@ -37,7 +37,12 @@ public enum ContainerType /// /// Represents any Azure Storage containers. /// - AzureStorage + AzureStorage, + + /// + /// Represents any Azure Workload containers. + /// + AzureWorkload } /// @@ -70,6 +75,7 @@ public enum BackupManagementType /// Represents Azure File Storage. https://docs.microsoft.com/en-in/azure/storage/files/storage-files-introduction /// AzureStorage, + AzureWorkload, } /// @@ -103,6 +109,7 @@ public enum WorkloadType /// Represents Azure File https://docs.microsoft.com/en-in/azure/storage/files/storage-files-introduction /// AzureFiles, + MSSQL, } /// @@ -134,6 +141,7 @@ public enum PsBackupProviderTypes /// Represents the Azure File provider for powershell cmdlets. /// AzureFiles, + AzureWorkload, } /// @@ -334,4 +342,14 @@ public enum SourceFileType File, Directory } -} + + /// + /// Options to select the protectable type + /// + public enum ProtectableItemType + { + SQLDataBase, + SQLInstance, + SQLAvailabilityGroupContainer, + } +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Utils.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Utils.cs index 526188855a4f..80968b51a6ff 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Utils.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Models/CommonModels/Utils.cs @@ -218,6 +218,8 @@ public static BackupManagementType GetPsBackupManagementType(string backupManage return BackupManagementType.AzureSQL; case ServiceClientModel.BackupManagementType.AzureStorage: return BackupManagementType.AzureStorage; + case ServiceClientModel.BackupManagementType.AzureWorkload: + return BackupManagementType.AzureWorkload; default: throw new Exception("Unsupported BackupManagmentType: " + backupManagementType); } @@ -248,6 +250,11 @@ public static ContainerType GetPsContainerType(string containerType) { return ContainerType.AzureStorage; } + else if (containerType == + ServiceClientModel.BackupManagementType.AzureWorkload) + { + return ContainerType.AzureWorkload; + } else { throw new Exception("Unsupported ContainerType: " + containerType); @@ -265,14 +272,22 @@ public static WorkloadType GetPsWorkloadType(string workloadType) { return WorkloadType.AzureVM; } - if (workloadType == ServiceClientModel.WorkloadType.AzureSqlDb.ToString()) + else if (workloadType == ServiceClientModel.WorkloadType.AzureSqlDb.ToString()) { return WorkloadType.AzureSQLDatabase; } - if (workloadType == ServiceClientModel.WorkloadType.AzureFileShare) + else if (workloadType == ServiceClientModel.WorkloadType.AzureFileShare) { return WorkloadType.AzureFiles; } + else if (workloadType == ServiceClientModel.WorkloadType.SQLDataBase) + { + return WorkloadType.MSSQL; + } + else if (workloadType == "SQL") + { + return WorkloadType.MSSQL; + } else { throw new Exception("Unsupported WorkloadType: " + workloadType); @@ -290,14 +305,18 @@ public static string GetServiceClientWorkloadType(string workloadType) { return ServiceClientModel.WorkloadType.VM; } - if (workloadType == WorkloadType.AzureSQLDatabase.ToString()) + else if (workloadType == WorkloadType.AzureSQLDatabase.ToString()) { return ServiceClientModel.WorkloadType.AzureSqlDb; } - if (workloadType == WorkloadType.AzureFiles.ToString()) + else if (workloadType == WorkloadType.AzureFiles.ToString()) { return ServiceClientModel.WorkloadType.AzureFileShare; } + else if (workloadType == WorkloadType.MSSQL.ToString()) + { + return ServiceClientModel.WorkloadType.SQLDataBase; + } else { throw new Exception("Unsupported WorkloadType: " + workloadType); @@ -343,4 +362,4 @@ public static string GetWorkloadTypeFromArmType(string armType) throw new Exception("Unsupported ArmType: " + armType); } } -} +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs index b7fb5f2a1bd8..682fcfbc4924 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/AzureWorkloadProviderHelper.cs @@ -352,5 +352,36 @@ public CmdletModel.RecoveryPointBase GetRecoveryPointDetails(Dictionary queryParams = new ODataQuery( + q => q.WorkloadType + == workloadType); + string errorMessage = string.Empty; + var inquiryResponse = ServiceClientAdapter.InquireContainer( + containerName, + queryParams, + vaultName, + vaultResourceGroupName); + + var operationStatus = TrackingHelpers.GetOperationResult( + inquiryResponse, + operationId => + ServiceClientAdapter.GetContainerRefreshOrInquiryOperationResult( + operationId, + vaultName: vaultName, + resourceGroupName: vaultResourceGroupName)); + + //Now wait for the operation to Complete + if (inquiryResponse.Response.StatusCode + != SystemNet.HttpStatusCode.NoContent) + { + errorMessage = string.Format(Resources.TriggerEnquiryFailureErrorCode, + inquiryResponse.Response.StatusCode); + Logger.Instance.WriteDebug(errorMessage); + } + } } } \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Commands.RecoveryServices.Backup.Providers.csproj b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Commands.RecoveryServices.Backup.Providers.csproj new file mode 100644 index 000000000000..a7c0bb54ea7e --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Commands.RecoveryServices.Backup.Providers.csproj @@ -0,0 +1,93 @@ + + + + + + Debug + AnyCPU + {02234E90-BCDE-4B20-B1F5-01B1005821DB} + Library + Properties + Microsoft.Azure.Commands.RecoveryServices.Backup.Providers + Microsoft.Azure.Commands.RecoveryServices.Backup.Providers + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + {142d7b0b-388a-4ceb-a228-7f6d423c5c2e} + Commands.Profile + + + {0e1d3f36-e6c8-4764-8c7d-6f9ee537490c} + Commands.RecoveryServices.Backup.Helpers + + + {5e675749-6139-464a-904c-59c0ffdfec82} + Commands.RecoveryServices.Backup.Logger + + + {30b92759-50b3-494e-b9f0-ec9a2ce9d57b} + Commands.RecoveryServices.Backup.Models + + + {b758fec1-35c1-4f93-a954-66dd33f6e0ec} + Commands.RecoveryServices.Backup.ServiceClientAdapter + + + + + + + + \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureFilesPsBackupProvider.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureFilesPsBackupProvider.cs index cd54f4a273cf..6a1f14301807 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureFilesPsBackupProvider.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureFilesPsBackupProvider.cs @@ -17,7 +17,6 @@ using Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers; using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; using Microsoft.Azure.Management.Internal.Resources.Models; -using Microsoft.Azure.Management.Internal.Resources.Utilities.Models; using Microsoft.Azure.Management.RecoveryServices.Backup.Models; using Microsoft.Rest.Azure.OData; using System; @@ -27,7 +26,6 @@ using CmdletModel = Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; using RestAzureNS = Microsoft.Rest.Azure; using ServiceClientModel = Microsoft.Azure.Management.RecoveryServices.Backup.Models; -using SystemNet = System.Net; namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.ProviderModel { @@ -476,7 +474,8 @@ private WorkloadProtectableItemResource GetAzureFileShareProtectableObject( } //inquiry - TriggerInquiry(vaultName, vaultResourceGroupName, storageContainerName); + AzureWorkloadProviderHelper.TriggerInquiry(vaultName, vaultResourceGroupName, + storageContainerName, ServiceClientModel.WorkloadType.AzureFileShare); //get protectable item WorkloadProtectableItemResource protectableObjectResource = null; @@ -532,37 +531,6 @@ private WorkloadProtectableItemResource GetProtectableItem(string vaultName, str return protectableObjectResource; } - private void TriggerInquiry(string vaultName, string vaultResourceGroupName, - string storageContainerName) - { - ODataQuery queryParams = new ODataQuery( - q => q.WorkloadType - == ServiceClientModel.WorkloadType.AzureFileShare); - string errorMessage = string.Empty; - var inquiryResponse = ServiceClientAdapter.InquireContainer( - storageContainerName, - queryParams, - vaultName, - vaultResourceGroupName); - - var operationStatus = TrackingHelpers.GetOperationResult( - inquiryResponse, - operationId => - ServiceClientAdapter.GetContainerRefreshOrInquiryOperationResult( - operationId, - vaultName: vaultName, - resourceGroupName: vaultResourceGroupName)); - - //Now wait for the operation to Complete - if (inquiryResponse.Response.StatusCode - != SystemNet.HttpStatusCode.NoContent) - { - errorMessage = string.Format(Resources.TriggerEnquiryFailureErrorCode, - inquiryResponse.Response.StatusCode); - Logger.Instance.WriteDebug(errorMessage); - } - } - private List GetRegisteredStorageAccounts(string vaultName = null, string vaultResourceGroupName = null) { diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs new file mode 100644 index 000000000000..8c65973ad16a --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/Providers/AzureWorkloadPsBackupProvider.cs @@ -0,0 +1,315 @@ +// ---------------------------------------------------------------------------------- +// +// 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.Azure.Commands.RecoveryServices.Backup.Cmdlets.ServiceClientAdapterNS; +using Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers; +using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; +using Microsoft.Azure.Management.RecoveryServices.Backup.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using CmdletModel = Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models; +using RestAzureNS = Microsoft.Rest.Azure; +using ServiceClientModel = Microsoft.Azure.Management.RecoveryServices.Backup.Models; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.ProviderModel +{ + /// + /// This class implements methods for azure DB Workload backup provider + /// + public class AzureWorkloadPsBackupProvider : IPsBackupProvider + { + private const int defaultOperationStatusRetryTimeInMilliSec = 5 * 1000; // 5 sec + private const string separator = ";"; + private const CmdletModel.RetentionDurationType defaultFileRetentionType = + CmdletModel.RetentionDurationType.Days; + private const int defaultFileRetentionCount = 30; + Dictionary ProviderData { get; set; } + ServiceClientAdapter ServiceClientAdapter { get; set; } + AzureWorkloadProviderHelper AzureWorkloadProviderHelper { get; set; } + /// + /// Initializes the provider with the data recieved from the cmdlet layer + /// + /// Data from the cmdlet layer intended for the provider + /// Service client adapter for communicating with the backend service + public void Initialize(Dictionary providerData, ServiceClientAdapter serviceClientAdapter) + { + ProviderData = providerData; + ServiceClientAdapter = serviceClientAdapter; + AzureWorkloadProviderHelper = new AzureWorkloadProviderHelper(ServiceClientAdapter); + } + + public ResourceBackupStatus CheckBackupStatus() + { + throw new NotImplementedException(); + } + + public ProtectionPolicyResource CreatePolicy() + { + throw new NotImplementedException(); + } + + public RestAzureNS.AzureOperationResponse DisableProtection() + { + string vaultName = (string)ProviderData[VaultParams.VaultName]; + string vaultResourceGroupName = (string)ProviderData[VaultParams.ResourceGroupName]; + bool deleteBackupData = ProviderData.ContainsKey(ItemParams.DeleteBackupData) ? + (bool)ProviderData[ItemParams.DeleteBackupData] : false; + + ItemBase itemBase = (ItemBase)ProviderData[ItemParams.Item]; + + AzureWorkloadSQLDatabaseProtectedItem item = (AzureWorkloadSQLDatabaseProtectedItem)ProviderData[ItemParams.Item]; + string containerUri = ""; + string protectedItemUri = ""; + AzureVmWorkloadSQLDatabaseProtectedItem properties = new AzureVmWorkloadSQLDatabaseProtectedItem(); + + if (deleteBackupData) + { + //Disable protection and delete backup data + ValidateAzureWorkloadSQLDatabaseDisableProtectionRequest(itemBase); + + Dictionary keyValueDict = HelperUtils.ParseUri(item.Id); + containerUri = HelperUtils.GetContainerUri(keyValueDict, item.Id); + protectedItemUri = HelperUtils.GetProtectedItemUri(keyValueDict, item.Id); + + return ServiceClientAdapter.DeleteProtectedItem( + containerUri, + protectedItemUri, + vaultName: vaultName, + resourceGroupName: vaultResourceGroupName); + } + else + { + return EnableOrModifyProtection(disableWithRetentionData: true); + } + } + + public RestAzureNS.AzureOperationResponse EnableProtection() + { + return EnableOrModifyProtection(); + } + + public RetentionPolicyBase GetDefaultRetentionPolicyObject() + { + throw new NotImplementedException(); + } + + public SchedulePolicyBase GetDefaultSchedulePolicyObject() + { + throw new NotImplementedException(); + } + + public ProtectedItemResource GetProtectedItem() + { + throw new NotImplementedException(); + } + + public RecoveryPointBase GetRecoveryPointDetails() + { + throw new NotImplementedException(); + } + + public List ListBackupManagementServers() + { + throw new NotImplementedException(); + } + + public List ListProtectedItems() + { + string vaultName = (string)ProviderData[VaultParams.VaultName]; + string resourceGroupName = (string)ProviderData[VaultParams.ResourceGroupName]; + ContainerBase container = + (ContainerBase)ProviderData[ItemParams.Container]; + string itemName = (string)ProviderData[ItemParams.ItemName]; + ItemProtectionStatus protectionStatus = + (ItemProtectionStatus)ProviderData[ItemParams.ProtectionStatus]; + ItemProtectionState status = + (ItemProtectionState)ProviderData[ItemParams.ProtectionState]; + CmdletModel.WorkloadType workloadType = + (CmdletModel.WorkloadType)ProviderData[ItemParams.WorkloadType]; + PolicyBase policy = (PolicyBase)ProviderData[PolicyParams.ProtectionPolicy]; + + // 1. Filter by container + List protectedItems = AzureWorkloadProviderHelper.ListProtectedItemsByContainer( + vaultName, + resourceGroupName, + container, + policy, + ServiceClientModel.BackupManagementType.AzureWorkload, + DataSourceType.SQLDataBase); + + List protectedItemGetResponses = + new List(); + + // 2. Filter by item name + List itemModels = AzureWorkloadProviderHelper.ListProtectedItemsByItemName( + protectedItems, + itemName, + vaultName, + resourceGroupName, + (itemModel, protectedItemGetResponse) => + { + AzureWorkloadSQLDatabaseProtectedItemExtendedInfo extendedInfo = new AzureWorkloadSQLDatabaseProtectedItemExtendedInfo(); + var serviceClientExtendedInfo = ((AzureVmWorkloadSQLDatabaseProtectedItem)protectedItemGetResponse.Properties).ExtendedInfo; + if (serviceClientExtendedInfo.OldestRecoveryPoint.HasValue) + { + extendedInfo.OldestRecoveryPoint = serviceClientExtendedInfo.OldestRecoveryPoint; + } + extendedInfo.PolicyState = serviceClientExtendedInfo.PolicyState.ToString(); + extendedInfo.RecoveryPointCount = + (int)(serviceClientExtendedInfo.RecoveryPointCount.HasValue ? + serviceClientExtendedInfo.RecoveryPointCount : 0); + ((AzureWorkloadSQLDatabaseProtectedItem)itemModel).ExtendedInfo = extendedInfo; + }); + + // 3. Filter by item's Protection Status + if (protectionStatus != 0) + { + itemModels = itemModels.Where(itemModel => + { + return ((AzureWorkloadSQLDatabaseProtectedItem)itemModel).ProtectionStatus == protectionStatus; + }).ToList(); + } + + // 4. Filter by item's Protection State + if (status != 0) + { + itemModels = itemModels.Where(itemModel => + { + return ((AzureWorkloadSQLDatabaseProtectedItem)itemModel).ProtectionState == status; + }).ToList(); + } + + // 5. Filter by workload type + if (workloadType != 0) + { + itemModels = itemModels.Where(itemModel => + { + return itemModel.WorkloadType == workloadType; + }).ToList(); + } + + return itemModels; + } + + public List ListProtectionContainers() + { + throw new NotImplementedException(); + } + + public List ListRecoveryPoints() + { + throw new NotImplementedException(); + } + + public RestAzureNS.AzureOperationResponse ModifyPolicy() + { + throw new NotImplementedException(); + } + + public RPMountScriptDetails ProvisionItemLevelRecoveryAccess() + { + throw new NotImplementedException(); + } + + public void RevokeItemLevelRecoveryAccess() + { + throw new NotImplementedException(); + } + + public RestAzureNS.AzureOperationResponse TriggerBackup() + { + throw new NotImplementedException(); + } + + public RestAzureNS.AzureOperationResponse TriggerRestore() + { + throw new NotImplementedException(); + } + + private RestAzureNS.AzureOperationResponse EnableOrModifyProtection(bool disableWithRetentionData = false) + { + string vaultName = (string)ProviderData[VaultParams.VaultName]; + string vaultResourceGroupName = (string)ProviderData[VaultParams.ResourceGroupName]; + + PolicyBase policy = ProviderData.ContainsKey(ItemParams.Policy) ? + (PolicyBase)ProviderData[ItemParams.Policy] : null; + + ProtectableItemBase protectableItemBase = (ProtectableItemBase)ProviderData[ItemParams.ProtectableItem]; + + AzureWorkloadProtectableItem protectableItem = (AzureWorkloadProtectableItem)ProviderData[ItemParams.ProtectableItem]; + + string containerUri = ""; + string protectedItemUri = ""; + AzureVmWorkloadSQLDatabaseProtectedItem properties = new AzureVmWorkloadSQLDatabaseProtectedItem(); + + if (protectableItemBase == null) + { + Dictionary keyValueDict = + HelperUtils.ParseUri(protectableItem.Id); + containerUri = HelperUtils.GetContainerUri( + keyValueDict, protectableItem.Id); + protectedItemUri = HelperUtils.GetProtectableItemUri( + keyValueDict, protectableItem.Id); + + properties.PolicyId = policy.Id; + } + ProtectedItemResource serviceClientRequest = new ProtectedItemResource() + { + Properties = properties + }; + + return ServiceClientAdapter.CreateOrUpdateProtectedItem( + containerUri, + protectedItemUri, + serviceClientRequest, + vaultName: vaultName, + resourceGroupName: vaultResourceGroupName); + } + + private void ValidateAzureWorkloadSQLDatabaseDisableProtectionRequest(ItemBase itemBase) + { + + if (itemBase == null || itemBase.GetType() != typeof(AzureWorkloadSQLDatabaseProtectedItem)) + { + throw new ArgumentException(string.Format(Resources.InvalidProtectionPolicyException, + typeof(AzureWorkloadSQLDatabaseProtectedItem).ToString())); + } + + ValidateAzureVmWorkloadType(itemBase.WorkloadType); + ValidateAzureVmContainerType(itemBase.ContainerType); + } + + private void ValidateAzureVmWorkloadType(CmdletModel.WorkloadType type) + { + if (type != CmdletModel.WorkloadType.MSSQL) + { + throw new ArgumentException(string.Format(Resources.UnExpectedWorkLoadTypeException, + CmdletModel.WorkloadType.MSSQL.ToString(), + type.ToString())); + } + } + + private void ValidateAzureVmContainerType(CmdletModel.ContainerType type) + { + if (type != CmdletModel.ContainerType.AzureWorkload) + { + throw new ArgumentException(string.Format(Resources.UnExpectedContainerTypeException, + CmdletModel.ContainerType.AzureWorkload.ToString(), + type.ToString())); + } + } + } +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/PsBackupProviderManager.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/PsBackupProviderManager.cs index 3495a997a853..d241d3e99a05 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/PsBackupProviderManager.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Providers/PsBackupProviderManager.cs @@ -215,6 +215,16 @@ public IPsBackupProvider GetProviderInstance( } psProviderType = PsBackupProviderTypes.AzureFiles; break; + case WorkloadType.MSSQL: + if (backupManagementType.HasValue && + backupManagementType != BackupManagementType.AzureWorkload) + { + throw new ArgumentException( + string.Format(Resources.BackupManagementTypeNotExpectedForWorkloadType, + workloadType.ToString())); + } + psProviderType = PsBackupProviderTypes.AzureWorkload; + break; default: throw new ArgumentException( string.Format(Resources.UnsupportedWorkloadTypeException, @@ -248,6 +258,9 @@ public IPsBackupProvider GetProviderInstance(PsBackupProviderTypes providerType) case PsBackupProviderTypes.AzureFiles: psBackupProvider = new AzureFilesPsBackupProvider(); break; + case PsBackupProviderTypes.AzureWorkload: + psBackupProvider = new AzureWorkloadPsBackupProvider(); + break; default: break; } @@ -277,4 +290,4 @@ public IPsBackupProvider GetProviderInstance(string resourceType) } } } -} +} \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.Netcore.csproj b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.Netcore.csproj index e9c4bd71e7bd..45171c3f5bee 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.Netcore.csproj +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/Commands.RecoveryServices.Backup.Test.Netcore.csproj @@ -23,10 +23,10 @@ - PreserveNewest + Always - PreserveNewest + Always \ No newline at end of file diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.cs new file mode 100644 index 000000000000..348ccba80103 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.cs @@ -0,0 +1,51 @@ +// ---------------------------------------------------------------------------------- +// +// 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 ItemTests : RMTestBase + { + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(TestConstants.Workload, TestConstants.AzureVmWorkload)] + public void TestAzureVmWorkloadProtectableItem() + { + TestController.NewInstance.RunPsTest( + _logger, PsBackupProviderTypes.AzureWorkload, "Test-AzureVmWorkloadProtectableItem"); + } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(TestConstants.Workload, TestConstants.AzureVmWorkload)] + public void TestAzureVmWorkloadProtectedItem() + { + TestController.NewInstance.RunPsTest( + _logger, PsBackupProviderTypes.AzureWorkload, "Test-AzureVmWorkloadProtectedItem"); + } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(TestConstants.Workload, TestConstants.AzureVmWorkload)] + public void TestAzureVmWorkloadNewProtectableItem() + { + TestController.NewInstance.RunPsTest( + _logger, PsBackupProviderTypes.AzureWorkload, "Test-AzureVmWorkloadNewProtectableItem"); + } + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.ps1 b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.ps1 new file mode 100644 index 000000000000..92f10e067aa4 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup.Test/ScenarioTests/AzureWorkload/ItemTests.ps1 @@ -0,0 +1,52 @@ +# ---------------------------------------------------------------------------------- +# +# 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. +# ---------------------------------------------------------------------------------- + +function Test-AzureVmWorkloadProtectableItem +{ + try + { + Get-AzureRmRecoveryServicesVault -ResourceGroupName 'shracrg' -Name 'shracsql' | Set-AzureRmRecoveryServicesVaultContext + $items = Get-AzRecoveryServicesBackupProtectableItem -ProtectableItemType "SQLDataBase" + } + finally + { + + } +} + +function Test-AzureVmWorkloadProtectedItem +{ + try + { + Get-AzureRmRecoveryServicesVault -ResourceGroupName 'shracrg' -Name 'shracsql' | Set-AzureRmRecoveryServicesVaultContext + $items = Get-AzRecoveryServicesBackupItem -BackupManagementType "AzureWorkload" -WorkloadType MSSQL + } + finally + { + + } +} + +function Test-AzureVmWorkloadNewProtectableItem +{ + try + { + Get-AzureRmRecoveryServicesVault -ResourceGroupName 'shracrg' -Name 'shracsql' | Set-AzureRmRecoveryServicesVaultContext + $items = New-AzRecoveryServicesBackupProtectableItem -WorkloadType MSSQL + } + finally + { + + } +} \ 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/Item/EnableAzureRmRecoveryServicesBackupProtection.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/EnableAzureRmRecoveryServicesBackupProtection.cs index 624920474b3e..4369aecded9f 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/EnableAzureRmRecoveryServicesBackupProtection.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/EnableAzureRmRecoveryServicesBackupProtection.cs @@ -33,6 +33,7 @@ public class EnableAzureRmRecoveryServicesBackupProtection : RSBackupVaultCmdlet internal const string AzureVMClassicComputeParameterSet = "AzureVMClassicComputeEnableProtection"; internal const string AzureVMComputeParameterSet = "AzureVMComputeEnableProtection"; internal const string AzureFileShareParameterSet = "AzureFileShareEnableProtection"; + internal const string AzureWorkloadParameterSet = "AzureWorkloadEnableProtection"; internal const string ModifyProtectionParameterSet = "ModifyProtection"; /// @@ -53,6 +54,11 @@ public class EnableAzureRmRecoveryServicesBackupProtection : RSBackupVaultCmdlet ParameterSetName = AzureFileShareParameterSet, HelpMessage = ParamHelpMsgs.Item.ItemName)] public string Name { get; set; } + [Parameter(Position = 2, Mandatory = true, ParameterSetName = AzureWorkloadParameterSet, + HelpMessage = ParamHelpMsgs.Item.ProtectedItem, ValueFromPipeline = true)] + [ValidateNotNullOrEmpty] + public ProtectableItemBase ProtectableItem { get; set; } + /// /// Service name of the classic Azure VM whose representative item needs to be protected. /// @@ -116,6 +122,7 @@ public override void ExecuteCmdlet() { ItemParams.AzureVMResourceGroupName, ResourceGroupName }, { ItemParams.Policy, Policy }, { ItemParams.Item, Item }, + { ItemParams.ProtectableItem, ProtectableItem }, { ItemParams.ParameterSetName, this.ParameterSetName }, }, ServiceClientAdapter); diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/GetAzureRMRecoveryServicesBackupProtectableItem.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/GetAzureRMRecoveryServicesBackupProtectableItem.cs new file mode 100644 index 000000000000..e84dc117b0e8 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/GetAzureRMRecoveryServicesBackupProtectableItem.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 Microsoft.Azure.Commands.RecoveryServices.Backup.Helpers; +using Microsoft.Azure.Management.Internal.Resources.Utilities.Models; +using Microsoft.Azure.Management.RecoveryServices.Backup.Models; +using Microsoft.Rest.Azure.OData; +using System.Collections.Generic; +using System.Management.Automation; +using BackupManagementType = Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.Models.BackupManagementType; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets +{ + /// + /// Get list of items associated with the recovery services vault + /// according to the filters passed via the cmdlet parameters. + /// + [Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesBackupProtectableItem"), OutputType(typeof(ProtectableItemBase))] + public class GetAzureRmRecoveryServicesBackupProtectableItem : RSBackupVaultCmdletBase + { + + /// + /// When this option is specified, only those items which belong to this container will be returned. + /// + [Parameter( + Mandatory = true, + Position = 1, + HelpMessage = ParamHelpMsgs.ProtectableItem.ItemType, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public ProtectableItemType ProtectableItemType { get; set; } + + ///// + ///// Backup management type of the items to be returned. + ///// + //[Parameter(Mandatory = true, Position = 2, HelpMessage = ParamHelpMsgs.Common.BackupManagementType)] + //[ValidateNotNullOrEmpty] + //public BackupManagementType BackupManagementType { get; set; } + + //[Parameter( + // Mandatory = true, + // Position = 2, + // HelpMessage = ParamHelpMsgs.Item.Container, + // ValueFromPipelineByPropertyName = true)] + //[ValidateNotNullOrEmpty] + //public ContainerBase Container { get; set; } + + public override void ExecuteCmdlet() + { + ExecutionBlock(() => + { + base.ExecuteCmdlet(); + + ResourceIdentifier resourceIdentifier = new ResourceIdentifier(VaultId); + string vaultName = resourceIdentifier.ResourceName; + string resourceGroupName = resourceIdentifier.ResourceGroupName; + + string backupManagementType = BackupManagementType.AzureWorkload.ToString(); + string workloadType = ProtectableItemType.ToString(); + ODataQuery queryParam = new ODataQuery( + q => q.BackupManagementType + == backupManagementType && + q.WorkloadType == workloadType); + + WriteDebug("going to query service to get list of protectable items"); + List protectableItems = + ServiceClientAdapter.ListProtectableItem( + queryParam, + vaultName: vaultName, + resourceGroupName: resourceGroupName); + WriteDebug("Successfully got response from service"); + List itemModels = ConversionHelpers.GetProtectableItemModelList(protectableItems); + + WriteObject(itemModels, enumerateCollection: true); + }); + } + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/NewAzureRmRecoveryServicesBackupProtectableItem.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/NewAzureRmRecoveryServicesBackupProtectableItem.cs new file mode 100644 index 000000000000..bab4cd0adf90 --- /dev/null +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/Cmdlets/Item/NewAzureRmRecoveryServicesBackupProtectableItem.cs @@ -0,0 +1,99 @@ +// ---------------------------------------------------------------------------------- +// +// 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.Azure.Commands.RecoveryServices.Backup.Helpers; +using Microsoft.Azure.Commands.RecoveryServices.Backup.Properties; +using Microsoft.Azure.Management.Internal.Resources.Utilities.Models; +using Microsoft.Azure.Management.RecoveryServices.Backup.Models; +using Microsoft.Rest.Azure.OData; +using System.Management.Automation; +using SystemNet = System.Net; + +namespace Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets +{ + /// + /// Get list of items associated with the recovery services vault + /// according to the filters passed via the cmdlet parameters. + /// + [Cmdlet("New", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "RecoveryServicesBackupProtectableItem"), OutputType(typeof(ItemBase))] + public class NewAzureRmRecoveryServicesBackupProtectableItem : RSBackupVaultCmdletBase + { + /// + /// Workload type of the item to be returned. + /// + [Parameter(Mandatory = true, Position = 1, + HelpMessage = ParamHelpMsgs.Common.WorkloadType)] + [ValidateNotNullOrEmpty] + public Models.WorkloadType WorkloadType { get; set; } + + + ///// + ///// Container base + ///// + //[Parameter( + // Mandatory = true, Position = 2, + // HelpMessage = ParamHelpMsgs.Item.Container, + // ValueFromPipelineByPropertyName = true)] + //[ValidateNotNullOrEmpty] + //public ContainerBase Container { get; set; } + + public override void ExecuteCmdlet() + { + ExecutionBlock(() => + { + base.ExecuteCmdlet(); + + ResourceIdentifier resourceIdentifier = new ResourceIdentifier(VaultId); + string vaultName = resourceIdentifier.ResourceName; + string vaultResourceGroupName = resourceIdentifier.ResourceGroupName; + string workloadType = ConversionUtils.GetServiceClientWorkloadType(WorkloadType.ToString()); + + ODataQuery queryParams = new ODataQuery( + q => q.WorkloadType + == workloadType); + string errorMessage = string.Empty; + var inquiryResponse = ServiceClientAdapter.InquireContainer( + "compute;shracrg;shrac3", + queryParams, + vaultName, + vaultResourceGroupName); + + var operationStatus = TrackingHelpers.GetOperationResult( + inquiryResponse, + operationId => + ServiceClientAdapter.GetContainerRefreshOrInquiryOperationResult( + operationId, + vaultName: vaultName, + resourceGroupName: vaultResourceGroupName)); + + if (inquiryResponse.Response.StatusCode + == SystemNet.HttpStatusCode.OK) + { + Logger.Instance.WriteDebug(errorMessage); + } + //Now wait for the operation to Complete + if (inquiryResponse.Response.StatusCode + != SystemNet.HttpStatusCode.NoContent) + { + errorMessage = string.Format(Resources.TriggerEnquiryFailureErrorCode, + inquiryResponse.Response.StatusCode); + Logger.Instance.WriteDebug(errorMessage); + } + + // WriteObject(itemModels, enumerateCollection: true); + }); + } + } +} diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/ParamHelpMsgs.cs b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/ParamHelpMsgs.cs index 3a14c9d7553d..d56385b80fa2 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/ParamHelpMsgs.cs +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices.Backup/ParamHelpMsgs.cs @@ -70,6 +70,7 @@ internal static class Item public const string AzureVMServiceName = "Cloud Service Name for Azure Classic Compute VM."; public const string AzureVMResourceGroupName = "Resource Group Name for Azure Compute VM ."; public const string ProtectedItem = "Filter value for status of job."; + public const string ProtectableItem = "Protectabe item"; public const string ProtectionStatus = "Protection status of Item"; public const string Status = "Status of the data source"; public const string Container = "Container where the item resides"; @@ -85,6 +86,11 @@ internal static class Item public const string AzureFileStorageAccountResourceGroupName = "Azure file share storage account resource group name"; } + internal static class ProtectableItem + { + public const string ItemType = "Protectable Item type."; + } + internal static class RecoveryPoint { public const string StartDate = "Start time of Time range for which recovery point need to be fetched"; diff --git a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices/Az.RecoveryServices.psd1 b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices/Az.RecoveryServices.psd1 index 3e71809e8fa6..3c7e7bc82ae1 100644 --- a/src/ResourceManager/RecoveryServices/Commands.RecoveryServices/Az.RecoveryServices.psd1 +++ b/src/ResourceManager/RecoveryServices/Commands.RecoveryServices/Az.RecoveryServices.psd1 @@ -97,7 +97,7 @@ CmdletsToExport = 'Get-AzRecoveryServicesBackupProperty', 'Get-AzRecoveryServicesAsrJob', 'Get-AzRecoveryServicesAsrNetwork', 'Get-AzRecoveryServicesAsrNetworkMapping', 'Get-AzRecoveryServicesAsrPolicy', - 'Get-AzRecoveryServicesAsrProtectableItem', + 'Get-AzRecoveryServicesAsrProtectableItem', 'Get-AzRecoveryServicesAsrProtectionContainer', 'Get-AzRecoveryServicesAsrProtectionContainerMapping', 'Get-AzRecoveryServicesAsrRecoveryPlan', @@ -159,7 +159,9 @@ CmdletsToExport = 'Get-AzRecoveryServicesBackupProperty', 'Unregister-AzRecoveryServicesBackupContainer', 'Disable-AzRecoveryServicesBackupProtection', 'Enable-AzRecoveryServicesBackupProtection', - 'Get-AzRecoveryServicesBackupItem', + 'Get-AzRecoveryServicesBackupItem', + 'Get-AzRecoveryServicesBackupProtectableItem', + 'New-AzRecoveryServicesBackupProtectableItem', 'Get-AzRecoveryServicesBackupJob', 'Get-AzRecoveryServicesBackupJobDetails', 'Stop-AzRecoveryServicesBackupJob',