/// <summary>
        /// Creates a new virtual machine from a gallery template
        /// </summary>
        /// <param name="properties">Can be any gallery template</param>
        /// <param name="cloudServiceName">The name of the cloud service - if it doesn't exist it will be created</param>
        /// <param name="serviceCertificate">The service certificate responsible for adding the ssh keys</param>
        /// <param name="location">Where the cloud service will be created if it doesn't exist</param>
        /// <param name="affinityGroup">Affinity group that this service will live in</param>
        public IVirtualMachineClient CreateNewVirtualMachineDeploymentFromTemplateGallery(List<LinuxVirtualMachineProperties> properties, string cloudServiceName, ServiceCertificateModel serviceCertificate = null, string location = LocationConstants.NorthEurope, string affinityGroup = "")
        {
            if(String.IsNullOrEmpty(cloudServiceName))
                throw new FluentManagementException("Cloud service name cannot be empty", "LinuxVirtualMachineClient");

            // if the cloud service doesn't exist we'll create it
            // first check that the service is available
            var checkCloudServiceAvailabilityCommand = new CheckCloudServiceNameAvailableCommand(cloudServiceName)
                {
                    SubscriptionId = SubscriptionId,
                    Certificate = ManagementCertificate
                };
            checkCloudServiceAvailabilityCommand.Execute();
            Trace.WriteLine(String.Format("Checked cloud service availability - is available: {0}", checkCloudServiceAvailabilityCommand.CloudServiceAvailable));
            // when the check is complete we'll create the cloud service in the specified or default region if it doesn't exist
            if (checkCloudServiceAvailabilityCommand.CloudServiceAvailable)
            {
                var cloudServiceCommand = new CreateCloudServiceCommand(cloudServiceName, "Created by Fluent Management", location, affinityGroup)
                    {
                        SubscriptionId = SubscriptionId,
                        Certificate = ManagementCertificate
                    };
                cloudServiceCommand.Execute();
                Trace.WriteLine(String.Format("Cloud service named {0} has been created", cloudServiceName));
            }
            // adds service certificate to the deployment
            if (serviceCertificate != null)
            {
                AddServiceCertificateToRoles(serviceCertificate, cloudServiceName, ref properties);
                Trace.WriteLine("A new service certificate has been added to the cloud service");
                ServiceCertificate = serviceCertificate.ServiceCertificate.Export(X509ContentType.Pfx);
            }

            // 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<LinuxVirtualMachineProperties>(new[]{properties[0]}), cloudServiceName)
            {
                SubscriptionId = SubscriptionId,
                Certificate = ManagementCertificate
            };
            command.Execute();
            // raise this event every time we create a VM
            if (LinuxVirtualMachineCreationEvent != null)
            {
                LinuxVirtualMachineCreationEvent(this, properties[0]);
            }
            Trace.WriteLine("Deployment created and first virtual machine added");
            // try and add the other concurrently
            // concurrency doesn't work - there is no way to build a fast deployment :-(
            for (int i = 1; i < properties.Count; i++)
            {
                // add this we'll need to ensure that it's populated for the command
                var theProperty = properties[i];
                theProperty.CloudServiceName = cloudServiceName;
                // clousrure may cause an exception here - proof is in the pudding!
                var startCommand = new AddLinuxVirtualMachineToDeploymentCommand(theProperty, cloudServiceName)
                    {
                        SubscriptionId = SubscriptionId,
                        Certificate = ManagementCertificate
                    };
                startCommand.Execute();
                // raise this event every time we create a VM
                if (LinuxVirtualMachineCreationEvent != null)
                {
                    LinuxVirtualMachineCreationEvent(this, theProperty);
                }
                Trace.WriteLine(String.Format("New VM added to deployment with hostname {0}", theProperty.HostName));
            }
            if (LinuxVirtualMachineStatusEvent != null)
            {
                Task.Factory.StartNew(() => CheckVmDeploymentIsRunning(properties));
            }

            // important here to force a refresh - just in case someone to conduct an operation on the VM in a single step
            Properties = properties;
            // create a new client and return this so that properties can be populated automatically
            return new LinuxVirtualMachineClient(properties, SubscriptionId, ManagementCertificate);
        }
        private void AddServiceCertificateToRoles(ServiceCertificateModel serviceCertificate, string cloudServiceName, ref List<LinuxVirtualMachineProperties> properties)
        {
            // upload the service certificate if it exists for the ssh keys
            if (serviceCertificate != null)
            {
                var client = new ServiceClient(SubscriptionId, ManagementCertificate, cloudServiceName);
                client.UploadServiceCertificate(serviceCertificate.ServiceCertificate, serviceCertificate.Password, true);
                foreach (var linuxVirtualMachineProperty in properties)
                {
                    linuxVirtualMachineProperty.PublicKeys.Add(new SSHKey(KeyType.PublicKey)
                    {
                        FingerPrint = serviceCertificate.ServiceCertificate.GetCertHashString(),
                        Path = String.Format("/home/{0}/.ssh/authorized_keys", linuxVirtualMachineProperty.UserName)
                    });
                    linuxVirtualMachineProperty.KeyPairs.Add(new SSHKey(KeyType.KeyPair)
                    {
                        FingerPrint = serviceCertificate.ServiceCertificate.GetCertHashString(),
                        Path = String.Format("/home/{0}/.ssh/id_rsa", linuxVirtualMachineProperty.UserName)
                    });

                    linuxVirtualMachineProperty.DisableSSHPasswordAuthentication = true;
                }
            }
        }
 public void AddRolesToExistingDeployment(List<LinuxVirtualMachineProperties> properties, string cloudServiceName, ServiceCertificateModel serviceCertificate)
 {
     // add the service certificate
     AddServiceCertificateToRoles(serviceCertificate, cloudServiceName, ref properties);
     // concurrency doesn't work - there is no way to build a fast deployment :-(
     foreach (var theProperty in properties)
     {
         theProperty.CloudServiceName = cloudServiceName;
         // clousrure may cause an exception here - proof is in the pudding!
         var startCommand = new AddLinuxVirtualMachineToDeploymentCommand(theProperty, cloudServiceName)
             {
                 SubscriptionId = SubscriptionId,
                 Certificate = ManagementCertificate
             };
         startCommand.Execute();
         Trace.WriteLine(String.Format("Added VM with hostname {0} to deployment", theProperty.HostName));
     }
 }