mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-17 14:18:55 +08:00
447 lines
15 KiB
Go
447 lines
15 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
// NotificationMechanismData holds a single public facing mechanism data
|
|
// integation.
|
|
type NotificationMechanismData struct {
|
|
Name string `json:"name"`
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
// NotificationMechanismIntegrations is a list of all the integrations of a
|
|
// certain mechanism type e.g. all email integrations.
|
|
type NotificationMechanismIntegrations []NotificationMechanismData
|
|
|
|
// NotificationPolicy represents the notification policy created along with
|
|
// the destinations.
|
|
type NotificationPolicy struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Enabled bool `json:"enabled"`
|
|
AlertType string `json:"alert_type"`
|
|
Mechanisms map[string]NotificationMechanismIntegrations `json:"mechanisms"`
|
|
Created time.Time `json:"created"`
|
|
Modified time.Time `json:"modified"`
|
|
Conditions map[string]interface{} `json:"conditions"`
|
|
Filters map[string][]string `json:"filters"`
|
|
}
|
|
|
|
// NotificationPoliciesResponse holds the response for listing all
|
|
// notification policies for an account.
|
|
type NotificationPoliciesResponse struct {
|
|
Response
|
|
ResultInfo
|
|
Result []NotificationPolicy
|
|
}
|
|
|
|
// NotificationPolicyResponse holds the response type when a single policy
|
|
// is retrieved.
|
|
type NotificationPolicyResponse struct {
|
|
Response
|
|
Result NotificationPolicy
|
|
}
|
|
|
|
// NotificationWebhookIntegration describes the webhook information along
|
|
// with its status.
|
|
type NotificationWebhookIntegration struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
URL string `json:"url"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
LastSuccess *time.Time `json:"last_success"`
|
|
LastFailure *time.Time `json:"last_failure"`
|
|
}
|
|
|
|
// NotificationWebhookResponse describes a single webhook retrieved.
|
|
type NotificationWebhookResponse struct {
|
|
Response
|
|
ResultInfo
|
|
Result NotificationWebhookIntegration
|
|
}
|
|
|
|
// NotificationWebhooksResponse describes a list of webhooks retrieved.
|
|
type NotificationWebhooksResponse struct {
|
|
Response
|
|
ResultInfo
|
|
Result []NotificationWebhookIntegration
|
|
}
|
|
|
|
// NotificationUpsertWebhooks describes a valid webhook request.
|
|
type NotificationUpsertWebhooks struct {
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Secret string `json:"secret"`
|
|
}
|
|
|
|
// NotificationPagerDutyResource describes a PagerDuty integration.
|
|
type NotificationPagerDutyResource struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
// NotificationPagerDutyResponse describes the PagerDuty integration
|
|
// retrieved.
|
|
type NotificationPagerDutyResponse struct {
|
|
Response
|
|
ResultInfo
|
|
Result NotificationPagerDutyResource
|
|
}
|
|
|
|
// NotificationResource describes the id of an inserted/updated/deleted
|
|
// resource.
|
|
type NotificationResource struct {
|
|
ID string
|
|
}
|
|
|
|
// SaveResponse is returned when a resource is inserted/updated/deleted.
|
|
type SaveResponse struct {
|
|
Response
|
|
Result NotificationResource
|
|
}
|
|
|
|
// NotificationMechanismMetaData represents the state of the delivery
|
|
// mechanism.
|
|
type NotificationMechanismMetaData struct {
|
|
Eligible bool `json:"eligible"`
|
|
Ready bool `json:"ready"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
// NotificationMechanisms are the different possible delivery mechanisms.
|
|
type NotificationMechanisms struct {
|
|
Email NotificationMechanismMetaData `json:"email"`
|
|
PagerDuty NotificationMechanismMetaData `json:"pagerduty"`
|
|
Webhooks NotificationMechanismMetaData `json:"webhooks,omitempty"`
|
|
}
|
|
|
|
// NotificationEligibilityResponse describes the eligible mechanisms that
|
|
// can be configured for a notification.
|
|
type NotificationEligibilityResponse struct {
|
|
Response
|
|
Result NotificationMechanisms
|
|
}
|
|
|
|
// NotificationsGroupedByProduct are grouped by products.
|
|
type NotificationsGroupedByProduct map[string][]NotificationAlertWithDescription
|
|
|
|
// NotificationAlertWithDescription represents the alert/notification
|
|
// available.
|
|
type NotificationAlertWithDescription struct {
|
|
DisplayName string `json:"display_name"`
|
|
Type string `json:"type"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
// NotificationAvailableAlertsResponse describes the available
|
|
// alerts/notifications grouped by products.
|
|
type NotificationAvailableAlertsResponse struct {
|
|
Response
|
|
Result NotificationsGroupedByProduct
|
|
}
|
|
|
|
// NotificationHistory describes the history
|
|
// of notifications sent for an account.
|
|
type NotificationHistory struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
AlertBody string `json:"alert_body"`
|
|
AlertType string `json:"alert_type"`
|
|
Mechanism string `json:"mechanism"`
|
|
MechanismType string `json:"mechanism_type"`
|
|
Sent time.Time `json:"sent"`
|
|
}
|
|
|
|
// NotificationHistoryResponse describes the notification history
|
|
// response for an account for a specific time period.
|
|
type NotificationHistoryResponse struct {
|
|
Response
|
|
ResultInfo `json:"result_info"`
|
|
Result []NotificationHistory
|
|
}
|
|
|
|
// ListNotificationPolicies will return the notification policies
|
|
// created by a user for a specific account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-policies-properties
|
|
func (api *API) ListNotificationPolicies(ctx context.Context, accountID string) (NotificationPoliciesResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/policies", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationPoliciesResponse{}, err
|
|
}
|
|
var r NotificationPoliciesResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// GetNotificationPolicy returns a specific created by a user, given the account
|
|
// id and the policy id.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-policies-properties
|
|
func (api *API) GetNotificationPolicy(ctx context.Context, accountID, policyID string) (NotificationPolicyResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/policies/%s", accountID, policyID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationPolicyResponse{}, err
|
|
}
|
|
var r NotificationPolicyResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// CreateNotificationPolicy creates a notification policy for an account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-policies-create-notification-policy
|
|
func (api *API) CreateNotificationPolicy(ctx context.Context, accountID string, policy NotificationPolicy) (SaveResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/policies", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, baseURL, policy)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// UpdateNotificationPolicy updates a notification policy, given the
|
|
// account id and the policy id and returns the policy id.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-policies-update-notification-policy
|
|
func (api *API) UpdateNotificationPolicy(ctx context.Context, accountID string, policy *NotificationPolicy) (SaveResponse, error) {
|
|
if policy == nil {
|
|
return SaveResponse{}, fmt.Errorf("policy cannot be nil")
|
|
}
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/policies/%s", accountID, policy.ID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPut, baseURL, policy)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// DeleteNotificationPolicy deletes a notification policy for an account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-policies-delete-notification-policy
|
|
func (api *API) DeleteNotificationPolicy(ctx context.Context, accountID, policyID string) (SaveResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/policies/%s", accountID, policyID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodDelete, baseURL, nil)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// ListNotificationWebhooks will return the webhook destinations configured
|
|
// for an account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-webhooks-list-webhooks
|
|
func (api *API) ListNotificationWebhooks(ctx context.Context, accountID string) (NotificationWebhooksResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/webhooks", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationWebhooksResponse{}, err
|
|
}
|
|
var r NotificationWebhooksResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// CreateNotificationWebhooks will help connect a webhooks destination.
|
|
// A test message will be sent to the webhooks endpoint during creation.
|
|
// If added successfully, the webhooks can be setup as a destination mechanism
|
|
// while creating policies.
|
|
//
|
|
// Notifications will be posted to this URL.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-webhooks-create-webhook
|
|
func (api *API) CreateNotificationWebhooks(ctx context.Context, accountID string, webhooks *NotificationUpsertWebhooks) (SaveResponse, error) {
|
|
if webhooks == nil {
|
|
return SaveResponse{}, fmt.Errorf("webhooks cannot be nil")
|
|
}
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/webhooks", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, baseURL, webhooks)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// GetNotificationWebhooks will return a specific webhook destination,
|
|
// given the account and webhooks ids.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-webhooks-get-webhook
|
|
func (api *API) GetNotificationWebhooks(ctx context.Context, accountID, webhookID string) (NotificationWebhookResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/webhooks/%s", accountID, webhookID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationWebhookResponse{}, err
|
|
}
|
|
var r NotificationWebhookResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// UpdateNotificationWebhooks will update a particular webhook's name,
|
|
// given the account and webhooks ids.
|
|
//
|
|
// The webhook url and secret cannot be updated.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-webhooks-update-webhook
|
|
func (api *API) UpdateNotificationWebhooks(ctx context.Context, accountID, webhookID string, webhooks *NotificationUpsertWebhooks) (SaveResponse, error) {
|
|
if webhooks == nil {
|
|
return SaveResponse{}, fmt.Errorf("webhooks cannot be nil")
|
|
}
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/webhooks/%s", accountID, webhookID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPut, baseURL, webhooks)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// DeleteNotificationWebhooks will delete a webhook, given the account and
|
|
// webhooks ids. Deleting the webhooks will remove it from any connected
|
|
// notification policies.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-webhooks-delete-webhook
|
|
func (api *API) DeleteNotificationWebhooks(ctx context.Context, accountID, webhookID string) (SaveResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/webhooks/%s", accountID, webhookID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodDelete, baseURL, nil)
|
|
if err != nil {
|
|
return SaveResponse{}, err
|
|
}
|
|
|
|
return unmarshalNotificationSaveResponse(res)
|
|
}
|
|
|
|
// ListPagerDutyNotificationDestinations will return the pagerduty
|
|
// destinations configured for an account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-destinations-with-pagerduty-list-pagerduty-services
|
|
func (api *API) ListPagerDutyNotificationDestinations(ctx context.Context, accountID string) (NotificationPagerDutyResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/pagerduty", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationPagerDutyResponse{}, err
|
|
}
|
|
var r NotificationPagerDutyResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// GetEligibleNotificationDestinations will return the types of
|
|
// destinations an account is eligible to configure.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-mechanism-eligibility-properties
|
|
func (api *API) GetEligibleNotificationDestinations(ctx context.Context, accountID string) (NotificationEligibilityResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/destinations/eligible", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationEligibilityResponse{}, err
|
|
}
|
|
var r NotificationEligibilityResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// GetAvailableNotificationTypes will return the alert types available for
|
|
// a given account.
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-mechanism-eligibility-properties
|
|
func (api *API) GetAvailableNotificationTypes(ctx context.Context, accountID string) (NotificationAvailableAlertsResponse, error) {
|
|
baseURL := fmt.Sprintf("/accounts/%s/alerting/v3/available_alerts", accountID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, baseURL, nil)
|
|
if err != nil {
|
|
return NotificationAvailableAlertsResponse{}, err
|
|
}
|
|
var r NotificationAvailableAlertsResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// TimeRange is an object for filtering the alert history based on timestamp.
|
|
type TimeRange struct {
|
|
Since string `json:"since,omitempty" url:"since,omitempty"`
|
|
Before string `json:"before,omitempty" url:"before,omitempty"`
|
|
}
|
|
|
|
// AlertHistoryFilter is an object for filtering the alert history response from the api.
|
|
type AlertHistoryFilter struct {
|
|
TimeRange
|
|
PaginationOptions
|
|
}
|
|
|
|
// ListNotificationHistory will return the history of alerts sent for
|
|
// a given account. The time period varies based on zone plan.
|
|
// Free, Biz, Pro = 30 days
|
|
// Ent = 90 days
|
|
//
|
|
// API Reference: https://api.cloudflare.com/#notification-history-list-history
|
|
func (api *API) ListNotificationHistory(ctx context.Context, accountID string, alertHistoryFilter AlertHistoryFilter) ([]NotificationHistory, ResultInfo, error) {
|
|
uri := buildURI(fmt.Sprintf("/accounts/%s/alerting/v3/history", accountID), alertHistoryFilter)
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return []NotificationHistory{}, ResultInfo{}, err
|
|
}
|
|
var r NotificationHistoryResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return []NotificationHistory{}, ResultInfo{}, err
|
|
}
|
|
return r.Result, r.ResultInfo, nil
|
|
}
|
|
|
|
// unmarshal will unmarshal bytes and return a SaveResponse.
|
|
func unmarshalNotificationSaveResponse(res []byte) (SaveResponse, error) {
|
|
var r SaveResponse
|
|
err := json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return r, err
|
|
}
|
|
return r, nil
|
|
}
|