public async Task AddVMEntityAsync(VMDetails newVM) { ValidateVMDetails(newVM); CloudTable table = tableClient.GetTableReference(tableName); TableOperation insertOperation = TableOperation.Insert(newVM); await table.ExecuteAsync(insertOperation); }
public async Task ModifyVMDetailsAsync(VMDetails updatedVM) { ValidateVMDetails(updatedVM); updatedVM.ETag = "*"; //required for the Merge operation CloudTable table = tableClient.GetTableReference(tableName); TableOperation updateOperation = TableOperation.Merge(updatedVM); var x = await table.ExecuteAsync(updateOperation); }
public void ValidateVMDetails(VMDetails entity) { if (string.IsNullOrEmpty(entity.VMID)) { throw new ArgumentException($"{nameof(entity.VMID)} should not be null"); } if (string.IsNullOrEmpty(entity.ResourceGroup)) { throw new ArgumentException($"{nameof(entity.ResourceGroup)} should not be null"); } }
public async Task ModifyVMStateByIdAsync(string VMID, VMState state) { if (string.IsNullOrEmpty(VMID)) { throw new Exception($"{nameof(VMID)} should have a value"); } CloudTable table = tableClient.GetTableReference(tableName); VMDetails vm = await GetVMByID(VMID); vm.State = state; TableOperation updateOperation = TableOperation.Merge(vm); await table.ExecuteAsync(updateOperation); }
public static async Task StartDeallocatedVMAsync(VMDetails vm) { // not awaiting here intentionally, since we want to return response immediately var task = AzureMgmtCredentials.Instance.Azure .VirtualMachines.StartAsync(vm.ResourceGroup, vm.VMID); // we do not wait for VM start to complete // so let's give it few seconds to start and return in case we have deployment exception // like service principal error await Task.WhenAny(task, Task.Delay(1000)); if (task.IsCompleted && task.IsFaulted) { throw task.Exception; } }
public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = "node/create")] HttpRequestMessage req, TraceWriter log, ExecutionContext context) { var content = await req.Content.ReadAsStringAsync(); var nodeParams = JsonConvert.DeserializeObject <NodeParameters>(content); var err = ValidateRequest(req, nodeParams, log); if (err != null) { return(err); } //find out if there is any VM in MarkedForDeallocation state var vm = (await TableStorageHelper.Instance.GetMatchingVMsInStateAsync( nodeParams.ResourceGroup, nodeParams.Region, nodeParams.Size, VMState.MarkedForDeallocation)) .FirstOrDefault(); if (vm != null) { //set it as running so as not to be deallocated when game rooms are 0 vm.State = VMState.Running; await TableStorageHelper.Instance.ModifyVMDetailsAsync(vm); //we're done, this VM can now be used return(req.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(vm), "application/json")); } //search if there are any deallocated VMs var deallocatedVM = (await TableStorageHelper.Instance .GetMatchingVMsInStateAsync(nodeParams.ResourceGroup, nodeParams.Region, nodeParams.Size, VMState.Deallocated)) .FirstOrDefault(); //no deallocated VMs, so let's create a new one if (deallocatedVM == null) { string vmName = "node" + System.Guid.NewGuid().ToString("N").Substring(0, 7); string sshKey = ConfigurationManager.AppSettings["VM_ADMIN_KEY"]?.ToString() ?? System.IO.File.ReadAllText(context.FunctionAppDirectory + "/default_key_rsa.pub"); string deploymentTemplate = System.IO.File.ReadAllText(context.FunctionAppDirectory + "/vmDeploy.json"); await DeployNodeAsync(vmName, nodeParams, sshKey, deploymentTemplate, log); var details = new VMDetails(vmName, nodeParams.ResourceGroup, VMState.Creating, nodeParams.Size, nodeParams.Region); await TableStorageHelper.Instance.AddVMEntityAsync(details); return(req.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(details), "application/json")); } else//there's at least one deallocated VM, so start the .First() one { await AzureAPIHelper.StartDeallocatedVMAsync(deallocatedVM); deallocatedVM.State = VMState.Creating; await TableStorageHelper.Instance.ModifyVMDetailsAsync(deallocatedVM); return(req.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(deallocatedVM), "application/json")); } }