Beispiel #1
0
        /// <summary>Get the virtual machine batch operation.</summary>
        /// <param name="virtualMachines">List of the virtual machines</param>
        /// <param name="partitionKey"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private static TableBatchOperation GetVirtualMachineBatchOperation(IList <IVirtualMachine> virtualMachines,
                                                                           string partitionKey, TraceWriter log)
        {
            if (virtualMachines == null)
            {
                return(null);
            }

            var virtualMachineTableBatchOperation = new TableBatchOperation();

            partitionKey = partitionKey.Replace(Delimeters.ForwardSlash, Delimeters.Exclamatory);
            foreach (var eachVirtualMachine in virtualMachines)
            {
                try
                {
                    var virtualMachineEntity = VirtualMachineHelper.ConvertToVirtualMachineEntity(
                        eachVirtualMachine, partitionKey,
                        eachVirtualMachine.ResourceGroupName);
                    virtualMachineEntity.VirtualMachineGroup = VirtualMachineGroup.AvailabilitySets.ToString();
                    virtualMachineTableBatchOperation.InsertOrReplace(virtualMachineEntity);
                }
                catch (Exception ex)
                {
                    log.Error($"timercrawlerforavailableset threw the exception ", ex,
                              "GetVirtualMachineBatchOperation");
                }
            }

            return(virtualMachineTableBatchOperation);
        }
        /// <summary>1. Convert the list of virtual machines into Virtual machine crawler entities
        /// 2. Add the entity into the table using the batch operation task</summary>
        /// <param name="virtualMachines">List of virtual machines, which needs to push into table</param>
        /// <param name="resourceGroupName"></param>
        /// <param name="log">Trace writer instance</param>
        /// <returns>Returns the list of the insert batch operation as task.</returns>
        private static TableBatchOperation InsertOrReplaceEntitiesIntoTable(List <IVirtualMachine> virtualMachines,
                                                                            string resourceGroupName, TraceWriter log)
        {
            if (virtualMachines.Count == 0)
            {
                return(null);
            }

            var batchOperation = new TableBatchOperation();

            foreach (var eachVirtualMachine in virtualMachines)
            {
                try
                {
                    var partitionKey = resourceGroupName;
                    batchOperation.InsertOrReplace(VirtualMachineHelper.ConvertToVirtualMachineEntity(eachVirtualMachine, partitionKey));
                }
                catch (Exception e)
                {
                    log.Error($"timercrawlerforvirtualmachines threw the exception ", e, "InsertEntitiesIntoTable");
                }
            }

            return(batchOperation);
        }
