public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Wait wut? Let me get resource changes");

            string subscriptionId = req.Query["subscriptionId"];

            string  requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            subscriptionId = subscriptionId ?? data?.subscriptionId;

            string responseMessage = string.IsNullOrEmpty(subscriptionId)
                ? "Please pass a subscriptionId"
                : $"Tried to check changes for {subscriptionId}";


            var APICall = new APICall();

            var accessToken = await APICall.GetToken();

            List <ChangeProperties> ChangeProperties = await APICall.GetChanges(accessToken, subscriptionId);

            return(new OkObjectResult(ChangeProperties));
        }
        public static async Task <List <string> > GetAllResourceIds(string subscriptionId)
        {
            var httpClient = await APICall.HTTPClient();

            // Not all resources report a clean history and perhaps you're not interested in all resources
            // Get all Resource Ids for resources with Tag "ReportChanges" and tagValue "true"
            string URI = $"https://management.azure.com/subscriptions/{subscriptionId}/resources?$filter=tagName eq 'ReportChanges' and tagValue eq 'true'&api-version=2020-06-01";

            HttpResponseMessage responsePost = await httpClient.GetAsync(URI);

            var HttpsResponse = await responsePost.Content.ReadAsStringAsync();

            // Want to use a normal object for this as well and create a list, however this is troublesome as the returned json
            // Is not always the same. LINQ seems to do the trick.
            // Parse resourceIds in JObject
            JObject results = JObject.Parse(HttpsResponse);

            // Store all resource Ids in list
            var resourceIds =
                from id in results["value"]
                select(string) id["id"];


            List <string> resourceIdsList = new List <string>();

            foreach (string item in resourceIds)
            {
                resourceIdsList.Add(item);
            }
            // Return the List
            return(resourceIdsList);
        }
        public static async Task <HttpClient> HTTPClient()
        {
            // Get the access token
            var token = await APICall.GetToken();

            // Creat the HTTP Client
            var httpClient = new HttpClient();

            // Create the Headers
            httpClient.DefaultRequestHeaders.Remove("Authorization");
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);

            return(httpClient);
        }
        public static async Task <List <ChangeProperties> > GetChanges(string token, string subscriptionId)
        {
            // Get the HTTP Client
            var httpClient = await APICall.HTTPClient();

            List <ChangeProperties> ChangeProperties = new List <ChangeProperties>();

            // Store the resourceIds in List "resourceIds"
            List <string> resourceIds = await APICall.GetAllResourceIds(subscriptionId);

            // Set Start and End date for changes (max 14 as ARG only stores history for 14 days)
            var startDateTime = DateTime.Now.AddDays(-14).ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'").ToString();
            var endDateTime   = DateTime.Now.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'").ToString();

            // URI of the Resource Changes API
            string URI = "https://management.azure.com/providers/Microsoft.ResourceGraph/resourceChanges?api-version=2018-09-01-preview";

            foreach (var resourceId in resourceIds)
            {
                // Build the body for the POST
                string str  = $"{{ 'resourceId': '{resourceId}', 'interval': {{ 'start': '{startDateTime}', 'end': '{endDateTime}' }}, 'fetchPropertyChanges': true }}";
                var    json = JsonConvert.DeserializeObject(str);

                // Perform POST, store results in HttpsResponse
                HttpResponseMessage responsePost = await httpClient.PostAsJsonAsync(URI, json);

                var HttpsResponse = await responsePost.Content.ReadAsStringAsync();

                // Store values in List
                RootChanges DeserializedClass = JsonConvert.DeserializeObject <RootChanges>(HttpsResponse);

                // Foreach detected change get the changed properties object and filter out "System"
                // Currently only interested in changes made by users

                foreach (var detectedChange in DeserializedClass.Changes)
                {
                    foreach (var propertyChange in detectedChange.PropertyChanges)
                    {
                        if (propertyChange.ChangeCategory != "System")
                        {
                            var timestamp = detectedChange.AfterSnapshot.Timestamp;
                            ChangeProperties.Add(new ChangeProperties(resourceId, propertyChange.PropertyName, propertyChange.BeforeValue, propertyChange.AfterValue, propertyChange.ChangeCategory, detectedChange.AfterSnapshot.Timestamp.ToString()));
                        }
                    }
                }
            }

            return(ChangeProperties);
        }