示例#1
0
        private async Task RejectAlertWhenRequirementsAreNotMet(int reportId, AlertRule alertRule, Alert inspectedAlert)
        {
            var alertReportsWitUpdatedLabels = await _nyssContext.AlertReports
                                               .Where(ar => ar.AlertId == inspectedAlert.Id)
                                               .Where(ar => ar.ReportId != reportId)
                                               .Select(ar => ar.Report)
                                               .ToListAsync();

            var updatedReportsGroupedByLabel = alertReportsWitUpdatedLabels.GroupBy(r => r.ReportGroupLabel).ToList();

            var noGroupWithinAlertSatisfiesCountThreshold = !updatedReportsGroupedByLabel.Any(g => g.Count() >= alertRule.CountThreshold);

            if (noGroupWithinAlertSatisfiesCountThreshold)
            {
                if (inspectedAlert.Status != AlertStatus.Dismissed)
                {
                    inspectedAlert.Status = AlertStatus.Rejected;
                }

                foreach (var groupNotSatisfyingThreshold in updatedReportsGroupedByLabel)
                {
                    var reportGroupLabel = groupNotSatisfyingThreshold.Key;
                    await IncludeAllReportsWithLabelInExistingAlert(reportGroupLabel, inspectedAlert.Id);
                }
            }
        }
示例#2
0
        public static PSSentinelAlertRule ConvertToPSType(this AlertRule value)
        {
            var convertedFusionValue = value as FusionAlertRule;

            if (convertedFusionValue != null)
            {
                return(convertedFusionValue.ConvertToPSType());
            }

            var convertedMicrosoftSecurityIncidentCreationValue = value as MicrosoftSecurityIncidentCreationAlertRule;

            if (convertedMicrosoftSecurityIncidentCreationValue != null)
            {
                return(convertedMicrosoftSecurityIncidentCreationValue.ConvertToPSType());
            }

            var convertedScheduledValue = value as ScheduledAlertRule;

            if (convertedScheduledValue != null)
            {
                return(convertedScheduledValue.ConvertToPSType());
            }

            return(new PSSentinelAlertRule()
            {
                Kind = "Error",
                Name = value.Name
            });
        }
示例#3
0
 private void StopOldRule(AlertRule oldExternalRule, InternalRule newInternalRule)
 {
     if (_ruleStore.TryGetValue(oldExternalRule.PrivateKey.ToLower(), out var oldInternalRule))
     {
         if (newInternalRule != null)
         {
             newInternalRule.LastStatus = oldInternalRule.LastStatus;
         }
         oldInternalRule.DataSubs?.Cancel();
     }
     // update rule store
     _ruleStore.Remove(oldExternalRule.PrivateKey.ToLower());
 }
示例#4
0
        public async Task RemoveHealthRisk_WhenAlertIsNotNull_ShouldRemoveAlertFromTheContext()
        {
            // Arrange
            var projectHealthRisks          = new List <ProjectHealthRisk>();
            var projectHealthRisksMockDbSet = projectHealthRisks.AsQueryable().BuildMockDbSet();

            _nyssContextMock.ProjectHealthRisks.Returns(projectHealthRisksMockDbSet);

            var alertRule = new AlertRule();

            _healthRisk.AlertRule = alertRule;

            // Act
            await _healthRiskService.Delete(HealthRiskId);

            // Assert
            _nyssContextMock.AlertRules.Received(1).Remove(alertRule);
        }
示例#5
0
        public InternalRule(AlertRule rule)
        {
            RuleName     = rule.RuleUniqueId;
            Disabled     = rule.Disabled;
            DataTypeName = rule.DataTypeName;
            DataSubsExpr = rule.DataSubsExpr != null?Expr.Create(rule.DataSubsExpr) : Expr.Const(false);

            DataItemKind = EnumHelper.Parse(rule.DataItemKind, true, ItemKind.Undefined);
            Condition    = rule.Condition != null?Expr.Create(rule.Condition) : Expr.Const(false);

            Constraint = rule.Constraint != null?Expr.Create(rule.Constraint) : Expr.Const(true);

            Properties    = rule.AlertProperties != null ? new NamedValueSet(rule.AlertProperties) : new NamedValueSet();
            MonitorPeriod = rule.MonitorPeriod != null?TimeSpan.Parse(rule.MonitorPeriod) : TimeSpan.FromMinutes(1);

            PublishPeriod = rule.PublishPeriod != null?TimeSpan.Parse(rule.PublishPeriod) : TimeSpan.FromMinutes(5);

            SignalFormat = rule.SignalFormat;
        }
