Exemplo n.º 1
0
        public CollectionCreator(String settingsFile)
#endif
        {
            try
            {
                csmManager = new CsmManager();

                if (String.IsNullOrEmpty(settingsFile))
                {
                    settingsFile = CCUtils.GetSettingsFilePath();
                }
                if (File.Exists(settingsFile))
                {
                    config = CCConfiguration.FromXml(settingsFile);
                }

                if (config == null)
                {
                    String errMsg = String.Format("{0}: [{1}], error code [{2}]", CCConstants.E0100, settingsFile ?? String.Empty, (int)CCEnums.CCErrorCodes.E0100);
                    throw new Exception(errMsg);
                }
            }
            catch (Exception ex)
            {
                ILog.LogError(ex);
                throw (ex);
            }
        }
Exemplo n.º 2
0
        // ARM
        private async Task LoadAzureResources()
        {
            // Load all subscriptions
            var csmSubscriptions = await CsmManager.GetSubscriptionNamesToIdMap();

            var subscriptions = SimpleSettings.Subscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                //It can be either a displayName or a subscriptionId
                                .Select(s => s.Trim())
                                .Where(n =>
            {
                Guid temp;
                return(csmSubscriptions.ContainsKey(n) || Guid.TryParse(n, out temp));
            })
                                .Select(sn =>
            {
                Guid temp;
                if (Guid.TryParse(sn, out temp))
                {
                    return(sn);
                }
                else
                {
                    return(csmSubscriptions[sn]);
                }
            });

            HostingEnvironment.QueueBackgroundWorkItem(_ =>
            {
                foreach (var subscription in subscriptions)
                {
                    _backgroundQueueManager.LoadSubscription(subscription);
                }
            });
        }
        private void LoadMonitoringToolResources()
        {
            var subscription = CsmManager.LoadMonitoringToolsSubscription();

            HostingEnvironment.QueueBackgroundWorkItem(_ =>
            {
                _backgroundQueueManager.LoadMonitoringToolSubscription(subscription);
            });
        }
Exemplo n.º 4
0
 private void CreateResourceGroupOperation(string subscriptionId, string geoRegion)
 {
     AddOperation(new BackgroundOperation <ResourceGroup>
     {
         Description = $"Creating resourceGroup in {subscriptionId} in {geoRegion}",
         Type        = OperationType.ResourceGroupCreate,
         Task        = CsmManager.CreateResourceGroup(subscriptionId, geoRegion),
         RetryAction = () => CreateResourceGroupOperation(subscriptionId, geoRegion)
     });
 }
Exemplo n.º 5
0
 private void SubscriptionCleanup(Subscription subscription)
 {
     AddOperation(new BackgroundOperation <Subscription>
     {
         Description = $"Cleaning subscriptions",
         Type        = OperationType.SubscriptionCleanup,
         Task        = CsmManager.SubscriptionCleanup(subscription),
         RetryAction = () => SubscriptionCleanup(subscription)
     });
 }
        // ARM
        private async Task LoadAzureResources()
        {
            LoadMonitoringToolResources();
            var subscriptions = await CsmManager.GetSubscriptions();

            HostingEnvironment.QueueBackgroundWorkItem(_ =>
            {
                foreach (var subscription in subscriptions)
                {
                    _backgroundQueueManager.LoadSubscription(subscription);
                }
            });
        }
