mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-11-11 00:40:53 +08:00
192 lines
6.4 KiB
Go
192 lines
6.4 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
// ZoneLockdown represents a Zone Lockdown rule. A rule only permits access to
|
|
// the provided URL pattern(s) from the given IP address(es) or subnet(s).
|
|
type ZoneLockdown struct {
|
|
ID string `json:"id"`
|
|
Description string `json:"description"`
|
|
URLs []string `json:"urls"`
|
|
Configurations []ZoneLockdownConfig `json:"configurations"`
|
|
Paused bool `json:"paused"`
|
|
Priority int `json:"priority,omitempty"`
|
|
CreatedOn *time.Time `json:"created_on,omitempty"`
|
|
ModifiedOn *time.Time `json:"modified_on,omitempty"`
|
|
}
|
|
|
|
// ZoneLockdownConfig represents a Zone Lockdown config, which comprises
|
|
// a Target ("ip" or "ip_range") and a Value (an IP address or IP+mask,
|
|
// respectively.)
|
|
type ZoneLockdownConfig struct {
|
|
Target string `json:"target"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
// ZoneLockdownResponse represents a response from the Zone Lockdown endpoint.
|
|
type ZoneLockdownResponse struct {
|
|
Result ZoneLockdown `json:"result"`
|
|
Response
|
|
ResultInfo `json:"result_info"`
|
|
}
|
|
|
|
// ZoneLockdownListResponse represents a response from the List Zone Lockdown
|
|
// endpoint.
|
|
type ZoneLockdownListResponse struct {
|
|
Result []ZoneLockdown `json:"result"`
|
|
Response
|
|
ResultInfo `json:"result_info"`
|
|
}
|
|
|
|
// ZoneLockdownCreateParams contains required and optional params
|
|
// for creating a zone lockdown.
|
|
type ZoneLockdownCreateParams struct {
|
|
Description string `json:"description"`
|
|
URLs []string `json:"urls"`
|
|
Configurations []ZoneLockdownConfig `json:"configurations"`
|
|
Paused bool `json:"paused"`
|
|
Priority int `json:"priority,omitempty"`
|
|
}
|
|
|
|
// ZoneLockdownUpdateParams contains required and optional params
|
|
// for updating a zone lockdown.
|
|
type ZoneLockdownUpdateParams struct {
|
|
ID string `json:"id"`
|
|
Description string `json:"description"`
|
|
URLs []string `json:"urls"`
|
|
Configurations []ZoneLockdownConfig `json:"configurations"`
|
|
Paused bool `json:"paused"`
|
|
Priority int `json:"priority,omitempty"`
|
|
}
|
|
|
|
type LockdownListParams struct {
|
|
ResultInfo
|
|
}
|
|
|
|
// CreateZoneLockdown creates a Zone ZoneLockdown rule for the given zone ID.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-create-a-ZoneLockdown-rule
|
|
func (api *API) CreateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownCreateParams) (ZoneLockdown, error) {
|
|
uri := fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier)
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
|
|
if err != nil {
|
|
return ZoneLockdown{}, err
|
|
}
|
|
|
|
response := &ZoneLockdownResponse{}
|
|
err = json.Unmarshal(res, &response)
|
|
if err != nil {
|
|
return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return response.Result, nil
|
|
}
|
|
|
|
// UpdateZoneLockdown updates a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-update-ZoneLockdown-rule
|
|
func (api *API) UpdateZoneLockdown(ctx context.Context, rc *ResourceContainer, params ZoneLockdownUpdateParams) (ZoneLockdown, error) {
|
|
uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, params.ID)
|
|
res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
|
|
if err != nil {
|
|
return ZoneLockdown{}, err
|
|
}
|
|
|
|
response := &ZoneLockdownResponse{}
|
|
err = json.Unmarshal(res, &response)
|
|
if err != nil {
|
|
return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return response.Result, nil
|
|
}
|
|
|
|
// DeleteZoneLockdown deletes a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-delete-ZoneLockdown-rule
|
|
func (api *API) DeleteZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
|
|
uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
|
|
res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
|
|
if err != nil {
|
|
return ZoneLockdown{}, err
|
|
}
|
|
|
|
response := &ZoneLockdownResponse{}
|
|
err = json.Unmarshal(res, &response)
|
|
if err != nil {
|
|
return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return response.Result, nil
|
|
}
|
|
|
|
// ZoneLockdown retrieves a Zone ZoneLockdown rule (based on the ID) for the given zone ID.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-ZoneLockdown-rule-details
|
|
func (api *API) ZoneLockdown(ctx context.Context, rc *ResourceContainer, id string) (ZoneLockdown, error) {
|
|
uri := fmt.Sprintf("/zones/%s/firewall/lockdowns/%s", rc.Identifier, id)
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return ZoneLockdown{}, err
|
|
}
|
|
|
|
response := &ZoneLockdownResponse{}
|
|
err = json.Unmarshal(res, &response)
|
|
if err != nil {
|
|
return ZoneLockdown{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
|
|
return response.Result, nil
|
|
}
|
|
|
|
// ListZoneLockdowns retrieves every Zone ZoneLockdown rules for a given zone ID.
|
|
//
|
|
// Automatically paginates all results unless `params.PerPage` and `params.Page`
|
|
// is set.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-list-ZoneLockdown-rules
|
|
func (api *API) ListZoneLockdowns(ctx context.Context, rc *ResourceContainer, params LockdownListParams) ([]ZoneLockdown, *ResultInfo, error) {
|
|
autoPaginate := true
|
|
if params.PerPage >= 1 || params.Page >= 1 {
|
|
autoPaginate = false
|
|
}
|
|
if params.PerPage < 1 {
|
|
params.PerPage = 50
|
|
}
|
|
if params.Page < 1 {
|
|
params.Page = 1
|
|
}
|
|
|
|
var zoneLockdowns []ZoneLockdown
|
|
var zResponse ZoneLockdownListResponse
|
|
for {
|
|
zResponse = ZoneLockdownListResponse{}
|
|
uri := buildURI(fmt.Sprintf("/zones/%s/firewall/lockdowns", rc.Identifier), params)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return []ZoneLockdown{}, &ResultInfo{}, err
|
|
}
|
|
|
|
err = json.Unmarshal(res, &zResponse)
|
|
if err != nil {
|
|
return []ZoneLockdown{}, &ResultInfo{}, fmt.Errorf("failed to unmarshal filters JSON data: %w", err)
|
|
}
|
|
|
|
zoneLockdowns = append(zoneLockdowns, zResponse.Result...)
|
|
params.ResultInfo = zResponse.ResultInfo.Next()
|
|
|
|
if params.ResultInfo.Done() || !autoPaginate {
|
|
break
|
|
}
|
|
}
|
|
|
|
return zoneLockdowns, &zResponse.ResultInfo, nil
|
|
}
|