diff --git a/pkg/alerts/nrql_conditions.go b/pkg/alerts/nrql_conditions.go index 467eb5798..0add9ae35 100644 --- a/pkg/alerts/nrql_conditions.go +++ b/pkg/alerts/nrql_conditions.go @@ -31,6 +31,7 @@ type AlertsNrqlConditionSignal struct { AggregationDelay *int `json:"aggregationDelay,omitempty"` AggregationTimer *int `json:"aggregationTimer,omitempty"` SlideBy *int `json:"slideBy,omitempty"` + PollingFrequency *int `json:"pollingFrequency,omitempty"` } // AlertsNrqlConditionCreateSignal - Configuration that defines the signal that the NRQL condition will use to evaluate for Create. @@ -45,6 +46,7 @@ type AlertsNrqlConditionCreateSignal struct { AggregationDelay *int `json:"aggregationDelay,omitempty"` AggregationTimer *int `json:"aggregationTimer,omitempty"` SlideBy *int `json:"slideBy,omitempty"` + PollingFrequency *int `json:"pollingFrequency"` } // AlertsNrqlConditionUpdateSignal - Configuration that defines the signal that the NRQL condition will use to evaluate for Update. @@ -59,6 +61,7 @@ type AlertsNrqlConditionUpdateSignal struct { AggregationDelay *int `json:"aggregationDelay"` AggregationTimer *int `json:"aggregationTimer"` SlideBy *int `json:"slideBy"` + PollingFrequency *int `json:"pollingFrequency,omitempty"` } // NrqlConditionAggregationMethod - The available aggregation methods. @@ -785,6 +788,7 @@ const ( aggregationDelay aggregationTimer slideBy + pollingFrequency } ` diff --git a/pkg/alerts/nrql_conditions_integration_test.go b/pkg/alerts/nrql_conditions_integration_test.go index e96c1b4b8..a2052642c 100644 --- a/pkg/alerts/nrql_conditions_integration_test.go +++ b/pkg/alerts/nrql_conditions_integration_test.go @@ -30,6 +30,8 @@ var ( nrqlConditionTitleTemplate = "Title {{ createdAt }}" // needed for setting pointer nrqlConditionPredictBy = 7200 // needed for setting pointer nrqlConditionSignalSeasonality = NrqlSignalSeasonalities.Weekly // needed for setting pointer + nrqlConditionBasePollingFrequency = 3600 // needed for setting pointer + nrqlConditionBasePollingAggWindow = 3600 // needed for setting pointer nrqlConditionCreateBase = NrqlConditionCreateBase{ Description: "test description", Enabled: true, @@ -1229,3 +1231,143 @@ func TestIntegrationNrqlConditions_DisableHealthStatusReporting(t *testing.T) { } }() } + +func TestIntegrationNrqlConditions_SignalPollingFrequency(t *testing.T) { + t.Parallel() + + testAccountID, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + var ( + updatedPollingFrequency = 7200 + ) + + var conditionCreateInput = NrqlConditionCreateInput{ + NrqlConditionCreateBase: NrqlConditionCreateBase{ + Enabled: true, + Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), + Nrql: NrqlConditionCreateQuery{ + Query: "select count(*) from CloudCost", + DataAccountId: &testAccountID, + }, + Terms: []NrqlConditionTerm{ + { + Threshold: &nrqlConditionBaseThreshold, + ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, + ThresholdDuration: 3600, + Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, + Priority: NrqlConditionPriorities.Critical, + }, + }, + ViolationTimeLimitSeconds: 3600, + Signal: &AlertsNrqlConditionCreateSignal{ + AggregationWindow: &nrqlConditionBasePollingAggWindow, + EvaluationDelay: &nrqlConditionEvaluationDelay, + AggregationDelay: &nrqlConditionBaseAggDelay, + PollingFrequency: &nrqlConditionBasePollingFrequency, + }, + }, + } + var conditionCreateNilInput = NrqlConditionCreateInput{ + NrqlConditionCreateBase: NrqlConditionCreateBase{ + Enabled: true, + Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), + Nrql: NrqlConditionCreateQuery{ + Query: "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as cpuUsage FROM Metric WHERE appName like 'Dummy App'", + DataAccountId: &testAccountID, + }, + Terms: []NrqlConditionTerm{ + { + Threshold: &nrqlConditionBaseThreshold, + ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, + ThresholdDuration: 3600, + Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, + Priority: NrqlConditionPriorities.Critical, + }, + }, + ViolationTimeLimitSeconds: 3600, + Signal: &AlertsNrqlConditionCreateSignal{ + AggregationWindow: &nrqlConditionBasePollingAggWindow, + EvaluationDelay: &nrqlConditionEvaluationDelay, + AggregationDelay: &nrqlConditionBaseAggDelay, + PollingFrequency: nil, + }, + }, + } + var conditionUpdateInput = NrqlConditionUpdateInput{ + NrqlConditionUpdateBase: NrqlConditionUpdateBase{ + Enabled: true, + Name: fmt.Sprintf("test-nrql-condition-%s", testNrqlConditionRandomString), + Nrql: NrqlConditionUpdateQuery{ + Query: "select count(*) from CloudCost", + DataAccountId: &testAccountID, + }, + Terms: []NrqlConditionTerm{ + { + Threshold: &nrqlConditionBaseThreshold, + ThresholdOccurrences: ThresholdOccurrences.AtLeastOnce, + ThresholdDuration: 7200, + Operator: AlertsNRQLConditionTermsOperatorTypes.ABOVE, + Priority: NrqlConditionPriorities.Critical, + }, + }, + ViolationTimeLimitSeconds: 3600, + Signal: &AlertsNrqlConditionUpdateSignal{ + AggregationWindow: &nrqlConditionBasePollingAggWindow, + EvaluationDelay: &nrqlConditionEvaluationDelay, + AggregationDelay: &nrqlConditionBaseAggDelay, + PollingFrequency: &updatedPollingFrequency, + }, + }, + } + + var randStr = mock.RandSeq(5) + + // Setup + client := newIntegrationTestClient(t) + testPolicy := AlertsPolicyInput{ + IncidentPreference: AlertsIncidentPreferenceTypes.PER_POLICY, + Name: fmt.Sprintf("test-alert-policy-%s", randStr), + } + policy, err := client.CreatePolicyMutation(testAccountID, testPolicy) + require.NoError(t, err) + + // Test: Create (condition with Signal.PollingFrequency field) + + createdCondition, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, conditionCreateInput) + require.NoError(t, err) + require.NotNil(t, createdCondition) + require.NotNil(t, createdCondition.ID) + require.NotNil(t, createdCondition.PolicyID) + require.Equal(t, &nrqlConditionBasePollingFrequency, createdCondition.Signal.PollingFrequency) + + // Test: Create nil (condition with Signal.PollingFrequency field that is nil) + + createdNilCondition, err := client.CreateNrqlConditionStaticMutation(testAccountID, policy.ID, conditionCreateNilInput) + require.NoError(t, err) + require.NotNil(t, createdNilCondition) + require.NotNil(t, createdNilCondition.ID) + require.NotNil(t, createdNilCondition.PolicyID) + require.Nil(t, createdNilCondition.Signal.PollingFrequency) + + // Test: Get (condition with Signal.PollingFrequency field) + readResult, err := client.GetNrqlConditionQuery(testAccountID, createdCondition.ID) + require.NoError(t, err) + require.NotNil(t, readResult) + require.Equal(t, &nrqlConditionBasePollingFrequency, readResult.Signal.PollingFrequency) + + // Test: Update (condition with non-default Signal.PollingFrequency field) + updatedCondition, err := client.UpdateNrqlConditionStaticMutation(testAccountID, createdCondition.ID, conditionUpdateInput) + require.NoError(t, err) + require.Equal(t, &updatedPollingFrequency, updatedCondition.Signal.PollingFrequency) + + // Deferred teardown + defer func() { + _, err := client.DeletePolicyMutation(testAccountID, policy.ID) + if err != nil { + t.Logf("error cleaning up alert policy %s (%s): %s", policy.ID, policy.Name, err) + } + }() +} diff --git a/pkg/entityrelationship/entityrelationship_api.go b/pkg/entityrelationship/entityrelationship_api.go index 652259efd..7dca982f2 100644 --- a/pkg/entityrelationship/entityrelationship_api.go +++ b/pkg/entityrelationship/entityrelationship_api.go @@ -3,6 +3,7 @@ package entityrelationship import ( "context" + "github.com/newrelic/newrelic-client-go/v2/pkg/common" )