Beispiel #3
0
        /// <summary>Get the virtual machines by resource group and availability set ids.</summary>
        /// <param name="resourceGroupName"></param>
        /// <param name="availabilitySetIds"></param>
        /// <param name="azureClient"></param>
        /// <returns></returns>
        private static IList <IGrouping <string, IVirtualMachine> > GetVirtualMachineListByResourceGroup(
            string resourceGroupName,
            List <string> availabilitySetIds,
            AzureClient azureClient)
        {
            // Get the virtual machines by resource group
            var virtualMachinesList = azureClient.AzureInstance.VirtualMachines.ListByResourceGroup(resourceGroupName).ToList();

            if (!virtualMachinesList.Any())
            {
                return(null);
            }
            var loadBalancerVmTask = VirtualMachineHelper.GetVirtualMachinesFromLoadBalancers(resourceGroupName, azureClient);
            var loadbalancerVms    = loadBalancerVmTask.Result;

            if (loadbalancerVms != null && loadbalancerVms.Any())
            {
                virtualMachinesList = virtualMachinesList.Where(x => !loadbalancerVms.Contains(x.Id))?.ToList();
            }

            // Group the the virtual machine based on the availability set id
            var virtualMachinesByAvailabilitySetId = virtualMachinesList?.Where(x => availabilitySetIds
                                                                                .Contains(x.AvailabilitySetId, StringComparer.OrdinalIgnoreCase))
                                                     .GroupBy(x => x.AvailabilitySetId, x => x).ToList();

            return(virtualMachinesByAvailabilitySetId);
        }
        public void CreateRule(TraceWriter log)
        {
            try
            {
                var loadBalancer = GetRandomLoadBalancer();
                if (loadBalancer == null)
                {
                    log.Info("Loadbalancer RuleEngine: No load balancer found with virtual machines.");
                    return;
                }

                var filteredVmSet = GetVirtualMachineSet(loadBalancer.Id);
                if (filteredVmSet == null)
                {
                    log.Info("Loadbalancer RuleEngine: No virtual machines found for the load balancer name: " + loadBalancer.ResourceName);
                    return;
                }

                var table = StorageAccountProvider.CreateOrGetTable(StorageTableNames.ScheduledRulesTableName);
                if (table == null)
                {
                    return;
                }

                var count = VmCount(filteredVmSet.Count);
                var tasks = new List <Task>();

                //  do
                //  {
                var randomSets = filteredVmSet.Take(count).ToList();
                filteredVmSet = filteredVmSet.Except(randomSets).ToList();
                for (var i = 0;
                     i < randomSets.Count;
                     i += TableConstants.TableServiceBatchMaximumOperations)
                {
                    var batchItems = randomSets.Skip(i)
                                     .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();

                    var batchOperation = VirtualMachineHelper.CreateScheduleEntity(batchItems,
                                                                                   _azureClient.AzureSettings.Chaos.SchedulerFrequency,
                                                                                   _azureClient.AzureSettings.Chaos.AzureFaultInjectionActions,
                                                                                   VirtualMachineGroup.LoadBalancer);

                    var operation = batchOperation;
                    tasks.Add(table.ExecuteBatchAsync(operation));
                }

                //  } while (filteredVmSet.Any());

                Task.WhenAll(tasks);
                log.Info("Loadbalancer RuleEngine: Completed creating rule engine.");
            }
            catch (Exception ex)
            {
                log.Error("LoadBalancer RuleEngine: Exception thrown. ", ex);
            }
        }
        private void InsertVirtualMachineAvailabilitySetDomainResults(string availabilitySetId, int domainNumber)
        {
            var virtualMachineQuery = TableQuery.CombineFilters(TableQuery.GenerateFilterCondition("AvailabilitySetId",
                                                                                                   QueryComparisons.Equal,
                                                                                                   availabilitySetId),
                                                                TableOperators.And,
                                                                _azureClient.AzureSettings.Chaos.AvailabilitySetChaos.FaultDomainEnabled
                    ? TableQuery.GenerateFilterConditionForInt("FaultDomain",
                                                               QueryComparisons.Equal,
                                                               domainNumber)
                    : TableQuery.GenerateFilterConditionForInt("UpdateDomain",
                                                               QueryComparisons.Equal,
                                                               domainNumber));

            //TableQuery.GenerateFilterConditionForInt("AvailabilityZone", QueryComparisons.GreaterThanOrEqual, 0);
            var virtualMachinesTableQuery     = new TableQuery <VirtualMachineCrawlerResponse>().Where(virtualMachineQuery);
            var crawledVirtualMachinesResults = StorageAccountProvider.GetEntities(virtualMachinesTableQuery,
                                                                                   StorageTableNames.VirtualMachineCrawlerTableName);
            var virtualMachinesResults = crawledVirtualMachinesResults.ToList();

            if (!virtualMachinesResults.Any())
            {
                return;
            }

            var domainFlag = !_azureClient.AzureSettings.Chaos.AvailabilitySetChaos.UpdateDomainEnabled;
            var batchTasks = new List <Task>();
            var table      = StorageAccountProvider.CreateOrGetTable(StorageTableNames.ScheduledRulesTableName);

            if (table == null)
            {
                return;
            }

            for (var i = 0; i < virtualMachinesResults.Count; i += TableConstants.TableServiceBatchMaximumOperations)
            {
                var batchItems = virtualMachinesResults.Skip(i)
                                 .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                var scheduledRulesbatchOperation =
                    VirtualMachineHelper.CreateScheduleEntityForAvailabilitySet(batchItems,
                                                                                _azureClient.AzureSettings.Chaos.SchedulerFrequency,
                                                                                _azureClient.AzureSettings.Chaos.AzureFaultInjectionActions,
                                                                                domainFlag);
                if (scheduledRulesbatchOperation.Count <= 0)
                {
                    return;
                }

                batchTasks.Add(table.ExecuteBatchAsync(scheduledRulesbatchOperation));
            }

            if (batchTasks.Count > 0)
            {
                Task.WhenAll(batchTasks);
            }
        }
        /// <summary>Get the list of the executer instances from the scheduled Rules data.</summary>
        /// <param name="scheduledRules">List of the scheduled Rules from the scheduled table.</param>
        ///  /// <param name="rollbackRules">List of the rollback Rules from the scheduled table.</param>
        /// <param name="starter">Durable Orchestration client instance, to start the executer function</param>
        /// <param name="log">Trace writer to log the information/warning/errors.</param>
        /// <returns>The list of task, which has the instances of the executers.</returns>
        private static List <Task> GetListOfExecuters(IEnumerable <ScheduledRules> scheduledRules, IEnumerable <ScheduledRules> rollbackRules, DurableOrchestrationClient starter, TraceWriter log)
        {
            var tasks = new List <Task>();

            foreach (var result in scheduledRules)
            {
                var partitionKey = result.ResourceType.Replace(Delimeters.Exclamatory, Delimeters.ForwardSlash);
                //Bug - need to map the vmss vm in the availability zone to vmscaleset executer
                if (!Mappings.FunctionNameMap.ContainsKey(partitionKey))
                {
                    continue;
                }

                var functionMapName = (partitionKey.Equals(VirtualMachineGroup.AvailabilityZones.ToString(), StringComparison.OrdinalIgnoreCase) &&
                                       result.RowKey.ToLowerInvariant().Contains(VirtualMachineGroup.VirtualMachineScaleSets.ToString().ToLowerInvariant()) ?
                                       VirtualMachineGroup.AvailabilityZones.ToString() + VirtualMachineGroup.VirtualMachineScaleSets.ToString()
                  : partitionKey);

                var functionName = Mappings.FunctionNameMap[functionMapName];
                log.Info($"Timely trigger: invoking function: {functionName}");
                var triggeredData = JsonConvert.DeserializeObject <InputObject>(result.TriggerData);
                tasks.Add(starter.StartNewAsync(functionName, result.TriggerData));
            }

            foreach (var result in rollbackRules)
            {
                var partitionKey = result.ResourceType.Replace(Delimeters.Exclamatory, Delimeters.ForwardSlash);
                if (!Mappings.FunctionNameMap.ContainsKey(partitionKey))
                {
                    continue;
                }

                var triggeredData = JsonConvert.DeserializeObject <InputObject>(result.TriggerData);
                triggeredData.Action = VirtualMachineHelper.GetAction(result.FinalState).ToString();
                if (!triggeredData.EnableRollback)
                {
                    triggeredData.EnableRollback = true;
                }

                var functionMapName = (partitionKey.Equals(VirtualMachineGroup.AvailabilityZones.ToString(), StringComparison.OrdinalIgnoreCase) &&
                                       result.RowKey.ToLowerInvariant().Contains(VirtualMachineGroup.VirtualMachineScaleSets.ToString().ToLowerInvariant()) ?
                                       VirtualMachineGroup.AvailabilityZones.ToString() + VirtualMachineGroup.VirtualMachineScaleSets.ToString()
                    : partitionKey);
                var functionName = Mappings.FunctionNameMap[functionMapName];
                log.Info($"Timely trigger: invoking function: {functionName}");
                tasks.Add(starter.StartNewAsync(functionName, JsonConvert.SerializeObject(triggeredData)));
            }

            return(tasks);
        }
        /// <summary>Create the virtual machine rules</summary>
        /// <param name="log"></param>
        public void CreateRule(TraceWriter log)
        {
            try
            {
                log.Info("VirtualMachine RuleEngine: Started the creating rules for the virtual machines.");
                var vmSets = GetRandomVmSet();
                if (vmSets == null)
                {
                    log.Info("VirtualMachine RuleEngine: No virtual machines found..");
                    return;
                }

                var table = StorageAccountProvider.CreateOrGetTable(StorageTableNames.ScheduledRulesTableName);
                var count = VmCount(vmSets.Count);
                var tasks = new List <Task>();

                //do
                //{
                var randomSets = vmSets.Take(count).ToList();
                vmSets = vmSets.Except(randomSets).ToList();
                for (var i = 0;
                     i < randomSets.Count;
                     i += TableConstants.TableServiceBatchMaximumOperations)
                {
                    var batchItems = randomSets.Skip(i)
                                     .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();

                    var batchOperation = VirtualMachineHelper.CreateScheduleEntity(batchItems,
                                                                                   azureClient.AzureSettings.Chaos.SchedulerFrequency,
                                                                                   azureClient.AzureSettings.Chaos.AzureFaultInjectionActions,
                                                                                   VirtualMachineGroup.VirtualMachines);
                    if (batchOperation == null)
                    {
                        continue;
                    }

                    tasks.Add(table.ExecuteBatchAsync(batchOperation));
                }
                // } while (vmSets.Any());

                Task.WhenAll(tasks);
                log.Info("VirtualMachine RuleEngine: Completed creating rule engine..");
            }
            catch (Exception ex)
            {
                log.Error("VirtualMachine RuleEngine: Exception thrown. ", ex);
            }
        }
