mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-11-10 16:30:38 +08:00
574 lines
17 KiB
Go
574 lines
17 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
testWebhookID = "fe49ee055d23404e9d58f9110b210c8d"
|
|
testPolicyID = "6ec8a5145d0d2263a36fad55c03cb43d"
|
|
)
|
|
|
|
var (
|
|
notificationTimestamp = time.Date(2021, 05, 01, 10, 47, 01, 01, time.UTC)
|
|
)
|
|
|
|
func TestGetEligibleNotificationDestinations(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
expected := NotificationMechanisms{
|
|
Email: NotificationMechanismMetaData{true, true, "email"},
|
|
PagerDuty: NotificationMechanismMetaData{true, true, "pagerduty"},
|
|
Webhooks: NotificationMechanismMetaData{true, true, "webhooks"},
|
|
}
|
|
b, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`, string(b))
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/eligible", handler)
|
|
|
|
actual, err := client.GetEligibleNotificationDestinations(context.Background(), testAccountID)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actual)
|
|
assert.Equal(t, expected, actual.Result)
|
|
}
|
|
func TestGetAvailableNotificationTypes(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
expected := make(NotificationsGroupedByProduct, 1)
|
|
alert1 := NotificationAlertWithDescription{Type: "secondary_dns_zone_successfully_updated", DisplayName: "Secondary DNS Successfully Updated", Description: "Secondary zone transfers are succeeding, the zone has been updated."}
|
|
alert2 := NotificationAlertWithDescription{Type: "secondary_dns_zone_validation_warning", DisplayName: "Secondary DNSSEC Validation Warning", Description: "The transferred DNSSEC zone is incorrectly configured."}
|
|
expected["DNS"] = []NotificationAlertWithDescription{alert1, alert2}
|
|
|
|
b, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/available_alerts", handler)
|
|
|
|
actual, err := client.GetAvailableNotificationTypes(context.Background(), testAccountID)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actual)
|
|
assert.Equal(t, expected, actual.Result)
|
|
}
|
|
func TestListPagerDutyDestinations(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
expected := NotificationPagerDutyResource{ID: "valid-uuid", Name: "my pagerduty connection"}
|
|
b, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/pagerduty", handler)
|
|
|
|
actual, err := client.ListPagerDutyNotificationDestinations(context.Background(), testAccountID)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actual)
|
|
assert.Equal(t, expected, actual.Result)
|
|
}
|
|
|
|
func TestCreateNotificationPolicy(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
mechanisms := make(map[string]NotificationMechanismIntegrations)
|
|
mechanisms["email"] = []NotificationMechanismData{{Name: "email to send notification", ID: "test@gmail.com"}}
|
|
policy := NotificationPolicy{
|
|
Description: "Notifies when my zones are under attack",
|
|
Name: "CF DOS attack alert - L4",
|
|
Enabled: true,
|
|
AlertType: "dos_attack_l4",
|
|
Mechanisms: mechanisms,
|
|
Conditions: nil,
|
|
Filters: nil,
|
|
}
|
|
b, err := json.Marshal(policy)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/policies", handler)
|
|
res, err := client.CreateNotificationPolicy(context.Background(), testAccountID, policy)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
}
|
|
|
|
func TestGetNotificationPolicy(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
mechanisms := make(map[string]NotificationMechanismIntegrations)
|
|
mechanisms["email"] = []NotificationMechanismData{{Name: "email to send notification", ID: "test@gmail.com"}}
|
|
policy := NotificationPolicy{
|
|
ID: testPolicyID,
|
|
Description: "Notifies when my zones are under attack",
|
|
Name: "CF DOS attack alert - L4",
|
|
Enabled: true,
|
|
AlertType: "dos_attack_l4",
|
|
Mechanisms: mechanisms,
|
|
Conditions: nil,
|
|
Filters: nil,
|
|
Created: notificationTimestamp,
|
|
Modified: notificationTimestamp,
|
|
}
|
|
b, err := json.Marshal(policy)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/policies/"+testPolicyID, handler)
|
|
|
|
res, err := client.GetNotificationPolicy(context.Background(), testAccountID, testPolicyID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, policy, res.Result)
|
|
}
|
|
|
|
func TestListNotificationPolicies(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
mechanisms := make(map[string]NotificationMechanismIntegrations)
|
|
mechanisms["email"] = []NotificationMechanismData{{Name: "email to send notification", ID: "test@gmail.com"}}
|
|
policy := NotificationPolicy{
|
|
ID: testPolicyID,
|
|
Description: "Notifies when my zones are under attack",
|
|
Name: "CF DOS attack alert - L4",
|
|
Enabled: true,
|
|
AlertType: "dos_attack_l4",
|
|
Mechanisms: mechanisms,
|
|
Conditions: nil,
|
|
Filters: nil,
|
|
Created: time.Date(2021, 05, 01, 10, 47, 01, 01, time.UTC),
|
|
Modified: time.Date(2021, 05, 01, 10, 47, 01, 01, time.UTC),
|
|
}
|
|
policies := []NotificationPolicy{
|
|
policy,
|
|
}
|
|
b, err := json.Marshal(policies)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/policies", handler)
|
|
|
|
res, err := client.ListNotificationPolicies(context.Background(), testAccountID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, policies, res.Result)
|
|
}
|
|
|
|
func TestUpdateNotificationPolicy(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
mechanisms := make(map[string]NotificationMechanismIntegrations)
|
|
mechanisms["email"] = []NotificationMechanismData{{Name: "email to send notification", ID: "test@gmail.com"}}
|
|
policy := NotificationPolicy{
|
|
ID: testPolicyID,
|
|
Description: "Notifies when my zones are under attack",
|
|
Name: "CF DOS attack alert - L4",
|
|
Enabled: true,
|
|
AlertType: "dos_attack_l4",
|
|
Mechanisms: mechanisms,
|
|
Conditions: nil,
|
|
Filters: nil,
|
|
Created: time.Date(2021, 05, 01, 10, 47, 01, 01, time.UTC),
|
|
Modified: time.Date(2021, 05, 01, 10, 47, 01, 01, time.UTC),
|
|
}
|
|
b, err := json.Marshal(policy)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/policies/"+testPolicyID, handler)
|
|
|
|
res, err := client.UpdateNotificationPolicy(context.Background(), testAccountID, &policy)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, testPolicyID, res.Result.ID)
|
|
}
|
|
|
|
func TestDeleteNotificationPolicy(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
result := NotificationResource{ID: testPolicyID}
|
|
b, err := json.Marshal(result)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/policies/"+testPolicyID, handler)
|
|
|
|
res, err := client.DeleteNotificationPolicy(context.Background(), testAccountID, testPolicyID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, testPolicyID, res.Result.ID)
|
|
}
|
|
|
|
func TestCreateNotificationWebhooks(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
webhook := NotificationUpsertWebhooks{
|
|
Name: "my test webhook",
|
|
URL: "https://example.com",
|
|
Secret: "mischief-managed", // optional
|
|
}
|
|
|
|
result := NotificationResource{ID: testWebhookID}
|
|
|
|
b, err := json.Marshal(result)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/webhooks", handler)
|
|
|
|
res, err := client.CreateNotificationWebhooks(context.Background(), testAccountID, &webhook)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, testWebhookID, res.Result.ID)
|
|
}
|
|
|
|
func TestListNotificationWebhooks(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
webhook := NotificationWebhookIntegration{
|
|
ID: testWebhookID,
|
|
Name: "my test webhook",
|
|
URL: "https://example.com",
|
|
Type: "generic",
|
|
CreatedAt: notificationTimestamp,
|
|
LastSuccess: ¬ificationTimestamp,
|
|
LastFailure: ¬ificationTimestamp,
|
|
}
|
|
webhooks := []NotificationWebhookIntegration{webhook}
|
|
b, err := json.Marshal(webhooks)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/webhooks", handler)
|
|
|
|
res, err := client.ListNotificationWebhooks(context.Background(), testAccountID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, webhooks, res.Result)
|
|
}
|
|
|
|
func TestGetNotificationWebhooks(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
webhook := NotificationWebhookIntegration{
|
|
ID: testWebhookID,
|
|
Name: "my test webhook",
|
|
URL: "https://example.com",
|
|
Type: "generic",
|
|
CreatedAt: notificationTimestamp,
|
|
LastSuccess: ¬ificationTimestamp,
|
|
LastFailure: ¬ificationTimestamp,
|
|
}
|
|
b, err := json.Marshal(webhook)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/webhooks/"+testWebhookID, handler)
|
|
|
|
res, err := client.GetNotificationWebhooks(context.Background(), testAccountID, testWebhookID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, webhook, res.Result)
|
|
}
|
|
|
|
func TestUpdateNotificationWebhooks(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
result := NotificationResource{ID: testWebhookID}
|
|
b, err := json.Marshal(result)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
webhook := NotificationUpsertWebhooks{
|
|
Name: "my test webhook with a new name",
|
|
URL: "https://example.com",
|
|
Secret: "mischief-managed",
|
|
}
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/webhooks/"+testWebhookID, handler)
|
|
|
|
res, err := client.UpdateNotificationWebhooks(context.Background(), testAccountID, testWebhookID, &webhook)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, testWebhookID, res.Result.ID)
|
|
}
|
|
|
|
func TestDeleteNotificationWebhooks(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
result := NotificationResource{ID: testWebhookID}
|
|
b, err := json.Marshal(result)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, b)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result":%s
|
|
}`,
|
|
string(b))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/destinations/webhooks/"+testWebhookID, handler)
|
|
|
|
res, err := client.DeleteNotificationWebhooks(context.Background(), testAccountID, testWebhookID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, res)
|
|
|
|
assert.Equal(t, testWebhookID, res.Result.ID)
|
|
}
|
|
|
|
func TestListNotificationHistory(t *testing.T) {
|
|
setup()
|
|
defer teardown()
|
|
|
|
expected := []NotificationHistory{
|
|
{
|
|
ID: "some-id",
|
|
Name: "some-name",
|
|
Description: "some-description",
|
|
AlertBody: "some-alert-body",
|
|
AlertType: "some-alert-type",
|
|
Mechanism: "some-mechanism",
|
|
MechanismType: "some-mechanism-type",
|
|
Sent: notificationTimestamp,
|
|
},
|
|
}
|
|
|
|
expectedResultInfo := ResultInfo{
|
|
Page: 0,
|
|
PerPage: 25,
|
|
Count: 1,
|
|
}
|
|
|
|
pageOptions := PaginationOptions{
|
|
PerPage: 25,
|
|
Page: 1,
|
|
}
|
|
|
|
timeRange := TimeRange{
|
|
Since: time.Now().Add(-15 * time.Minute).Format(time.RFC3339),
|
|
Before: time.Now().Format(time.RFC3339),
|
|
}
|
|
|
|
historyFilters := AlertHistoryFilter{TimeRange: timeRange, PaginationOptions: pageOptions}
|
|
|
|
alertHistory, err := json.Marshal(expected)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, alertHistory)
|
|
|
|
resultInfo, err := json.Marshal(expectedResultInfo)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, resultInfo)
|
|
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
assert.Equal(t, http.MethodGet, r.Method, "expected method 'GET', got %s", r.Method)
|
|
w.Header().Set("content-type", "application/json")
|
|
_, err = fmt.Fprintf(w, `{
|
|
"success": true,
|
|
"errors": [],
|
|
"messages": [],
|
|
"result_info": %s,
|
|
"result": %s
|
|
}`,
|
|
string(resultInfo),
|
|
string(alertHistory))
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
mux.HandleFunc("/accounts/"+testAccountID+"/alerting/v3/history", handler)
|
|
|
|
actualResult, actualResultInfo, err := client.ListNotificationHistory(context.Background(), testAccountID, historyFilters)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, actualResult)
|
|
require.Equal(t, expected, actualResult)
|
|
require.Equal(t, expectedResultInfo, actualResultInfo)
|
|
}
|