예제 #1
0
        /// <summary>Include the virtual machine batch operation into existing batch opeation</summary>
        /// <param name="virtualMachineConcurrentBag"></param>
        /// <param name="batchTasks"></param>
        /// <param name="log"></param>
        private static void IncludeVirtualMachineTask(ConcurrentBag <IEnumerable <IGrouping <string, IVirtualMachine> > > virtualMachineConcurrentBag,
                                                      ConcurrentBag <Task> batchTasks, TraceWriter log)
        {
            var groupsByVirtulaMachine   = virtualMachineConcurrentBag.SelectMany(x => x);
            var virtualmachineCloudTable = StorageAccountProvider.CreateOrGetTable(StorageTableNames.VirtualMachineCrawlerTableName);

            if (virtualmachineCloudTable == null)
            {
                return;
            }

            Parallel.ForEach(groupsByVirtulaMachine, groupItem =>
            {
                // table batch operation currently allows only 100 per batch, So ensuring the one batch operation will have only 100 items
                for (var i = 0; i < groupItem.Count(); i += TableConstants.TableServiceBatchMaximumOperations)
                {
                    var batchItems = groupItem.Skip(i)
                                     .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                    var virtualMachineBatchOperation = GetVirtualMachineBatchOperation(batchItems, groupItem.Key, log);
                    if (virtualMachineBatchOperation != null && virtualMachineBatchOperation.Count > 0 && virtualmachineCloudTable != null)
                    {
                        batchTasks.Add(virtualmachineCloudTable.ExecuteBatchAsync(virtualMachineBatchOperation));
                    }
                }
            });
        }
        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 availability sets by resource group.
        /// And get the virtual machine by resource group and the availability sets.
        /// And get the batch operation for the availability sets</summary>
        /// <param name="resourceGroupList"></param>
        /// <param name="virtualMachinesConcurrent"></param>
        /// <param name="batchTasks"></param>
        /// <param name="azureClient"></param>
        /// <param name="log"></param>
        private static void SetTheVirtualMachinesAndAvailabilitySetBatchTask(IEnumerable <IResourceGroup> resourceGroupList,
                                                                             ConcurrentBag <IEnumerable <IGrouping <string, IVirtualMachine> > > virtualMachinesConcurrent,
                                                                             ConcurrentBag <Task> batchTasks,
                                                                             AzureClient azureClient,
                                                                             TraceWriter log)
        {
            var availabilitySetCloudTable = StorageAccountProvider.CreateOrGetTable(StorageTableNames.AvailabilitySetCrawlerTableName);

            if (availabilitySetCloudTable == null)
            {
                return;
            }

            Parallel.ForEach(resourceGroupList, eachResourceGroup =>
            {
                try
                {
                    var availabilitySetIds = new List <string>();
                    var availabilitySetsByResourceGroup = azureClient.AzureInstance.AvailabilitySets.ListByResourceGroup(eachResourceGroup.Name);
                    // table batch operation currently allows only 100 per batch, So ensuring the one batch operation will have only 100 items
                    var setsByResourceGroup = availabilitySetsByResourceGroup.ToList();
                    for (var i = 0; i < setsByResourceGroup.Count; i += TableConstants.TableServiceBatchMaximumOperations)
                    {
                        var batchItems = setsByResourceGroup.Skip(i)
                                         .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                        // get the availability sets by resource group
                        // get the availability sets batch operation and get the list of availability set ids
                        var availabilitySetbatchOperation =
                            GetAvailabilitySetBatchOperation(batchItems, availabilitySetIds);

                        // add the batch operation into task list
                        if (availabilitySetbatchOperation.Count > 0 && availabilitySetCloudTable != null)
                        {
                            batchTasks.Add(availabilitySetCloudTable.ExecuteBatchAsync(availabilitySetbatchOperation));
                        }
                    }

                    // Get the virtual machines by resource group and by availability set ids
                    var virtualMachinesByAvailabilitySetId = GetVirtualMachineListByResourceGroup(eachResourceGroup.Name, availabilitySetIds, azureClient);
                    if (virtualMachinesByAvailabilitySetId != null && virtualMachinesByAvailabilitySetId.Count > 0)
                    {
                        virtualMachinesConcurrent.Add(virtualMachinesByAvailabilitySetId);
                    }
                }
                catch (Exception e)
                {
                    log.Error($"timercrawlerforavailableset threw the exception ", e,
                              "for resource group: " + eachResourceGroup.Name);
                }
            });
        }
        /// <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);
            }
        }