Beispiel #8
0
        private static TableBatchOperation InsertLoadBalancerVirtualMachines(List <string> virtualMachineIds, ILoadBalancer eachLoadBalancer, AzureClient azureClient, TraceWriter log)
        {
            if (virtualMachineIds == null)
            {
                return(null);
            }

            var virtualMachineBatchOperation = new TableBatchOperation();

            foreach (var eachvirtualMachineId in virtualMachineIds)
            {
                var virtualMachine = azureClient.AzureInstance.VirtualMachines.GetById(eachvirtualMachineId);
                var partitionKey   = eachLoadBalancer.Id.Replace(Delimeters.ForwardSlash, Delimeters.Exclamatory);
                virtualMachineBatchOperation.InsertOrReplace(VirtualMachineHelper.ConvertToVirtualMachineEntityFromLB(virtualMachine,
                                                                                                                      partitionKey, VirtualMachineGroup.LoadBalancer.ToString()));
            }

            return(virtualMachineBatchOperation);
        }
        /// <summary>Insert the list of the scale set virtual machine instances into the table.</summary>
        /// <param name="virtualMachines">List of the virtual machines.</param>
        /// <param name="resourceGroupName">Resource group name of the scale set</param>
        /// <param name="scaleSetId">Id of the scale set</param>
        /// <param name="availabilityZone">Availability zone id of the scale set</param>
        /// <returns></returns>
        private static TableBatchOperation GetVirtualMachineBatchOperation(IEnumerable <IVirtualMachineScaleSetVM> virtualMachines,
                                                                           string resourceGroupName, string scaleSetId,
                                                                           int?availabilityZone)
        {
            if (virtualMachines == null)
            {
                return(null);
            }

            var virtualMachineBatchOperation = new TableBatchOperation();

            foreach (var eachVirtualMachine in virtualMachines)
            {
                // Azure table doesnot allow partition key  with forward slash
                var partitionKey = scaleSetId.Replace(Delimeters.ForwardSlash, Delimeters.Exclamatory);
                virtualMachineBatchOperation.InsertOrReplace(VirtualMachineHelper.ConvertToVirtualMachineEntity(eachVirtualMachine,
                                                                                                                resourceGroupName, scaleSetId, partitionKey,
                                                                                                                availabilityZone, VirtualMachineGroup.VirtualMachineScaleSets.ToString()));
            }

            return(virtualMachineBatchOperation);
        }
        /// <summary>1. Get the List of virtual machines for the resource group.
        /// 2. Get all the virtual machines from the load balancers.</summary>
        /// <param name="resourceGroup">From which resource group needs to get the virtual machines.</param>
        /// <param name="log">Trace writer instance</param>
        /// <returns>List of virtual machines which excludes the load balancer virtual machines and availability set virtual machines.</returns>
        private static async Task <IEnumerable <IVirtualMachine> > GetVirtualMachinesByResourceGroup(
            IResourceGroup resourceGroup, TraceWriter log)
        {
            try
            {
                var azureClient = new AzureClient();
                var loadBalancersVirtualMachines = VirtualMachineHelper.GetVirtualMachinesFromLoadBalancers(resourceGroup.Name, azureClient);
                var pagedCollection =
                    azureClient.AzureInstance.VirtualMachines.ListByResourceGroupAsync(resourceGroup.Name);
                var tasks = new List <Task>
                {
                    loadBalancersVirtualMachines,
                    pagedCollection
                };

                await Task.WhenAll(tasks);

                if (pagedCollection.Result == null || !pagedCollection.Result.Any())
                {
                    log.Info(
                        $"timercrawlerforvirtualmachines: no virtual machines for the resource group: {resourceGroup.Name}");
                    return(null);
                }

                var loadBalancerIds  = loadBalancersVirtualMachines.Result;
                var virtuallMachines = pagedCollection.Result;
                return(virtuallMachines?.Select(x => x).Where(x => string.IsNullOrWhiteSpace(x.AvailabilitySetId) &&
                                                              !loadBalancerIds.Contains(x.Id,
                                                                                        StringComparer.OrdinalIgnoreCase)));
            }
            catch (Exception e)
            {
                log.Error("Error occured on GetVirtualMachinesByResourceGroup", e);
                return(null);
            }
        }
