Skip to content

Commit

Permalink
complete delete vm functionality - tests written have to do one final…
Browse files Browse the repository at this point in the history
… functional test and windows vms more or less complete

Signed-off-by: Richard Conway <richard@elastacloud.com>
  • Loading branch information
azurecoder committed Feb 27, 2013
1 parent 9422dfb commit 6068447
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public IExecute GetExecutor()
{
return new VmGet(this);
}
if (Term == "vm" && Operation == "delete")
{
return new VmDelete(this);
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ApplicationFactory.cs" />
<Compile Include="VmDelete.cs" />
<Compile Include="VmCreate.cs" />
<Compile Include="IExecute.cs" />
<Compile Include="MobileCreate.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>vm read bc5cafb3-e135-45ca-bc31-1387d15069fb "C:\Users\Richard\Desktop\Engagements\AllAccounts.publishsettings" rubytest rubytest rubytest Microsoft123</StartArguments>
<StartArguments>vm delete fe5717d5-c56d-4fc2-b408-b7e178244bf5 "C:\Users\Richard\Desktop\Engagements\AllAccounts.publishsettings" richtest5 richtest5 richtest5 Microsoft123</StartArguments>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion Elastacloud.AzureManagement.Fluent.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ public static IExecute ParseTokens(string[] args)
return factory.GetExecutor();
}
}
}
}
2 changes: 1 addition & 1 deletion Elastacloud.AzureManagement.Fluent.Console/VmCreate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void Execute()
SubscriptionId = _applicationFactory.SubscriptionId,
CloudServiceName = _applicationFactory.CloudServiceName,
PublicEndpoints = new Dictionary<string, int>(){{"web",80}},
VirtualMachineType = VirtualMachineTemplates.WindowsServer2012,
VirtualMachineType = VirtualMachineTemplates.WindowsServer2008R2SP1,
VmSize = VmSize.Small,
StorageAccountName = "elastastorage",
DataDisks = new List<DataVirtualHardDisk>(){new DataVirtualHardDisk(){LogicalDiskSizeInGB = 100}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="TestConfigFiles.cs" />
<Compile Include="TestHttpUrlParse.cs" />
<Compile Include="TestPublishSettings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down
28 changes: 28 additions & 0 deletions Elastacloud.AzureManagement.Fluent/Clients/BlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
* Web at: www.elastacloud.com *
* Email: info@elastacloud.com *
************************************************************************************************************/

using System.Security.Cryptography.X509Certificates;
using Elastacloud.AzureManagement.Fluent.Commands.Blobs;
using Elastacloud.AzureManagement.Fluent.Commands.Storage;
using Elastacloud.AzureManagement.Fluent.Types;

namespace Elastacloud.AzureManagement.Fluent.Clients
Expand All @@ -24,6 +27,17 @@ public BlobClient(string subscriptionId, string containerName, string accountNam
ContainerName = containerName;
}

/// <summary>
/// This is the BlobClient and is used to create the account without the key and get the key automatically
/// </summary>
public BlobClient(string subscriptionId, string containerName, string accountName, X509Certificate2 certificate)
: this(subscriptionId, containerName, accountName, string.Empty)
{
ManagementCertificate = certificate;
}

protected X509Certificate2 ManagementCertificate { get; set; }

#region Implementation of IBlobClient

/// <summary>
Expand Down Expand Up @@ -69,6 +83,20 @@ public void DeleteBlob(string blobName)
deleteblob.Execute();
}

/// <summary>
/// Gets the blob account key
/// </summary>
public string GetAccountKey()
{
var getStorageAccountKeysCommand = new GetStorageAccountKeysCommand(AccountName)
{
SubscriptionId = SubscriptionId,
Certificate = ManagementCertificate
};
getStorageAccountKeysCommand.Execute();
return (AccountKey = getStorageAccountKeysCommand.PrimaryStorageKey);
}

/// <summary>
/// Deletes a blob container
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions Elastacloud.AzureManagement.Fluent/Clients/IBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public interface IBlobClient
/// </summary>
/// <param name="blobName">The name of a valid blob</param>
void DeleteBlob(string blobName);
/// <summary>
/// Gets the blob account key
/// </summary>
string GetAccountKey();

/// <summary>
/// Deletes a blob container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@ public interface IVirtualMachineClient
/// </summary>
/// <param name="properties">Can be any gallery template</param>
IVirtualMachineClient CreateNewVirtualMachineFromTemplateGallery(WindowsVirtualMachineProperties properties);

