diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0fc2f2c..c3a8f48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,10 +41,12 @@ Here are a few things you can do that will increase the likelihood of your pull ## Development setup ``` -pip install -r requirements.txt -pip install -r requirements-dev.txt +./scipt/bootstrap +source env/bin/activate ``` +See the [`script/`](/script) if you'd like to run tests and coverage ([`script/coverage`](/script/coverage)) and coverage ([`script/lint`](/script/lint)). After bootstrapping and sourcing the `env/` commands in the [`octodns/cmds/`](/octodns/cmds) directory can be run with `PYTHONPATH=. ./octodns/cmds/sync.py ...` + ## License note We can only accept contributions that are compatible with the MIT license. diff --git a/octodns/provider/cloudflare.py b/octodns/provider/cloudflare.py index ac1fe9f..d83a523 100644 --- a/octodns/provider/cloudflare.py +++ b/octodns/provider/cloudflare.py @@ -37,9 +37,9 @@ class CloudflareProvider(BaseProvider): cloudflare: class: octodns.provider.cloudflare.CloudflareProvider - # Your Cloudflare account email address (required) - email: dns-manager@example.com # The api key (required) + # Your Cloudflare account email address (required) + email: dns-manager@example.com (optional if using token) token: foo # Import CDN enabled records as CNAME to {}.cdn.cloudflare.net. Records # ending at .cdn.cloudflare.net. will be ignored when this provider is @@ -66,17 +66,24 @@ class CloudflareProvider(BaseProvider): MIN_TTL = 120 TIMEOUT = 15 - def __init__(self, id, email, token, cdn=False, *args, **kwargs): + def __init__(self, id, email=None, token=None, cdn=False, *args, **kwargs): self.log = getLogger('CloudflareProvider[{}]'.format(id)) self.log.debug('__init__: id=%s, email=%s, token=***, cdn=%s', id, email, cdn) super(CloudflareProvider, self).__init__(id, *args, **kwargs) sess = Session() - sess.headers.update({ - 'X-Auth-Email': email, - 'X-Auth-Key': token, - }) + if email and token: + sess.headers.update({ + 'X-Auth-Email': email, + 'X-Auth-Key': token, + }) + else: + # https://api.cloudflare.com/#getting-started-requests + # https://tools.ietf.org/html/rfc6750#section-2.1 + sess.headers.update({ + 'Authorization': 'Bearer {}'.format(token), + }) self.cdn = cdn self._sess = sess diff --git a/tests/test_octodns_provider_cloudflare.py b/tests/test_octodns_provider_cloudflare.py index 3581033..5bcf25f 100644 --- a/tests/test_octodns_provider_cloudflare.py +++ b/tests/test_octodns_provider_cloudflare.py @@ -1212,3 +1212,14 @@ class TestCloudflareProvider(TestCase): self.assertFalse( extra_changes[0].new._octodns['cloudflare']['proxied'] ) + + def test_emailless_auth(self): + provider = CloudflareProvider('test', token='token 123', + email='email 234') + headers = provider._sess.headers + self.assertEquals('email 234', headers['X-Auth-Email']) + self.assertEquals('token 123', headers['X-Auth-Key']) + + provider = CloudflareProvider('test', token='token 123') + headers = provider._sess.headers + self.assertEquals('Bearer token 123', headers['Authorization'])