public async Task <TableResult> InsertAgentUpdateEntity(AgentUpdateEntity entity) { TableOperation tableOperation = TableOperation.Insert(entity); var result = await _table.ExecuteAsync(tableOperation); return(result); }
public static async Task UpdateAllTenantAgents( [TimerTrigger("%UpdateSchedule%")] TimerInfo timerInfo, ILogger log) { // Get Credentials string acronisCloudBaseURL = GetEnvironmentVariable("AcronisCloudBaseURL"); string acronisUsername = GetEnvironmentVariable("AcronisUsername"); string acronisPassword = GetEnvironmentVariable("AcronisPassword"); string tableStorageConnectionString = GetEnvironmentVariable("AzureWebJobsStorage"); // Get Mail Settings bool sendMailNotification = Convert.ToBoolean(GetEnvironmentVariable("SendMailNotification")); // Get Acronis settings string acronisExcludeTenantIds = GetEnvironmentVariable("ExcludeTenantIds", true); Int32 apiTimeout = Convert.ToInt32(GetEnvironmentVariable("ApiTimeOut")); bool testMode = Convert.ToBoolean(GetEnvironmentVariable("TestMode")); // define variables List <Guid> excludeTenantList = new List <Guid>(); string updateRunDateTime = DateTime.Now.ToString("s"); int agentUpdatedCounter = 0; log.LogInformation("C# HTTP trigger function is processing a request."); log.LogDebug($"Using Acronis Base URL {acronisCloudBaseURL}"); log.LogDebug($"Update Run Timestamp: {updateRunDateTime}"); log.LogDebug($"Using Acronis Username {acronisUsername}"); // Get array of excluded tenants if (!string.IsNullOrEmpty(acronisExcludeTenantIds)) { string[] excludeListStr = acronisExcludeTenantIds.Split(","); foreach (string excludeStr in excludeListStr) { try { Guid excludeGuid = new Guid(excludeStr); excludeTenantList.Add(excludeGuid); log.LogInformation($"Tenant Exclusion: added tenant ID {excludeStr} to exclusion list"); } catch { log.LogError($"Tenant Exclusion: failed to parse tenant ID {excludeStr}"); } } } else { log.LogInformation("Tenant Exclusion: no tenants identified"); } // Instantiate acronis API Uri acronisBaseUri = new Uri(acronisCloudBaseURL); AcronisAPI.AcronisAPIRestClient apiClient = new AcronisAPI.AcronisAPIRestClient(ref log, apiTimeout); apiClient.ExcludeTenantIdsList = excludeTenantList; // Authenticate and get auth token await apiClient.Authenticate(acronisUsername, acronisPassword); log.LogDebug("Using Acronis Tenant URL " + apiClient.TenantBaseUri.ToString()); log.LogInformation("Successfully authenticated"); // Initiate Table Storage Client TableStorageClient tableStorageClient = new TableStorageClient(tableStorageConnectionString); log.LogInformation("Successfully initiated Table Storage"); // Fetching all tenants and iterate them ConcurrentBag <APITenant> tenantBag = await apiClient.GetAllTenantsForUpdate(); foreach (APITenant tenant in tenantBag) { log.LogInformation($"Processing tenant ID {tenant.TenantID} / {tenant.Name}"); foreach (APIUser tenantUser in tenant.TenantUsers) { log.LogDebug($"Processing tenant user {tenantUser.UserName}"); try { // Scoped auth to gain access to tenant resources AcronisAPIRestClient scopedApiClient = new AcronisAPIRestClient(ref log, apiTimeout); scopedApiClient.AuthenticateScoped(apiClient, tenantUser.PersonalTenantID); // Getting all agents for scoped tenant ConcurrentBag <APIAgent> agentBag = await scopedApiClient.GetAgents(tenant.TenantID); foreach (APIAgent agent in agentBag) { if (agent.Online) { if (agent.UpdateAvailable) { log.LogInformation($"Updating Agent {agent.Hostname} from version {agent.AgentVersion} to version {agent.AvailableUpdateVersion}"); Guid updateActivtiyId = new Guid(); if (!testMode) { updateActivtiyId = await scopedApiClient.UpdateAgent(agent.AgentID); agentUpdatedCounter++; log.LogDebug($"Update started - activity ID: {updateActivtiyId}"); } else { log.LogWarning("Test Mode enabled, skipping update."); } var updateEntity = new AgentUpdateEntity(updateRunDateTime, agent.AgentID); updateEntity.AgentID = agent.AgentID.ToString(); updateEntity.AgentOS = agent.OS; updateEntity.AgentVersionAfterUpdate = agent.AvailableUpdateVersion; updateEntity.AgentVersionBeforeUpdate = agent.AgentVersion; updateEntity.HostName = agent.Hostname; updateEntity.TenantID = tenant.TenantID.ToString(); updateEntity.TenantName = tenant.Name; updateEntity.ParentTenantID = tenant.ParentTenantID.ToString(); updateEntity.ParentTenantName = tenant.ParentTenantName; updateEntity.UpdateActivityID = updateActivtiyId.ToString(); var tableResult = await tableStorageClient.InsertAgentUpdateEntity(updateEntity); log.LogDebug($"Written Agent Update Entity to Table Storage. Result: {tableResult.HttpStatusCode} / {tableResult.Etag}"); } else { log.LogInformation($"Agent {agent.Hostname} version {agent.AvailableUpdateVersion} is already up-to-date"); } } else { log.LogWarning($"Agent {agent.Hostname} is offline and will not being updated!"); } } } catch (Exception ex) { log.LogError($"Error processing tenant: {ex.Message}"); } } log.LogInformation($"Finished processing tenant ID {tenant.TenantID} / {tenant.Name}"); } // Send E-Mail Notification if (sendMailNotification && agentUpdatedCounter > 0) { string mailServer = GetEnvironmentVariable("MailServer", true); int mailServerPort = Convert.ToInt32(GetEnvironmentVariable("MailServerPort", true)); bool mailUseTls = Convert.ToBoolean(GetEnvironmentVariable("MailServerUseTls")); bool mailAuthenticated = Convert.ToBoolean(GetEnvironmentVariable("MailAuthenticated")); string mailUsername = GetEnvironmentVariable("MailUsername", true); string mailPassword = GetEnvironmentVariable("MailPassword", true); MailboxAddress mailFromAddress = MailboxAddress.Parse(GetEnvironmentVariable("MailFrom")); List <MailboxAddress> mailToAddresses = new List <MailboxAddress>(); // Get array of to addresses string[] toAddressesStr = GetEnvironmentVariable("MailTo").Split(","); foreach (string toAddressStr in toAddressesStr) { try { MailboxAddress toAddress = MailboxAddress.Parse(toAddressStr); mailToAddresses.Add(toAddress); log.LogDebug($"Added {toAddressStr} to status mail recipient list"); } catch { log.LogError($"Failed to parse email address {toAddressStr}"); } } log.LogDebug($"E-Mail notification in the making..."); List <AgentUpdateEntity> updateTable = await tableStorageClient.GetTableDataForUpdateRun(updateRunDateTime); log.LogDebug($"Fetched Table"); SecureSocketOptions socketOptions = SecureSocketOptions.Auto; if (mailUseTls) { socketOptions = SecureSocketOptions.StartTls; } EMailController mailController = new EMailController(mailServer, mailServerPort, socketOptions, mailAuthenticated, mailUsername, mailPassword); mailController.sendAgentUpdateTable(mailFromAddress, mailToAddresses, updateTable); log.LogInformation($"Status Mail sent"); } log.LogInformation($"Updated {agentUpdatedCounter} agents :-)"); }