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); }
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); }
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); }
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") }); } }
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); } ; }