예제 #6
0
        /// <summary>1. Iterate the resource groups to get the scale sets for individual resource group.
        /// 2. Convert the List of scale sets into scale set entity and add them into the table batch operation.
        /// 3. Get the list of virtual machine instances, convert into entity and them into the table batach operation
        /// 3. Execute all the task parallely</summary>
        /// <param name="resourceGroups">List of resource groups for the particular subscription.</param>
        /// <param name="log">Trace writer instance</param>
        private static async Task GetLoadBalancersForResourceGroupsAsync(IEnumerable <IResourceGroup> resourceGroups,
                                                                         TraceWriter log)
        {
            try
            {
                var virtualMachineCloudTable = StorageAccountProvider.CreateOrGetTable(StorageTableNames.VirtualMachineCrawlerTableName);
                var loadBalancerTable        = StorageAccountProvider.CreateOrGetTable(StorageTableNames.LoadBalancerCrawlerTableName);
                if (virtualMachineCloudTable == null || loadBalancerTable == null)
                {
                    return;
                }

                var batchTasks  = new ConcurrentBag <Task>();
                var azureClient = new AzureClient();
                // using parallel here to run all the resource groups parallelly, parallel is 10times faster than normal foreach.
                foreach (var eachResourceGroup in resourceGroups)
                //Parallel.ForEach(resourceGroups, eachResourceGroup =>
                {
                    try
                    {
                        var loadBalancersList = azureClient.AzureInstance.LoadBalancers
                                                .ListByResourceGroup(eachResourceGroup.Name);
                        //var count = loadBalancersList.Count();
                        if (loadBalancersList.Count() > 0)
                        {
                            GetVirtualMachineAndLoadBalancerBatch(loadBalancersList.ToList(), batchTasks,
                                                                  virtualMachineCloudTable,
                                                                  loadBalancerTable, azureClient, log);
                        }
                    }
                    catch (Exception e)
                    {
                        //  catch the error, to continue adding other entities to table
                        log.Error($"timercrawlerforloadbalancer threw the exception ", e,
                                  "GetLoadBalancerForResourceGroups: for the resource group " + eachResourceGroup.Name);
                    }
                }
                //);

                // execute all batch operation as parallel
                await Task.WhenAll(batchTasks);
            }
            catch (Exception ex)
            {
                log.Error($"timercrawlerforloadbalancer threw the exception ", ex, "GetLoadBalancerForResourceGroups");
            }
        }
        /// <summary>1. Iterate the resource groups to get the virtual machines for individual resource group.
        /// 2. Convert the List of virtual machines into entities and add them into tasklist, repeat this process for the VM's under the resource group.
        /// 3. Execute all the task parallely</summary>
        /// <param name="resourceGroups">List of resource groups for the particular subscription.</param>
        /// <param name="log">Trace writer instance</param>
        private static async Task GetVirtualMachinesByResourceGroups(IEnumerable <IResourceGroup> resourceGroups,
                                                                     TraceWriter log)
        {
            try
            {
                var virtualMachineCloudTable = StorageAccountProvider.CreateOrGetTable(StorageTableNames.VirtualMachineCrawlerTableName);
                if (virtualMachineCloudTable == null)
                {
                    return;
                }

                var batchTasks = new ConcurrentBag <Task>();

                // using parallel here to run all the resource groups parallelly, parallel is 10times faster than normal foreach.
                Parallel.ForEach(resourceGroups, async eachResourceGroup =>
                {
                    var virtualMachinesByResourceGroup = await GetVirtualMachinesByResourceGroup(eachResourceGroup, log);
                    if (virtualMachinesByResourceGroup == null)
                    {
                        return;
                    }
                    var virtualMachineList = virtualMachinesByResourceGroup.ToList();

                    // table batch operation currently allows only 100 per batch, So ensuring the one batch operation will have only 100 items
                    for (var i = 0; i < virtualMachineList.Count(); i += TableConstants.TableServiceBatchMaximumOperations)
                    {
                        var batchItems = virtualMachineList.Skip(i)
                                         .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                        var batchOperation = InsertOrReplaceEntitiesIntoTable(batchItems,
                                                                              eachResourceGroup.Name, log);
                        if (batchOperation != null)
                        {
                            batchTasks.Add(virtualMachineCloudTable.ExecuteBatchAsync(batchOperation));
                        }
                    }
                });

                await Task.WhenAll(batchTasks);
            }
            catch (Exception e)
            {
                log.Error($"timercrawlerforvirtualmachines:threw exception", e, "GetVirtualMachinesForResourceGroups");
            }
        }
예제 #8
0
        private static async Task InsertOrReplaceResourceGroupsAsync(List <IResourceGroup> resourceGroups, TraceWriter log)
        {
            var tableBatchOperation = new TableBatchOperation();

            // table batch operation currently allows only 100 per batch, So ensuring the one batch operation will have only 100 items
            for (var i = 0; i < resourceGroups.Count; i += TableConstants.TableServiceBatchMaximumOperations)
            {
                var batchItems = resourceGroups.Skip(i)
                                 .Take(TableConstants.TableServiceBatchMaximumOperations).ToList();
                foreach (var eachResourceGroup in batchItems)
                {
                    var resourceGroupCrawlerResponseEntity =
                        new ResourceGroupCrawlerResponse("", eachResourceGroup.Name);
                    try
                    {
                        resourceGroupCrawlerResponseEntity.Id         = eachResourceGroup.Id;
                        resourceGroupCrawlerResponseEntity.RegionName = eachResourceGroup.RegionName;
                        tableBatchOperation.InsertOrReplace(resourceGroupCrawlerResponseEntity);
                    }
                    catch (Exception ex)
                    {
                        resourceGroupCrawlerResponseEntity.Error = ex.Message;
                        log.Error($"timercrawlerresourcegroups threw exception ", ex, "timercrawlerresourcegroups");
                    }
                }
            }

            if (tableBatchOperation.Count > 0)
            {
                try
                {
                    var table = StorageAccountProvider.CreateOrGetTable(StorageTableNames.ResourceGroupCrawlerTableName);
                    await table.ExecuteBatchAsync(tableBatchOperation);
                }
                catch (Exception ex)
                {
                    log.Error($"timercrawlerresourcegroups threw exception ", ex, "timercrawlerresourcegroups");
                }
            }
        }
예제 #9
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);
            }
        }