예제 #1
0
        public IWebApp GetOrCreateWebsite(string subscriptionId, string resourceGroupName, string appName, string regionName, string planName, bool allowAutomaticRename)
        {
            var resourceGroup = GetOrCreateResourceGroup(subscriptionId, resourceGroupName, regionName);

            var webApp = GetWebsite(subscriptionId, resourceGroupName, appName);

            if (webApp == null)
            {
                IAppServicePlan plan;
                if (string.IsNullOrEmpty(planName))
                {
                    planName = $"Catapult-Apps-{Guid.NewGuid()}";
                    _logger.LogInformation($"Creating new plan name {planName} in resource group {resourceGroupName}");
                    plan = ExecuteWithRetry(() => _authenticatedAzure.WithSubscription(subscriptionId).AppServices.AppServicePlans
                                            .Define(planName)
                                            .WithRegion(resourceGroup.Region)
                                            .WithExistingResourceGroup(resourceGroup)
                                            .WithFreePricingTier()
                                            .Create());
                }
                else
                {
                    plan = ExecuteWithRetry(() => _authenticatedAzure.WithSubscription(subscriptionId).AppServices.AppServicePlans.GetByResourceGroup(resourceGroupName, planName));
                }

                if (plan != null)
                {
                    webApp = CreateWebsite(subscriptionId, appName, resourceGroupName, plan, allowAutomaticRename);
                }
                else
                {
                    throw new ArgumentException($"Plan {planName} is not found in resource group {resourceGroupName}");
                }
            }

            return(webApp);
        }
예제 #2
0
 public void Init(ISubscription subscription)
 {
     _azure = _authenticated
              .WithSubscription(subscription.SubscriptionId);
 }