/// <summary>
/// Deletes the virtual machine that has context with the client
/// </summary>
/// <param name="removeDisks">True if the underlying disks in blob storage should be removed</param>
void DeleteVirtualMachine(bool removeDisks);
/// <param name="removeCloudService">Removes the cloud service container</param>
/// <param name="removeStorageAccount">The storage account that the vhd is in</param>
void DeleteVirtualMachine(bool removeDisks, bool removeCloudService, bool removeStorageAccount);
/// <summary>
/// Deletes a vm disk if a name is known
/// </summary>
/// <param name="name">The name of the vm disk</param>
void DeleteNamedVirtualMachineDisk(string name);
/// <summary>
/// Restarts the virtual machine instance
/// </summary>
Expand All @@ -40,5 +48,13 @@ public interface IVirtualMachineClient
/// Gets thye configuration for the virtual machine
/// </summary>
PersistentVMRole VirtualMachine { get; }
/// <summary>
/// Gets the container that the storage blob resides in
/// </summary>
string StorageContainerName { get; }
/// <summary>
/// The name of the blob which is stored for the vm
/// </summary>
string StorageFileName { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
************************************************************************************************************/
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using Elastacloud.AzureManagement.Fluent.Commands.Blobs;
using Elastacloud.AzureManagement.Fluent.Commands.Services;
using Elastacloud.AzureManagement.Fluent.Commands.VirtualMachines;
using Elastacloud.AzureManagement.Fluent.Helpers;
using Elastacloud.AzureManagement.Fluent.Types.Exceptions;
using Elastacloud.AzureManagement.Fluent.Types.VirtualMachines;
using Elastacloud.AzureManagement.Fluent.VirtualMachines.Classes;
Expand All @@ -21,6 +25,8 @@ public class WindowsVirtualMachineClient : IVirtualMachineClient
{
// the name of the cloud service to look up
private string _cloudServiceName;
// The Vm role which is being used to hold the state of the windows virtual machine
private PersistentVMRole _vmRole;

/// <summary>
/// Constructs a WindowsVirtualMachineClient and will get the details of a virtual machine given a cloud service
Expand All @@ -44,7 +50,9 @@ public WindowsVirtualMachineClient(WindowsVirtualMachineProperties properties)
{
Properties = properties;
}

/// <summary>
/// The virtual machine properties necessary to get any of the details for the virtual machine
/// </summary>
public WindowsVirtualMachineProperties Properties { get; set; }

/// <summary>
Expand Down Expand Up @@ -98,9 +106,95 @@ public IVirtualMachineClient CreateNewVirtualMachineFromTemplateGallery(WindowsV
/// Deletes the virtual machine that has context with the client
/// </summary>
/// <param name="removeDisks">True if the underlying disks in blob storage should be removed</param>
public void DeleteVirtualMachine(bool removeDisks)
/// <param name="removeCloudService">Removes the cloud service container</param>
/// <param name="removeStorageAccount">The storage account that the vhd is in</param>
public void DeleteVirtualMachine(bool removeDisks = true, bool removeCloudService = true, bool removeStorageAccount = true)
{
// first delete the virtual machine command
var deleteVirtualMachine = new DeleteVirtualMachineCommand(Properties)
{
SubscriptionId = Properties.SubscriptionId,
Certificate = Properties.Certificate
};
try
{
deleteVirtualMachine.Execute();
}
catch (Exception ex)
{
// should be a 400 here if this is the case then there is only a single role in the deployment - quicker to do it this way!
var deleteVirtualMachineDeployment = new DeleteVirtualMachineDeploymentCommand(Properties)
{
SubscriptionId = Properties.SubscriptionId,
Certificate = Properties.Certificate
};
deleteVirtualMachineDeployment.Execute();
}
// when this is finished we'll delete the operating system disk - check this as we may need to putin a pause
if (removeDisks)
{
string diskName = _vmRole.OSHardDisk.DiskName;
DeleteNamedVirtualMachineDisk(diskName);
}

if (removeCloudService)
{
// delete the cloud service here
var deleteCloudService = new DeleteHostedServiceCommand(Properties.CloudServiceName)
{
SubscriptionId = Properties.SubscriptionId,
Certificate = Properties.Certificate
};
deleteCloudService.Execute();
}

if (removeStorageAccount)
{
string storageAccount = ParseBlobDetails(_vmRole.OSHardDisk.MediaLink);
var blobClient = new BlobClient(SubscriptionId, StorageContainerName, storageAccount,
ManagementCertificate);
blobClient.DeleteBlob(StorageFileName);
}


// TODO: Build the command to remove all of the associated data disks
//if (_vmRole.HardDisks.HardDiskCollection != null)
//{
// foreach (var hardDisk in _vmRole.HardDisks.HardDiskCollection)
// {

// }
//}

}

/// <summary>
/// Deletes a vm disk if a name is known
/// </summary>
/// <param name="name">The name of the vm disk</param>
public void DeleteNamedVirtualMachineDisk(string name)
{
throw new System.NotImplementedException();
bool diskErased = false;
int count = 0;
// keep this going until we delete the disk or time out!
while (count < 20 && !diskErased)
{
try
{
var deleteVirtualMachineDisk = new DeleteVirtualMachineDiskCommand(name)
{
SubscriptionId = Properties.SubscriptionId,
Certificate = Properties.Certificate
};
deleteVirtualMachineDisk.Execute();
diskErased = true;
}
catch (Exception)
{
count++;
}
Thread.Sleep(3000);
}
}

/// <summary>
Expand Down Expand Up @@ -141,16 +235,29 @@ public PersistentVMRole VirtualMachine
// this should really be an async process
get
{
if (_vmRole != null)
return _vmRole;

var command = new GetWindowsVirtualMachineContextCommand(Properties)
{
SubscriptionId = Properties.SubscriptionId,
Certificate = Properties.Certificate
};
command.Execute();
return command.PersistentVm;
return (_vmRole = command.PersistentVm);
}
}

/// <summary>
/// Gets the container that the storage blob resides in
/// </summary>
public string StorageContainerName { get; private set; }

/// <summary>
/// The name of the blob which is stored for the vm
/// </summary>
public string StorageFileName { get; private set; }

/// <summary>
/// download rdp file for the windows vm
/// </summary>
Expand Down Expand Up @@ -179,5 +286,17 @@ private void EnsureVirtualMachineProperties(WindowsVirtualMachineProperties prop
String.IsNullOrEmpty(properties.StorageAccountName) || String.IsNullOrEmpty(properties.Location))
throw new FluentManagementException("Either certificate, subscription id cloud service name or storage account name not present in properties", "CreateWindowsVirtualMachineDeploymentCommand");
}

/// <summary>
/// Returns the name of the blob and container
/// </summary>
/// <param name="blobAddress"></param>
private string ParseBlobDetails(string blobAddress)
{
var helper = new UrlHelper(blobAddress);
StorageContainerName = helper.Path;
StorageFileName = helper.File;
return helper.HostSubDomain;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal class ServiceCommand : ICommand
private string _httpVerb = "POST";
private static IQueryManager _queryManager;
private string _subscriptionId;
private WebException _exception;

#endregion

Expand Down Expand Up @@ -106,9 +107,9 @@ protected virtual void ErrorResponseCallback(WebException exception)
// TODO: Place and error router here

// if we have an error it's probably best to release this
//SitAndWait.Set();
_exception = exception;
SitAndWait.Set();
// rethrow this otherwise we'll lose this
throw exception;
}

#endregion
Expand Down Expand Up @@ -241,6 +242,7 @@ protected ServiceCommand()
/// </summary>
public virtual void Execute()
{
_exception = null;
var serviceManagementRequest = new ServiceManagementRequest
{
BaseUri = BaseRequestUri,
Expand All @@ -261,6 +263,8 @@ public virtual void Execute()
CurrentQueryManager.MakeASyncRequest(serviceManagementRequest, ResponseCallback, ErrorResponseCallback);
// wait for up to 30 minutes - if a deployment takes longer than that ... it's probably HPC!
SitAndWait.WaitOne(200000);
if (_exception != null)
throw _exception;
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@
<Compile Include="Commands\Storage\CreateStorageAccountCommand.cs" />
<Compile Include="Commands\Subscriptions\GetSubscriberLocationsCommand.cs" />
<Compile Include="Commands\Subscriptions\GetSubscriptionCommand.cs" />
<Compile Include="Commands\Virtual Machines\DeleteVirtualMachineDeploymentCommand.cs" />
<Compile Include="Commands\Virtual Machines\DeleteVirtualMachineDiskCommand.cs" />
<Compile Include="Commands\Virtual Machines\DeleteVirtualMachineCommand.cs" />
<Compile Include="Commands\Virtual Machines\DownloadWindowsRemoteDesktopCommand.cs" />
<Compile Include="Commands\Virtual Machines\GetWindowsVirtualMachineContextCommand.cs" />
<Compile Include="Commands\Virtual Machines\StopVirtualMachineCommand.cs" />
Expand Down
Loading

0 comments on commit 6068447

Please sign in to comment.