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);
            }
        }
示例#4
0
        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));
                }
            }
        }