示例#6
0
        public async Task WhenUpdatingAlertRuleThenUpdateIsCalledCorrectly()
        {
            var ruleToUpdate = new AlertRule
            {
                Id = "ruleId",
                SmartDetectorId = "smartDetectorId",
                Cadence         = TimeSpan.FromMinutes(1440),
                ResourceId      = "resourceId"
            };

            await this.alertRuleStore.AddOrReplaceAlertRuleAsync(ruleToUpdate, CancellationToken.None);

            this.tableMock.Verify(m => m.ExecuteAsync(
                                      It.Is <TableOperation>(operation =>
                                                             operation.OperationType == TableOperationType.InsertOrReplace &&
                                                             operation.Entity.RowKey.Equals(ruleToUpdate.Id) &&
                                                             ((AlertRuleEntity)operation.Entity).SmartDetectorId.Equals(ruleToUpdate.SmartDetectorId) &&
                                                             ((AlertRuleEntity)operation.Entity).CadenceInMinutes.Equals(1440) &&
                                                             ((AlertRuleEntity)operation.Entity).ResourceId.Equals(ruleToUpdate.ResourceId)),
                                      It.IsAny <CancellationToken>()));
        }
示例#7
0
 private void StartNewRule(AlertRule newExternalRule, InternalRule newInternalRule)
 {
     if (!newInternalRule.Disabled && newInternalRule.DataSubsExpr != null)
     {
         newInternalRule.DataSubs = IntClient.Target.CreateUntypedSubscription(null, newInternalRule.DataSubsExpr);
         newInternalRule.DataSubs.UserCallback =
             delegate(ISubscription subscription, ICoreItem item)
         {
             var       rule     = (InternalRule)subscription.UserContext;
             ICoreItem lastItem = rule.CurrentReceivedItem;
             if (lastItem == null || (item.Created > lastItem.Created))
             {
                 rule.CurrentReceivedItem = item;
             }
         };
         newInternalRule.DataSubs.UserContext     = newInternalRule;
         newInternalRule.DataSubs.DataTypeName    = newInternalRule.DataTypeName;
         newInternalRule.DataSubs.WaitForExisting = true;
         newInternalRule.DataSubs.Start();
         Thread.Sleep(2000);
     }
     // update rule store
     _ruleStore[newExternalRule.PrivateKey.ToLower()] = newInternalRule;
 }
示例#8
0
        private IEnumerable <AlertRule> ReadAlertRules(IResourceGroup resourceGroup)
        {
            var alertRule  = new AlertRule(resourceGroup);
            var alertRules = new List <AlertRule> {
                alertRule
            };
            var azureAlertRules = _azure.AlertRules;

            foreach (var metricAlert in azureAlertRules.MetricAlerts.ListByResourceGroup(resourceGroup.Name))
            {
                MetricAlert metric = new MetricAlert(metricAlert.Name);
                alertRule.MetricAlerts.Add(metric);
            }

            // Microsoft.Azure.Management.Monitor.Fluent.Models.ErrorResponseException. v
            // Operation returned an invalid status code 'NotFound'
            foreach (var activityLogAlert in azureAlertRules.ActivityLogAlerts.ListByResourceGroup(resourceGroup.Name))
            {
                ActivityLogAlert activity = new ActivityLogAlert(activityLogAlert.Name);
                alertRule.ActivityLogAlerts.Add(activity);
            }

            return(alertRules);
        }
示例#9
0
        private async Task RecalculateAlert(Report report, AlertRule alertRule)
        {
            var pointsWithLabels = await _reportLabelingService.CalculateNewLabelsInLabelGroup(report.ReportGroupLabel, alertRule.KilometersThreshold.Value * 1000 * 2, report.Id);

            await _reportLabelingService.UpdateLabelsInDatabaseDirect(pointsWithLabels);
        }
 private void ValidateAlertRule(AlertRule AlertRule)
 {
     Assert.NotNull(AlertRule);
 }
示例#11
0
 /// <summary>
 ///     Saves an alert rule
 /// </summary>
 /// <param name="alertRule">The alert rule</param>
 /// <param name="cancellationToken">The cancellation token</param>
 public async Task SaveAlertRuleAsync(AlertRule alertRule, CancellationToken cancellationToken = default)
 => await PutAsync($"setting/alert/rules/{alertRule.Id}?data=%5Bobject+Object%5D", alertRule, cancellationToken).ConfigureAwait(false);
示例#12
0
 /// <summary>
 /// Creates or updates the alert rule.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group. The name is case insensitive.
 /// </param>
 /// <param name='workspaceName'>
 /// The name of the workspace.
 /// </param>
 /// <param name='ruleId'>
 /// Alert rule ID
 /// </param>
 /// <param name='alertRule'>
 /// The alert rule
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task <AlertRule> CreateOrUpdateAsync(this IAlertRulesOperations operations, string resourceGroupName, string workspaceName, string ruleId, AlertRule alertRule, CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var _result = await operations.CreateOrUpdateWithHttpMessagesAsync(resourceGroupName, workspaceName, ruleId, alertRule, null, cancellationToken).ConfigureAwait(false))
     {
         return(_result.Body);
     }
 }
