private async Task LoadAsync()
        {
            var tenantId = _options.TenantId ?? GetCurrentTenantId();

            var resourceGraphClient = new ResourceGraphClient(new TokenCredentials(new AppAuthenticationTokenProvider(tenantId)));

            var subscriptionId = _options.SubscriptionId ?? GetCurrentSubscriptionId();
            var resourceGroup  = _options.ResourceGroup ?? GetCurrentResourceGroup();
            var tagName        = _options.CustomTagName ?? DefaultTagName;

            var query = new QueryRequest
            {
                Subscriptions = new[] { subscriptionId },
                Query         = $"where type =~ 'microsoft.web/sites' and resourceGroup =~ '{resourceGroup}' and not(isnull(tags['{tagName}'])) | project hostName = properties.defaultHostName, serviceName = tags['{tagName}']",
                Options       = new QueryRequestOptions {
                    ResultFormat = ResultFormat.ObjectArray
                }
            };

            var response = await resourceGraphClient.ResourcesAsync(query).ConfigureAwait(false);

            var resources = ((JToken)response.Data).ToObject <QueryResult[]>();

            var newResources = resources.GroupBy(x => x.ServiceName, x => x.HostName)
                               .ToDictionary(x => x.Key, x => x.ToArray());

            Interlocked.Exchange(ref _loadedResources, newResources);
        }
示例#2
0
文件: Scanner.cs 项目: jpda/azman-v2
        private async Task <IEnumerable <ResourceSearchResult> > QueryResourceGraph(string queryText)
        {
            var subscriptions = await FindAccessibleSubscriptions();

            var token = await _tokenProvider.GetAccessTokenAsync(new[] { _managementAzureAdResourceId });

            var graphClient = new ResourceGraphClient(new Microsoft.Rest.TokenCredentials(token.Token));


            var resources = new List <ResourceSearchResult>();

            try
            {
                var query = await graphClient.ResourcesAsync(new QueryRequest(subscriptions.ToList(), queryText));

                _log.LogInformation($"Resource graph response: {query.Data}");

                if (((dynamic)query.Data).rows is Newtonsoft.Json.Linq.JArray j)
                {
                    resources.AddRange(
                        j.Select(x => new ResourceSearchResult(
                                     resourceId: x.ElementAt(0).ToString(),
                                     subscriptionId: x.ElementAt(1).ToString())));
                }
            }
            catch (Exception ex)
            {
                _log.LogError(ex, ex.Message);
            }
            return(resources);
        }
示例#3
0
文件: Scanner.cs 项目: jpda/azman-v2
        private async Task <IEnumerable <T> > QueryResourceGraph <T>(string queryText) where T : SearchResult, new()
        {
            var subscriptions = await FindAccessibleSubscriptions();

            var token = await _tokenProvider.GetAccessTokenAsync(new[] { _managementAzureAdResourceId });

            var graphClient = new ResourceGraphClient(new Microsoft.Rest.TokenCredentials(token.Token));
            var resources   = new List <T>();

            try
            {
                var query = await graphClient.ResourcesAsync(new QueryRequest(subscriptions.ToList(), queryText));

                // the ResourceGraphClient uses Newtonsoft under the hood
                if (((dynamic)query.Data).rows is Newtonsoft.Json.Linq.JArray j)
                {
                    var result = new T();
                    resources.AddRange(
                        j.Select(x => new T()
                    {
                        ResourceId     = x.ElementAt(0).ToString(),
                        SubscriptionId = x.ElementAt(1).ToString()
                    }));
                }
            }
            catch (Exception ex)
            {
                _log.LogError(ex, ex.Message);
            }
            return(resources);
        }
示例#4
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
            HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Starting function...");
            var resources = new QueryResponse();

            try
            {
                var credentials         = AzureCredential.GetCredentialsFromSp();
                var subscriptionClient  = new SubscriptionClient(credentials);
                var resourceGraphClient = new ResourceGraphClient(credentials);
                var subscriptionQuery   =
                    Environment.GetEnvironmentVariable("GET_SUBSCRIPTIONS_QUERY", EnvironmentVariableTarget.Process);

                IEnumerable <SubscriptionModel> subscriptions = await subscriptionClient.Subscriptions.ListAsync();

                var subscriptionIds = subscriptions
                                      .Where(s => s.State == SubscriptionState.Enabled)
                                      .Select(s => s.SubscriptionId)
                                      .ToList();

                const int groupSize = 100;
                for (var i = 0; i <= subscriptionIds.Count / groupSize; ++i)
                {
                    var currSubscriptionGroup = subscriptionIds.Skip(i * groupSize).Take(groupSize).ToList();
                    var query = new QueryRequest
                    {
                        Subscriptions = currSubscriptionGroup,
                        Query         = subscriptionQuery,
                        Options       = new QueryRequestOptions
                        {
                            ResultFormat = ResultFormat.ObjectArray
                        }
                    };

                    resources = await resourceGraphClient.ResourcesAsync(query);
                }

                return(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(
                        resources.Data.ToString(),
                        Encoding.UTF8,
                        "application/json")
                });
            }
            catch
            {
                return(new HttpResponseMessage(HttpStatusCode.NotFound)
                {
                    Content = new StringContent(
                        "{}",
                        Encoding.UTF8,
                        "application/json")
                });
            }
        }
