Exemple #1
0
        public static async Task Run(string myQueueItem, CloudTable invalidResourceTable, TraceWriter log)
        {
            log.Info($"C# Queue trigger function triggered: {myQueueItem}");

            ResourceItem           updateItem      = JsonConvert.DeserializeObject <ResourceItem>(myQueueItem);
            ResourceManagerService resourceManager = null;

            try
            {
                string token = await AuthenticationService.GetAccessTokenAsync();

                resourceManager = new ResourceManagerService(token);
            }
            catch (Exception ex)
            {
                log.Error("Unable to connect to the ARM API, Message: " + ex.Message);
            }

            try
            {
                await resourceManager.UpdateResource(updateItem);
            }
            catch (Exception ex)
            {
                log.Error(updateItem.Id + " failed with: " + ex.Message);

                InvalidTagResource matchingInvalidResource = null;
                var invalidTagResourcesQuery = await invalidResourceTable.ExecuteQuerySegmentedAsync(new TableQuery <InvalidTagResource>(), null);

                if (invalidTagResourcesQuery.Results != null)
                {
                    matchingInvalidResource = invalidTagResourcesQuery.Results.Where(x => x.Type == updateItem.Type).FirstOrDefault();
                }

                if (matchingInvalidResource == null)
                {
                    InvalidTagResource invalidItem = new InvalidTagResource
                    {
                        Type         = updateItem.Type,
                        Message      = ex.Message,
                        RowKey       = Guid.NewGuid().ToString(),
                        PartitionKey = updateItem.Subscription
                    };

                    TableOperation insertOperation = TableOperation.InsertOrReplace(invalidItem);
                    await invalidResourceTable.ExecuteAsync(insertOperation);
                }
            }
        }
Exemple #2
0
        public static async Task Run([QueueTrigger("resources-to-tag", Connection = "AzureWebJobsStorage"), Disable("true")] string myQueueItem,
                                     [Table("InvalidTagResources")] CloudTable invalidResourceTable,
                                     TraceWriter log)
        {
            log.Info($"C# Queue trigger function triggered: {myQueueItem}");

            ResourceItem updateItem = JsonConvert.DeserializeObject <ResourceItem>(myQueueItem);

            TokenCredentials tokenCredential;

            if (Environment.GetEnvironmentVariable("MSI_ENDPOINT") == null)
            {
                log.Info("Using service principal");
                string appId     = Environment.GetEnvironmentVariable("appId");
                string appSecret = Environment.GetEnvironmentVariable("appSecret");
                string tenantId  = Environment.GetEnvironmentVariable("tenantId");
                tokenCredential = AuthenticationService.GetAccessToken(appId, appSecret, tenantId);
            }
            else
            {
                log.Info("Using MSI");
                var    azureServiceTokenProvider = new AzureServiceTokenProvider();
                string token = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.core.windows.net/");

                tokenCredential = new TokenCredentials(token);
            }

            var client = new ResourceManagementClient(tokenCredential);

            client.SubscriptionId = updateItem.Subscription;
            GenericResourceInner resource = null;

            try
            {
                resource = await client.Resources.GetByIdAsync(updateItem.Id, updateItem.ApiVersion);

                resource.Tags       = updateItem.Tags;
                resource.Properties = null;  // some resource types support PATCH operations ONLY on tags.
                await client.Resources.UpdateByIdAsync(updateItem.Id, updateItem.ApiVersion, resource);
            }
            catch (Exception ex)
            {
                if (resource == null)
                {
                    log.Error("Failed to get resource: " + updateItem.Id);
                    log.Error("Error is: " + ex.Message);
                }
                else
                {
                    log.Error(resource.Id + " failed with: " + ex.Message);
                }

                InvalidTagResource matchingInvalidResource = null;
                var invalidTagResourcesQuery = await invalidResourceTable.ExecuteQuerySegmentedAsync(new TableQuery <InvalidTagResource>(), null);

                if (invalidTagResourcesQuery.Results != null)
                {
                    matchingInvalidResource = invalidTagResourcesQuery.Results.Where(x => x.Type == updateItem.Type).FirstOrDefault();
                }

                if (matchingInvalidResource == null)
                {
                    InvalidTagResource invalidItem = new InvalidTagResource
                    {
                        Type         = updateItem.Type,
                        Message      = ex.Message,
                        RowKey       = Guid.NewGuid().ToString(),
                        PartitionKey = updateItem.Subscription
                    };

                    TableOperation insertOperation = TableOperation.InsertOrReplace(invalidItem);
                    await invalidResourceTable.ExecuteAsync(insertOperation);
                }
            }
        }
        static async Task ProcessResourceGroups(IEnumerable <string> requiredTagsList, IEnumerable <ResourceGroupInner> resourceGroups, List <InvalidTagResource> invalidTypes, string subscriptionId, AuditStats stats)
        {
            foreach (ResourceGroupInner rg in resourceGroups)
            {
                _log.Info("*** Resource Group: " + rg.Name);

                Dictionary <string, string> requiredRgTags = new Dictionary <string, string>();
                foreach (string tagKey in requiredTagsList)
                {
                    if (rg.Tags != null && rg.Tags.ContainsKey(tagKey))
                    {
                        requiredRgTags.Add(tagKey, rg.Tags[tagKey]);
                    }
                }

                if (requiredRgTags.Count != requiredTagsList.Count())
                {
                    _log.Warning("Resource group: " + rg.Name + " does not have required tags.");
                    stats.ResourceGroupsSkipped += 1;
                }
                else
                {
                    IEnumerable <GenericResourceInner> resources = await _client.Resources.ListByResourceGroupAsync(rg.Name);

                    stats.ResourceItemsTotal = resources.Count();

                    foreach (var resource in resources)
                    {
                        // InvalidTagResource invalidResourceMatch = invalidTagResourcesQuery.Results.Where(x => x.Type == resource.Type).FirstOrDefault();
                        InvalidTagResource invalidType = invalidTypes.Where(x => x.Type == resource.Type).FirstOrDefault();

                        if (invalidType == null)
                        {
                            string apiVersion;

                            try
                            {
                                apiVersion = await GetApiVersion(_client, resource.Type);
                            }
                            catch (Exception ex)
                            {
                                _log.Error(ex.Message);
                                break;
                            }

                            var result = SetTags(resource.Tags, requiredRgTags);

                            if (result.Count > 0)
                            {
                                stats.ResourceItemsWithUpdates += 1;
                                resource.Tags = result;
                                ResourceItem newItem = new ResourceItem {
                                    Id           = resource.Id,
                                    ApiVersion   = apiVersion,
                                    Location     = resource.Location,
                                    Tags         = resource.Tags,
                                    Type         = resource.Type,
                                    Subscription = subscriptionId
                                };

                                string messageText = JsonConvert.SerializeObject(newItem);
                                _outQueue.Add(messageText);
                                _log.Info("Requesting tags for: " + resource.Id);
                            }
                            else
                            {
                                stats.ResourceItemsSkipped += 1;
                            }
                        }
                        else
                        {
                            _log.Warning("Item type does not support tagging: " + resource.Type);
                            stats.ResourceItemsSkipped += 1;
                        }
                    }
                }
            }
        }