示例#13
0
 /// <summary>
 /// Creates or updates the alert rule.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group. The name is case insensitive.
 /// </param>
 /// <param name='workspaceName'>
 /// The name of the workspace.
 /// </param>
 /// <param name='ruleId'>
 /// Alert rule ID
 /// </param>
 /// <param name='alertRule'>
 /// The alert rule
 /// </param>
 public static AlertRule CreateOrUpdate(this IAlertRulesOperations operations, string resourceGroupName, string workspaceName, string ruleId, AlertRule alertRule)
 {
     return(operations.CreateOrUpdateAsync(resourceGroupName, workspaceName, ruleId, alertRule).GetAwaiter().GetResult());
 }
示例#14
0
 public AlertRuleRunner(AlertRule alertRule)
 {
     _alertRule = alertRule;
 }
示例#15
0
        /// <summary>
        /// Sends the Smart Signal result Email.
        /// </summary>
        /// <param name="signalExecution">The signals execution information.</param>
        /// <param name="smartSignalResultItems">The Smart Signal result items.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public async Task SendSignalResultEmailAsync(SignalExecutionInfo signalExecution, IList <SmartSignalResultItemPresentation> smartSignalResultItems)
        {
            AlertRule alertRule = signalExecution.AlertRule;

            if (this.sendGridClient == null)
            {
                this.tracer.TraceWarning("SendGrid API key was not found, not sending email");
                return;
            }

            if (alertRule.EmailRecipients == null || !alertRule.EmailRecipients.Any())
            {
                this.tracer.TraceWarning("Email recipients were not provided, not sending email");
                return;
            }

            if (smartSignalResultItems == null || !smartSignalResultItems.Any())
            {
                this.tracer.TraceInformation($"no result items to publish for signal {alertRule.SignalId}");
                return;
            }

            this.tracer.TraceInformation($"Sending signal result email for signal {alertRule.SignalId}");

            var exceptions = new List <Exception>();

            foreach (SmartSignalResultItemPresentation resultItem in smartSignalResultItems)
            {
                ResourceIdentifier resource = ResourceIdentifier.CreateFromResourceId(alertRule.ResourceId);

                // TODO: Fix links
                string emailBody = Resources.SmartSignalEmailTemplate
                                   .Replace(SignalNamePlaceHolder, resultItem.SignalName)
                                   .Replace(ResourceNamePlaceHolder, resultItem.ResourceId)
                                   .Replace(LinkToPortalPlaceHolder, "LinkToPortal")
                                   .Replace(RuleNamePlaceHolder, alertRule.Name)
                                   .Replace(RuleDescriptionPlaceHolder, alertRule.Description)
                                   .Replace(ServiceNamePlaceHolder, $@"{resource.ResourceType}: {resource.ResourceName} ({resource.ResourceGroupName})")
                                   .Replace(AlertActivatedTimePlaceHolder, signalExecution.LastExecutionTime.ToString())
                                   .Replace(SubscriptionNamePlaceHolder, resource.SubscriptionId)
                                   .Replace(LinkToFeedbackPlaceHolder, "https://ms.portal.azure.com/");

                var msg = new SendGridMessage
                {
                    From             = new EmailAddress("*****@*****.**", "Smart Signals"),
                    Subject          = $"Azure Smart Alerts (preview) - {resultItem.SignalName} detected",
                    PlainTextContent = $@"{resultItem.SignalName} was detected for {resultItem.ResourceId}. 
                                        You can view more details for this alert here: {"LinkToPortal"}",
                    HtmlContent      = emailBody
                };

                var emailAddresses = alertRule.EmailRecipients.Select(email => new EmailAddress(email)).ToList();
                msg.AddTos(emailAddresses);

                try
                {
                    var response = await this.sendGridClient.SendEmailAsync(msg);

                    if (!IsSuccessStatusCode(response.StatusCode))
                    {
                        string content = response.Body != null ? await response.Body.ReadAsStringAsync() : string.Empty;

                        var message = $"Failed to send signal results Email for signal {alertRule.SignalId}. Fail StatusCode: {response.StatusCode}. Content: {content}.";
                        this.tracer.TraceError(message);
                        exceptions.Add(new EmailSendingException(message));
                    }
                }
                catch (Exception e)
                {
                    this.tracer.TraceError($"Failed to send email. Exception: {e}");
                    exceptions.Add(new EmailSendingException($"Exception was thrown fo sending signal results Email for signal {alertRule.SignalId}. Exception: {e}"));
                }
            }

            if (exceptions.Count > 0)
            {
                this.tracer.TraceError(
                    $"Failed to send one or more signal result emails." +
                    $"Number of exceptions thrown: {exceptions.Count()}.");
                throw new AggregateException("Failed to send one or more signal result emails", exceptions);
            }

            this.tracer.TraceInformation($"Sent signal result emails successfully for signal {alertRule.SignalId}");
        }