예제 #3
0
        private static async Task Run()
        {
            string subscriptionIds = ConfigurationManager.AppSettings["subscriptionIds"];
            string ownerTagName    = ConfigurationManager.AppSettings["ownerTagName"];
            string startDate       = DateTime.Now.ToUniversalTime().AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
            string endDate         = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ");


            string clientId     = ConfigurationManager.AppSettings["clientId"];
            string clientSecret = ConfigurationManager.AppSettings["clientSecret"];
            string tenantId     = ConfigurationManager.AppSettings["tenantId"];

            AzureCredentialsFactory factory    = new AzureCredentialsFactory();
            AzureCredentials        azureCreds = factory.FromServicePrincipal(clientId, clientSecret, tenantId,
                                                                              AzureEnvironment.AzureGlobalCloud);

            Azure.IAuthenticated azure = Azure.Configure().Authenticate(azureCreds);

            string body     = @"
{
    ""type"": ""Usage"",
    ""timeframe"": ""Custom"",
    ""timePeriod"": {
        ""from"": """ + startDate + @""",
        ""to"": """ + endDate + @""",
    },
    ""dataset"": {
        ""granularity"": ""Daily"",
        ""aggregation"": {
            ""totalCost"": {
                ""name"": ""PreTaxCost"",
                ""function"": ""Sum""
            }
        },
        ""grouping"": [
            {
            ""type"": ""Dimension"",
            ""name"": ""ResourceGroup""
            }
        ]
    }
}
";
            string currency = String.Empty;
            Dictionary <string, Double> costPerUser  = new Dictionary <string, Double>();
            Dictionary <string, Double> costPerGroup = new Dictionary <string, Double>();
            Dictionary <string, string> groupOwner   = new Dictionary <string, string>();
            string token = await GetOAuthTokenFromAAD();

            foreach (var subscriptionId in subscriptionIds.Split(",", StringSplitOptions.RemoveEmptyEntries))
            {
                var azureSub       = azure.WithSubscription(subscriptionId);
                var resourceGroups = azureSub.ResourceGroups.List();

                string uri = $"https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.CostManagement/query?api-version=2019-01-01";

                while (!String.IsNullOrEmpty(uri))
                {
                    QueryResult result        = null;
                    int         costIndex     = -1;
                    int         currencyIndex = -1;
                    int         groupIndex    = -1;

                    var request = HttpWebRequest.CreateHttp(uri);
                    request.ContentType = "application/json";
                    request.Method      = "POST";
                    request.Headers.Add("Authorization", $"Bearer {token}");
                    try
                    {
                        using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                        {
                            writer.Write(body);
                            writer.Flush();
                        }

                        var response = await request.GetResponseAsync();

                        var responseString = String.Empty;
                        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                        {
                            responseString = reader.ReadToEnd();
                        }
                        result        = JsonConvert.DeserializeObject <QueryResult>(responseString);
                        uri           = result.properties.nextLink;
                        costIndex     = GetColumnIndex(result.properties.columns, "PreTaxCost");
                        currencyIndex = GetColumnIndex(result.properties.columns, "Currency");
                        groupIndex    = GetColumnIndex(result.properties.columns, "ResourceGroup");
                        if (costIndex < 0)
                        {
                            Console.WriteLine($"Could not find cost index for subscription {subscriptionId}");
                            continue;
                        }
                    }
                    catch (WebException wex)
                    {
                        string errorMessage = string.Empty;
                        if (wex.Response != null)
                        {
                            using (StreamReader reader = new StreamReader(wex.Response.GetResponseStream()))
                            {
                                errorMessage = reader.ReadToEnd();
                            }
                        }
                        Console.WriteLine($"Error while calculating costs for subscription {subscriptionId}: {wex} ({errorMessage})");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error while calculating costs for subscription {subscriptionId}: {ex}");
                    }

                    if (result != null)
                    {
                        foreach (var group in resourceGroups)
                        {
                            var resourceGroupOwner  = OWNER_UNKNOWN;
                            var defaultKeyValuePair = default(KeyValuePair <String, String>);
                            var ownerTag            = defaultKeyValuePair;
                            if (group.Tags != null)
                            {
                                ownerTag = group.Tags.Where(tag => tag.Key.Equals(ownerTagName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                            }

                            if (!ownerTag.Equals(defaultKeyValuePair))
                            {
                                resourceGroupOwner = ownerTag.Value;
                            }

                            //Console.WriteLine($"Calculating costs for resource group {group.Name} in subscription {subscriptionId} which belongs to {resourceGroupOwner}");

                            string keyNameGroup = $"{subscriptionId}/{group.Name}";
                            if (!costPerUser.ContainsKey(resourceGroupOwner))
                            {
                                costPerUser.Add(resourceGroupOwner, 0);
                            }
                            if (!costPerGroup.ContainsKey(keyNameGroup))
                            {
                                costPerGroup.Add(keyNameGroup, 0);
                            }
                            if (!groupOwner.ContainsKey(keyNameGroup))
                            {
                                groupOwner.Add(keyNameGroup, resourceGroupOwner);
                            }

                            var groupRows = result.properties.rows.Where(rTemp => rTemp[groupIndex].ToString().Equals(group.Name,
                                                                                                                      StringComparison.InvariantCultureIgnoreCase)).ToArray();
                            foreach (var row in groupRows)
                            {
                                costPerUser[resourceGroupOwner] += (Double)row[costIndex];
                                costPerGroup[keyNameGroup]      += (Double)row[costIndex];

                                var currencyOfRow = (string)row[currencyIndex];
                                if (String.IsNullOrEmpty(currency))
                                {
                                    currency = currencyOfRow;
                                }
                                else if (!currency.Equals(currencyOfRow))
                                {
                                    throw new Exception("There are different currencies");
                                }
                            }
                        }
                    }
                }

                Console.WriteLine($"##########################################");
                Console.WriteLine($"Cost between {startDate} and {endDate} per resource group for unknown owner");
                Console.WriteLine($"##########################################");
                var subscriptionRgUnknown = costPerGroup.Where(temp => temp.Key.Split("/")[0].
                                                               Equals(subscriptionId, StringComparison.InvariantCultureIgnoreCase));
                foreach (KeyValuePair <string, double> costEntry in subscriptionRgUnknown.OrderByDescending(temp => temp.Value))
                {
                    if (groupOwner[costEntry.Key].Equals(OWNER_UNKNOWN, StringComparison.InvariantCultureIgnoreCase))
                    {
                        Console.WriteLine($"{costEntry.Key}: {currency} {costEntry.Value}");
                    }
                }
            }

            Console.WriteLine($"##########################################");
            Console.WriteLine($"Cost between {startDate} and {endDate} per user");
            Console.WriteLine($"##########################################");
            foreach (KeyValuePair <string, double> costEntry in costPerUser.OrderByDescending(temp => temp.Value))
            {
                Console.WriteLine($"{costEntry.Key}: {currency} {costEntry.Value}");
            }
            Console.WriteLine($"##########################################");
            Console.WriteLine($"Cost between {startDate} and {endDate} per resource group");
            Console.WriteLine($"##########################################");
            foreach (KeyValuePair <string, double> costEntry in costPerGroup.OrderByDescending(temp => temp.Value))
            {
                Console.WriteLine($"{costEntry.Key}: {currency} {costEntry.Value} (owner: {groupOwner[costEntry.Key]})");
            }
        }
예제 #4
0
        public static async Task Run()
        {
            string tag_owner           = GetConfigItem("tag_owner");
            string tag_deallocate      = GetConfigItem("tag_deallocate");
            int    tag_deallocate_days = int.Parse(GetConfigItem("tag_deallocate_days"));
            string tag_deletevm        = GetConfigItem("tag_deletevm");
            int    tag_deletevm_days   = int.Parse(GetConfigItem("tag_deletevm_days"));
            string tag_deleterg        = GetConfigItem("tag_deleterg");
            int    tag_deleterg_days   = int.Parse(GetConfigItem("tag_deleterg_days"));
            string subscriptionIds     = GetConfigItem("subscriptionIds");
            string clientId            = GetConfigItem("clientId");
            string clientSecret        = GetConfigItem("clientSecret");
            string tenantId            = GetConfigItem("tenantId");

            AzureCredentialsFactory factory    = new AzureCredentialsFactory();
            AzureCredentials        azureCreds = factory.FromServicePrincipal(clientId, clientSecret, tenantId,
                                                                              AzureEnvironment.AzureGlobalCloud);

            Azure.IAuthenticated azure = Azure.Configure().Authenticate(azureCreds);

            foreach (var subscriptionId in subscriptionIds.Split(",", StringSplitOptions.RemoveEmptyEntries))
            {
                Console.WriteLine($"Looking for new resources without an owner tag in subscription {subscriptionId}");

                var azureSub       = azure.WithSubscription(subscriptionId);
                var insightsClient = new InsightsClient(azureCreds);
                insightsClient.SubscriptionId = subscriptionId;

                var resourceGroups = azureSub.ResourceGroups.List();
                foreach (var group in resourceGroups)
                {
                    try
                    {
                        var defaultKeyValuePair = default(KeyValuePair <String, String>);
                        var ownerTag            = defaultKeyValuePair;
                        if (group.Tags != null)
                        {
                            ownerTag = group.Tags.Where(tag => tag.Key.Equals(tag_owner, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        }

                        String endTime    = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
                        String resourceId = group.Id;
                        if (ownerTag.Equals(defaultKeyValuePair))
                        {
                            //Console.WriteLine($"Resource group {group.Name} does not contain owner tag...looking in activity log");
                            String startTime = DateTime.Now.ToUniversalTime().AddHours(-25).ToString("yyyy-MM-ddTHH:mm:ss.fffZ");

                            string newOwner = UNKNOWN_OWNER;
                            var    resourceGroupCreateLogs = await GetCreationLogs(startTime, endTime, resourceId, OPERATION_RESOURCEGROUP_WRITE, insightsClient);

                            if (resourceGroupCreateLogs.Length == 0)
                            {
                                startTime = DateTime.Now.ToUniversalTime().AddDays(-90).ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
                                resourceGroupCreateLogs = await GetCreationLogs(startTime, endTime, resourceId, OPERATION_RESOURCEGROUP_WRITE, insightsClient);
                            }
                            if (resourceGroupCreateLogs.Length != 0)
                            {
                                newOwner = resourceGroupCreateLogs[0].Caller;
                            }
                            if (!UNKNOWN_OWNER.Equals(newOwner))
                            {
                                await group.Update().WithTag(tag_owner, newOwner).ApplyAsync();

                                Console.WriteLine($"Resource group {group.Name} tagged with owner {newOwner}");
                            }
                        }
                        else if (UNKNOWN_OWNER.Equals(ownerTag.Value))
                        {
                            bool needsUpdate = false;
                            var  updateGroup = group.Update();
                            if (group.Tags.Where(tag => tag.Key.Equals(tag_deallocate, StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
                            {
                                needsUpdate = true;
                                updateGroup.WithTag(tag_deallocate, DateTime.Now.ToUniversalTime().AddDays(tag_deallocate_days).ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
                            }
                            if (group.Tags.Where(tag => tag.Key.Equals(tag_deletevm, StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
                            {
                                needsUpdate = true;
                                updateGroup.WithTag(tag_deletevm, DateTime.Now.ToUniversalTime().AddDays(tag_deletevm_days).ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
                            }
                            if (group.Tags.Where(tag => tag.Key.Equals(tag_deleterg, StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
                            {
                                needsUpdate = true;
                                updateGroup.WithTag(tag_deleterg, DateTime.Now.ToUniversalTime().AddDays(tag_deleterg_days).ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
                            }

                            if (needsUpdate)
                            {
                                await updateGroup.ApplyAsync();
                            }
                        }
                        else
                        {
                            //Console.WriteLine($"Resource group {group.Name} is already owned by {ownerTag.Value}");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Exception: " + ex);
                    }
                }
            }

            Console.WriteLine("Done Tagging");
        }