1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import
3
from __future__ import print_function
9
from .base import Provider as BaseProvider
11
logger = logging.getLogger(__name__)
14
def ProviderParser(subparser):
15
subparser.add_argument("--auth-username", help="specify api id used to authenticate")
16
subparser.add_argument("--auth-token", help="specify token used authenticate to DNS provider")
18
class Provider(BaseProvider):
20
def __init__(self, options, engine_overrides=None):
21
super(Provider, self).__init__(options, engine_overrides)
23
self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://dnsapi.cn')
25
def authenticate(self):
27
payload = self._post('/Domain.Info', {'domain':self.options['domain']})
29
if payload['status']['code'] != '1':
30
raise Exception(payload['status']['message'])
32
self.domain_id = payload['domain']['id']
35
# Create record. If record already exists with the same content, do nothing'
36
def create_record(self, type, name, content):
38
'domain_id': self.domain_id,
39
'sub_domain': self._relative_name(name),
44
if self.options.get('ttl'):
45
record['ttl'] = self.options.get('ttl')
47
payload = self._post('/Record.Create', record)
49
if payload['status']['code'] not in ['1', '31']:
50
raise Exception(payload['status']['message'])
52
logger.debug('create_record: %s', payload['status']['code'] == '1')
53
return payload['status']['code'] == '1'
55
# List all records. Return an empty list if no records found
56
# type, name and content are used to filter records.
57
# If possible filter during the query, otherwise filter after response is received.
58
def list_records(self, type=None, name=None, content=None):
61
payload = self._post('/Record.List', {'domain':self.options['domain']})
62
logger.debug('payload: %s', payload)
64
for record in payload['records']:
66
'type': record['type'],
67
'name': self._full_name(record['name']),
69
'content': record['value'],
70
#this id is useless unless your doing record linking. Lets return the original record identifier.
73
records.append(processed_record)
76
records = [record for record in records if record['type'] == type]
78
records = [record for record in records if record['name'] == self._full_name(name)]
80
records = [record for record in records if record['content'] == content]
82
logger.debug('list_records: %s', records)
85
# Create or update a record.
86
def update_record(self, identifier, type=None, name=None, content=None):
89
'domain_id': self.domain_id,
90
'record_id': identifier,
91
'sub_domain': self._relative_name(name),
96
if self.options.get('ttl'):
97
data['ttl'] = self.options.get('ttl')
98
logger.debug('data: %s', data)
99
payload = self._post('/Record.Modify', data)
100
logger.debug('payload: %s', payload)
101
if payload['status']['code'] != '1':
102
raise Exception(payload['status']['message'])
104
logger.debug('update_record: %s', True)
107
# Delete an existing record.
108
# If record does not exist, do nothing.
109
def delete_record(self, identifier=None, type=None, name=None, content=None):
111
records = self.list_records(type, name, content)
112
logger.debug('records: %s', records)
113
if len(records) == 1:
114
identifier = records[0]['id']
116
raise Exception('Record identifier could not be found.')
117
payload = self._post('/Record.Remove', {'domain_id': self.domain_id, 'record_id': identifier})
119
if payload['status']['code'] != '1':
120
raise Exception(payload['status']['message'])
122
# is always True at this point, if a non 200 response is returned an error is raised.
123
logger.debug('delete_record: %s', True)
128
def _request(self, action='GET', url='/', data=None, query_params=None):
131
data['login_token'] = self.options['auth_username'] + ',' + self.options['auth_token']
132
data['format'] = 'json'
133
if query_params is None:
137
r = requests.request(action, self.api_endpoint + url, params=query_params,
139
headers=default_headers,
141
r.raise_for_status() # if the request fails for any reason, throw an error.