Beispiel #11
0
        private void InsertVirtualMachineAvailabilityZoneRegionResults(string region, int availbilityZone, TraceWriter log)
        {
            try
            {
                var virtualMachineQuery = TableQuery.CombineFilters(TableQuery.GenerateFilterConditionForInt(
                                                                        "AvailabilityZone",
                                                                        QueryComparisons.Equal,
                                                                        availbilityZone),
                                                                    TableOperators.And,
                                                                    TableQuery.GenerateFilterCondition("RegionName",
                                                                                                       QueryComparisons.Equal,
                                                                                                       region));

                //TableQuery.GenerateFilterConditionForInt("AvailabilityZone", QueryComparisons.GreaterThanOrEqual, 0);
                var virtualMachinesTableQuery     = new TableQuery <VirtualMachineCrawlerResponse>().Where(virtualMachineQuery);
                var crawledVirtualMachinesResults = StorageAccountProvider.GetEntities(
                    virtualMachinesTableQuery,
                    StorageTableNames.VirtualMachineCrawlerTableName);
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                crawledVirtualMachinesResults = crawledVirtualMachinesResults.Where(x => PowerState.Parse(x.State) == PowerState.Running);
                var virtualMachinesResults = crawledVirtualMachinesResults.ToList();
                var meanTimeQuery          = TableQuery.GenerateFilterConditionForDate("ScheduledExecutionTime",
                                                                                       QueryComparisons.GreaterThanOrEqual,
                                                                                       DateTimeOffset.UtcNow.AddMinutes(-azureClient.AzureSettings.Chaos.MeanTime));

                var recentlyExecutedAvailabilityZoneRegionCombinationQuery = TableQuery.GenerateFilterCondition(
                    "ResourceType",
                    QueryComparisons.Equal,
                    VirtualMachineGroup.VirtualMachineScaleSets.ToString());

                var recentlyExecutedVMScaleSetsQuery = TableQuery.CombineFilters(meanTimeQuery,
                                                                                 TableOperators.And,
                                                                                 recentlyExecutedAvailabilityZoneRegionCombinationQuery);

                var scheduledQuery = new TableQuery <ScheduledRules>().Where(recentlyExecutedVMScaleSetsQuery);
                //Will get the executed query results.
                var executedVMScaleSetsResults = StorageAccountProvider.GetEntities(scheduledQuery,
                                                                                    StorageTableNames.ScheduledRulesTableName);

                List <VirtualMachineCrawlerResponse> executedVMAvailabilityZones = null;

                if (virtualMachinesResults.Count() != 0 && executedVMScaleSetsResults.Count() != 0)
                {
                    foreach (var virtualMachineResult in virtualMachinesResults)
                    {
                        foreach (var executedVMScaleSetsResult in executedVMScaleSetsResults)
                        {
                            if ((executedVMScaleSetsResult.RowKey.ToLowerInvariant().Contains(virtualMachineResult.ResourceName.ToLowerInvariant())) &&
                                (executedVMScaleSetsResult.RowKey.ToLowerInvariant().Contains(virtualMachineResult.ResourceGroupName.ToLowerInvariant())) &&
                                (executedVMScaleSetsResult.RowKey.ToLowerInvariant().Contains(virtualMachineResult.AvailabilityZone.ToString()))
                                //&& (executedVMScaleSetsResult.RowKey.ToLowerInvariant().Contains(executedVMScaleSetsResult..ToLowerInvariant()))
                                )
                            {
                                executedVMAvailabilityZones.Add(virtualMachineResult);
                            }
                        }
                    }
                    if (executedVMAvailabilityZones != null && executedVMAvailabilityZones.Count() != 0)
                    {
                        virtualMachinesResults = virtualMachinesResults.Except(executedVMAvailabilityZones).ToList();
                    }
                }
                if (!virtualMachinesResults.Any())
                {
                    return;
                }
                var batchTasks = new List <Task>();
                var table      = StorageAccountProvider.CreateOrGetTable(StorageTableNames.ScheduledRulesTableName);
                if (table == null)
                {
                    return;
                }

                for (var i = 0; i < virtualMachinesResults.Count; i += TableConstants.TableServiceBatchMaximumOperations)
                {
                    var batchItems = virtualMachinesResults.Skip(i)
                                     .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                    var scheduledRulesbatchOperation = VirtualMachineHelper
                                                       .CreateScheduleEntityForAvailabilityZone(
                        batchItems,
                        azureClient.AzureSettings.Chaos.SchedulerFrequency,
                        azureClient.AzureSettings.Chaos.AzureFaultInjectionActions);

                    if (scheduledRulesbatchOperation.Count <= 0)
                    {
                        return;
                    }
                    batchTasks.Add(table.ExecuteBatchAsync(scheduledRulesbatchOperation));
                }

                if (batchTasks.Count > 0)
                {
                    Task.WhenAll(batchTasks);
                }
            }
            catch (Exception ex)
            {
                log.Error("AvailabilityZone RuleEngine: thrown exception", ex);
                log.Error(ex.Source);
                log.Error(ex.Message);
            }
        }
