197 lines
5.9 KiB
Go
197 lines
5.9 KiB
Go
|
package cloudflare
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
// FirewallRule is the struct of the firewall rule.
|
||
|
type FirewallRule struct {
|
||
|
ID string `json:"id,omitempty"`
|
||
|
Paused bool `json:"paused"`
|
||
|
Description string `json:"description"`
|
||
|
Action string `json:"action"`
|
||
|
Priority interface{} `json:"priority"`
|
||
|
Filter Filter `json:"filter"`
|
||
|
CreatedOn time.Time `json:"created_on,omitempty"`
|
||
|
ModifiedOn time.Time `json:"modified_on,omitempty"`
|
||
|
}
|
||
|
|
||
|
// FirewallRulesDetailResponse is the API response for the firewall
|
||
|
// rules.
|
||
|
type FirewallRulesDetailResponse struct {
|
||
|
Result []FirewallRule `json:"result"`
|
||
|
ResultInfo `json:"result_info"`
|
||
|
Response
|
||
|
}
|
||
|
|
||
|
// FirewallRuleResponse is the API response that is returned
|
||
|
// for requesting a single firewall rule on a zone.
|
||
|
type FirewallRuleResponse struct {
|
||
|
Result FirewallRule `json:"result"`
|
||
|
ResultInfo `json:"result_info"`
|
||
|
Response
|
||
|
}
|
||
|
|
||
|
// FirewallRules returns all firewall rules.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/get/#get-all-rules
|
||
|
func (api *API) FirewallRules(zoneID string, pageOpts PaginationOptions) ([]FirewallRule, error) {
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID)
|
||
|
v := url.Values{}
|
||
|
|
||
|
if pageOpts.PerPage > 0 {
|
||
|
v.Set("per_page", strconv.Itoa(pageOpts.PerPage))
|
||
|
}
|
||
|
|
||
|
if pageOpts.Page > 0 {
|
||
|
v.Set("page", strconv.Itoa(pageOpts.Page))
|
||
|
}
|
||
|
|
||
|
if len(v) > 0 {
|
||
|
uri = uri + "?" + v.Encode()
|
||
|
}
|
||
|
|
||
|
res, err := api.makeRequest("GET", uri, nil)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
var firewallDetailResponse FirewallRulesDetailResponse
|
||
|
err = json.Unmarshal(res, &firewallDetailResponse)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errUnmarshalError)
|
||
|
}
|
||
|
|
||
|
return firewallDetailResponse.Result, nil
|
||
|
}
|
||
|
|
||
|
// FirewallRule returns a single firewall rule based on the ID.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/get/#get-by-rule-id
|
||
|
func (api *API) FirewallRule(zoneID, firewallRuleID string) (FirewallRule, error) {
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRuleID)
|
||
|
|
||
|
res, err := api.makeRequest("GET", uri, nil)
|
||
|
if err != nil {
|
||
|
return FirewallRule{}, errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
var firewallRuleResponse FirewallRuleResponse
|
||
|
err = json.Unmarshal(res, &firewallRuleResponse)
|
||
|
if err != nil {
|
||
|
return FirewallRule{}, errors.Wrap(err, errUnmarshalError)
|
||
|
}
|
||
|
|
||
|
return firewallRuleResponse.Result, nil
|
||
|
}
|
||
|
|
||
|
// CreateFirewallRules creates new firewall rules.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/post/
|
||
|
func (api *API) CreateFirewallRules(zoneID string, firewallRules []FirewallRule) ([]FirewallRule, error) {
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID)
|
||
|
|
||
|
res, err := api.makeRequest("POST", uri, firewallRules)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
var firewallRulesDetailResponse FirewallRulesDetailResponse
|
||
|
err = json.Unmarshal(res, &firewallRulesDetailResponse)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errUnmarshalError)
|
||
|
}
|
||
|
|
||
|
return firewallRulesDetailResponse.Result, nil
|
||
|
}
|
||
|
|
||
|
// UpdateFirewallRule updates a single firewall rule.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/put/#update-a-single-rule
|
||
|
func (api *API) UpdateFirewallRule(zoneID string, firewallRule FirewallRule) (FirewallRule, error) {
|
||
|
if firewallRule.ID == "" {
|
||
|
return FirewallRule{}, errors.Errorf("firewall rule ID cannot be empty")
|
||
|
}
|
||
|
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRule.ID)
|
||
|
|
||
|
res, err := api.makeRequest("PUT", uri, firewallRule)
|
||
|
if err != nil {
|
||
|
return FirewallRule{}, errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
var firewallRuleResponse FirewallRuleResponse
|
||
|
err = json.Unmarshal(res, &firewallRuleResponse)
|
||
|
if err != nil {
|
||
|
return FirewallRule{}, errors.Wrap(err, errUnmarshalError)
|
||
|
}
|
||
|
|
||
|
return firewallRuleResponse.Result, nil
|
||
|
}
|
||
|
|
||
|
// UpdateFirewallRules updates a single firewall rule.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/put/#update-multiple-rules
|
||
|
func (api *API) UpdateFirewallRules(zoneID string, firewallRules []FirewallRule) ([]FirewallRule, error) {
|
||
|
for _, firewallRule := range firewallRules {
|
||
|
if firewallRule.ID == "" {
|
||
|
return []FirewallRule{}, errors.Errorf("firewall ID cannot be empty")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID)
|
||
|
|
||
|
res, err := api.makeRequest("PUT", uri, firewallRules)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
var firewallRulesDetailResponse FirewallRulesDetailResponse
|
||
|
err = json.Unmarshal(res, &firewallRulesDetailResponse)
|
||
|
if err != nil {
|
||
|
return []FirewallRule{}, errors.Wrap(err, errUnmarshalError)
|
||
|
}
|
||
|
|
||
|
return firewallRulesDetailResponse.Result, nil
|
||
|
}
|
||
|
|
||
|
// DeleteFirewallRule updates a single firewall rule.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/delete/#delete-a-single-rule
|
||
|
func (api *API) DeleteFirewallRule(zoneID, firewallRuleID string) error {
|
||
|
if firewallRuleID == "" {
|
||
|
return errors.Errorf("firewall rule ID cannot be empty")
|
||
|
}
|
||
|
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRuleID)
|
||
|
|
||
|
_, err := api.makeRequest("DELETE", uri, nil)
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// DeleteFirewallRules updates a single firewall rule.
|
||
|
//
|
||
|
// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/delete/#delete-multiple-rules
|
||
|
func (api *API) DeleteFirewallRules(zoneID string, firewallRuleIDs []string) error {
|
||
|
ids := strings.Join(firewallRuleIDs, ",")
|
||
|
uri := fmt.Sprintf("/zones/%s/firewall/rules?id=%s", zoneID, ids)
|
||
|
|
||
|
_, err := api.makeRequest("DELETE", uri, nil)
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, errMakeRequestError)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|