terraform/vendor/github.com/mitchellh/cloudflare-go/cloudflare.go

452 lines
13 KiB
Go

/*
Package cloudflare implements the CloudFlare v4 API.
New API requests created like:
api := cloudflare.New(apikey, apiemail)
*/
package cloudflare
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"github.com/pkg/errors"
)
const apiURL = "https://api.cloudflare.com/client/v4"
// Error messages
const errMakeRequestError = "Error from makeRequest"
const errUnmarshalError = "Error unmarshalling JSON"
type API struct {
APIKey string
APIEmail string
}
// Initializes the API configuration.
func New(key, email string) *API {
return &API{key, email}
}
// Initializes a new zone.
func NewZone() *Zone {
return &Zone{}
}
// ZoneIDByName retrieves a zone's ID from the name.
func (api *API) ZoneIDByName(zoneName string) (string, error) {
res, err := api.ListZones(zoneName)
if err != nil {
return "", errors.Wrap(err, "ListZones command failed")
}
for _, zone := range res {
if zone.Name == zoneName {
return zone.ID, nil
}
}
return "", errors.New("Zone could not be found")
}
// Params can be turned into a URL query string or a body
// TODO: Give this func a better name
func (api *API) makeRequest(method, uri string, params interface{}) ([]byte, error) {
// Replace nil with a JSON object if needed
var reqBody io.Reader
if params != nil {
json, err := json.Marshal(params)
if err != nil {
return nil, errors.Wrap(err, "Error marshalling params to JSON")
}
reqBody = bytes.NewReader(json)
} else {
reqBody = nil
}
req, err := http.NewRequest(method, apiURL+uri, reqBody)
if err != nil {
return nil, errors.Wrap(err, "HTTP request creation failed")
}
req.Header.Add("X-Auth-Key", api.APIKey)
req.Header.Add("X-Auth-Email", api.APIEmail)
// Could be application/json or multipart/form-data
// req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "HTTP request failed")
}
defer resp.Body.Close()
resBody, err := ioutil.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
if err != nil {
return nil, errors.Wrap(err, "Error returned from API")
} else if resBody != nil {
return nil, errors.New(string(resBody))
} else {
return nil, errors.New(resp.Status)
}
}
return resBody, nil
}
// The Response struct is a template. There will also be a result struct.
// There will be a unique response type for each response, which will include
// this type.
type Response struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
}
type ResultInfo struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Count int `json:"count"`
Total int `json:"total_count"`
}
// An Organization describes a multi-user organization. (Enterprise only.)
type Organization struct {
ID string
Name string
Status string
Permissions []string
Roles []string
}
// A User describes a user account.
type User struct {
ID string `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
Telephone string `json:"telephone"`
Country string `json:"country"`
Zipcode string `json:"zipcode"`
CreatedOn string `json:"created_on"` // Should this be a time.Date?
ModifiedOn string `json:"modified_on"`
APIKey string `json:"api_key"`
TwoFA bool `json:"two_factor_authentication_enabled"`
Betas []string `json:"betas"`
Organizations []Organization `json:"organizations"`
}
type UserResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result User `json:"result"`
}
type Owner struct {
ID string `json:"id"`
Email string `json:"email"`
OwnerType string `json:"owner_type"`
}
// A Zone describes a CloudFlare zone.
type Zone struct {
ID string `json:"id"`
Name string `json:"name"`
DevMode int `json:"development_mode"`
OriginalNS []string `json:"original_name_servers"`
OriginalRegistrar string `json:"original_registrar"`
OriginalDNSHost string `json:"original_dnshost"`
CreatedOn string `json:"created_on"`
ModifiedOn string `json:"modified_on"`
NameServers []string `json:"name_servers"`
Owner Owner `json:"owner"`
Permissions []string `json:"permissions"`
Plan ZonePlan `json:"plan"`
Status string `json:"status"`
Paused bool `json:"paused"`
Type string `json:"type"`
Host struct {
Name string
Website string
} `json:"host"`
VanityNS []string `json:"vanity_name_servers"`
Betas []string `json:"betas"`
DeactReason string `json:"deactivation_reason"`
Meta ZoneMeta `json:"meta"`
}
// Contains metadata about a zone.
type ZoneMeta struct {
// custom_certificate_quota is broken - sometimes it's a string, sometimes a number!
// CustCertQuota int `json:"custom_certificate_quota"`
PageRuleQuota int `json:"page_rule_quota"`
WildcardProxiable bool `json:"wildcard_proxiable"`
PhishingDetected bool `json:"phishing_detected"`
}
// Contains the plan information for a zone.
type ZonePlan struct {
ID string `json:"id"`
Name string `json:"name"`
Price int `json:"price"`
Currency string `json:"currency"`
Frequency string `json:"frequency"`
LegacyID string `json:"legacy_id"`
IsSubscribed bool `json:"is_subscribed"`
CanSubscribe bool `json:"can_subscribe"`
}
type ZoneResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []Zone `json:"result"`
}
type ZonePlanResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []ZonePlan `json:"result"`
}
// type zoneSetting struct {
// ID string `json:"id"`
// Editable bool `json:"editable"`
// ModifiedOn string `json:"modified_on"`
// }
// type zoneSettingStringVal struct {
// zoneSetting
// Value string `json:"value"`
// }
// type zoneSettingIntVal struct {
// zoneSetting
// Value int64 `json:"value"`
// }
type ZoneSetting struct {
ID string `json:"id"`
Editable bool `json:"editable"`
ModifiedOn string `json:"modified_on"`
Value interface{} `json:"value"`
TimeRemaining int `json:"time_remaining"`
}
type ZoneSettingResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []ZoneSetting `json:"result"`
}
// Describes a DNS record for a zone.
type DNSRecord struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
Content string `json:"content,omitempty"`
Proxiable bool `json:"proxiable,omitempty"`
Proxied bool `json:"proxied,omitempty"`
TTL int `json:"ttl,omitempty"`
Locked bool `json:"locked,omitempty"`
ZoneID string `json:"zone_id,omitempty"`
ZoneName string `json:"zone_name,omitempty"`
CreatedOn string `json:"created_on,omitempty"`
ModifiedOn string `json:"modified_on,omitempty"`
Data interface{} `json:"data,omitempty"` // data returned by: SRV, LOC
Meta interface{} `json:"meta,omitempty"`
Priority int `json:"priority,omitempty"`
}
// The response for creating or updating a DNS record.
type DNSRecordResponse struct {
Success bool `json:"success"`
Errors []interface{} `json:"errors"`
Messages []string `json:"messages"`
Result DNSRecord `json:"result"`
}
// The response for listing DNS records.
type DNSListResponse struct {
Success bool `json:"success"`
Errors []interface{} `json:"errors"`
Messages []string `json:"messages"`
Result []DNSRecord `json:"result"`
}
// Railgun status for a zone.
type ZoneRailgun struct {
ID string `json:"id"`
Name string `json:"string"`
Enabled bool `json:"enabled"`
Connected bool `json:"connected"`
}
type ZoneRailgunResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []ZoneRailgun `json:"result"`
}
// Custom SSL certificates for a zone.
type ZoneCustomSSL struct {
ID string `json:"id"`
Hosts []string `json:"hosts"`
Issuer string `json:"issuer"`
Priority int `json:"priority"`
Status string `json:"success"`
BundleMethod string `json:"bundle_method"`
ZoneID string `json:"zone_id"`
Permissions []string `json:"permissions"`
UploadedOn string `json:"uploaded_on"`
ModifiedOn string `json:"modified_on"`
ExpiresOn string `json:"expires_on"`
KeylessServer KeylessSSL `json:"keyless_server"`
}
type ZoneCustomSSLResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []ZoneCustomSSL `json:"result"`
}
type KeylessSSL struct {
ID string `json:"id"`
Name string `json:"name"`
Host string `json:"host"`
Port int `json:"port"`
Status string `json:"success"`
Enabled bool `json:"enabled"`
Permissions []string `json:"permissions"`
CreatedOn string `json:"created_on"`
ModifiedOn string `json:"modifed_on"`
}
type KeylessSSLResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []KeylessSSL `json:"result"`
}
type Railgun struct {
ID string `json:"id"`
Name string `json:"name"`
Status string `json:"success"`
Enabled bool `json:"enabled"`
ZonesConnected int `json:"zones_connected"`
Build string `json:"build"`
Version string `json:"version"`
Revision string `json:"revision"`
ActivationKey string `json:"activation_key"`
ActivatedOn string `json:"activated_on"`
CreatedOn string `json:"created_on"`
ModifiedOn string `json:"modified_on"`
// XXX: UpgradeInfo struct {
// version string
// url string
// } `json:"upgrade_info"`
}
type RailgunResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []Railgun `json:"result"`
}
// Custom error pages.
type CustomPage struct {
CreatedOn string `json:"created_on"`
ModifiedOn string `json:"modified_on"`
URL string `json:"url"`
State string `json:"state"`
RequiredTokens []string `json:"required_tokens"`
PreviewTarget string `json:"preview_target"`
Description string `json:"description"`
}
type CustomPageResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result []CustomPage `json:"result"`
}
// WAF packages
type WAFPackage struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
ZoneID string `json:"zone_id"`
DetectionMode string `json:"detection_mode"`
Sensitivity string `json:"sensitivity"`
ActionMode string `json:"action_mode"`
}
type WAFPackagesResponse struct {
Result []WAFPackage `json:"result"`
Success bool `json:"success"`
ResultInfo struct {
Page uint `json:"page"`
PerPage uint `json:"per_page"`
Count uint `json:"count"`
TotalCount uint `json:"total_count"`
} `json:"result_info"`
}
type WAFRule struct {
ID string `json:"id"`
Description string `json:"description"`
Priority string `json:"priority"`
PackageID string `json:"package_id"`
Group struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"group"`
Mode string `json:"mode"`
DefaultMode string `json:"default_mode"`
AllowedModes []string `json:"allowed_modes"`
}
type WAFRulesResponse struct {
Result []WAFRule `json:"result"`
Success bool `json:"success"`
ResultInfo struct {
Page uint `json:"page"`
PerPage uint `json:"per_page"`
Count uint `json:"count"`
TotalCount uint `json:"total_count"`
} `json:"result_info"`
}
type PurgeCacheRequest struct {
Everything bool `json:"purge_everything,omitempty"`
Files []string `json:"files,omitempty"`
Tags []string `json:"tags,omitempty"`
}
type PurgeCacheResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
}
// IPs contains a list of IPv4 and IPv6 CIDRs
type IPRanges struct {
IPv4CIDRs []string `json:"ipv4_cidrs"`
IPv6CIDRs []string `json:"ipv6_cidrs"`
}
// IPsResponse is the API response containing a list of IPs
type IPsResponse struct {
Success bool `json:"success"`
Errors []string `json:"errors"`
Messages []string `json:"messages"`
Result IPRanges `json:"result"`
}