private async Task <ResourceGraphClient> CreateClientAsync() { var azureEnvironment = _resourceDeclarationMonitor.CurrentValue.AzureLandscape.Cloud.GetAzureEnvironment(); var azureAuthorityHost = _resourceDeclarationMonitor.CurrentValue.AzureLandscape.Cloud.GetAzureAuthorityHost(); var credentials = await AzureAuthenticationFactory.GetTokenCredentialsAsync(azureEnvironment.ManagementEndpoint, TenantId, _azureAuthenticationInfo, azureAuthorityHost); var resourceManagerBaseUri = new Uri(azureEnvironment.ResourceManagerEndpoint); var appId = DetermineApplicationId(_azureAuthenticationInfo); var metricLabels = new Dictionary <string, string> { { "tenant_id", TenantId }, { "cloud", azureEnvironment.GetDisplayName() }, { "app_id", appId }, { "auth_mode", _azureAuthenticationInfo.Mode.ToString() }, }; var resourceGraphClient = new ResourceGraphClient(resourceManagerBaseUri, credentials, new AzureResourceGraphThrottlingRequestHandler(_prometheusMetricsCollector, metricLabels, _logger)); var version = Promitor.Core.Version.Get(); var promitorUserAgent = UserAgent.Generate("Resource-Discovery", version); resourceGraphClient.UserAgent.Clear(); resourceGraphClient.UserAgent.TryParseAdd(promitorUserAgent); return(resourceGraphClient); }
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") }); } }
private async Task <ResourceGraphClient> GetOrCreateClient() { if (_graphClient == null) { _graphClient = await CreateClientAsync(); } return(_graphClient); }
public static object readAzureGraph(string accessToken, string subscriptionId, string query) { //*** Need to grant application Delegated user_impersonation against Azure Service management *** ServiceClientCredentials serviceClientCreds = new TokenCredentials(accessToken); ResourceGraphClient client = new ResourceGraphClient(serviceClientCreds); QueryResponse response = client.Resources(new QueryRequest(new List <string>() { subscriptionId }, query)); return(response.Data); }
private async Task <ResourceGraphClient> CreateClientAsync() { var azureEnvironment = _resourceDeclarationMonitor.CurrentValue.AzureLandscape.Cloud.GetAzureEnvironment(); var credentials = await Authentication.GetServiceClientCredentialsAsync(azureEnvironment.ManagementEndpoint, QueryApplicationId, _queryApplicationSecret, TenantId); var resourceGraphClient = new ResourceGraphClient(credentials); var version = Promitor.Core.Version.Get(); var promitorUserAgent = UserAgent.Generate("Resource-Discovery", version); resourceGraphClient.UserAgent.TryParseAdd(promitorUserAgent); return(resourceGraphClient); }
public ResourceGraphClientResponse CallResourceGraphClient(string token, string strQuery, List <string> subscriptions) { try { QueryRequest request = new QueryRequest(); request.Query = strQuery; request.Subscriptions = subscriptions; ServiceClientCredentials serviceClientCreds = new TokenCredentials(token); ResourceGraphClient argClient = new ResourceGraphClient(serviceClientCreds); Microsoft.Azure.Management.ResourceGraph.Models.QueryResponse response = argClient.Resources(request); var resourceGraphClientResponse = Newtonsoft.Json.Linq.JObject.Parse(response.Data.ToString()).ToObject <ResourceGraphClientResponse>(); return(resourceGraphClientResponse); } catch (Exception ex) { throw ex; } }
static void Main(string[] args) { string clientId = "[clientid]"; string clientSecret = "[clientSecret]"; string tenantId = "[tenantId]"; string subscriptionId = "[subscriptionId]"; string query = "Resources | project name, type | limit 5"; string authority = $"https://login.microsoftonline.com/{tenantId}"; ResourceGraphClient client = new ResourceGraphClient(AuthenticationHelper.GetServiceClientCredentials("https://management.core.windows.net", clientId, clientSecret, authority).Result); var response = client.Resources(new QueryRequest(new List <string>() { subscriptionId }, query)); Console.WriteLine(response); }
public async Task <IReadOnlyList <ResourceDto> > GetSqlResourcesAsync(string _subscriptionId) { if (string.IsNullOrWhiteSpace(_subscriptionId)) { return(null); } DefaultAzureCredential credential; if (_sqlResourceInventoryConfiguration.UseSystemAssignedManagedIdentity) { credential = new DefaultAzureCredential(); } else { credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = _sqlResourceInventoryConfiguration.UserAssignedManagedIdentityClientId }); } TokenRequestContext tokenRequestContext = new TokenRequestContext(new[] { Constants.AzureResourceManagerAPIDefaultScope }); AccessToken tokenRequestResult = await credential.GetTokenAsync(tokenRequestContext); ServiceClientCredentials serviceClientCreds = new TokenCredentials(tokenRequestResult.Token); ResourceGraphClient argClient = new ResourceGraphClient(serviceClientCreds); QueryRequest request = new QueryRequest(); request.Subscriptions = new List <string>() { _subscriptionId }; request.Query = "Resources |" + " where type in ('microsoft.sql/servers','microsoft.sqlvirtualmachine/sqlvirtualmachines','Microsoft.Sql/managedInstances') |" + " project id, name, type, location, resourceGroup, subscriptionId, tenantId"; request.Options = new QueryRequestOptions() { ResultFormat = ResultFormat.ObjectArray }; // Parameter to hold full list of returned resources List <ResourceDto> results = new List <ResourceDto>(); // Send query to the ResourceGraphClient and get response QueryResponse response = argClient.Resources(request); // IMPORTANT: The query must project the id field in order for pagination to work. // If it's missing from the query, the response won't include the $skipToken. if (response.Count > 0) { // Add response results to list results.AddRange(((JArray)response.Data).ToObject <List <ResourceDto> >()); // Continue till SkipToken is null while (!string.IsNullOrWhiteSpace(response.SkipToken)) { // Update request with new skip token returned from response request.Options.SkipToken = response.SkipToken; // Send query with SkipToken to the ResourceGraphClient and get response response = argClient.Resources(request); // Add response results to list results.AddRange(((JArray)response.Data).ToObject <List <ResourceDto> >()); } } IReadOnlyList <ResourceDto> returnList = results.ToList().AsReadOnly(); return(returnList); }
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); } ; }
protected void SetupManagementClients(MockContext context) { ResourceGraphClient = GetResourceGraphClient(context); _helper.SetupManagementClients(ResourceGraphClient); }
private async Task OpenConnectionAsync() { _graphClient = await CreateClientAsync(); }
public static async Task FindResources() { // Initialize a DefaultAzureCredential which is a part of the // Azure.Identity package which provides an authentication flow // for more information: https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet DefaultAzureCredential credential = new DefaultAzureCredential(); // If utilizing a user assigned managed identity, then uncomment the // second line and comment out the first line //var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = UserAssignedManagedIdentityId }); // Create token request context with scope set to .default TokenRequestContext tokenRequestContext = new TokenRequestContext(new[] { "https://management.core.windows.net//.default" }); // Get token which will sequentially call the included credentials in the order // EnvironmentCredential, ManagedIdentityCredential, SharedTokenCacheCredential, // and InteractiveBrowserCredential returning the first successfully obtained AccessToken // for more information: https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential.gettokenasync?view=azure-dotnet AccessToken tokenRequestResult = await credential.GetTokenAsync(tokenRequestContext); // Initialize ServiceClientCredential utilizing acquired token ServiceClientCredentials serviceClientCreds = new TokenCredentials(tokenRequestResult.Token); // Initialize ResourceGraphClient with the credentials ResourceGraphClient argClient = new ResourceGraphClient(serviceClientCreds); // Create query that will get max 5 resources found in the subscription 'SubscriptionId' QueryRequest request = new QueryRequest(); request.Subscriptions = new List <string>() { SubscriptionId }; request.Query = "Resources | project id, name, type"; request.Options = new QueryRequestOptions() { Top = 5, ResultFormat = ResultFormat.ObjectArray }; // NOTE: top 5 is being passed in here to 'force' the implementation of pagination. It can be excluded // and then will default to 1000 items returned. // ResultFormat can be set to Table or ObjectArray (and defaults to Table if not set). // More info can be found at https://docs.microsoft.com/en-us/azure/governance/resource-graph/concepts/work-with-data#formatting-results // Parameter to hold full list of returned resources var results = new List <ResourceItem>(); // Send query to the ResourceGraphClient and get response QueryResponse response = argClient.Resources(request); // IMPORTANT: The query must project the id field in order for pagination to work. // If it's missing from the query, the response won't include the $skipToken. if (response.Count > 0) { // Add response results to list results.AddRange(((JArray)response.Data).ToObject <List <ResourceItem> >()); // Continue till SkipToken is null while (!string.IsNullOrWhiteSpace(response.SkipToken)) { // Update request with new skip token returned from response request.Options.SkipToken = response.SkipToken; // Send query with SkipToken to the ResourceGraphClient and get response response = argClient.Resources(request); // Add response results to list results.AddRange(((JArray)response.Data).ToObject <List <ResourceItem> >()); } } // Print out results to the console // When deployed as a trigger webjob, by default // these will be written out to the webjob run log Console.WriteLine("List of resource names found:"); foreach (var res in results) { Console.WriteLine(res.name); } }