mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-09-20 14:56:20 +08:00
CLOUDFLARE: Support API tokens (#555)
Cloudflare API tokens are a new way to authenticate to Cloudflare API. Unlike the Global API key, tokens can be given specific permissions to only access parts of the API. See [1] for details. [1] https://blog.cloudflare.com/api-tokens-general-availability/ This commit introduces a new credential for cloudflare called `apitoken`, which is mutually exclusive with `apiuser` and `apikey`. In order for DNSControl to work with this token, it should have the right to read DNS zones and edit DNS records. Closes #534
This commit is contained in:
parent
96583a9188
commit
4e6d05b716
|
@ -11,7 +11,21 @@ jsId: CLOUDFLAREAPI
|
|||
* When using `SPF()` or the `SPF_BUILDER()` the records are converted to RecordType `TXT` as Cloudflare API fails otherwise. See more [here](https://github.com/StackExchange/dnscontrol/issues/446).
|
||||
|
||||
## Configuration
|
||||
In the credentials file you must provide your Cloudflare API username and access token:
|
||||
In the credentials file you must provide a [Cloudflare API token](https://dash.cloudflare.com/profile/api-tokens):
|
||||
|
||||
{% highlight json %}
|
||||
{
|
||||
"cloudflare": {
|
||||
"apitoken": "your-cloudflare-api-token"
|
||||
}
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
Make sure the token has at least the right read zones and edit DNS records (i.e. `Zone → Zone → Read` and `Zone → DNS → Edit`);
|
||||
checkout [Cloudflare's documentation](https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys) for instructions on how to generate and configure permissions on API tokens.
|
||||
|
||||
|
||||
Or you can provide your Cloudflare API username and access key instead, but it isn't recommended because those credentials give DNSControl access to the complete Cloudflare API rather:
|
||||
|
||||
{% highlight json %}
|
||||
{
|
||||
|
@ -27,8 +41,7 @@ If your Cloudflare account has access to multiple Cloudflare accounts, you can s
|
|||
{% highlight json %}
|
||||
{
|
||||
"cloudflare": {
|
||||
"apikey": "...",
|
||||
"apiuser": "...",
|
||||
"apitoken": "...",
|
||||
"accountid": "your-cloudflare-account-id",
|
||||
"accountname": "your-cloudflare-account-name"
|
||||
}
|
||||
|
|
|
@ -66,8 +66,7 @@ If you are using other providers, you will likely need to make a `creds.json` fi
|
|||
{% highlight js %}
|
||||
{
|
||||
"cloudflare":{ // provider name to be used in dnsconfig.js
|
||||
"apikey": "key", // API key
|
||||
"apiuser": "username" // username for cloudflare
|
||||
"apitoken": "token" // API token
|
||||
},
|
||||
"namecom":{ // provider name to be used in dnsconfig.js
|
||||
"apikey": "key", // API Key
|
||||
|
@ -259,4 +258,4 @@ If you are going to use this in production, we highly recommend the following:
|
|||
* Store the configuration files in Git.
|
||||
* Encrypt the `creds.json` file before storing it in Git.
|
||||
* Use a CI/CD tool like Jenkins to automatically push DNS changes.
|
||||
* Join the DNSControl community. File [issues and PRs](https://github.com/StackExchange/dnscontrol).
|
||||
* Join the DNSControl community. File [issues and PRs](https://github.com/StackExchange/dnscontrol).
|
||||
|
|
|
@ -58,6 +58,7 @@ func init() {
|
|||
// CloudflareApi is the handle for API calls.
|
||||
type CloudflareApi struct {
|
||||
ApiKey string `json:"apikey"`
|
||||
ApiToken string `json:apitoken`
|
||||
ApiUser string `json:"apiuser"`
|
||||
AccountID string `json:"accountid"`
|
||||
AccountName string `json:"accountname"`
|
||||
|
@ -370,10 +371,13 @@ func (c *CloudflareApi) preprocessConfig(dc *models.DomainConfig) error {
|
|||
|
||||
func newCloudflare(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
api := &CloudflareApi{}
|
||||
api.ApiUser, api.ApiKey = m["apiuser"], m["apikey"]
|
||||
api.ApiUser, api.ApiKey, api.ApiToken = m["apiuser"], m["apikey"], m["apitoken"]
|
||||
// check api keys from creds json file
|
||||
if api.ApiKey == "" || api.ApiUser == "" {
|
||||
return nil, errors.Errorf("cloudflare apikey and apiuser must be provided")
|
||||
if api.ApiToken == "" && (api.ApiKey == "" || api.ApiUser == "") {
|
||||
return nil, errors.Errorf("if cloudflare apitoken is not set, apikey and apiuser must be provided")
|
||||
}
|
||||
if api.ApiToken != "" && (api.ApiKey != "" || api.ApiUser != "") {
|
||||
return nil, errors.Errorf("if cloudflare apitoken is set, apikey and apiuser should not be provided")
|
||||
}
|
||||
|
||||
// Check account data if set
|
||||
|
|
|
@ -355,8 +355,12 @@ func handleActionResponse(resp *http.Response, err error) (id string, e error) {
|
|||
}
|
||||
|
||||
func (c *CloudflareApi) setHeaders(req *http.Request) {
|
||||
req.Header.Set("X-Auth-Key", c.ApiKey)
|
||||
req.Header.Set("X-Auth-Email", c.ApiUser)
|
||||
if len(c.ApiToken) > 0 {
|
||||
req.Header.Set("Authorization", "Bearer "+c.ApiToken)
|
||||
} else {
|
||||
req.Header.Set("X-Auth-Key", c.ApiKey)
|
||||
req.Header.Set("X-Auth-Email", c.ApiUser)
|
||||
}
|
||||
}
|
||||
|
||||
// generic get handler. makes request and unmarshalls response to given interface
|
||||
|
|
Loading…
Reference in a new issue