diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/AzureBackupCmdletHelpMessage.cs b/src/ResourceManager/AzureBackup/Commands.AzureBackup/AzureBackupCmdletHelpMessage.cs
index eca778111c9f..31fa28afd861 100644
--- a/src/ResourceManager/AzureBackup/Commands.AzureBackup/AzureBackupCmdletHelpMessage.cs
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/AzureBackupCmdletHelpMessage.cs
@@ -26,6 +26,7 @@ internal static class AzureBackupCmdletHelpMessage
public const string ContainerId = "The container ID.";
public const string ContainerRegistrationStatus = "The container registration status.";
public const string ContainerType = "The container type.";
+ public const string VirtualMachine = "Virtual Machine.";
public const string ContainerResourceGroupName = "The container resource group name.";
public const string ProtectionStatus = "Protection Status of the azure backup item.";
public const string AzureBackUpItem = "Azure BackUp Item.";
diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/GetAzureBackupContainer.cs b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/GetAzureBackupContainer.cs
index 0e3edf307f2d..ebeb8f0748eb 100644
--- a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/GetAzureBackupContainer.cs
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/GetAzureBackupContainer.cs
@@ -40,11 +40,11 @@ public class GetAzureBackupContainer : AzureBackupVaultCmdletBase
[Parameter(Mandatory = false, HelpMessage = AzureBackupCmdletHelpMessage.ContainerRegistrationStatus)]
[ValidateNotNullOrEmpty]
- public AzureBackupContainerStatus Status { get; set; }
+ public AzureBackupContainerStatusInput Status { get; set; }
[Parameter(Mandatory = false, HelpMessage = AzureBackupCmdletHelpMessage.ContainerType)]
[ValidateNotNullOrEmpty]
- public AzureBackupContainerType Type { get; set; }
+ public AzureBackupContainerTypeInput Type { get; set; }
public override void ExecuteCmdlet()
{
@@ -98,7 +98,7 @@ private string ConstructQueryFilterString()
switch (Type)
{
- case AzureBackupContainerType.AzureVirtualMachine:
+ case AzureBackupContainerTypeInput.AzureVirtualMachine:
containerQueryObject.Type = BCI.ContainerType.IaasVMContainer.ToString();
break;
default:
@@ -107,15 +107,12 @@ private string ConstructQueryFilterString()
switch (Status)
{
- case AzureBackupContainerStatus.Registered:
+ case AzureBackupContainerStatusInput.Registered:
containerQueryObject.Status = BCI.RegistrationStatus.Registered.ToString();
break;
- case AzureBackupContainerStatus.Registering:
+ case AzureBackupContainerStatusInput.Registering:
containerQueryObject.Status = BCI.RegistrationStatus.Registering.ToString();
break;
- case AzureBackupContainerStatus.NotRegistered:
- containerQueryObject.Status = BCI.RegistrationStatus.NotRegistered.ToString();
- break;
default:
break;
}
diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/RegisterAzureBackupContainer.cs b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/RegisterAzureBackupContainer.cs
new file mode 100644
index 000000000000..2b3d175c37dd
--- /dev/null
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/RegisterAzureBackupContainer.cs
@@ -0,0 +1,202 @@
+// ----------------------------------------------------------------------------------
+//
+// 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;
+using System.Web;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Management.Automation;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Azure.Commands.Compute;
+using Microsoft.Azure.Management.BackupServices.Models;
+using MBS = Microsoft.Azure.Management.BackupServices;
+using Microsoft.Azure.Commands.Compute.Models;
+
+namespace Microsoft.Azure.Commands.AzureBackup.Cmdlets
+{
+ ///
+ /// Get list of containers
+ ///
+ [Cmdlet(VerbsLifecycle.Register, "AzureBackupContainer"), OutputType(typeof(Guid))]
+ public class RegisterAzureBackupContainer : AzureBackupVaultCmdletBase
+ {
+ //[Parameter(Position = 2, Mandatory = true, HelpMessage = AzureBackupCmdletHelpMessage.VirtualMachine)]
+ //[ValidateNotNullOrEmpty]
+ //public PSVirtualMachineInstanceView VirtualMachine { get; set; }
+ [Parameter(Position = 2, Mandatory = true, HelpMessage = AzureBackupCmdletHelpMessage.VirtualMachine)]
+ [ValidateNotNullOrEmpty]
+ public string VirtualMachineName { get; set; }
+
+ [Parameter(Position = 3, Mandatory = true, HelpMessage = AzureBackupCmdletHelpMessage.VirtualMachine)]
+ [ValidateNotNullOrEmpty]
+ public string VirtualMachineRGName { get; set; }
+
+ public override void ExecuteCmdlet()
+ {
+ base.ExecuteCmdlet();
+
+ ExecutionBlock(() =>
+ {
+ //string vmName = VirtualMachine.Name;
+ //string rgName = VirtualMachine.ResourceGroupName;
+ string vmName = VirtualMachineName;
+ string rgName = VirtualMachineRGName;
+ Guid jobId = Guid.Empty;
+ bool isDiscoveryNeed = false;
+ MBS.OperationResponse operationResponse;
+
+ ContainerInfo container = null;
+ isDiscoveryNeed = IsDiscoveryNeeded(vmName, rgName, out container);
+ if(isDiscoveryNeed)
+ {
+ RefreshContainer();
+ isDiscoveryNeed = IsDiscoveryNeeded(vmName, rgName, out container);
+ if ((isDiscoveryNeed == true) || (container == null))
+ {
+ //Container is not discovered. Throw exception
+ throw new NotImplementedException();
+ }
+ }
+
+ //Container is discovered. Register the container
+ List containerNameList = new List();
+ containerNameList.Add(container.Name);
+ RegisterContainerRequestInput registrationRequest = new RegisterContainerRequestInput(containerNameList, AzureBackupContainerType.IaasVMContainer.ToString());
+ operationResponse = AzureBackupClient.Container.RegisterAsync(registrationRequest, GetCustomRequestHeaders(), CmdletCancellationToken).Result;
+
+ //TODO fix the OperationResponse to JobID conversion
+ jobId = operationResponse.OperationId;
+ WriteObject(jobId);
+ });
+ }
+
+ private void RefreshContainer()
+ {
+ bool isRetyNeeded = true;
+ int retryCount = 1;
+ bool isDiscoverySuccessful = false;
+ while (isRetyNeeded && retryCount <= 3)
+ {
+ MBS.OperationResponse opResponse =
+ AzureBackupClient.Container.RefreshAsync(GetCustomRequestHeaders(), CmdletCancellationToken).Result;
+
+ //Now wait for the operation to Complete
+ isRetyNeeded = WaitForDiscoveryToCOmplete(opResponse.OperationId.ToString(), out isDiscoverySuccessful);
+ retryCount++;
+ }
+
+ if (!isDiscoverySuccessful)
+ {
+ //Discovery failed
+ throw new Exception(); //TODO:
+ }
+ }
+
+ private bool WaitForDiscoveryToCOmplete(string operationId, out bool isDiscoverySuccessful)
+ {
+ bool isRetryNeeded = false;
+
+
+ BMSOperationStatusResponse status = new BMSOperationStatusResponse()
+ {
+ OperationStatus = AzureBackupOperationStatus.InProgress.ToString()
+ };
+
+ while (status.OperationStatus != AzureBackupOperationStatus.Completed.ToString())
+ {
+ status = AzureBackupClient.OperationStatus.GetAsync(operationId, GetCustomRequestHeaders(), CmdletCancellationToken).Result;
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(15));
+ }
+
+ isDiscoverySuccessful = true;
+ //If operation fails check if retry is needed or not
+ if (status.OperationResult != AzureBackupOperationResult.Succeeded.ToString())
+ {
+ isDiscoverySuccessful = false;
+ if ((status.ErrorCode == AzureBackupOperationErrorCode.DiscoveryInProgress.ToString() ||
+ (status.ErrorCode == AzureBackupOperationErrorCode.BMSUserErrorObjectLocked.ToString())))
+ {
+ //Need to retry for this errors
+ isRetryNeeded = true;
+ }
+ }
+ return isRetryNeeded;
+ }
+
+ private bool IsDiscoveryNeeded(string vmName, string rgName, out ContainerInfo container)
+ {
+ bool isDiscoveryNeed = false;
+ //First check if container is discoverd or not
+ ListContainerQueryParameter queryParams = new ListContainerQueryParameter();
+ queryParams.ContainerTypeField = AzureBackupContainerType.IaasVMContainer.ToString();
+ queryParams.ContainerStatusField = String.Empty;
+ queryParams.ContainerFriendlyNameField = vmName;
+ string queryString = GetQueryFileter(queryParams);
+
+ ListContainerResponse containers = AzureBackupClient.Container.ListAsync(queryString,
+ GetCustomRequestHeaders(), CmdletCancellationToken).Result;
+ if (containers.Objects.Count() == 0)
+ {
+ //Container is not discover
+ WriteVerbose("Container is not discovered");
+ container = null;
+ isDiscoveryNeed = true;
+ }
+
+ else
+ {
+ //We can have multiple container with same friendly name.
+ //Look for resourceGroup name in the container unoque name
+ container = containers.Objects.Where(c => c.ParentContainerFriendlyName.ToLower().Equals(rgName.ToLower())).FirstOrDefault();
+ if (container == null)
+ {
+ //Container is not in list of registered container
+ isDiscoveryNeed = true;
+ }
+ }
+ return isDiscoveryNeed;
+ }
+
+ private string GetQueryFileter(ListContainerQueryParameter queryParams)
+ {
+ NameValueCollection collection = new NameValueCollection();
+ if (!String.IsNullOrEmpty(queryParams.ContainerTypeField))
+ {
+ collection.Add("ContainerType", queryParams.ContainerTypeField);
+ }
+
+ if (!String.IsNullOrEmpty(queryParams.ContainerStatusField))
+ {
+ collection.Add("ContainerStatus", queryParams.ContainerStatusField);
+ }
+
+ if (!String.IsNullOrEmpty(queryParams.ContainerFriendlyNameField))
+ {
+ collection.Add("FriendlyName", queryParams.ContainerFriendlyNameField);
+ }
+
+ if (collection == null || collection.Count == 0)
+ {
+ return String.Empty;
+ }
+
+ var httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
+ httpValueCollection.Add(collection);
+
+ return "&" + httpValueCollection.ToString();
+ }
+ }
+}
diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/UnregisterAzureBackupContainer.cs b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/UnregisterAzureBackupContainer.cs
new file mode 100644
index 000000000000..0d7ec45cbd7b
--- /dev/null
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/Container/UnregisterAzureBackupContainer.cs
@@ -0,0 +1,84 @@
+// ----------------------------------------------------------------------------------
+//
+// 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;
+using System.Web;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Management.Automation;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Azure.Commands.Compute;
+using Microsoft.Azure.Management.BackupServices.Models;
+using MBS = Microsoft.Azure.Management.BackupServices;
+using Microsoft.Azure.Commands.Compute.Models;
+
+namespace Microsoft.Azure.Commands.AzureBackup.Cmdlets
+{
+ ///
+ /// Get list of containers
+ ///
+ [Cmdlet(VerbsLifecycle.Unregister, "AzureBackupContainer"), OutputType(typeof(Guid))]
+ public class UnregisterAzureBackupContainer : AzureBackupVaultCmdletBase
+ {
+ [Parameter(Position = 2, Mandatory = true, HelpMessage = AzureBackupCmdletHelpMessage.VirtualMachine, ValueFromPipelineByPropertyName = true)]
+ [ValidateNotNullOrEmpty]
+ public string ContainerUniqueName { get; set; }
+
+ public override void ExecuteCmdlet()
+ {
+ base.ExecuteCmdlet();
+
+ ExecutionBlock(() =>
+ {
+ UnregisterContainerRequestInput unregRequest = new UnregisterContainerRequestInput(ContainerUniqueName, AzureBackupContainerType.IaasVMContainer.ToString());
+ MBS.OperationResponse operationResponse = AzureBackupClient.Container.UnregisterAsync(unregRequest, GetCustomRequestHeaders(), CmdletCancellationToken).Result;
+ Guid jobId = operationResponse.OperationId; //TODO: Fix it once PiyushKa publish the rest APi to get jobId based on operationId
+
+ WriteObject(jobId);
+ });
+ }
+
+ private string GetQueryFileter(ListContainerQueryParameter queryParams)
+ {
+ NameValueCollection collection = new NameValueCollection();
+ if (!String.IsNullOrEmpty(queryParams.ContainerTypeField))
+ {
+ collection.Add("ContainerType", queryParams.ContainerTypeField);
+ }
+
+ if (!String.IsNullOrEmpty(queryParams.ContainerStatusField))
+ {
+ collection.Add("ContainerStatus", queryParams.ContainerStatusField);
+ }
+
+ if (!String.IsNullOrEmpty(queryParams.ContainerFriendlyNameField))
+ {
+ collection.Add("FriendlyName", queryParams.ContainerFriendlyNameField);
+ }
+
+ if (collection == null || collection.Count == 0)
+ {
+ return String.Empty;
+ }
+
+ var httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
+ httpValueCollection.Add(collection);
+
+ return "&" + httpValueCollection.ToString();
+
+ }
+ }
+}
diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/RegisterContainer/RegisterAzureBackupContainer.cs b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/RegisterContainer/RegisterAzureBackupContainer.cs
new file mode 100644
index 000000000000..1f896324275f
--- /dev/null
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Cmdlets/RegisterContainer/RegisterAzureBackupContainer.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Management.Automation;
+
+namespace Microsoft.Azure.Commands.AzureBackup.Cmdlets.RegisterContainer
+{
+ [Cmdlet(VerbsCommon.Get, ProfileNouns.VirtualMachine, DefaultParameterSetName = ListAllVirtualMachinesParamSet)]
+ class RegisterAzureBackupContainer
+ {
+ }
+}
diff --git a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Commands.AzureBackup.csproj b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Commands.AzureBackup.csproj
index 9368865fe23e..27938f9f65a5 100644
--- a/src/ResourceManager/AzureBackup/Commands.AzureBackup/Commands.AzureBackup.csproj
+++ b/src/ResourceManager/AzureBackup/Commands.AzureBackup/Commands.AzureBackup.csproj
@@ -117,6 +117,7 @@
+
@@ -132,6 +133,8 @@
+
+
@@ -141,10 +144,10 @@
-
-
+
+
True
@@ -158,6 +161,10 @@
{5ee72c53-1720-4309-b54b-5fb79703195f}
Commands.Common
+
+ {52643bd5-6378-49bd-9f6e-dac9dd8a867b}
+ Commands.Compute
+
@@ -194,6 +201,10 @@
+
+
+
+