示例#5
0
        public async void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, ILogger log)
        {
            string strQuery = "Resources | where tags['resize-Enable'] =~ 'True'";

            var resizeUpList   = new List <JObject>();
            var resizeDownList = new List <JObject>();

            string storageKeyName    = "storageAccount";
            string storageAppSetting = _configuration[storageKeyName];

            log.LogInformation("Storage Account: " + storageAppSetting);

            string queueKeyName    = "storageQueue";
            string queueAppSetting = _configuration[queueKeyName];

            log.LogInformation("Storage Queue: " + queueAppSetting);

            string debugKeyName    = "debugMode";
            string debugAppSetting = _configuration[debugKeyName];

            log.LogInformation("Debug: " + debugAppSetting);

            bool debugFlag = bool.Parse(debugAppSetting);

            QueueClient messageQueue = getQueueClient(storageAppSetting, queueAppSetting);

            ManagedIdentityCredential managedIdentityCredential = new ManagedIdentityCredential();

            string[] scope       = new string[] { "https://management.azure.com/.default" };
            var      accessToken = (await managedIdentityCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(scope))).Token;

            TokenCredentials    serviceClientCreds = new TokenCredentials(accessToken);
            ResourceGraphClient rgClient           = new ResourceGraphClient(serviceClientCreds);
            SubscriptionClient  subscriptionClient = new SubscriptionClient(serviceClientCreds);

            IEnumerable <SubscriptionModel> subscriptions = await subscriptionClient.Subscriptions.ListAsync();

            var subscriptionIds = subscriptions
                                  .Where(s => s.State == SubscriptionState.Enabled)
                                  .Select(s => s.SubscriptionId)
                                  .ToList();

            QueryRequest request = new QueryRequest
            {
                Subscriptions = subscriptionIds,
                Query         = strQuery,
                Options       = new QueryRequestOptions(resultFormat: ResultFormat.ObjectArray)
            };

            var response = await rgClient.ResourcesAsync(request);

            JArray resources = JArray.Parse(response.Data.ToString());

            log.LogInformation("Current Time: " + DateTime.UtcNow.ToString("dddd htt"));

            foreach (JObject resource in resources)
            {
                log.LogInformation("Target: " + resource["name"].ToString());

                Hashtable times = new Hashtable()
                {
                    { "StartTime", resource["tags"]["resize-StartTime"].ToString() },
                    { "EndTime", resource["tags"]["resize-EndTime"].ToString() }
                };

                foreach (string key in times.Keys)
                {
                    log.LogInformation(string.Format("{0}: {1}", key, times[key]));
                }

                Regex rg = new Regex("saveState-.*");

                if (resizeTime(times))
                {
                    // log.LogInformation("Resize Time: YES");
                    if (resource["tags"].Children <JProperty>().Any(prop => rg.IsMatch(prop.Name.ToString())))
                    {
                        log.LogInformation(resource["name"].ToString() + " Already Scaled Down...");
                    }
                    else
                    {
                        log.LogInformation(resource["name"].ToString() + " Needs to be Scaled Down...");
                        resizeDownList.Add(resource);
                    }
                }
                else
                {
                    // log.LogInformation("Resize Time: NO");
                    if (resource["tags"].Children <JProperty>().Any(prop => rg.IsMatch(prop.Name.ToString())))
                    {
                        log.LogInformation(resource["name"].ToString() + " Needs to be Scaled Up...");
                        resizeUpList.Add(resource);
                    }
                    else
                    {
                        log.LogInformation(resource["name"].ToString() + " Already Scaled Up...");
                    }
                }
            }

            foreach (var item in resizeUpList)
            {
                log.LogInformation(item["name"].ToString() + " => up");

                var messageData = new JObject();
                messageData.Add(new JProperty("debug", debugFlag));
                messageData.Add(new JProperty("direction", "up"));
                messageData.Add(new JProperty("graphResults", item));

                writeQueueMessage(messageData, messageQueue);
            }
            ;

            foreach (var item in resizeDownList)
            {
                log.LogInformation(item["name"].ToString() + " => down");

                var messageData = new JObject();
                messageData.Add(new JProperty("debug", debugFlag));
                messageData.Add(new JProperty("direction", "down"));
                messageData.Add(new JProperty("graphResults", item));

                writeQueueMessage(messageData, messageQueue);
            }
            ;
        }