diff --git a/.nuget/packages.config b/.nuget/packages.config new file mode 100644 index 0000000..086897c --- /dev/null +++ b/.nuget/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Elastacloud.AzureManagement.Fluent.0.5.1.10.nupkg b/Elastacloud.AzureManagement.Fluent.0.5.1.10.nupkg new file mode 100644 index 0000000..1c929fd Binary files /dev/null and b/Elastacloud.AzureManagement.Fluent.0.5.1.10.nupkg differ diff --git a/Elastacloud.AzureManagement.Fluent.0.5.1.11.nupkg b/Elastacloud.AzureManagement.Fluent.0.5.1.11.nupkg new file mode 100644 index 0000000..2e80181 Binary files /dev/null and b/Elastacloud.AzureManagement.Fluent.0.5.1.11.nupkg differ diff --git a/Elastacloud.AzureManagement.Fluent.0.5.1.9.nupkg b/Elastacloud.AzureManagement.Fluent.0.5.1.9.nupkg deleted file mode 100644 index 82b327f..0000000 Binary files a/Elastacloud.AzureManagement.Fluent.0.5.1.9.nupkg and /dev/null differ diff --git a/Elastacloud.AzureManagement.Fluent/Clients/ImageManagementClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/ImageManagementClient.cs index 4b41991..e67b092 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/ImageManagementClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/ImageManagementClient.cs @@ -16,6 +16,7 @@ using Elastacloud.AzureManagement.Fluent.Clients.Helpers; using Elastacloud.AzureManagement.Fluent.Clients.Interfaces; using Elastacloud.AzureManagement.Fluent.Commands.VirtualMachines; +using Elastacloud.AzureManagement.Fluent.Helpers; using Elastacloud.AzureManagement.Fluent.Types.VirtualMachines; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.Storage; @@ -29,16 +30,19 @@ namespace Elastacloud.AzureManagement.Fluent.Clients /// public class ImageManagementClient : GenerateEventClientBase, IImageManagementClient { - public ImageManagementClient(string subscriptionId, X509Certificate2 certificate) + public ImageManagementClient(string subscriptionId, X509Certificate2 certificate, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; ManagementCertificate = certificate; + Location = defaultLocation; } public X509Certificate2 ManagementCertificate { get; set; } public string SubscriptionId { get; set; } + public string Location { get; set; } + /// /// Used to copy or register an image from one subscription to another /// @@ -110,7 +114,8 @@ public void CopyAndRegisterImageInNewSubscription(ImageProperties imagePropertie var registerImageCommand = new RegisterImageCommand(imageProperties) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; registerImageCommand.Execute(); RaiseClientUpdate(100, "Completed registration of image into target account"); @@ -126,7 +131,8 @@ public List ImageList var listImagesCommand = new ListImagesCommand() { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; listImagesCommand.Execute(); return listImagesCommand.Properties; diff --git a/Elastacloud.AzureManagement.Fluent/Clients/LinuxVirtualMachineClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/LinuxVirtualMachineClient.cs index 55e40b4..a338be7 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/LinuxVirtualMachineClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/LinuxVirtualMachineClient.cs @@ -40,11 +40,17 @@ public class LinuxVirtualMachineClient : ILinuxVirtualMachineClient /// /// the subscription id /// A management certificate for the subscription - public LinuxVirtualMachineClient(string subscriptionId, X509Certificate2 certificate) + /// The location to which service management request is sent to + public LinuxVirtualMachineClient(string subscriptionId, X509Certificate2 certificate, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; ManagementCertificate = certificate; + Location = defaultLocation; } + /// + /// The default location that the service management api is being called from + /// + public string Location { get; set; } /// /// Constructs a VirtualMachinenClient @@ -52,10 +58,11 @@ public LinuxVirtualMachineClient(string subscriptionId, X509Certificate2 certifi /// A valid VirtualMachineProperties object /// The susbcription id for the subscription /// The susbcription id for the subscription - public LinuxVirtualMachineClient(List properties, string subscriptionId, X509Certificate2 certificate) + public LinuxVirtualMachineClient(List properties, string subscriptionId, X509Certificate2 certificate, string defaultLocation = LocationConstants.NorthEurope) : this(subscriptionId, certificate) { Properties = properties; + Location = defaultLocation; } /// @@ -81,7 +88,8 @@ public List VirtualMachine var command = new GetVirtualMachineContextCommand(Properties.First()) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return (_vmRoles = command.PersistentVm.ToList()); @@ -102,7 +110,8 @@ private void CheckVmDeploymentIsRunning(List prop var command = new GetVirtualMachineContextCommand(vmProperties) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); command.PersistentVm.ForEach(vm => @@ -148,7 +157,8 @@ public IVirtualMachineClient CreateNewVirtualMachineDeploymentFromTemplateGaller var checkCloudServiceAvailabilityCommand = new CheckCloudServiceNameAvailableCommand(cloudServiceName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; checkCloudServiceAvailabilityCommand.Execute(); Trace.WriteLine(String.Format("Checked cloud service availability - is available: {0}", checkCloudServiceAvailabilityCommand.CloudServiceAvailable)); @@ -158,7 +168,8 @@ public IVirtualMachineClient CreateNewVirtualMachineDeploymentFromTemplateGaller var cloudServiceCommand = new CreateCloudServiceCommand(cloudServiceName, "Created by Fluent Management", location, affinityGroup) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; cloudServiceCommand.Execute(); Trace.WriteLine(String.Format("Cloud service named {0} has been created", cloudServiceName)); @@ -173,10 +184,11 @@ public IVirtualMachineClient CreateNewVirtualMachineDeploymentFromTemplateGaller // This is really unfortunate and not documented anywhere - unable to add multiple roles to a rolelist!!! // continue to the create the virtual machine in the cloud service - var command = new CreateLinuxVirtualMachineDeploymentCommand(new List(new[]{properties[0]}), cloudServiceName) + var command = new CreateLinuxVirtualMachineDeploymentCommand(new List(new[]{properties[0]}), cloudServiceName, Location) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); // raise this event every time we create a VM @@ -196,7 +208,8 @@ public IVirtualMachineClient CreateNewVirtualMachineDeploymentFromTemplateGaller var startCommand = new AddLinuxVirtualMachineToDeploymentCommand(theProperty, cloudServiceName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; startCommand.Execute(); // raise this event every time we create a VM diff --git a/Elastacloud.AzureManagement.Fluent/Clients/ServiceBusClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/ServiceBusClient.cs index be892f7..12dd171 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/ServiceBusClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/ServiceBusClient.cs @@ -26,14 +26,16 @@ public class ServiceBusClient : IServiceBusClient private readonly string _subscriptionId; private readonly X509Certificate2 _managementCertificate; - public ServiceBusClient(string subscriptionId, X509Certificate2 certificate) + public ServiceBusClient(string subscriptionId, X509Certificate2 certificate, string defaultLocation = LocationConstants.NorthEurope) { _subscriptionId = subscriptionId; _managementCertificate = certificate; + Location = defaultLocation; } #region Implementation of IServiceBusClient + public string Location { get; set; } /// /// Creates a namespace given a name value /// @@ -50,7 +52,8 @@ public void CreateNamespace(string name, string location = LocationConstants.Nor var command = new CreateServiceBusNamespaceCommand(name, location) { SubscriptionId = _subscriptionId, - Certificate = _managementCertificate + Certificate = _managementCertificate, + Location = Location }; command.Execute(); Namespace = name; @@ -64,7 +67,8 @@ public bool CheckNamespaceExists(string name) var command = new CheckServiceBusNamespaceAvailabilityCommand(name) { SubscriptionId = _subscriptionId, - Certificate = _managementCertificate + Certificate = _managementCertificate, + Location = Location }; command.Execute(); return command.IsAvailable; @@ -78,7 +82,8 @@ public void DeleteNamespace(string name) var command = new DeleteServiceBusNamespaceCommand(name) { SubscriptionId = _subscriptionId, - Certificate = _managementCertificate + Certificate = _managementCertificate, + Location = Location }; command.Execute(); } @@ -91,7 +96,8 @@ public IEnumerable GetServiceBusNamspaceList(string location) var command = new GetServiceBusNamespaceListCommand(location) { SubscriptionId = _subscriptionId, - Certificate = _managementCertificate + Certificate = _managementCertificate, + Location = Location }; command.Execute(); return command.Namespaces; @@ -105,7 +111,8 @@ public string GetServiceBusConnectionString(string @namespace, string ruleName) var command = new GetServiceBusPolicyConnectionStringCommand(@namespace, ruleName) { SubscriptionId = _subscriptionId, - Certificate = _managementCertificate + Certificate = _managementCertificate, + Location = Location }; command.Execute(); if (command.ConnectionString == null) diff --git a/Elastacloud.AzureManagement.Fluent/Clients/ServiceClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/ServiceClient.cs index a41becc..1d81746 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/ServiceClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/ServiceClient.cs @@ -33,12 +33,13 @@ public class ServiceClient : IServiceClient /// /// Used to construct the ServiceClient /// - public ServiceClient(string subscriptionId, X509Certificate2 certificate, string cloudService, DeploymentSlot slot = DeploymentSlot.Production) + public ServiceClient(string subscriptionId, X509Certificate2 certificate, string cloudService, string defaultLocation = LocationConstants.NorthEurope, DeploymentSlot slot = DeploymentSlot.Production) { SubscriptionId = subscriptionId; ManagementCertificate = certificate; Name = cloudService; Slot = slot; + Location = defaultLocation; } /// @@ -54,7 +55,8 @@ public void Start() var command = new UpdateRoleStatusCommand(Name, Slot, UpdateDeploymentStatus.Running) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); } @@ -67,7 +69,8 @@ public void Stop() var command = new UpdateRoleStatusCommand(Name, Slot, UpdateDeploymentStatus.Suspended) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); } @@ -79,7 +82,8 @@ public bool IsCloudServiceNameAvailable var command = new CheckCloudServiceNameAvailableCommand(Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); @@ -99,7 +103,8 @@ public List AvailableLocations var command = new GetSubscriberLocationsCommand { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return (_locations = command.Locations); @@ -124,6 +129,10 @@ public List AvailableLocations /// public string Name { get; set; } /// + /// Used to determine whether this is Mooncake or otherwise + /// + public string Location { get; set; } + /// /// Gets the deployment name of the current deployment /// public string DeploymentName @@ -133,7 +142,8 @@ public string DeploymentName var command = new GetCloudServicePropertiesCommand(Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.CloudServiceDeployments[0].Name; @@ -174,7 +184,8 @@ public void UploadServiceCertificate(X509Certificate2 certificate, string passwo var cert = new AddServiceCertificateCommand(certBytes, password, Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; cert.Execute(); } @@ -213,7 +224,8 @@ public List CloudServicesInSubscription var command = new GetHostedServiceListCommand() { Certificate = ManagementCertificate, - SubscriptionId = SubscriptionId + SubscriptionId = SubscriptionId, + Location = Location }; command.Execute(); return @@ -232,13 +244,15 @@ public void DeleteCloudServiceAndDeployment(string deploymentName) var command = new DeleteCloudServiceAndDeploymentCommand(Name, deploymentName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); var csDelete = new DeleteHostedServiceCommand(Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; csDelete.Execute(); } @@ -258,7 +272,8 @@ public SubscriptionInformation SubscriptionDetails var command = new GetSubscriptionCommand() { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.SubscriptionInformation; @@ -293,7 +308,8 @@ public IEnumerable GetRoleInstances() var command = new GetCloudServicePropertiesCommand(Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.CloudServiceDeployments.First(slot => slot.Slot == Slot) @@ -302,7 +318,7 @@ public IEnumerable GetRoleInstances() private CertificateGenerator BuildCertGenerator(string name, string password) { - var generator = new CertificateGenerator(SubscriptionId, ManagementCertificate); + var generator = new CertificateGenerator(SubscriptionId, ManagementCertificate, Location); generator.Create(name, DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)), DateTime.UtcNow.AddYears(2), password); return generator; } @@ -317,7 +333,8 @@ public void CreateNewCloudService(string location, string description = "Fluent var hostedServiceCreate = new CreateCloudServiceCommand(Name, description, location) { Certificate = ManagementCertificate, - SubscriptionId = SubscriptionId + SubscriptionId = SubscriptionId, + Location = Location }; hostedServiceCreate.Execute(); } @@ -331,7 +348,8 @@ public void DeleteCloudService() var deleteService = new DeleteHostedServiceCommand(Name) { Certificate = ManagementCertificate, - SubscriptionId = SubscriptionId + SubscriptionId = SubscriptionId, + Location = Location }; deleteService.Execute(); } @@ -345,7 +363,8 @@ public void DeleteDeployment(DeploymentSlot slot = DeploymentSlot.Production) var deleteDeployment = new DeleteDeploymentCommand(Name, slot) { Certificate = ManagementCertificate, - SubscriptionId = SubscriptionId + SubscriptionId = SubscriptionId, + Location = Location }; deleteDeployment.Execute(); } @@ -358,14 +377,17 @@ public void UpdateRoleInstanceCount(string roleName, int instanceCount) var config = new GetDeploymenConfigurationCommand(Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; config.Execute(); config.Configuration.SetInstanceCountForRole(roleName, instanceCount); var update = new SetDeploymenConfigurationCommand(Name, config.Configuration) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location + }; update.Execute(); } @@ -376,7 +398,7 @@ public void UpdateRoleInstanceCount(string roleName, int instanceCount) public ServiceCertificate CreateServiceCertificateAndAddRemoteDesktop(string username, string password, ref CscfgFile file) { var certificate = new ServiceCertificate(username, password); - certificate.Create(); + certificate.Create(Location); var desktop = new RemoteDesktop(certificate) { @@ -397,7 +419,8 @@ public List Roles var command = new GetDeploymenRoleNamesCommand(Name, Slot) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.RoleNames; diff --git a/Elastacloud.AzureManagement.Fluent/Clients/StorageClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/StorageClient.cs index 338e9aa..702ae27 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/StorageClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/StorageClient.cs @@ -30,10 +30,11 @@ public class StorageClient : IStorageClient /// /// Used to construct a storage client with a subscription id and management certificate /// - public StorageClient(string subscriptionId, X509Certificate2 certificate) + public StorageClient(string subscriptionId, X509Certificate2 certificate, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; ManagementCertificate = certificate; + Location = defaultLocation; } /// /// Used to construct a client with an account name and account key @@ -55,6 +56,10 @@ public StorageClient(string accountName, string accountKey) protected X509Certificate2 ManagementCertificate { get; set; } protected string SubscriptionId { get; set; } /// + /// The default location for the storage accounts + /// + protected string Location { get; set; } + /// /// Creates a new storage account given a name and location /// public void CreateNewStorageAccount(string name, string location = LocationConstants.NorthEurope @@ -67,7 +72,8 @@ public void CreateNewStorageAccount(string name, string location = LocationConst var create = new CreateStorageAccountCommand(name, "Created with Fluent Management", options, location) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; create.Execute(); var status = StorageStatus.Creating; @@ -76,7 +82,8 @@ public void CreateNewStorageAccount(string name, string location = LocationConst var command = new GetStorageAccountStatusCommand(name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); status = command.Status; @@ -100,7 +107,8 @@ public void DeleteStorageAccount(string name) var delete = new DeleteStorageAccountCommand(name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; delete.Execute(); } @@ -110,7 +118,8 @@ public string[] GetStorageAccountKeys(string name) var keys = new GetStorageAccountKeysCommand(name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; keys.Execute(); return new string[2] {keys.PrimaryStorageKey, keys.SecondaryStorageKey}; @@ -121,7 +130,8 @@ public List GetStorageAccountList() var getStorageAccountList = new ListStorageAccountsCommand { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; getStorageAccountList.Execute(); return getStorageAccountList.StorageAccounts; @@ -146,7 +156,8 @@ public StorageStatus GetStorageStatus(string name) var storageAccounts = new GetStorageAccountStatusCommand(name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; storageAccounts.Execute(); return storageAccounts.Status; diff --git a/Elastacloud.AzureManagement.Fluent/Clients/VirtualNetworkClient.cs b/Elastacloud.AzureManagement.Fluent/Clients/VirtualNetworkClient.cs index f52935b..da68db1 100644 --- a/Elastacloud.AzureManagement.Fluent/Clients/VirtualNetworkClient.cs +++ b/Elastacloud.AzureManagement.Fluent/Clients/VirtualNetworkClient.cs @@ -29,15 +29,18 @@ namespace Elastacloud.AzureManagement.Fluent.Clients /// public class VirtualNetworkClient : IVirtualNetworkingClient { - public VirtualNetworkClient(string subscriptionId, X509Certificate2 managementCertificate) + public VirtualNetworkClient(string subscriptionId, X509Certificate2 managementCertificate, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; ManagementCertificate = managementCertificate; + Location = defaultLocation; } public X509Certificate2 ManagementCertificate { get; set; } public string SubscriptionId { get; set; } + + public string Location { get; set; } /// /// Gets the available virtual networks in the correct order binding the address ranges to the subnets /// @@ -46,7 +49,8 @@ public VirtualNetworkClient(string subscriptionId, X509Certificate2 managementCe var command = new ListVirtualNetworksCommand() { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); List virtualNetworks = command.VirtualNetworks; @@ -88,7 +92,8 @@ public string AddSubnetToAddressRange(string networkName, string addressRange, s var command = new SetVirtualNetworkConfigCommand(xml) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return xml; @@ -102,7 +107,8 @@ public AvailableIpAddresses IsIpAddressAvailable(string vnet, string ipToCheck) var command = new GetAvailableIpAddressesCommand(vnet, ipToCheck) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.IpAddressCheck; @@ -116,7 +122,8 @@ public string GetAllNetworkingConfig() var command = new GetVirtualNetworkConfigCommand() { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.VirtualNetworkConfig; @@ -149,7 +156,8 @@ public void RemoveSubnet(string networkName, string subnetName) var command = new SetVirtualNetworkConfigCommand(document.ToStringFullXmlDeclaration()) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); } @@ -159,7 +167,8 @@ public CloudServiceNetworking GetCloudServiceSubnetCollection(string cloudServic var command = new GetVirtualNetworkAndSubnetsFromCloudServiceCommand(cloudServiceName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = Location }; command.Execute(); return command.NetworkDetails; diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/BlobCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/BlobCommand.cs index 5a82f15..091a581 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/BlobCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/BlobCommand.cs @@ -15,6 +15,7 @@ using System.Security.Cryptography; using System.Text; using System.Threading; +using Elastacloud.AzureManagement.Fluent.Helpers; using Elastacloud.AzureManagement.Fluent.Types.Exceptions; namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs @@ -78,11 +79,17 @@ internal string HttpVerb #endregion - protected BlobCommand() + protected BlobCommand(string defaultLocation = LocationConstants.NorthEurope) { DateHeader = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); + Postfix = (defaultLocation == LocationConstants.ChinaNorth || defaultLocation == LocationConstants.ChinaEast) + ? "chinacloudapi.cn" + : "windows.net"; + } + public string Postfix { get; set; } + protected abstract StorageServiceType StorageServiceType { get; } /// @@ -99,7 +106,7 @@ public bool CheckStorageAccountExists(int timeoutInSeconds) { try { - var request = HttpWebRequest.Create(String.Format("http://{0}.blob.core.windows.net/", AccountName)); + var request = HttpWebRequest.Create(String.Format("http://{0}.blob.core.{1}/", AccountName, Postfix)); request.GetResponse(); } catch (WebException ex) diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateAndUploadBlobCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateAndUploadBlobCommand.cs index eb9359c..3ccc233 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateAndUploadBlobCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateAndUploadBlobCommand.cs @@ -9,6 +9,7 @@ using System; using System.IO; +using Elastacloud.AzureManagement.Fluent.Helpers; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Blob; @@ -20,14 +21,17 @@ namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs /// internal class CreateAndUploadBlobCommand : BlobCommand { - internal CreateAndUploadBlobCommand(string containerName, string blobName, string fileNamePath) + internal CreateAndUploadBlobCommand(string containerName, string blobName, string fileNamePath, string defaultLocation = LocationConstants.NorthEurope) + : base(defaultLocation) { ContainerName = containerName; BlobName = blobName; FileNamePath = fileNamePath; HttpVerb = HttpVerbPut; + Location = defaultLocation; + } - + internal string Location { get; set; } internal string FileNamePath { get; set; } internal string DeploymentPath { get; set; } @@ -38,8 +42,8 @@ protected override StorageServiceType StorageServiceType public override void Execute() { - string accessContainer = DeploymentPath = String.Format("http://{0}.blob.core.windows.net/%7B1%7D/%7B2%7D", AccountName, ContainerName, BlobName); - string baseUri = String.Format("http://{0}.blob.core.windows.net/", AccountName); + string accessContainer = DeploymentPath = String.Format("http://{0}.blob.core.{1}/%7B2%7D/%7B3%7D", AccountName, Postfix, ContainerName, BlobName); + string baseUri = String.Format("http://{0}.blob.core.{1}/", AccountName, Postfix); var client = new CloudBlobClient(new Uri(baseUri), new StorageCredentials(AccountName, AccountKey)); var container = client.GetContainerReference(ContainerName); diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateBlobContainerCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateBlobContainerCommand.cs index a65f212..932f3da 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateBlobContainerCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/CreateBlobContainerCommand.cs @@ -8,6 +8,7 @@ ************************************************************************************************************/ using System; +using Elastacloud.AzureManagement.Fluent.Helpers; namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs { @@ -16,7 +17,8 @@ namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs /// internal class CreateBlobContainerCommand : BlobCommand { - internal CreateBlobContainerCommand(string containerName) + internal CreateBlobContainerCommand(string containerName, string defaultLocation = LocationConstants.NorthEurope) + : base(defaultLocation) { ContainerName = containerName; HttpVerb = HttpVerbPut; @@ -29,8 +31,8 @@ protected override StorageServiceType StorageServiceType public override void Execute() { - string accessContainer = String.Format("http://{0}.blob.core.windows.net/%7B1%7D?restype=container", AccountName, - ContainerName); + string accessContainer = String.Format("http://{0}.blob.core.{1}/%7B2%7D?restype=container", AccountName, + Postfix, ContainerName); string canResource = String.Format("/{0}/{1}\nrestype:container", AccountName, ContainerName); string authHeader = CreateAuthorizationHeader(canResource); diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobCommand.cs index 7b3b20b..422842c 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobCommand.cs @@ -8,6 +8,7 @@ ************************************************************************************************************/ using System; +using Elastacloud.AzureManagement.Fluent.Helpers; namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs { @@ -16,7 +17,8 @@ namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs /// internal class DeleteBlobCommand : BlobCommand { - internal DeleteBlobCommand(string containerName, string blobName) + internal DeleteBlobCommand(string containerName, string blobName, string defaultLocation = LocationConstants.NorthEurope) + : base(defaultLocation) { ContainerName = containerName; BlobName = blobName; @@ -30,7 +32,7 @@ protected override StorageServiceType StorageServiceType public override void Execute() { - string accessContainer = String.Format("http://{0}.blob.core.windows.net/%7B1%7D/%7B2%7D", AccountName, + string accessContainer = String.Format("http://{0}.blob.core.{1}/%7B2%7D/%7B3%7D", AccountName, Postfix, ContainerName, BlobName); string canResource = String.Format("/{0}/{1}/{2}", AccountName, ContainerName, BlobName); string authHeader = CreateAuthorizationHeader(canResource); diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobContainerCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobContainerCommand.cs index c35fa7f..8e0f95d 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobContainerCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Blobs/DeleteBlobContainerCommand.cs @@ -8,6 +8,7 @@ ************************************************************************************************************/ using System; +using Elastacloud.AzureManagement.Fluent.Helpers; namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs { @@ -16,7 +17,8 @@ namespace Elastacloud.AzureManagement.Fluent.Commands.Blobs /// internal class DeleteBlobContainerCommand : BlobCommand { - internal DeleteBlobContainerCommand(string containerName) + internal DeleteBlobContainerCommand(string containerName, string defaultLocation = LocationConstants.NorthEurope) + : base(defaultLocation) { ContainerName = containerName; HttpVerb = HttpVerbDelete; @@ -29,8 +31,8 @@ protected override StorageServiceType StorageServiceType public override void Execute() { - string accessContainer = String.Format("http://{0}.blob.core.windows.net/%7B1%7D?restype=container", AccountName, - ContainerName); + string accessContainer = String.Format("http://{0}.blob.core.{1}/%7B2%7D?restype=container", AccountName, + Postfix, ContainerName); string canResource = String.Format("/{0}/{1}\nrestype:container", AccountName, ContainerName); string authHeader = CreateAuthorizationHeader(canResource); diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Service Bus/GetSErviceBusPolicyConnectionStringCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Service Bus/GetSErviceBusPolicyConnectionStringCommand.cs index 3e2d68b..bbf6528 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Service Bus/GetSErviceBusPolicyConnectionStringCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Service Bus/GetSErviceBusPolicyConnectionStringCommand.cs @@ -57,10 +57,12 @@ protected override void ResponseCallback(HttpWebResponse webResponse) } var root = document.Descendants(netservices + "SharedAccessAuthorizationRule"); var keyNode = root.FirstOrDefault(item => item.Element(netservices + "KeyName").Value == RuleName); - + var region = webResponse.GetResponseHeader("x-ms-servedbyregion"); + var useMooncake = (region == "chinanorth" || region == "chinaeast"); + string postfix = useMooncake ? "chinacloudapi.cn" : "windows.net"; ConnectionString = keyNode == null ? null : - String.Format("Endpoint=sb://{0}.servicebus.windows.net/;SharedAccessKeyName={1};SharedAccessKey={2}", - Namespace, keyNode.Element(netservices + "KeyName").Value, keyNode.Element(netservices + "PrimaryKey").Value); + String.Format("Endpoint=sb://{0}.servicebus.{1}/;SharedAccessKeyName={2};SharedAccessKey={3}", + Namespace, postfix, keyNode.Element(netservices + "KeyName").Value, keyNode.Element(netservices + "PrimaryKey").Value); SitAndWait.Set(); } } diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Services/ServiceCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Services/ServiceCommand.cs index 8cbcfa9..9a0d8a6 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Services/ServiceCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Services/ServiceCommand.cs @@ -63,6 +63,11 @@ protected virtual void ResponseCallback(HttpWebResponse webResponse) { //Track and throw up the X-ms request id (x-ms-request-id) MsftAsyncResponseId = webResponse.GetResponseHeader("x-ms-request-id"); + // We need to know whether we are using Mooncake or not + string region = webResponse.GetResponseHeader("x-ms-servedbyregion"); + string location = (region == "chinanorth" || region == "chinaeast") + ? LocationConstants.ChinaNorth + : LocationConstants.NorthEurope; // Trace.WriteLine("Hosted Service Response Id: {0}", MsftAsyncResponseId); for (;;) { @@ -72,7 +77,8 @@ protected virtual void ResponseCallback(HttpWebResponse webResponse) SubscriptionId = SubscriptionId, OperationId = MsftAsyncResponseId, ServiceType = "operations", - Certificate = Certificate + Certificate = Certificate, + Location = location }; asyncCommand.Execute(); Thread.Sleep(1000); @@ -211,6 +217,14 @@ internal string HttpVerb /// internal bool IsManagement { get; set; } + /// + /// Whether to use China which has a seperate service management api + /// + internal bool UseMooncake + { + get { return (Location == LocationConstants.ChinaEast || Location == LocationConstants.ChinaNorth); } + } + #endregion #region Constants @@ -220,6 +234,8 @@ internal string HttpVerb /// internal const string BaseUri = "https://management.core.windows.net/"; + internal const string ChinaUri = "https://management.core.chinacloudapi.cn/"; + #endregion /// @@ -256,7 +272,7 @@ public virtual void Execute() _exception = null; var serviceManagementRequest = new ServiceManagementRequest { - BaseUri = BaseRequestUri + (IsManagement ? ":8443" : ""), + BaseUri = (UseMooncake ? ChinaUri : BaseRequestUri) + (IsManagement ? ":8443" : ""), HttpVerb = HttpVerb, OptionalData = HttpCommand, ServiceType = ServiceType, diff --git a/Elastacloud.AzureManagement.Fluent/Commands/Virtual Machines/CreateLinuxVirtualMachineDeploymentCommand.cs b/Elastacloud.AzureManagement.Fluent/Commands/Virtual Machines/CreateLinuxVirtualMachineDeploymentCommand.cs index de51747..6bc07ac 100644 --- a/Elastacloud.AzureManagement.Fluent/Commands/Virtual Machines/CreateLinuxVirtualMachineDeploymentCommand.cs +++ b/Elastacloud.AzureManagement.Fluent/Commands/Virtual Machines/CreateLinuxVirtualMachineDeploymentCommand.cs @@ -26,13 +26,14 @@ internal class CreateLinuxVirtualMachineDeploymentCommand : ServiceCommand /// Used to construct the command to create a virtual machine deployment including the creation of a role /// // https://management.core.windows.net//services/hostedservices//deployments - internal CreateLinuxVirtualMachineDeploymentCommand(List properties, string cloudServiceName) + internal CreateLinuxVirtualMachineDeploymentCommand(List properties, string cloudServiceName, string defaultLocation = LocationConstants.NorthEurope) { AdditionalHeaders["x-ms-version"] = "2012-03-01"; OperationId = "hostedservices"; ServiceType = "services"; HttpCommand = (CloudServiceName = cloudServiceName) + "/deployments"; Properties = properties; + DefaultLocation = defaultLocation; } /// @@ -40,6 +41,7 @@ internal CreateLinuxVirtualMachineDeploymentCommand(List public string CloudServiceName { get; set; } + public string DefaultLocation { get; set; } /// /// The full virtual machine properties of the windows instance the needs to be deployed /// @@ -53,7 +55,10 @@ protected override string CreatePayload() { var deployment = Deployment.GetAdHocLinuxTemplateDeployment(Properties); var document = new XDocument(deployment.GetXmlTree()); - return document.ToStringFullXmlDeclarationWithReplace(); + string ammended = document.ToStringFullXmlDeclarationWithReplace(); + return (DefaultLocation == LocationConstants.ChinaNorth || DefaultLocation == LocationConstants.ChinaEast) + ? ammended.Replace("blob.core.windows.net", "blob.core.chinacloudapi.cn") : ammended; + } /// diff --git a/Elastacloud.AzureManagement.Fluent/Fluent API/Services/Classes/ServiceCertificate.cs b/Elastacloud.AzureManagement.Fluent/Fluent API/Services/Classes/ServiceCertificate.cs index 0250249..f11b904 100644 --- a/Elastacloud.AzureManagement.Fluent/Fluent API/Services/Classes/ServiceCertificate.cs +++ b/Elastacloud.AzureManagement.Fluent/Fluent API/Services/Classes/ServiceCertificate.cs @@ -89,9 +89,9 @@ public ServiceCertificate() /// /// Used to create the Cert /// - public X509Certificate2 Create() + public X509Certificate2 Create(string location) { - var generator = new CertificateGenerator(); + var generator = new CertificateGenerator(location); return generator.Create(Name, ValidFrom, ValidTo, PvkPassword, true); } diff --git a/Elastacloud.AzureManagement.Fluent/Fluent API/Services/DeploymentManager.cs b/Elastacloud.AzureManagement.Fluent/Fluent API/Services/DeploymentManager.cs index ba25191..1e86d90 100644 --- a/Elastacloud.AzureManagement.Fluent/Fluent API/Services/DeploymentManager.cs +++ b/Elastacloud.AzureManagement.Fluent/Fluent API/Services/DeploymentManager.cs @@ -74,14 +74,17 @@ public class DeploymentManager : IAzureManager, IDeploymentActivity, IDeployment #endregion - internal DeploymentManager(string subscriptionId) + internal DeploymentManager(string subscriptionId, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; RolesInstances = new Dictionary(); CloudConfigChanges = new List(); EnableSsl = EnableRemoteDesktop = false; + DefaultLocation = defaultLocation; } + public string DefaultLocation { get; set; } + #region Implementation of IDefinitionActivity /// @@ -167,7 +170,7 @@ IHostedServiceActivity IServiceCertificate.GenerateAndAddServiceCertificate(stri { ServiceCertificate = new ServiceCertificate(name); // we have to also create the certificate! - ServiceCertificate.Create(); + ServiceCertificate.Create(Location); // add these to the config list we have to implement changes to if (EnableSsl) @@ -455,7 +458,8 @@ List IQueryCloudService.GetHostedServiceList() var command = new GetHostedServiceListCommand { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; command.Execute(); return command.HostedServices; @@ -472,7 +476,8 @@ List IQueryCloudService.GetCloudServiceListWithDeployments() var command = new GetCloudServicePropertiesCommand(cloudService.Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; command.Execute(); cloudService.Deployments = command.CloudServiceDeployments; @@ -491,7 +496,8 @@ List IQueryCloudService.GetRoleNamesForProductionDeploymentForServiceWit var command = new GetDeploymenRoleNamesCommand(serviceName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; command.Execute(); return command.RoleNames; @@ -508,7 +514,8 @@ CscfgFile IQueryCloudService.GetConfigurationForProductionDeploymentForServiceWi var command = new GetDeploymenConfigurationCommand(serviceName) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; command.Execute(); return command.Configuration; @@ -526,7 +533,8 @@ List IQueryCloudService.GetHostedServiceListContainingProductionDe var command = new GetHostedServiceListCommand { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; command.Execute(); // enumerate the collection to see whether any of the hosted services @@ -535,7 +543,8 @@ List IQueryCloudService.GetHostedServiceListContainingProductionDe var serviceCommand = new GetHostedServiceContainsDeploymentCommand(a.Name) { SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate + Certificate = ManagementCertificate, + Location = DefaultLocation }; serviceCommand.Execute(); if (serviceCommand.ContainsProductionDeployment) diff --git a/Elastacloud.AzureManagement.Fluent/Fluent API/Subscriptions/SubscriptionDetailsManager.cs b/Elastacloud.AzureManagement.Fluent/Fluent API/Subscriptions/SubscriptionDetailsManager.cs index e8b8270..af638df 100644 --- a/Elastacloud.AzureManagement.Fluent/Fluent API/Subscriptions/SubscriptionDetailsManager.cs +++ b/Elastacloud.AzureManagement.Fluent/Fluent API/Subscriptions/SubscriptionDetailsManager.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Security.Cryptography.X509Certificates; using Elastacloud.AzureManagement.Fluent.Commands.Subscriptions; +using Elastacloud.AzureManagement.Fluent.Helpers; using Elastacloud.AzureManagement.Fluent.Helpers.PublishSettings; using Elastacloud.AzureManagement.Fluent.Types; @@ -23,13 +24,15 @@ public class SubscriptionDetailsManager : IAzureManager, ICertificateActivity, I /// /// Sets the subscription id with the manager class /// - internal SubscriptionDetailsManager(string subscriptionId) + internal SubscriptionDetailsManager(string subscriptionId, string defaultLocation = LocationConstants.NorthEurope) { SubscriptionId = subscriptionId; + Location = defaultLocation; } #region Implementation of IAzureManager + public string Location { get; set; } /// /// Event used to capture any trace information for long running async processes /// @@ -96,10 +99,11 @@ ISubscriptionQuery ICertificateActivity.AddCertificateFromStore(string thumbprin SubscriptionInformation ISubscriptionQuery.GetSubscriptionInformation() { var subscriptionCommand = new GetSubscriptionCommand - { - SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate - }; + { + SubscriptionId = SubscriptionId, + Certificate = ManagementCertificate, + Location = Location + }; subscriptionCommand.Execute(); return subscriptionCommand.SubscriptionInformation; } @@ -112,10 +116,11 @@ SubscriptionInformation ISubscriptionQuery.GetSubscriptionInformation() List ISubscriptionQuery.GetSubscriberLocations() { var subscriptionCommand = new GetSubscriberLocationsCommand - { - SubscriptionId = SubscriptionId, - Certificate = ManagementCertificate - }; + { + SubscriptionId = SubscriptionId, + Certificate = ManagementCertificate, + Location = Location + }; subscriptionCommand.Execute(); return subscriptionCommand.Locations; } diff --git a/Elastacloud.AzureManagement.Fluent/Helpers/CertificateGenerator.cs b/Elastacloud.AzureManagement.Fluent/Helpers/CertificateGenerator.cs index 674b9e8..3c11e64 100644 --- a/Elastacloud.AzureManagement.Fluent/Helpers/CertificateGenerator.cs +++ b/Elastacloud.AzureManagement.Fluent/Helpers/CertificateGenerator.cs @@ -35,16 +35,20 @@ namespace Elastacloud.AzureManagement.Fluent.Helpers /// public class CertificateGenerator { - public CertificateGenerator() + public CertificateGenerator(string defaultLocation) { + Postfix = (defaultLocation == LocationConstants.ChinaNorth || defaultLocation == LocationConstants.ChinaEast) + ? "chinacloudapi.cn" + : "windows.net"; } - - public CertificateGenerator(string subscriptionId, X509Certificate2 managementCertificate) + public CertificateGenerator(string subscriptionId, X509Certificate2 managementCertificate, string defaultLocation) + : this(defaultLocation) { SubscriptionId = subscriptionId; ManagementCertificate = managementCertificate; } + public string Postfix { get; set; } public X509Certificate2 ManagementCertificate { get; set; } public string SubscriptionId { get; set; } @@ -192,7 +196,7 @@ public string ExportToStorageAccount(string account, string container, string fo var cerBlob = blobContainer.GetBlockBlobReference(String.Format("{0}/{1}.{2}.cer", folder, DerEncodedCertificate.Thumbprint, DateTime.UtcNow.ToString("ddMMyyyy"))); cerBlob.UploadFromByteArray(GetCerData(), 0, GetCerData().Count()); - return String.Format("http://{0}.blob.core.windows.net/%7B1%7D/%7B2%7D/%7B3%7D.%7B4%7D", account, container, folder, + return String.Format("http://{0}.blob.core.{1}/%7B2%7D/%7B3%7D/%7B4%7D.%7B5%7D", account, Postfix, container, folder, DerEncodedCertificate.Thumbprint, DateTime.UtcNow.ToString("ddMMyyyy")); } diff --git a/Elastacloud.AzureManagement.Fluent/Helpers/LocationConstants.cs b/Elastacloud.AzureManagement.Fluent/Helpers/LocationConstants.cs index a35a78d..5781bf7 100644 --- a/Elastacloud.AzureManagement.Fluent/Helpers/LocationConstants.cs +++ b/Elastacloud.AzureManagement.Fluent/Helpers/LocationConstants.cs @@ -20,6 +20,8 @@ public static class LocationConstants public const string WestUS = "West US"; public const string EastUS = "East US"; public const string EastAsia = "East Asia"; - public const string SouthEastAsia = "South East Asia"; + public const string SouthEastAsia = "South East Asia"; + public const string ChinaNorth = "China North"; + public const string ChinaEast = "China East"; } } \ No newline at end of file diff --git a/Elastacloud.AzureManagement.Fluent/Properties/AssemblyInfo.cs b/Elastacloud.AzureManagement.Fluent/Properties/AssemblyInfo.cs index 179ec09..831cc78 100644 --- a/Elastacloud.AzureManagement.Fluent/Properties/AssemblyInfo.cs +++ b/Elastacloud.AzureManagement.Fluent/Properties/AssemblyInfo.cs @@ -12,10 +12,10 @@ [assembly: GuidAttribute("909b2b8c-10bf-4f0d-a94e-208ef3bdca52")] [assembly: InternalsVisibleToAttribute("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleToAttribute("Elastacloud.AzureManagement.Fluent.Tests")] -[assembly: AssemblyVersionAttribute("0.5.1.9")] -[assembly: AssemblyFileVersionAttribute("0.5.1.9")] +[assembly: AssemblyVersionAttribute("0.5.1.11")] +[assembly: AssemblyFileVersionAttribute("0.5.1.11")] namespace System { internal static class AssemblyVersionInformation { - internal const string Version = "0.5.1.9"; + internal const string Version = "0.5.1.11"; } } diff --git a/Elastacloud.AzureManagement.Fluent/QueryManager.cs b/Elastacloud.AzureManagement.Fluent/QueryManager.cs index 1e3fd36..64ec343 100644 --- a/Elastacloud.AzureManagement.Fluent/QueryManager.cs +++ b/Elastacloud.AzureManagement.Fluent/QueryManager.cs @@ -16,6 +16,8 @@ using System.Threading.Tasks; using System.Xml.Linq; using Elastacloud.AzureManagement.Fluent.Helpers; +using FSharp.Data; +using Org.BouncyCastle.Asn1.Ocsp; namespace Elastacloud.AzureManagement.Fluent { @@ -93,9 +95,15 @@ public Task MakeASyncRequest(ServiceManagementRequest serviceManage return null; } var response = (HttpWebResponse)task.Result; + // we can get a 307 from Azure sometimes so important to react with the new location parser(response); return response; - }); + }); + } + + public string ExtractLocation(HttpWebResponse response) + { + return response.Headers[HttpResponseHeaders.Location]; } public void MakeASyncRequest(ServiceManagementRequest serviceManagementRequest, ServiceManager.AsyncResponseParser parser) diff --git a/Elastacloud.AzureManagement.Fluent/SubscriptionManager.cs b/Elastacloud.AzureManagement.Fluent/SubscriptionManager.cs index 630d9a2..4744e23 100644 --- a/Elastacloud.AzureManagement.Fluent/SubscriptionManager.cs +++ b/Elastacloud.AzureManagement.Fluent/SubscriptionManager.cs @@ -31,21 +31,24 @@ public class SubscriptionManager /// private readonly string _subscriptionId; - /// + /// , /// Constructs a subscription manager which can be used to get other managers specific to the operations being requested /// /// the subscription id - public SubscriptionManager(string subscriptionId) + public SubscriptionManager(string subscriptionId, string defaultLocation = LocationConstants.NorthEurope) { _subscriptionId = subscriptionId; + Location = defaultLocation; } + public string Location { get; set; } + /// /// Gets a manager to use on all types of deployment for PaaS /// public Services.ICertificateActivity GetDeploymentManager() { - return new DeploymentManager(_subscriptionId); + return new DeploymentManager(_subscriptionId, Location); } /// @@ -71,7 +74,7 @@ public StorageManager GetStorageManager() /// A SubscriptionDetailsManager instance public Subscriptions.ICertificateActivity GetSubscriptionDetailsManager() { - return new SubscriptionDetailsManager(_subscriptionId); + return new SubscriptionDetailsManager(_subscriptionId, Location); } /// diff --git a/Elastacloud.AzureManagement.Fluent/Types/VmSize.cs b/Elastacloud.AzureManagement.Fluent/Types/VmSize.cs index 1e5c856..841d5eb 100644 --- a/Elastacloud.AzureManagement.Fluent/Types/VmSize.cs +++ b/Elastacloud.AzureManagement.Fluent/Types/VmSize.cs @@ -59,6 +59,8 @@ public enum VmSize /// A7 (8 x 1.6GHz CPU, 112GB RAM, 2,040GB Storage) /// A9, + A10, + A11, // this is the basic tariff which doesn't include the load balancing so is cheaper // ReSharper disable InconsistentNaming Basic_A0, @@ -73,66 +75,66 @@ public enum VmSize Basic_A4, // 1 core, 3.5G, 127 OS, 50G SSD // ReSharper disable once InconsistentNaming - STANDARD_D1, + Standard_D1, // 2 core, 7G, 127 OS, 100G SSD // ReSharper disable once InconsistentNaming - STANDARD_D2, + Standard_D2, // 4 core, 14G, 127 OS, 200G SSD // ReSharper disable once InconsistentNaming - STANDARD_D3, + Standard_D3, // 8 core, 28G, 127 OS, 400G SSD // ReSharper disable once InconsistentNaming - STANDARD_D4, + Standard_D4, // 2 core, 14G, 127 OS, 100G SSD // ReSharper disable once InconsistentNaming - STANDARD_D11, + Standard_D11, // 4 core, 28G, 127 OS, 200G SSD // ReSharper disable once InconsistentNaming - STANDARD_D12, + Standard_D12, // 8 core, 56G, 127 OS, 400G SSD // ReSharper disable once InconsistentNaming - STANDARD_D13, + Standard_D13, // 1 core, 112G, 127 OS, 800G SSD // ReSharper disable once InconsistentNaming - STANDARD_D14, + Standard_D14, // 1 core, 3.5G, 127 OS, 7G SSD, 3200/32MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS1, + Standard_DS1, // 2 core, 7G, 127 OS, 14G SSD, 6400/64MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS2, + Standard_DS2, // 4 core, 14G, 127 OS, 28G SSD, 12800/128MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS3, + Standard_DS3, // 8 core, 28G, 127 OS, 56G SSD, 25600/256MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS4, + Standard_DS4, // 1 core, 28G, 127 OS, 28G SSD, 6400/64MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS11, + Standard_DS11, // 2 core, 56G, 127 OS, 56G SSD, 12800/128MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS12, + Standard_DS12, // 4 core, 112G, 127 OS, 112G SSD, 25600/256MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS13, + Standard_DS13, // 8 core, 224G, 127 OS, 224G SSD, 56200/512MBsec // ReSharper disable once InconsistentNaming - STANDARD_DS14, + Standard_DS14, // 2 core, 28G, 127 OS, 384G SSD // ReSharper disable once InconsistentNaming - STANDARD_G1, + Standard_G1, // 4 core, 56G, 127 OS, 768G SSD // ReSharper disable once InconsistentNaming - STANDARD_G2, + Standard_G2, // 8 core, 112G, 127 OS, 1536G SSD // ReSharper disable once InconsistentNaming - STANDARD_G3, + Standard_G3, // 16 core, 224G, 127 OS, 3072G SSD // ReSharper disable once InconsistentNaming - STANDARD_G4, + Standard_G4, // 32 core, 448G, 127 OS, 6144G SSD // ReSharper disable once InconsistentNaming - STANDARD_G5 + Standard_G5 } } \ No newline at end of file diff --git a/Elastacloud.FluentManagement.FSTest/Elastacloud.FluentManagement.FSTest.fsproj b/Elastacloud.FluentManagement.FSTest/Elastacloud.FluentManagement.FSTest.fsproj index 1867dde..e1b3c05 100644 --- a/Elastacloud.FluentManagement.FSTest/Elastacloud.FluentManagement.FSTest.fsproj +++ b/Elastacloud.FluentManagement.FSTest/Elastacloud.FluentManagement.FSTest.fsproj @@ -64,6 +64,7 @@ + diff --git a/Elastacloud.FluentManagement.FSTest/Mooncake.fsx b/Elastacloud.FluentManagement.FSTest/Mooncake.fsx new file mode 100644 index 0000000..e831493 --- /dev/null +++ b/Elastacloud.FluentManagement.FSTest/Mooncake.fsx @@ -0,0 +1,90 @@ +#r "D:\\Projects\\Elastacloud\\fluent-management\\Elastacloud.AzureManagement.Fluent\\bin\\Debug\\Elastacloud.AzureManagement.Fluent.dll" +#r "D:\\Projects\\Elastacloud\\fluent-management\\Elastacloud.AzureManagement.Fluent\\bin\\Debug\\Elastacloud.AzureManagement.Fluent.Types.dll" +#r "D:\\Projects\\Elastacloud\\fluent-management\\Elastacloud.AzureManagement.Fluent\\bin\\Debug\\Elastacloud.AzureManagement.Fluent.Utils.dll" +#r "C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\System.Xml.Linq.dll" +#r @"..\packages\IPNetwork.1.3.1.0\lib\LukeSkywalker.IPNetwork.dll" +#r @"..\packages\FSharp.Data.2.0.14\lib\net40\FSharp.Data.dll" + +open Elastacloud.AzureManagement.Fluent +open Elastacloud.AzureManagement.Fluent.Types +open Elastacloud.AzureManagement.Fluent.Clients +open Elastacloud.AzureManagement.Fluent.VirtualNetwork +open Elastacloud.AzureManagement.Fluent.Helpers.PublishSettings +open FSharp.Data +open System.Xml.Linq +open System.Net +open LukeSkywalker.IPNetwork +open System +open Elastacloud.AzureManagement.Fluent.VirtualMachines.Classes +open Elastacloud.AzureManagement.Fluent.Types.VirtualMachines +open System.Collections.Generic +open System.Security.Cryptography.X509Certificates +open Elastacloud.AzureManagement.Fluent.Types.VirtualNetworks +open Elastacloud.AzureManagement.Fluent.Watchers +open Elastacloud.AzureManagement.Fluent.Helpers + +let subscriptionId = "1631f3af-fc17-48e7-9dc7-b519f52534ab" +/// Start Fuctions +let settingCert fileName subscriptionId = + let settings = PublishSettingsExtractor fileName + settings.AddAllPublishSettingsCertificatesToPersonalMachineStore(subscriptionId).[0] +let getFromBizsparkPlus = settingCert "D:\\Projects\\Windows Azure 内部使用-3-10-2015-credentials.publishsettings" + +// Cloud Services +let serviceClient = ServiceClient(subscriptionId, getFromBizsparkPlus subscriptionId, "briskchina", LocationConstants.ChinaNorth) +serviceClient.CreateNewCloudService(LocationConstants.ChinaNorth, "My First Fluent Service") +let mutable available = serviceClient.IsCloudServiceNameAvailable +serviceClient.DeleteCloudService() +available <- serviceClient.IsCloudServiceNameAvailable +let locations = serviceClient.AvailableLocations +// Storage Accounts +let storageClient = StorageClient(subscriptionId, getFromBizsparkPlus subscriptionId, LocationConstants.ChinaEast) +let mutable accounts = storageClient.GetStorageAccountList() +storageClient.CreateNewStorageAccount("briskchina", LocationConstants.ChinaNorth) +accounts <- storageClient.GetStorageAccountList() +storageClient.DeleteStorageAccount("briskchina") +accounts <- storageClient.GetStorageAccountList() +// Virtual Networking +let vnClient = VirtualNetworkClient(subscriptionId, (getFromBizsparkPlus subscriptionId), LocationConstants.ChinaEast) +let vNets = vnClient.GetAvailableVirtualNetworks() +let vNetToTest = vNets |> Seq.head +let addressRange1 = vNetToTest.AddressRanges |> Seq.head +vnClient.AddSubnetToAddressRange(vNetToTest.Name, addressRange1.AddressPrefix, "fred") +let we = vnClient.GetAvailableVirtualNetworks(LocationConstants.ChinaEast) +let ne = vnClient.GetAvailableVirtualNetworks(LocationConstants.ChinaNorth) +vnClient.RemoveSubnet(vNetToTest.Name, "fred") +vnClient.GetAllNetworkingConfig() +// Service Bus +let sbClient = ServiceBusClient(subscriptionId, (getFromBizsparkPlus subscriptionId), LocationConstants.ChinaNorth) +let bobbydavro = sbClient.CheckNamespaceExists("bobbydavro") +let fred = sbClient.CheckNamespaceExists("fred") +let fred2 = sbClient.CreateNamespace("fred") +let toolscheck = sbClient.CheckNamespaceExists("elastatools3") +let elastacloud = sbClient.CreateNamespace("elastatools3") +let clouddelete = sbClient.DeleteNamespace("elastatools3") +let sblist = sbClient.GetServiceBusNamspaceList(LocationConstants.ChinaEast) +let sblist1 = sbClient.GetServiceBusNamspaceList(LocationConstants.ChinaNorth) +let sbpolicy = sbClient.GetServiceBusConnectionString("elastatools3", "RootManageSharedAccessKey") +// Image Management +let imClient = ImageManagementClient(subscriptionId, getFromBizsparkPlus subscriptionId, LocationConstants.ChinaEast) +let imageList = imClient.ImageList +let ubuntuList = imageList + |> Seq.filter(fun image -> image.Name.ToLower().Contains("ubuntu")) + |> Seq.toList + |> Seq.iter(fun image -> printfn "%s" image.Name) +// Virtual Machines +let vmClient = LinuxVirtualMachineClient(subscriptionId, getFromBizsparkPlus subscriptionId, LocationConstants.ChinaEast) +let sshEndpoint = InputEndpoint(EndpointName = "ssh", LocalPort = 22, Port = Nullable(22), Protocol = Protocol.TCP) +let properties = new LinuxVirtualMachineProperties( + VmSize = VmSize.Small, + UserName = "azurecoder", + AdministratorPassword = "P@ssword761", + HostName = "briskit", + RoleName = "briskit", + CloudServiceName = "briskchina", + PublicEndpoints = List([|sshEndpoint|]), + CustomTemplateName = "b549f4301d0b4295b8e76ceb65df47d4__Ubuntu-14_04_1-LTS-amd64-server-20150123-en-us-30GB", + DeploymentName = "briskchina", + StorageAccountName = "briskchina") +vmClient.LinuxVirtualMachineStatusEvent.Subscribe(fun vmstatus -> printfn "from %s to %s" (vmstatus.OldStatus.ToString()) (vmstatus.NewStatus.ToString())) +vmClient.CreateNewVirtualMachineDeploymentFromTemplateGallery(List([|properties|]), "briskchina") \ No newline at end of file diff --git a/Elastacloud.FluentManagement.FSTest/VirtualMachines.fsx b/Elastacloud.FluentManagement.FSTest/VirtualMachines.fsx index 5d41979..3c87451 100644 --- a/Elastacloud.FluentManagement.FSTest/VirtualMachines.fsx +++ b/Elastacloud.FluentManagement.FSTest/VirtualMachines.fsx @@ -28,6 +28,7 @@ let settingCert fileName subscriptionId = let settings = PublishSettingsExtractor fileName settings.AddAllPublishSettingsCertificatesToPersonalMachineStore(subscriptionId).[0] let getFromBizsparkPlus = settingCert "D:\\Projects\\BizSpark Plus-7-8-2014-credentials.publishsettings" + let vmClient = LinuxVirtualMachineClient(subscriptionId, getFromBizsparkPlus subscriptionId) @@ -96,3 +97,7 @@ let watcher = manager.GetRoleStatusChangedWatcher("isaacfoobar", (getFromBizsparkPlus subscriptionId).Thumbprint) watcher.RoleStatusChangeHandler.Add(fun status -> printfn "from %s to %s" (status.OldState.ToString()) (status.NewState.ToString())) +let serviceClient = ServiceClient(subscriptionId, getFromBizsparkPlus subscriptionId, "briskchina") +let locations = serviceClient.AvailableLocations +locations.[0].VirtualMachineRolesSizes +|> Seq.iter (fun size -> printfn "%s" (size.ToString())) \ No newline at end of file diff --git a/Elastacloud.FluentManagement.FSTest/VirtualNetworking.fsx b/Elastacloud.FluentManagement.FSTest/VirtualNetworking.fsx index d6401ed..35efa46 100644 --- a/Elastacloud.FluentManagement.FSTest/VirtualNetworking.fsx +++ b/Elastacloud.FluentManagement.FSTest/VirtualNetworking.fsx @@ -60,8 +60,8 @@ let vnClient = VirtualNetworkClient(subscriptionId, (getFromBizsparkPlus subscri let vNets = vnClient.GetAvailableVirtualNetworks() let vNetToTest = vNets |> Seq.head let addressRange1 = vNetToTest.AddressRanges |> Seq.head -vnClient.AddSubnetToAddressRange(vNetToTest.Name, addressRange1.AddressPrefix, "fred"); - +vnClient.AddSubnetToAddressRange(vNetToTest.Name, addressRange1.AddressPrefix, "fred") +vnClient.RemoveSubnet(vNetToTest.Name, "fred") validateNextAvailableSubnetAddress "10.1.0.255" "10.1.0.0/16" NextAvailableSubnet addressRange1.AddressPrefix vNetToTest diff --git a/RebexPacker.1.0.0.nupkg b/RebexPacker.1.0.0.nupkg new file mode 100644 index 0000000..d585a60 Binary files /dev/null and b/RebexPacker.1.0.0.nupkg differ diff --git a/package.fsx b/package.fsx index 21d5bc5..6777d14 100644 --- a/package.fsx +++ b/package.fsx @@ -1,4 +1,4 @@ -#r @"packages\FAKE\tools\FakeLib.dll" // include Fake lib +#r @"packages\FAKE.3.17.0\tools\FakeLib.dll" // include Fake lib open Fake open Fake.AssemblyInfoFile open Fake.NuGetHelper @@ -9,7 +9,7 @@ open Fake.Git.Staging Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ [] -let version = "0.5.1.9" +let version = "0.5.1.10" // 1. Increment the minor number assemblyinfo version CreateCSharpAssemblyInfo (sprintf @"%s\Elastacloud.AzureManagement.Fluent\Properties\AssemblyInfo.cs" Environment.CurrentDirectory) [Attribute.Title("Elastacloud.AzureManagement.Fluent") Attribute.Description("Library used for management of Windows Azure services, SQL, storage, networking, WASD, WAMS and VM's")