Exemplo n.º 7
0
        internal async Task CleanupSubscriptions()
        {
            try
            {
                _cleanupOperationsTriggered++;
                var subscriptions = await CsmManager.GetSubscriptions();

                var       totalDeletedRGs = 0;
                Stopwatch sw = new Stopwatch();
                sw.Start();
                foreach (var sub in subscriptions)
                {
                    var s = await new Subscription(sub).Load(false);
                    SimpleTrace.Diagnostics.Information($"Deleting resources in {s.Type} subscription {s.SubscriptionId}");

                    //Delete any leaking resourcegroups in subscription that cannot be loaded
                    var csmResourceGroups = await s.LoadResourceGroupsForSubscription();

                    var deleteLeakingRGs = csmResourceGroups.value
                                           .Where(p => !LoadedResourceGroups.Any(p2 => string.Equals(p.id, p2.CsmId, StringComparison.OrdinalIgnoreCase))).GroupBy(rg => rg.location)
                                           .Select(g => new { Region = g.Key, ResourceGroups = g.Select(r => r), Count = g.Count() })
                                           .Where(g => g.Count > s.ResourceGroupsPerGeoRegion)
                                           .Select(g => g.ResourceGroups.Where(rg => rg.tags != null && !rg.tags.ContainsKey("UserId")))
                                           .SelectMany(i => i);

                    totalDeletedRGs += (deleteLeakingRGs == null)? 0: deleteLeakingRGs.Count();
                    AppInsights.TelemetryClient.TrackMetric("deletedLeakingRGs", deleteLeakingRGs.Count());
                    Parallel.ForEach(deleteLeakingRGs, async resourceGroup =>
                    {
                        try
                        {
                            var georegion = CsmManager.RegionHashTable[resourceGroup.location].ToString();
                            SimpleTrace.Diagnostics.Information($"Deleting leaked {georegion} resource  {resourceGroup.name}");
                            await new ResourceGroup(s.SubscriptionId, resourceGroup.name, georegion).Delete(false);
                        }
                        catch (Exception ex)
                        {
                            SimpleTrace.Diagnostics.Error($"Leaking RG Delete Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                        }
                    });
                }
                AppInsights.TelemetryClient.TrackMetric("totalDeletedLeakingRGs", totalDeletedRGs);
                AppInsights.TelemetryClient.TrackMetric("leakingRGsCleanupTime", sw.Elapsed.TotalSeconds);

                //Delete any duplicate resourcegroups in same subscription loaded in the same region
                //or create any missing resourcegroups in a region
                IList <Tuple <string, MakeSubscriptionFreeTrialResult> > subscriptionStates = new List <Tuple <string, MakeSubscriptionFreeTrialResult> >();
                var deletedDuplicateRGs = 0;
                var createdMissingRGs   = 0;
                foreach (var subscription in subscriptions)
                {
                    var sub = new Subscription(subscription);
                    sub.ResourceGroups = LoadedResourceGroups.Where(r => r.SubscriptionId == sub.SubscriptionId);
                    var trialsubresult = sub.MakeTrialSubscription();
                    if (trialsubresult.ToCreateInRegions.Any() || trialsubresult.ToDelete.Any())
                    {
                        subscriptionStates.Add(new Tuple <string, MakeSubscriptionFreeTrialResult>(subscription, trialsubresult));
                    }
                }

                AppInsights.TelemetryClient.TrackMetric("subsWithIncorrectRGs", subscriptionStates.Count());

                foreach (var subscriptionState in subscriptionStates)
                {
                    foreach (var geoRegion in subscriptionState.Item2.ToCreateInRegions)
                    {
                        CreateResourceGroupOperation(subscriptionState.Item1, geoRegion);
                        createdMissingRGs++;
                    }
                    foreach (var resourceGroup in subscriptionState.Item2.ToDelete)
                    {
                        RemoveFromFreeQueue(resourceGroup);
                        DeleteResourceGroupOperation(resourceGroup);
                        deletedDuplicateRGs++;
                    }
                }
                AppInsights.TelemetryClient.TrackMetric("createdMissingRGs", createdMissingRGs);
                AppInsights.TelemetryClient.TrackMetric("deletedDuplicateRGs", deletedDuplicateRGs);
                AppInsights.TelemetryClient.TrackMetric("fullCleanupTime", sw.Elapsed.TotalSeconds);
                sw.Stop();
            }
            catch (Exception e)
            {
                SimpleTrace.Diagnostics.Fatal(e, "CleanupSubscriptions error, Count {Count}", Interlocked.Increment(ref _maintainResourceGroupListErrorCount));
            }
        }
Exemplo n.º 8
0
        public static async Task MainAsync()
        {
            var subscriptionNames = System.Environment.GetEnvironmentVariable("Subscriptions").Split(',');
            var csmSubscriptions  = await CsmManager.GetSubscriptionNamesToIdMap();

            var subscriptionsIds = SimpleSettings.Subscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   //It can be either a displayName or a subscriptionId
                                   .Select(s => s.Trim())
                                   .Where(n =>
            {
                Guid temp;
                return(csmSubscriptions.ContainsKey(n) || Guid.TryParse(n, out temp));
            })
                                   .Select(sn =>
            {
                Guid temp;
                if (Guid.TryParse(sn, out temp))
                {
                    return(sn);
                }
                else
                {
                    return(csmSubscriptions[sn]);
                }
            });
            //var subscriptionNames = new[] { "bd5cf6af-4d44-449e-adaf-20626ae5013e" };
            var startTime = DateTime.UtcNow;

            Action <object>       console  = (s) => System.Console.WriteLine("[" + (DateTime.UtcNow - startTime).TotalMilliseconds + "] " + s);
            Action <Subscription> printSub = (sub) => sub.ResourceGroups.ToList().ForEach(e =>
                                                                                          console(string.Format("RG: {0} has {1} sites, named: {2}",
                                                                                                                e.ResourceGroupName,
                                                                                                                e.Sites.Count(),
                                                                                                                e.Sites.Count() > 0
                ? e.Sites.Select(s => s.SiteName).Aggregate((a, b) => string.Join(",", a, b))
                : "No sites")
                                                                                                  ));


            console("start loading subscriptions");
            console("We have " + subscriptionsIds.Count() + " subscriptions");
            var subscriptions = await subscriptionsIds.Select(s => new Subscription(s).Load()).WhenAll();

            console("done loading subscriptions");

            console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");

            //foreach (var resourcegroup in subscriptions.SelectMany(subscription => subscription.ResourceGroups))
            //        {
            //            try
            //            {
            //                if (!resourcegroup.IsSimpleWAWS)
            //                {
            //                    console($" Replacing Resource Group : {resourcegroup.CsmId}");
            //                    await resourcegroup.DeleteAndCreateReplacement(true);
            //                    console($" Replaced");
            //                }
            //            }
            //            catch (Exception ex)
            //            {
            //                console(ex.ToString());
            //            }

            //}

            console("calling MakeTrialSubscription on all subscriptions");
            await subscriptions.Select(async s =>
            {
                var result = s.MakeTrialSubscription();
                foreach (var resourceGroup in result.Ready)
                {
                    try
                    {
                        await resourceGroup.PutInDesiredState();
                    }
                    catch (Exception ex)
                    {
                        console(
                            $"RG PIDS Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                    }
                }
                foreach (var geoRegion in result.ToCreateInRegions)
                {
                    try
                    {
                        await CsmManager.CreateResourceGroup(s.SubscriptionId, geoRegion).Result.PutInDesiredState();
                    }
                    catch (Exception ex)
                    {
                        console($"GR Create Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                    }
                }
                foreach (var resourceGroup in result.ToDelete)
                {
                    try { await resourceGroup.Delete(true); }
                    catch (Exception ex)
                    {
                        console($"RG Delete Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                    }
                }
            }).WhenAll();

            console("done calling make trial subscription");

            ////console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");
            ////console(subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()));
            ////console("make free trial");
            //////Parallel.ForEach(
            //////    subscriptions.SelectMany(subscription => subscription.ResourceGroups), async (resourcegroup) =>
            //////    {
            //////        console($"Deleting resourcegroup:{resourcegroup.ResourceGroupName} from \tsubscription:{resourcegroup.SubscriptionId}");
            //////        await resourcegroup.Delete(true);
            //////    });

            console("Re-start loading subscriptions");
            console("We have " + subscriptionsIds.Count() + " subscriptions");
            subscriptions = await subscriptionsIds.Select(s => new Subscription(s).Load()).WhenAll();

            console("done loading subscriptions");

            //Parallel.ForEach(
            //    subscriptions.SelectMany(subscription => subscription.ResourceGroups), async (resourcegroup) =>
            //    {
            ////foreach (var resourcegroup in subscriptions.SelectMany(subscription => subscription.ResourceGroups))
            ////{
            ////    try
            ////    {
            ////        console($" Replacing Resource Group : {resourcegroup.CsmId}");
            ////        await resourcegroup.Delete(true);//DeleteAndCreateReplacement(true);
            ////        console($" Replaced");
            ////    }
            ////    catch (Exception ex)
            ////    {
            ////        console(ex.ToString());
            ////    }

            ////}

            //}
            //);
            //subscriptions.ToList().ForEach(printSub);
            console("Done");
        }
Exemplo n.º 9
0
        public static async Task FixFunctionsSetting()
        {
            var             startTime = DateTime.UtcNow;
            Action <object> console   = (s) => System.Console.WriteLine("[" + (DateTime.UtcNow - startTime).TotalMilliseconds + "] " + s);

            console("start");
            var csmSubscriptions = await CsmManager.GetSubscriptionNamesToIdMap();

            var subscriptionsIds = SimpleSettings.Subscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   //It can be either a displayName or a subscriptionId
                                   .Select(s => s.Trim())
                                   .Where(n =>
            {
                Guid temp;
                return(csmSubscriptions.ContainsKey(n) || Guid.TryParse(n, out temp));
            })
                                   .Select(sn =>
            {
                Guid temp;
                if (Guid.TryParse(sn, out temp))
                {
                    return(sn);
                }
                else
                {
                    return(csmSubscriptions[sn]);
                }
            });


            console("start loading subscriptions");
            console("We have " + subscriptionsIds.Count() + " subscriptions");
            var subscriptions = await subscriptionsIds.Select(s => new Subscription(s).Load()).WhenAll();

            console("done loading subscriptions");

            console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");

            foreach (var resourcegroup in subscriptions.SelectMany(subscription => subscription.ResourceGroups))
            {
                try
                {
                    console($" Updating Resource Group : {resourcegroup.CsmId}");
                    await resourcegroup.Load();

                    var site = resourcegroup.Sites.First(s => s.IsSimpleWAWSOriginalSite);

                    if (site != null && site.AppSettings.ContainsKey("FUNCTIONS_EXTENSION_VERSION"))
                    {
                        site.AppSettings.Remove("FUNCTIONS_EXTENSION_VERSION");
                    }
                    await site.UpdateAppSettings();

                    site = resourcegroup.Sites.First(s => !s.IsSimpleWAWSOriginalSite);
                    if (site != null && site.AppSettings.ContainsKey("FUNCTIONS_EXTENSION_VERSION") &&
                        !string.Equals(site.AppSettings["FUNCTIONS_EXTENSION_VERSION"], SimpleSettings.FunctionsExtensionVersion))
                    {
                        site.AppSettings["FUNCTIONS_EXTENSION_VERSION"] = SimpleSettings.FunctionsExtensionVersion;
                    }
                    await site.UpdateAppSettings();

                    console($" Updated");
                }
                catch (Exception ex)
                {
                    console(ex.ToString());
                }
            }
        }
Exemplo n.º 10
0
        public static async Task MainAsync()
        {
            var subscriptionNames = System.Environment.GetEnvironmentVariable("Subscriptions").Split(',');
            var csmSubscriptions  = await CsmManager.GetSubscriptionNamesToIdMap();

            var subscriptionsIds = SimpleSettings.Subscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   //It can be either a displayName or a subscriptionId
                                   .Select(s => s.Trim())
                                   .Where(n =>
            {
                Guid temp;
                return(csmSubscriptions.ContainsKey(n) || Guid.TryParse(n, out temp));
            })
                                   .Select(sn =>
            {
                Guid temp;
                if (Guid.TryParse(sn, out temp))
                {
                    return(sn);
                }
                else
                {
                    return(csmSubscriptions[sn]);
                }
            });
            //var subscriptionNames = new[] { "bd5cf6af-4d44-449e-adaf-20626ae5013e" };
            var startTime = DateTime.UtcNow;

            Action <object>       console  = (s) => System.Console.WriteLine("[" + (DateTime.UtcNow - startTime).TotalMilliseconds + "] " + s);
            Action <Subscription> printSub = (sub) => sub.ResourceGroups.ToList().ForEach(e =>
                                                                                          console(string.Format("RG: {0} has {1} sites, named: {2}",
                                                                                                                e.ResourceGroupName,
                                                                                                                e.Sites.Count(),
                                                                                                                e.Sites.Count() > 0
                ? e.Sites.Select(s => s.SiteName).Aggregate((a, b) => string.Join(",", a, b))
                : "No sites")
                                                                                                  ));


            console("start loading subscriptions");
            console("We have " + subscriptionsIds.Count() + " subscriptions");
            var subscriptions = await subscriptionsIds.Select(s => new Subscription(s).Load()).WhenAll();

            console("done loading subscriptions");

            console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");

            console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Where(r => !r.Tags.ContainsKey("CommonApiAppsDeployed")).Count()) + " bad resourceGroups");

            //console("calling MakeTrialSubscription on all subscriptions");
            //subscriptions = await subscriptions.Select(s => s.MakeTrialSubscription()).WhenAll();
            //console("done calling make trial subscription");

            console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");
            console(subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()));
            console("make free trial");
            foreach (var subscription in subscriptions)
            {
                var freeTrial = subscription.MakeTrialSubscription();
                console(subscription.SubscriptionId + "\thas\t" + freeTrial.Ready.Count() + "\twill delete\t" + freeTrial.ToDelete.Count() + "\tcreate\t" + freeTrial.ToCreateInRegions.Count());
            }
            //await Task.WhenAll(subscriptions.Select(subscription => subscription.ResourceGroups.Where(r => !r.Tags.ContainsKey("CommonApiAppsDeployed")).Select(rg => rg.Delete(false))).SelectMany(i => i));

            //subscriptions.ToList().ForEach(printSub);
            console("Done");
        }
        internal async Task CleanupSubscriptions()
        {
            try
            {
                _cleanupOperationsTriggered++;
                var subscriptions = await CsmManager.GetSubscriptions();

                Stopwatch sw = new Stopwatch();
                sw.Start();

                //Delete any duplicate resourcegroups in same subscription loaded in the same region
                //or create any missing resourcegroups in a region
                List <ResourceGroup> toDelete = new List <ResourceGroup>();
                List <ResourceGroup> ready    = new List <ResourceGroup>();

                var deletedDuplicateRGs     = 0;
                var createdMissingRGs       = 0;
                var createdMissingTemplates = 0;
                foreach (var subscription in subscriptions)
                {
                    var sub = new Subscription(subscription);
                    await sub.Load();

                    //sub.ResourceGroups = (await LoadedResourceGroups()).Where(r => r.SubscriptionId == sub.SubscriptionId);
                    var trialsubresult = sub.GetSubscriptionStats();
                    toDelete.AddRange(trialsubresult.ToDelete);
                    ready.AddRange(trialsubresult.Ready);
                }

                var rand = new Random();
                foreach (var resourceGroup in toDelete)
                {
                    //RemoveFromFreeResourcesQueue(resourceGroup);
                    DeleteResourceGroupOperation(resourceGroup);
                    deletedDuplicateRGs++;
                }
                foreach (var template in TemplatesManager.GetTemplates().Where(a => a.QueueSizeToMaintain > 0))
                {
                    var deployedTemplates = ready.Count(a => a.DeployedTemplateName == template.Name);
                    var delta             = template.QueueSizeToMaintain - deployedTemplates;
                    SimpleTrace.TraceInformation($"Template {template.Name} has {deployedTemplates} RGs deployed and requires {template.QueueSizeToMaintain}");

                    for (int i = 1; i <= delta; i++)
                    {
                        SimpleTrace.TraceInformation($"Template {template.Name} creating {i} of {delta}");
                        CreateResourceGroupOperation(template.Config.Subscriptions.OrderBy(a => Guid.NewGuid()).First(), template.Config.Regions.OrderBy(a => Guid.NewGuid()).First(), template.Name);
                        createdMissingTemplates++;
                    }
                    for (int i = 1; i <= -delta; i++)
                    {
                        var resourceGroup = await StorageHelper.GetQueueMessage(template.QueueName);

                        if (resourceGroup != null)
                        {
                            SimpleTrace.TraceInformation($"Template {template.Name} deleting {i} of {-delta}->{resourceGroup.CsmId}");
                            //RemoveFromFreeResourcesQueue(resourceGroup);
                            DeleteResourceGroupOperation(resourceGroup);
                        }
                    }
                }
                AppInsights.TelemetryClient.TrackMetric("createdMissingTemplates", createdMissingTemplates);
                AppInsights.TelemetryClient.TrackMetric("createdMissingRGs", createdMissingRGs);
                AppInsights.TelemetryClient.TrackMetric("deletedDuplicateRGs", deletedDuplicateRGs);
                AppInsights.TelemetryClient.TrackMetric("fullCleanupTime", sw.Elapsed.TotalSeconds);
                sw.Stop();
            }
            catch (Exception e)
            {
                SimpleTrace.Diagnostics.Fatal(e, "CleanupSubscriptions error, Count {Count}", Interlocked.Increment(ref _maintainResourceGroupListErrorCount));
            }
        }
Exemplo n.º 12
0
        public static async Task MainAsync()
        {
            foreach (var a in SimpleSettings.GeoRegions.Split(','))
            {
                georegionHashMap.Add(a.ToLowerInvariant().Replace(" ", ""), a);
            }

            //var subscriptionNames = System.Environment.GetEnvironmentVariable("Subscriptions").Split(',');
            var csmSubscriptions = await CsmManager.GetSubscriptionNamesToIdMap();

            var subscriptionsIds = SimpleSettings.Subscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   //.Union(SimpleSettings.LinuxSubscriptions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                                   //.Union(SimpleSettings.MonitoringToolsSubscription.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                                   //It can be either a displayName or a subscriptionId
                                   .Select(s => s.Trim())
                                   .Where(n =>
            {
                Guid temp;
                return(csmSubscriptions.ContainsKey(n) || Guid.TryParse(n, out temp));
            })
                                   .Select(sn =>
            {
                Guid temp;
                if (Guid.TryParse(sn, out temp))
                {
                    return(sn);
                }
                else
                {
                    return(csmSubscriptions[sn]);
                }
            }).OrderByDescending(s => s);
            //var subscriptionNames = new[] { "bd5cf6af-4d44-449e-adaf-20626ae5013e" };
            var startTime = DateTime.UtcNow;

            Action <object>       console  = (s) => System.Console.WriteLine("[" + (DateTime.UtcNow - startTime).TotalMilliseconds + "] " + s);
            Action <Subscription> printSub = (sub) => sub.ResourceGroups.ToList().ForEach(e =>
                                                                                          console(string.Format("RG: {0} has {1} sites, named: {2}",
                                                                                                                e.ResourceGroupName,
                                                                                                                e.Sites.Count(),
                                                                                                                e.Sites.Count() > 0
                ? e.Sites.Select(s => s.SiteName).Aggregate((a, b) => string.Join(",", a, b))
                : "No sites")
                                                                                                  ));


            console("start loading subscriptions");
            console("We have " + subscriptionsIds.Count() + " subscriptions");
            //var subscriptions = await subscriptionsIds.Select(s => new Subscription(s).Load(false)).WhenAll();
            //console("done loading subscriptions");

            //console("subscriptions have: " + subscriptions.Aggregate(0, (count, sub) => count += sub.ResourceGroups.Count()) + " resourceGroups");

            //var resources = await CsmManager.GetLoadedResources();
            console("calling MakeTrialSubscription on all subscriptions");
            foreach (var sub in subscriptionsIds)
            {
                var s = await new Subscription(sub).Load(false);
                console($"Deleting resources in {s.Type} subscription {s.SubscriptionId}");

                var csmResourceGroups = await s.LoadResourceGroupsForSubscription();

                //var deleteExtras = csmResourceGroups.value
                //    .GroupBy(rg => rg.location)
                //    .Select(g => new { Region = g.Key, ResourceGroups = g.Select(r => r), Count = g.Count() })
                //    .Where(g => g.Count > s.ResourceGroupsPerGeoRegion)
                //    .Select(g => g.ResourceGroups.Where(rg => rg.tags!=null && !rg.tags.ContainsKey("UserId") ).Skip((s.ResourceGroupsPerGeoRegion)))
                //    .SelectMany(i => i);

                Parallel.ForEach(csmResourceGroups.value, async(resourceGroup) =>
                {
                    try
                    {
                        var georegion = getGeoRegionfromLocation(resourceGroup.location);
                        console($"Deleting leaked {georegion} resource  {resourceGroup.name}");
                        await new ResourceGroup(s.SubscriptionId, resourceGroup.name, georegion).Delete(false);
                    }
                    catch (Exception ex)
                    {
                        console($"Extra RG Delete Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                    }
                });
                //var result = s.MakeTrialSubscription();

                //Parallel.ForEach(result.ToDelete, async (resourceGroup) =>
                //{
                //    try
                //    {
                //        console($"Deleting {resourceGroup.ResourceGroupName} resource in {s.Type} subscription {s.SubscriptionId}");
                //        await resourceGroup.Delete(false);
                //    }
                //    catch (Exception ex)
                //    {
                //        console($"RG Delete Exception:{ex.ToString()}-{ex.StackTrace}-{ex.InnerException?.StackTrace.ToString() ?? String.Empty}");
                //    }
                //});
            }
            //subscriptions.ToList().ForEach(printSub);
            console("Done");
        }