internal async Task <bool> ConfigureAsync(InstanceName instance, string name, bool?disable = null, bool?impersonate = null, bool?bypassrules = null, CancellationToken cancellationToken = default) { var webFunctionApp = await GetWebApp(instance, cancellationToken); var configuration = await AggregatorConfiguration.ReadConfiguration(webFunctionApp); var ruleConfig = configuration.GetRuleConfiguration(name); if (disable.HasValue) { ruleConfig.IsDisabled = disable.Value; } if (impersonate.HasValue) { ruleConfig.Impersonate = impersonate.Value; } if (bypassrules.HasValue) { ruleConfig.BypassRules = impersonate.Value; } ruleConfig.WriteConfiguration(webFunctionApp); return(true); }
internal async Task <bool> ChangeAppSettingsAsync(InstanceName instance, DevOpsLogon devopsLogonData, SaveMode saveMode, CancellationToken cancellationToken) { var webFunctionApp = await GetWebApp(instance, cancellationToken); var configuration = await AggregatorConfiguration.ReadConfiguration(webFunctionApp); configuration.DevOpsTokenType = devopsLogonData.Mode; configuration.DevOpsToken = devopsLogonData.Token; configuration.SaveMode = saveMode; configuration.WriteConfiguration(webFunctionApp); return(true); }
internal async Task <IEnumerable <RuleOutputData> > ListAsync(InstanceName instance, CancellationToken cancellationToken) { var kudu = GetKudu(instance); _logger.WriteInfo($"Retrieving Functions in {instance.PlainName}..."); var webFunctionApp = await GetWebApp(instance, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); var configuration = await AggregatorConfiguration.ReadConfiguration(webFunctionApp); using (var client = new HttpClient()) { KuduFunction[] kuduFunctions; using (var request = await kudu.GetRequestAsync(HttpMethod.Get, $"api/functions", cancellationToken)) using (var response = await client.SendAsync(request, cancellationToken)) { var stream = await response.Content.ReadAsStreamAsync(); if (!response.IsSuccessStatusCode) { _logger.WriteError($"{response.ReasonPhrase} {await response.Content.ReadAsStringAsync()}"); return(Enumerable.Empty <RuleOutputData>()); } using (var sr = new StreamReader(stream)) using (var jtr = new JsonTextReader(sr)) { var js = new JsonSerializer(); kuduFunctions = js.Deserialize <KuduFunction[]>(jtr); } } List <RuleOutputData> ruleData = new List <RuleOutputData>(); foreach (var kuduFunction in kuduFunctions) { var ruleName = kuduFunction.Name; var ruleFileUrl = $"api/vfs/site/wwwroot/{ruleName}/{ruleName}.rule"; _logger.WriteInfo($"Retrieving Function Rule Details {ruleName}..."); using (var request = await kudu.GetRequestAsync(HttpMethod.Get, ruleFileUrl, cancellationToken)) using (var response = await client.SendAsync(request, cancellationToken)) { var stream = await response.Content.ReadAsStreamAsync(); if (!response.IsSuccessStatusCode) { _logger.WriteError($"{response.ReasonPhrase} {await response.Content.ReadAsStringAsync()}"); continue; } var ruleCode = new List <string>(); using (var sr = new StreamReader(stream)) { string line; while ((line = sr.ReadLine()) != null) { ruleCode.Add(line); } } var ruleConfiguration = configuration.GetRuleConfiguration(ruleName); var(preprocessedRule, _) = RuleFileParser.Read(ruleCode.ToArray()); ruleData.Add(new RuleOutputData(instance, ruleConfiguration, preprocessedRule.LanguageAsString())); } } return(ruleData); } }
public async Task <IActionResult> PostAsync(WebHookEvent eventData, string ruleName, CancellationToken cancellationToken) { var aggregatorVersion = RequestHelper.AggregatorVersion; _log.LogInformation($"Aggregator v{aggregatorVersion} executing rule '{ruleName}'"); var webHookStartEvent = new EventTelemetry() { Name = "WebHookEvent Start" }; webHookStartEvent.Properties["rule"] = ruleName; webHookStartEvent.Properties["eventType"] = eventData?.EventType; webHookStartEvent.Properties["resourceVersion"] = eventData?.ResourceVersion; Telemetry.TrackEvent(webHookStartEvent); if (eventData == null) { return(BadRequest("Request body is empty")); } // sanity check if (!DevOpsEvents.IsValidEvent(eventData.EventType) || eventData.PublisherId != DevOpsEvents.PublisherId) { _log.LogDebug("return BadRequest"); return(BadRequest(new { Error = "Not a good Azure DevOps post..." })); } var helper = new RequestHelper(_log); var eventContext = helper.CreateContextFromEvent(eventData); if (eventContext.IsTestEvent()) { Response.AddCustomHeaders(aggregatorVersion, ruleName); return(RespondToTestEventMessage(aggregatorVersion, ruleName)); } var configContext = _configuration; var configuration = AggregatorConfiguration.ReadConfiguration(configContext) .UpdateFromUrl(ruleName, GetRequestUri()); var logger = new ForwarderLogger(_log); var ruleProvider = new AspNetRuleProvider(logger, _configuration); var ruleExecutor = new RuleExecutor(logger, configuration); using (_log.BeginScope($"WorkItem #{eventContext.WorkItemPayload.WorkItem.Id}")) { try { var rule = await ruleProvider.GetRule(ruleName); var ruleStartEvent = new EventTelemetry() { Name = "Rule Exec Start" }; ruleStartEvent.Properties["rule"] = rule.Name; ruleStartEvent.Properties["ImpersonateExecution"] = rule.ImpersonateExecution.ToString(); ruleStartEvent.Properties["EnableRevisionCheck"] = rule.Settings.EnableRevisionCheck.ToString(); ruleStartEvent.Properties["eventType"] = eventContext.EventType; Telemetry.TrackEvent(ruleStartEvent); var ruleExecTimer = new Stopwatch(); ruleExecTimer.Start(); var execResult = await ruleExecutor.ExecuteAsync(rule, eventContext, cancellationToken); ruleExecTimer.Stop(); var ruleEndEvent = new EventTelemetry() { Name = "Rule Exec End" }; ruleEndEvent.Properties["rule"] = ruleName; ruleEndEvent.Metrics["duration"] = ruleExecTimer.ElapsedMilliseconds; Telemetry.TrackEvent(ruleEndEvent); if (string.IsNullOrEmpty(execResult)) { return(Ok()); } else { _log.LogInformation($"Returning '{execResult}' from '{rule.Name}'"); return(Ok(execResult)); } } catch (Exception ex) { _log.LogWarning($"Rule '{ruleName}' failed: {ex.Message}"); Telemetry.TrackException(ex); return(BadRequest(ex.Message)); } } }