Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
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")
                });
            }
        }
        private async Task <ResourceGraphClient> GetOrCreateClient()
        {
            if (_graphClient == null)
            {
                _graphClient = await CreateClientAsync();
            }

            return(_graphClient);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
 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;
     }
 }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 12
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);
            }
            ;
        }
Ejemplo n.º 13
0
 protected void SetupManagementClients(MockContext context)
 {
     ResourceGraphClient = GetResourceGraphClient(context);
     _helper.SetupManagementClients(ResourceGraphClient);
 }
Ejemplo n.º 14
0
 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);
            }
        }