Beispiel #12
0
        private async Task ProcessAllVirtualMachinesActionAsync(IDialogContext context, LuisResult result,
                                                                Operations operation, ResumeAfter <AllVirtualMachinesFormState> resume)
        {
            EntityRecommendation resourceGroupEntity;

            var accessToken = await context.GetAccessToken(resourceId.Value);

            if (string.IsNullOrEmpty(accessToken))
            {
                return;
            }

            var subscriptionId = context.GetSubscriptionId();
            var availableVMs   = (await new VMDomain().ListVirtualMachinesAsync(accessToken, subscriptionId)).ToList();

            // retrieve the list of VMs that are in the correct power state
            var validPowerStates = VirtualMachineHelper.RetrieveValidPowerStateByOperation(operation);
            IEnumerable <VirtualMachine> candidateVMs = null;

            if (result.TryFindEntity("ResourceGroup", out resourceGroupEntity))
            {
                // obtain the name specified by the user - text in LUIS result is different
                var resourceGroup = resourceGroupEntity.GetEntityOriginalText(result.Query);

                candidateVMs = availableVMs.Where(vm => vm.ResourceGroup.Equals(resourceGroup, StringComparison.InvariantCultureIgnoreCase)).ToList();

                if (candidateVMs == null || !candidateVMs.Any())
                {
                    var operationText = VirtualMachineHelper.RetrieveOperationTextByOperation(operation);
                    await context.PostAsync($"The {resourceGroup} resource group doesn't contain VMs or doesn't exist in the current subscription.");

                    context.Done <string>(null);
                    return;
                }

                candidateVMs = candidateVMs.Where(vm => validPowerStates.Contains(vm.PowerState)).ToList();

                if (candidateVMs == null || !candidateVMs.Any())
                {
                    var operationText = VirtualMachineHelper.RetrieveOperationTextByOperation(operation);
                    await context.PostAsync($"No virtual machines that can be {operationText} were found in the {resourceGroup} resource group of the current subscription.");

                    context.Done <string>(null);
                    return;
                }
            }
            else
            {
                candidateVMs = availableVMs.Where(vm => validPowerStates.Contains(vm.PowerState)).ToList();

                if (!candidateVMs.Any())
                {
                    var operationText = VirtualMachineHelper.RetrieveOperationTextByOperation(operation);
                    await context.PostAsync($"No virtual machines that can be {operationText} were found in the current subscription.");

                    context.Done <string>(null);
                    return;
                }
            }

            // prompt the user to select a VM from the list
            var form = new FormDialog <AllVirtualMachinesFormState>(
                new AllVirtualMachinesFormState(candidateVMs, operation),
                VMForms.BuildAllVirtualMachinesForm,
                FormOptions.PromptInStart,
                null);

            context.Call(form, resume);
        }
