-
-
Notifications
You must be signed in to change notification settings - Fork 299
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
154 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
from __future__ import absolute_import | ||
from .base import Provider as BaseProvider | ||
from transip.client import DomainClient | ||
|
||
|
||
def ProviderParser(subparser): | ||
subparser.add_argument("--auth-username", help="specify username used to authenticate") | ||
subparser.add_argument("--auth-api-key", help="specify API private key to authenticate") | ||
subparser.add_argument("--auth-ca-bundle", help="specify CA bundle to use to verify API SSL certificate") | ||
|
||
|
||
class Provider(BaseProvider): | ||
def __init__(self, options): | ||
super(Provider, self).__init__(options) | ||
self.provider_name = 'transip' | ||
self.domain_id = None | ||
username = self.options.get('auth_username') | ||
key_file = self.options.get('auth_api_key') | ||
|
||
if not username or not key_file: | ||
raise StandardError("No username and/or keyfile was specified") | ||
|
||
self.client = DomainClient( | ||
username=username, | ||
key_file=key_file, | ||
mode="readwrite", | ||
cacert=self.options.get('auth_ca_bundle', False) | ||
) | ||
|
||
# Authenticate against provider, | ||
# Make any requests required to get the domain's id for this provider, so it can be used in subsequent calls. | ||
# Should throw an error if authentication fails for any reason, of if the domain does not exist. | ||
def authenticate(self): | ||
## This request will fail when the domain does not exist, | ||
## allowing us to check for existence | ||
self.client.getInfo(self.options.get('domain')) | ||
|
||
# Create record. If record already exists with the same content, do nothing' | ||
def create_record(self, type, name, content): | ||
records = self.client.getInfo(self.options.get('domain')).dnsEntries | ||
if self._filter_records(records, type, name, content): | ||
# Nothing to do, record already exists | ||
print 'create_record: already exists' | ||
return True | ||
|
||
records.append({ | ||
"name": self._relative_name(name), | ||
"type": type, | ||
"content": content, | ||
"expire": self.options.get('ttl') or 86400 | ||
}) | ||
|
||
self.client.setDnsEntries(self.options.get('domain'), records) | ||
status = len(self.list_records(type, name, content, show_output=False)) >= 1 | ||
print "create_record: {0}".format(status) | ||
return status | ||
|
||
# List all records. Return an empty list if no records found | ||
# type, name and content are used to filter records. | ||
# If possible filter during the query, otherwise filter after response is received. | ||
def list_records(self, type=None, name=None, content=None, show_output=True): | ||
all_records = self._convert_records(self.client.getInfo(self.options.get('domain')).dnsEntries) | ||
records = self._filter_records( | ||
records=all_records, | ||
type=type, | ||
name=name, | ||
content=content | ||
) | ||
|
||
if show_output: | ||
print 'list_records: {0}'.format(records) | ||
return records | ||
|
||
# Update a record. Identifier must be specified. | ||
def update_record(self, identifier=None, type=None, name=None, content=None): | ||
if not (type or name or content): | ||
raise StandardError("At least one of type, name or content must be specified.") | ||
|
||
all_records = self.list_records(show_output=False) | ||
filtered_records = self._filter_records(all_records, type, name) | ||
|
||
for record in filtered_records: | ||
all_records.remove(record) | ||
for record in all_records: | ||
record['expire'] = record['ttl'] | ||
del record['ttl'] | ||
all_records.append({ | ||
"name": self._relative_name(name), | ||
"type": type, | ||
"content": content, | ||
"expire": self.options.get('ttl') or 86400 | ||
}) | ||
|
||
self.client.setDnsEntries(self.options.get('domain'), all_records) | ||
status = len(self.list_records(type, name, content, show_output=False)) >= 1 | ||
print "update_record: {0}".format(status) | ||
return status | ||
|
||
# Delete an existing record. | ||
# If record does not exist, do nothing. | ||
# If an identifier is specified, use it, otherwise do a lookup using type, name and content. | ||
def delete_record(self, identifier=None, type=None, name=None, content=None): | ||
if not (type or name or content): | ||
raise StandardError("At least one of type, name or content must be specified.") | ||
|
||
all_records = self.list_records(show_output=False) | ||
filtered_records = self._filter_records(all_records, type, name, content) | ||
|
||
for record in filtered_records: | ||
all_records.remove(record) | ||
for record in all_records: | ||
record['expire'] = record['ttl'] | ||
del record['ttl'] | ||
|
||
self.client.setDnsEntries(self.options.get('domain'), all_records) | ||
status = len(self.list_records(type, name, content, show_output=False)) == 0 | ||
print "delete_record: {0}".format(status) | ||
return status | ||
|
||
def _relative_name(self, record_name): | ||
name = super(Provider, self)._relative_name(record_name) | ||
if not name: | ||
name = "@" | ||
return name | ||
|
||
# Convert the objects from transip to dicts, for easier processing | ||
def _convert_records(self, records): | ||
_records = [] | ||
for record in records: | ||
_records.append({ | ||
"name": record.name, | ||
"type": record.type, | ||
"content": record.content, | ||
"ttl": record.expire | ||
}) | ||
return _records | ||
|
||
# Filter a list of records based on criteria | ||
def _filter_records(self, records, type=None, name=None, content=None): | ||
_records = [] | ||
for record in records: | ||
if (not type or record['type'] == type) and \ | ||
(not name or record['name'] == self._relative_name(name)) and \ | ||
(not content or record['content'] == content): | ||
_records.append(record) | ||
return _records |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
requests[security] | ||
tldextract | ||
tldextract | ||
transip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,5 +111,9 @@ | |
'lexicon=lexicon.__main__:main', | ||
], | ||
}, | ||
|
||
extras_require={ | ||
'transip': ['transip'] | ||
}, | ||
test_suite='tests' | ||
) | ||
) |