/// <summary> /// Adds a certificate to the Azure certificate store /// </summary> private IAsyncAzureOperation AddCertificateToAzureStore(X509Certificate2 certificate, string password) { AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response; IEnumerable<X509Certificate2> currentCerts = this.EnumerateServiceCertificates(CertificateLocation.AzureManagement); foreach (X509Certificate2 existingCert in currentCerts) { if (existingCert.Thumbprint == certificate.Thumbprint && existingCert.Thumbprint != null && existingCert.GetCertHashString() == certificate.GetCertHashString()) { return new AsyncAzureOperation(this, string.Empty, true); } // If the certificate does not match, but has a matching name we should delete it if (string.Equals(existingCert.SubjectName.Name, certificate.SubjectName.Name)) { // Delete the certificate using Azure APIs response = client.SubmitRequest( RequestType.DELETE, "2009-10-01", "services/hostedservices/{0}/certificates/SHA1-{1}", this.serviceName, existingCert.Thumbprint ); IAsyncAzureOperation op = new AsyncAzureOperation(this, response.OperationId, false); op.WaitForCompletion(TimeSpan.FromSeconds(30)); } } string request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<CertificateFile xmlns=\"http://schemas.microsoft.com/windowsazure\">" + "<Data>{0}</Data>" + "<CertificateFormat>pfx</CertificateFormat>" + "<Password>{1}</Password>" + "</CertificateFile>"; byte[] content = certificate.Export(X509ContentType.Pfx, password); request = string.Format(request, Convert.ToBase64String(content), System.Security.SecurityElement.Escape(password)); response = client.SubmitRequestWithBody( RequestType.POST, request, "2009-10-01", "services/hostedservices/{0}/certificates", this.serviceName ); return new AsyncAzureOperation(this, response.OperationId, false); }
/// <summary> /// Creates a hosted service for the given subscription /// </summary> /// <param name="name"></param> /// <param name="description"></param> /// <param name="label"></param> /// <param name="location"></param> /// <returns></returns> private IAsyncAzureOperation CreateHostedService(string name, string description, string label, string location) { string request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<CreateHostedService xmlns=\"http://schemas.microsoft.com/windowsazure\">" + "<ServiceName>{0}</ServiceName>" + "<Label>{1}</Label>" + "<Description>{2}</Description>" + "<Location>{3}</Location>" + //"<AffinityGroup></AffinityGroup>" + "</CreateHostedService>"; request = string.Format( request, name, Utility.Base64EncodeString(label), description, location ); AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.POST, request, "2010-10-28", "services/hostedservices" ); string operationId = response.OperationId; AsyncAzureOperation op = new AsyncAzureOperation(this, operationId, false); return op; }
/// <summary> /// check whether a storage account with a different locaiton exists /// </summary> /// <param name="location"></param> /// <returns></returns> public string GetStorageAccountLocation(string storageAccountName) { try { AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.GET, null, "2009-10-01", "services/storageservices/{0}", storageAccountName ); XmlNode node = response.GetXmlNode("StorageServiceProperties"); return response.GetXmlValue(node, "Location"); ; } catch (AzureManagementException) { return null; // Storage Account does not exist } }
/// <summary> /// Starts an azure deployment immediately after it is created /// </summary> public IAsyncAzureOperation CreateAzureDeployment(string configXml, string packageFileName, out AzureDeployment deployment) { // Initialize the return deployment struct deployment = new AzureDeployment(); // Start generating an Azure deployment request from this template string azureRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + "<CreateDeployment xmlns=\"http://schemas.microsoft.com/windowsazure\">\r\n" + "<Name>{0}</Name>\r\n" + "<PackageUrl>{1}</PackageUrl>\r\n" + "<Label>{2}</Label>\r\n" + "<Configuration>{3}</Configuration>\r\n" + "<StartDeployment>true</StartDeployment>\r\n" + "</CreateDeployment>"; // Generate the URL of the HPC runtime package string blobUrl = string.Format( "https://{0}.{1}/{2}/{3}", this.storageServiceName, AzureNaming.AzureBlobStorageDomain, AzureNaming.GenerateAzureEntityName("HpcRuntime", this.clusterName, this.subscriptionId, this.serviceName), packageFileName ); // Generate a name for the deployment string deploymentName = AzureNaming.GenerateAzureEntityName("HpcDeployment", this.clusterName, this.subscriptionId, this.serviceName); // Generate a label string label = string.Format( "Deployment for Windows Azure HPC Scheduler: {0}", this.clusterName); label = Utility.Base64EncodeString(label); if (label.Length > 100) { label = label.Substring(0, 100); } // Fill in the request template azureRequest = string.Format( azureRequest, deploymentName, blobUrl, label, Utility.Base64EncodeString(configXml) ); // Submit the request AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.POST, azureRequest, "2010-04-01", "services/hostedservices/{0}/deploymentslots/production", this.serviceName ); // Generate an Async operation to track the deployment AsyncAzureOperation op = new AsyncAzureOperation(this, response.OperationId, false); // Need to poll Azure to find detailed information about the deployment for (; ; ) { // Loop through all deployments looking for the one we created foreach (AzureDeployment deploy in this.EnumerateAzureDeployments()) { // If we find it, return it if (string.Equals(deploy.Name, deploymentName, StringComparison.InvariantCultureIgnoreCase)) { deployment = deploy; return op; } } // Abort polling if the operation has failed if (op.GetOperationStatus() == AzureOperationStatus.Failed) { break; } // Wait 2 seconds before polling next System.Threading.Thread.Sleep(2 * 1000); } return op; }
/// <summary> /// Change Azure deployment state between the suspended and running states /// </summary> public IAsyncAzureOperation ChangeAzureDeploymentState(string deploymentName, out AzureDeployment deployment, AzureDeploymentState state) { string request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<UpdateDeploymentStatus xmlns=\"http://schemas.microsoft.com/windowsazure\">" + "<Status>{0}</Status>" + "</UpdateDeploymentStatus>"; request = string.Format(request, state.ToString()); AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.POST, request, "2009-10-01", "services/hostedservices/{0}/deployments/{1}/?comp=status", this.serviceName, deploymentName ); string operationId = response.OperationId; AsyncAzureOperation op = new AsyncAzureOperation(this, operationId, false); deployment = this.QueryAzureDeployment(deploymentName); return op; }
/// <summary> /// Return the primary access key of a storage account /// </summary> /// <returns>the associated primary key of a storage account</returns> private string GetStorageAccountPrimaryKey(string storageAccount) { AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.GET, null, "2009-10-01", "services/storageservices/" + storageAccount + "/keys" ); XmlNode node = response.GetXmlNode("StorageServiceKeys"); string accountName = String.Empty; accountName = response.GetXmlValue(node, "Primary"); return accountName; }
/// <summary> /// Enumerates all the hosted services on the subscription by name /// </summary> /// <returns></returns> private IEnumerable<string> GetHostedServiceNames() { AzureManagementClient client = new AzureManagementClient(this.certificate, this.subscriptionId); AzureManagementResponse response = client.SubmitRequestWithBody( RequestType.GET, null, "2009-10-01", "services/hostedservices" ); XmlNode node = response.GetXmlNode("HostedServices"); List<string> accountNames = new List<string>(); foreach (XmlNode child in node.ChildNodes) { accountNames.Add(response.GetXmlValue(child, "ServiceName")); } return accountNames; }