Beispiel #13
0
        private async Task ProcessVirtualMachineActionAsync(IDialogContext context, LuisResult result,
                                                            Operations operation, ResumeAfter <VirtualMachineFormState> resume)
        {
            EntityRecommendation virtualMachineEntity;

            // retrieve the list virtual machines from the subscription
            var accessToken = await context.GetAccessToken(resourceId.Value);

            if (string.IsNullOrEmpty(accessToken))
            {
                return;
            }

            var subscriptionId = context.GetSubscriptionId();
            var availableVMs   = (await new VMDomain().ListVirtualMachinesAsync(accessToken, subscriptionId)).ToList();

            // check if the user specified a virtual machine name in the command
            if (result.TryFindEntity("VirtualMachine", out virtualMachineEntity))
            {
                // obtain the name specified by the user - text in LUIS result is different
                var virtualMachineName = virtualMachineEntity.GetEntityOriginalText(result.Query);

                // ensure that the virtual machine exists in the subscription
                var selectedVM = availableVMs.FirstOrDefault(p => p.Name.Equals(virtualMachineName, StringComparison.InvariantCultureIgnoreCase));
                if (selectedVM == null)
                {
                    await context.PostAsync($"The '{virtualMachineName}' virtual machine was not found in the current subscription.");

                    context.Done <string>(null);
                    return;
                }

                // ensure that the virtual machine is in the correct power state for the requested operation
                if ((operation == Operations.Start && (selectedVM.PowerState == VirtualMachinePowerState.Starting || selectedVM.PowerState == VirtualMachinePowerState.Running)) ||
                    (operation == Operations.Shutdown && (selectedVM.PowerState == VirtualMachinePowerState.Stopping || selectedVM.PowerState == VirtualMachinePowerState.Stopped)) ||
                    (operation == Operations.Stop && (selectedVM.PowerState == VirtualMachinePowerState.Deallocating || selectedVM.PowerState == VirtualMachinePowerState.Deallocated)))
                {
                    var powerState = selectedVM.PowerState.ToString().ToLower();
                    await context.PostAsync($"The '{virtualMachineName}' virtual machine is already {powerState}.");

                    context.Done <string>(null);
                    return;
                }

                virtualMachineEntity.Entity = selectedVM.Name;
            }

            // retrieve the list of VMs that are in the correct power state
            var validPowerStates = VirtualMachineHelper.RetrieveValidPowerStateByOperation(operation);

            var candidateVMs = availableVMs.Where(vm => validPowerStates.Contains(vm.PowerState)).ToList();

            if (candidateVMs.Any())
            {
                // prompt the user to select a VM from the list
                var form = new FormDialog <VirtualMachineFormState>(
                    new VirtualMachineFormState(candidateVMs, operation),
                    VMForms.BuildVirtualMachinesForm,
                    FormOptions.PromptInStart,
                    result.Entities);

                context.Call(form, resume);
            }
            else
            {
                var operationText = VirtualMachineHelper.RetrieveOperationTextByOperation(operation);
                await context.PostAsync($"No virtual machines that can be {operationText} were found in the current subscription.");

                context.Done <string>(null);
                //context.Wait(this.MessageReceived);
            }
        }