mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
major update: progressed on populate(), implemented _data_for_TYPE fxns, but not all are verfied to work as expected yet
This commit is contained in:
3
octodns/.vscode/settings.json
vendored
Normal file
3
octodns/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.pythonPath": "C:\\Python27\\python.exe"
|
||||
}
|
1
octodns/provider/.vscode/settings.json
vendored
1
octodns/provider/.vscode/settings.json
vendored
@@ -1,2 +1,3 @@
|
||||
{
|
||||
"python.pythonPath": "C:\\Python27\\python.exe"
|
||||
}
|
@@ -1,417 +1,582 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
from __future__ import absolute_import, division, print_function, \
|
||||
unicode_literals
|
||||
|
||||
## octodns specfic imports:
|
||||
import requests
|
||||
from akamai.edgegrid import EdgeGridAuth
|
||||
from urlparse import urljoin
|
||||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
import logging
|
||||
from functools import reduce
|
||||
from ..record import Record
|
||||
from .base import BaseProvider
|
||||
|
||||
TESTING = True
|
||||
|
||||
class AkamaiClientException(Exception):
|
||||
|
||||
_errorMessages = {
|
||||
400: "400: Bad request",
|
||||
403: "403: Access is forbidden",
|
||||
404: "404: Resource not found",
|
||||
405: "405: Method not supported",
|
||||
406: "406: Not Acceptable",
|
||||
409: "409: Request not allowed due to conflict with current state of resource",
|
||||
415: "415: Unsupported media type",
|
||||
422: "422: Request body contains an error preventing processing",
|
||||
500: "500: Internal server error"
|
||||
}
|
||||
|
||||
def __init__(self, code):
|
||||
message = self._errorMessages.get(code)
|
||||
super(AkamaiClientException, self).__init__(message)
|
||||
|
||||
|
||||
class _AkamaiRecord(object):
|
||||
pass
|
||||
|
||||
|
||||
class AkamaiClient(object):
|
||||
|
||||
def __init__(self, _client_secret, _host, _access_token, _client_token):
|
||||
|
||||
self.base = "https://" + _host + "/config-dns/v2/"
|
||||
self.basev1 = "https://" + _host + "/config-dns/v1/"
|
||||
|
||||
sess = requests.Session()
|
||||
sess.auth = EdgeGridAuth(
|
||||
client_token=_client_token,
|
||||
client_secret=_client_secret,
|
||||
access_token=_access_token
|
||||
)
|
||||
self._sess = sess
|
||||
|
||||
|
||||
def _writePrepped(self, prepped):
|
||||
filename = str(prepped.method) + ".json"
|
||||
f = open(filename, 'w')
|
||||
|
||||
f.write("headers: \n")
|
||||
f.write(str(prepped.headers))
|
||||
f.write("\nbody: \n")
|
||||
f.write(str(prepped.body))
|
||||
f.write("\nhooks:\n")
|
||||
f.write(str(prepped.hooks))
|
||||
f.write("\nmethod: " + str(prepped.method))
|
||||
f.write("\nurl: " + str(prepped.url) + "\n")
|
||||
|
||||
f.close()
|
||||
|
||||
def _request(self, method, path, params=None, data=None, v1=False):
|
||||
|
||||
url = urljoin(self.base, path)
|
||||
if v1:
|
||||
url = urljoin(self.basev1, path)
|
||||
|
||||
if (TESTING):
|
||||
print("testing mode")
|
||||
print(method, url)
|
||||
req = requests.Request(method, url, params=params, json=data)
|
||||
prepped = req.prepare()
|
||||
self._writePrepped(prepped)
|
||||
|
||||
resp = self._sess.request(method, url, params=params, json=data)
|
||||
|
||||
|
||||
if resp.status_code > 299:
|
||||
raise AkamaiClientException(resp.status_code)
|
||||
|
||||
resp.raise_for_status()
|
||||
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def record_get(self, zone, name, record_type):
|
||||
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('GET', path)
|
||||
|
||||
return result
|
||||
|
||||
def record_create(self, zone, name, record_type, params):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('POST', path, data=params)
|
||||
|
||||
return result
|
||||
|
||||
def record_delete(self, zone, name, record_type):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('DELETE', path)
|
||||
|
||||
if result.status_code == 204:
|
||||
print ("successfully deleted ", path)
|
||||
|
||||
return result
|
||||
|
||||
def record_replace(self, zone, name, record_type, params):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('PUT', path, data=params)
|
||||
|
||||
return result
|
||||
|
||||
def zones_get(self, contractIds=None, page=None, pageSize=None, search=None,
|
||||
showAll="true", sortBy="zone", types=None):
|
||||
path = 'zones'
|
||||
|
||||
params = {
|
||||
'contractIds': contractIds,
|
||||
'page': page,
|
||||
'pageSize': pageSize,
|
||||
'search': search,
|
||||
'showAll': showAll,
|
||||
'sortBy': sortBy,
|
||||
'types': types
|
||||
}
|
||||
|
||||
result = self._request('GET', path, params=params)
|
||||
|
||||
return result
|
||||
|
||||
def zone_recordset_get(self, zone, page=None, pageSize=30, search=None,
|
||||
showAll="true", sortBy="name", types=None):
|
||||
|
||||
|
||||
params = {
|
||||
'page': page,
|
||||
'pageSize': pageSize,
|
||||
'search': search,
|
||||
'showAll': showAll,
|
||||
'sortBy': sortBy,
|
||||
'types': types
|
||||
}
|
||||
|
||||
path = 'zones/{}/recordsets'.format(zone)
|
||||
result = self._request('GET', path, params=params)
|
||||
|
||||
return result
|
||||
|
||||
def records(self, zone_name):
|
||||
|
||||
recordset = self.zone_recordset_get(zone_name, showAll="true").json().get("recordsets")
|
||||
|
||||
return recordset
|
||||
|
||||
def master_zone_file_get(self, zone):
|
||||
|
||||
path = 'zones/{}/zone-file'.format(zone)
|
||||
|
||||
try:
|
||||
result = self._request('GET', path)
|
||||
|
||||
except AkamaiClientException as e:
|
||||
# not working with API v2, API v1 fallback
|
||||
path = 'zones/{}'.format(zone)
|
||||
result = self._request('GET', path, v1=True)
|
||||
print("Using API v1 fallback")
|
||||
print("(Probably Ignore)", e.message)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class AkamaiProvider(BaseProvider):
|
||||
|
||||
SUPPORTS_GEO = False
|
||||
SUPPORTS_DYNAMIC = False
|
||||
SUPPORTS = set(('A', 'AAAA', 'CNAME', 'MX', 'NAPTR', 'NS', 'PTR', 'SPF',
|
||||
'SRV', 'SSHFP', 'TXT'))
|
||||
|
||||
|
||||
def __init__(self, id, client_secret, host, access_token, client_token,
|
||||
*args, **kwargs):
|
||||
|
||||
self.log = logging.getLogger('AkamaiProvider[{}]'.format(id))
|
||||
self.log.debug('__init__: id=%s, ')
|
||||
super(AkamaiProvider, self).__init__(id, *args, **kwargs)
|
||||
|
||||
|
||||
self._dns_client = AkamaiClient(client_secret, host, access_token, client_token)
|
||||
|
||||
|
||||
self._zone_records = {}
|
||||
|
||||
|
||||
def zone_records(self, zone):
|
||||
if zone.name not in self._zone_records:
|
||||
try:
|
||||
self._zone_records[zone.name] = self._dns_client.records(zone.name[:-1])
|
||||
|
||||
except AkamaiClientException:
|
||||
return []
|
||||
|
||||
return self._zone_records[zone.name]
|
||||
|
||||
|
||||
def populate(self, zone, target=False, lenient=False):
|
||||
self.log.debug('populate: name=%s, target=%s, lenient=%s', zone.name, target, lenient)
|
||||
|
||||
# self._test(zone)
|
||||
|
||||
values = defaultdict(lambda: defaultdict(list))
|
||||
|
||||
for record in self.zone_records(zone):
|
||||
_type=record['type']
|
||||
if _type not in self.SUPPORTS:
|
||||
continue
|
||||
elif _type == 'TXT' and record['content'].startswith('ALIAS for'):
|
||||
# ALIAS has a "ride along" TXT record with 'ALIAS for XXXX',
|
||||
# we're ignoring it
|
||||
continue
|
||||
values[record['name']][record['type']].append(record)
|
||||
|
||||
|
||||
|
||||
def _test(self, zone) :
|
||||
|
||||
zone_name = zone.name[:len(zone.name)-1]
|
||||
|
||||
record_name = "octo.basir-test.com"
|
||||
record_type = "A"
|
||||
params = {
|
||||
"name": "octo.basir-test.com",
|
||||
"type": "A",
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"10.0.0.2",
|
||||
"10.0.0.3"
|
||||
]
|
||||
}
|
||||
repl_params = {
|
||||
"name": "octo.basir-test.com",
|
||||
"type": "A",
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"99.99.99.99",
|
||||
"10.0.0.3",
|
||||
"1.2.3.4"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# print("\n\nRunning test: record get..........\n")
|
||||
# self._test_record_get(zone_name, "test.basir-test.com", record_type)
|
||||
# print("\n\nRunning test: record create..........\n")
|
||||
# self._test_record_create(zone_name, record_name, record_type, params)
|
||||
# print("\n\nRunning test: record replace..........\n")
|
||||
# self._test_record_replace(zone_name, record_name, record_type, repl_params)
|
||||
# print("\n\nRunning test: record delete..........\n")
|
||||
# self._test_record_delete(zone_name, record_name, record_type)
|
||||
|
||||
# print("\n\nRunning test: zones get..........\n")
|
||||
# self._test_zones_get()
|
||||
|
||||
print("\n\nRunning test: zone recordset get..........\n")
|
||||
self._test_zones_recordset_get(zone_name)
|
||||
|
||||
# print("\n\nRunning test: Master Zone File get..........\n")
|
||||
# self._test_master_zone_file_get(zone_name)
|
||||
|
||||
return
|
||||
|
||||
def _test_record_get(self, zone_name, record_name, record_type):
|
||||
try:
|
||||
get = self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print ("record get test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("record get test result: ")
|
||||
print(json.dumps(get.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
|
||||
def _test_record_delete(self, zone_name, record_name, record_type):
|
||||
|
||||
try:
|
||||
delete = self._dns_client.record_delete(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("delete failed")
|
||||
print(e.message)
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("get on record failed as expected, since record was succesfully deleted")
|
||||
print ("(Probably Ignore):", e.message)
|
||||
print ("delete status:", delete.status_code)
|
||||
else:
|
||||
print("unexpected condition in test delete")
|
||||
|
||||
return
|
||||
|
||||
def _test_record_create(self, zone_name, record_name, record_type, params):
|
||||
|
||||
try:
|
||||
create = self._dns_client.record_create(zone_name, record_name, record_type, params)
|
||||
except AkamaiClientException as e:
|
||||
print ("create unsuccessful, presumably because it already exists")
|
||||
print ("(Probably Ignore)", e.message)
|
||||
else:
|
||||
print("initial create of", create.json().get("name"), "succesful: ", create.status_code)
|
||||
|
||||
return
|
||||
|
||||
def _test_record_replace(self, zone_name, record_name, record_type, params):
|
||||
|
||||
## create record to be replaced, if it doesn't already exist
|
||||
try:
|
||||
old_params = {
|
||||
"name": record_name,
|
||||
"type": record_type,
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"10.0.0.2",
|
||||
"10.0.0.3"
|
||||
]
|
||||
}
|
||||
create = self._dns_client.record_create(zone_name, record_name, record_type, old_params)
|
||||
except AkamaiClientException as e:
|
||||
print ("initial create unsuccessful, presumably because it already exists")
|
||||
print ("(Probably Ignore)", e.message)
|
||||
else:
|
||||
print("initial create of record to be replaced", create.json().get("name"), "succesful: ", create.status_code)
|
||||
|
||||
|
||||
## test replace
|
||||
try:
|
||||
replace = self._dns_client.record_replace(zone_name, record_name, record_type, params)
|
||||
except AkamaiClientException as e:
|
||||
print("replace failed")
|
||||
print(e.message)
|
||||
return
|
||||
else:
|
||||
try:
|
||||
record = self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("retrieval in replacement failed")
|
||||
print(e.message)
|
||||
else:
|
||||
new_data = record.json()
|
||||
|
||||
if (new_data != params):
|
||||
print("replace failed, records don't match")
|
||||
print("current data:")
|
||||
print(new_data)
|
||||
print("expected data:")
|
||||
print(params)
|
||||
|
||||
else:
|
||||
print("replace succesful")
|
||||
print("replace status:", replace.status_code)
|
||||
|
||||
def _test_zones_get(self):
|
||||
try:
|
||||
zonesList = self._dns_client.zones_get()
|
||||
except AkamaiClientException as e:
|
||||
print ("zones get test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("zones list: ")
|
||||
print(json.dumps(zonesList.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
|
||||
def _test_zones_recordset_get(self, zone_name):
|
||||
try:
|
||||
zoneRecordset = self._dns_client.zone_recordset_get(zone_name)
|
||||
except AkamaiClientException as e:
|
||||
print("zone recordset retrieval test failed")
|
||||
print (e.message)
|
||||
else:
|
||||
print("zone recordset: ")
|
||||
print(json.dumps(zoneRecordset.json(), indent=4, separators=(',', ': ')))
|
||||
return
|
||||
|
||||
def _test_master_zone_file_get(self, zone_name):
|
||||
try:
|
||||
mzf = self._dns_client.master_zone_file_get(zone_name)
|
||||
|
||||
except AkamaiClientException as e:
|
||||
print("MZF retrieval test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("Master Zone File:")
|
||||
print(json.dumps(mzf.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
from __future__ import absolute_import, division, print_function, \
|
||||
unicode_literals
|
||||
|
||||
## octodns specfic imports:
|
||||
import requests
|
||||
from akamai.edgegrid import EdgeGridAuth
|
||||
from urlparse import urljoin
|
||||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
import logging
|
||||
from ..record import Record
|
||||
from .base import BaseProvider
|
||||
|
||||
TESTING = True
|
||||
|
||||
class AkamaiClientException(Exception):
|
||||
|
||||
_errorMessages = {
|
||||
400: "400: Bad request",
|
||||
403: "403: Access is forbidden",
|
||||
404: "404: Resource not found",
|
||||
405: "405: Method not supported",
|
||||
406: "406: Not Acceptable",
|
||||
409: "409: Request not allowed due to conflict with current state of resource",
|
||||
415: "415: Unsupported media type",
|
||||
422: "422: Request body contains an error preventing processing",
|
||||
500: "500: Internal server error"
|
||||
}
|
||||
|
||||
def __init__(self, code):
|
||||
message = self._errorMessages.get(code)
|
||||
super(AkamaiClientException, self).__init__(message)
|
||||
|
||||
|
||||
class _AkamaiRecord(object):
|
||||
pass
|
||||
|
||||
|
||||
class AkamaiClient(object):
|
||||
|
||||
def __init__(self, _client_secret, _host, _access_token, _client_token):
|
||||
|
||||
self.base = "https://" + _host + "/config-dns/v2/"
|
||||
self.basev1 = "https://" + _host + "/config-dns/v1/"
|
||||
|
||||
sess = requests.Session()
|
||||
sess.auth = EdgeGridAuth(
|
||||
client_token=_client_token,
|
||||
client_secret=_client_secret,
|
||||
access_token=_access_token
|
||||
)
|
||||
self._sess = sess
|
||||
|
||||
|
||||
def _writePrepped(self, prepped):
|
||||
filename = str(prepped.method) + ".json"
|
||||
f = open(filename, 'w')
|
||||
|
||||
f.write("headers: \n")
|
||||
f.write(str(prepped.headers))
|
||||
f.write("\nbody: \n")
|
||||
f.write(str(prepped.body))
|
||||
f.write("\nhooks:\n")
|
||||
f.write(str(prepped.hooks))
|
||||
f.write("\nmethod: " + str(prepped.method))
|
||||
f.write("\nurl: " + str(prepped.url) + "\n")
|
||||
|
||||
f.close()
|
||||
|
||||
def _request(self, method, path, params=None, data=None, v1=False):
|
||||
|
||||
url = urljoin(self.base, path)
|
||||
if v1:
|
||||
url = urljoin(self.basev1, path)
|
||||
|
||||
if (TESTING):
|
||||
print("testing mode")
|
||||
print(method, url)
|
||||
req = requests.Request(method, url, params=params, json=data)
|
||||
prepped = req.prepare()
|
||||
self._writePrepped(prepped)
|
||||
|
||||
resp = self._sess.request(method, url, params=params, json=data)
|
||||
|
||||
|
||||
if resp.status_code > 299:
|
||||
raise AkamaiClientException(resp.status_code)
|
||||
|
||||
resp.raise_for_status()
|
||||
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def record_get(self, zone, name, record_type):
|
||||
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('GET', path)
|
||||
|
||||
return result
|
||||
|
||||
def record_create(self, zone, name, record_type, params):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('POST', path, data=params)
|
||||
|
||||
return result
|
||||
|
||||
def record_delete(self, zone, name, record_type):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('DELETE', path)
|
||||
|
||||
if result.status_code == 204:
|
||||
print ("successfully deleted ", path)
|
||||
|
||||
return result
|
||||
|
||||
def record_replace(self, zone, name, record_type, params):
|
||||
path = 'zones/{}/names/{}/types/{}'.format(zone, name, record_type)
|
||||
result = self._request('PUT', path, data=params)
|
||||
|
||||
return result
|
||||
|
||||
def zones_get(self, contractIds=None, page=None, pageSize=None, search=None,
|
||||
showAll="true", sortBy="zone", types=None):
|
||||
path = 'zones'
|
||||
|
||||
params = {
|
||||
'contractIds': contractIds,
|
||||
'page': page,
|
||||
'pageSize': pageSize,
|
||||
'search': search,
|
||||
'showAll': showAll,
|
||||
'sortBy': sortBy,
|
||||
'types': types
|
||||
}
|
||||
|
||||
result = self._request('GET', path, params=params)
|
||||
|
||||
return result
|
||||
|
||||
def zone_recordset_get(self, zone, page=None, pageSize=30, search=None,
|
||||
showAll="true", sortBy="name", types=None):
|
||||
|
||||
|
||||
params = {
|
||||
'page': page,
|
||||
'pageSize': pageSize,
|
||||
'search': search,
|
||||
'showAll': showAll,
|
||||
'sortBy': sortBy,
|
||||
'types': types
|
||||
}
|
||||
|
||||
path = 'zones/{}/recordsets'.format(zone)
|
||||
result = self._request('GET', path, params=params)
|
||||
|
||||
|
||||
return result
|
||||
|
||||
def records(self, zone_name):
|
||||
|
||||
resp = self.zone_recordset_get(zone_name, showAll="true")
|
||||
recordset = resp.json().get("recordsets")
|
||||
|
||||
return recordset
|
||||
|
||||
def master_zone_file_get(self, zone):
|
||||
|
||||
path = 'zones/{}/zone-file'.format(zone)
|
||||
|
||||
try:
|
||||
result = self._request('GET', path)
|
||||
|
||||
except AkamaiClientException as e:
|
||||
# not working with API v2, API v1 fallback
|
||||
path = 'zones/{}'.format(zone)
|
||||
result = self._request('GET', path, v1=True)
|
||||
print("Using API v1 fallback")
|
||||
print("(Probably Ignore)", e.message)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class AkamaiProvider(BaseProvider):
|
||||
|
||||
SUPPORTS_GEO = False
|
||||
SUPPORTS_DYNAMIC = False
|
||||
|
||||
SUPPORTS = set(('A', 'AAAA', 'CNAME', 'MX', 'NAPTR', 'NS', 'PTR', 'SPF',
|
||||
'SRV', 'SSHFP', 'TXT'))
|
||||
# SUPPORTS = set(('NAPTR', 'MX'))
|
||||
|
||||
def __init__(self, id, client_secret, host, access_token, client_token,
|
||||
*args, **kwargs):
|
||||
|
||||
self.log = logging.getLogger('AkamaiProvider[{}]'.format(id))
|
||||
self.log.debug('__init__: id=%s, ')
|
||||
super(AkamaiProvider, self).__init__(id, *args, **kwargs)
|
||||
|
||||
self._dns_client = AkamaiClient(client_secret, host, access_token,
|
||||
client_token)
|
||||
|
||||
self._zone_records = {}
|
||||
|
||||
|
||||
def zone_records(self, zone):
|
||||
""" returns records for a zone, finds it if not present, or
|
||||
returns empty if doesnt exist
|
||||
"""
|
||||
if zone.name not in self._zone_records:
|
||||
try:
|
||||
name = zone.name[:-1]
|
||||
self._zone_records[zone.name] = self._dns_client.records(name)
|
||||
|
||||
except AkamaiClientException:
|
||||
return []
|
||||
|
||||
|
||||
# fileName = "zone_records_for_" + zone.name +".json"
|
||||
# path = "/mnt/c/Users/bajamil/Desktop/" + fileName
|
||||
# f = open(path, 'w')
|
||||
# f.write(json.dumps(self._zone_records[zone.name], indent=4, separators=(',', ': ')))
|
||||
# f.close()
|
||||
|
||||
return self._zone_records[zone.name]
|
||||
|
||||
|
||||
def populate(self, zone, target=False, lenient=False):
|
||||
self.log.debug('populate: name=%s', zone.name)
|
||||
# self._test(zone)
|
||||
|
||||
values = defaultdict(lambda: defaultdict(list))
|
||||
for record in self.zone_records(zone):
|
||||
|
||||
_type =record.get('type')
|
||||
_name = record.get('name')
|
||||
|
||||
if _type not in self.SUPPORTS:
|
||||
continue
|
||||
|
||||
values[_name][_type].append(record)
|
||||
|
||||
|
||||
|
||||
fileName = "values_for_" + zone.name +".json"
|
||||
path = "/mnt/c/Users/bajamil/Desktop/" + fileName
|
||||
f = open(path, 'w')
|
||||
f.write(json.dumps(values, indent=4, separators=(',', ': ')))
|
||||
f.close()
|
||||
|
||||
return ###
|
||||
before = len(zone.records)
|
||||
for name, types in values.items():
|
||||
for _type, records in types.items():
|
||||
data_for = getattr(self, '_data_for_{}'.format(_type))
|
||||
|
||||
data = data_for(_type, records)
|
||||
|
||||
print()
|
||||
print ("data processed for", name, ":")
|
||||
print (json.dumps(data, indent=4, separators=(',', ': ')))
|
||||
print()
|
||||
|
||||
record = Record.new(zone, name, data_for(_type, records), source=self, lenient=lenient)
|
||||
|
||||
|
||||
exists = zone.name in self._zone_records
|
||||
self.log.info('populate: found %s records, exists=%s',
|
||||
len(zone.records) - before, exists)
|
||||
|
||||
return exists
|
||||
|
||||
|
||||
def _data_for_multiple(self, _type, records):
|
||||
|
||||
return {
|
||||
'ttl': records[0]['ttl'],
|
||||
'type': _type,
|
||||
'values': [r['rdata'][0] for r in records]
|
||||
}
|
||||
|
||||
_data_for_A = _data_for_multiple
|
||||
_data_for_AAAA = _data_for_multiple
|
||||
_data_for_SPF = _data_for_multiple
|
||||
|
||||
def _data_for_CNAME(self, _type, records):
|
||||
record = records[0]
|
||||
value = record['rdata'][0]
|
||||
if (value[-1] != "."):
|
||||
value = '{}.'.format(value)
|
||||
|
||||
return {
|
||||
'ttl': records[0]['ttl'],
|
||||
'type': _type,
|
||||
'value': value
|
||||
}
|
||||
|
||||
def _data_for_MX(self, _type, records):
|
||||
values = []
|
||||
for record in records:
|
||||
print ("MX record: ", record)
|
||||
values.append({
|
||||
'preference': record['priority'],
|
||||
'exchange': '{}.'.format(record['rdata'][0])
|
||||
})
|
||||
return {
|
||||
'ttl': records[0]['ttl'],
|
||||
'type': _type,
|
||||
'values': values
|
||||
}
|
||||
|
||||
def _data_for_NAPTR(self, _type, records):
|
||||
print ("NAPTR Record")
|
||||
print(json.dumps(records, indent=4, separators=(',', ': ')))
|
||||
values = []
|
||||
for record in records:
|
||||
order, preference, flags, service, regexp, replacement = \
|
||||
record['rdata'][0].split(' ', 5)
|
||||
|
||||
values.append({
|
||||
'flags': flags[1:-1],
|
||||
'order': order,
|
||||
'preference': preference,
|
||||
'regexp': regexp[1:-1],
|
||||
'replacement': replacement,
|
||||
'service': service[1:-1]
|
||||
})
|
||||
return {
|
||||
'type': _type,
|
||||
'ttl': records[0]['ttl'],
|
||||
'values': values
|
||||
}
|
||||
|
||||
def _data_for_NS(self, _type, records):
|
||||
values = []
|
||||
for record in records:
|
||||
rdata = record['rdata']
|
||||
for content in rdata:
|
||||
if content[-1] != '.':
|
||||
content = '{}.'.format(content)
|
||||
values.append(content)
|
||||
return {
|
||||
'ttl': records[0]['ttl'],
|
||||
'type': _type,
|
||||
'value': values
|
||||
}
|
||||
|
||||
def _data_for_PTR(self, _type, records):
|
||||
return self._data_for_multiple(_type, records[0])
|
||||
|
||||
# rdata[0]?
|
||||
def _data_for_SRV(self, _type, records):
|
||||
values = []
|
||||
for record in records:
|
||||
weight, port, target = record['rdata'].split(', ', 2)
|
||||
values.append({
|
||||
'port': port,
|
||||
'priority': record['priority'],
|
||||
'target': '{}.'.format(target),
|
||||
'weight': weight
|
||||
})
|
||||
return {
|
||||
'type': _type,
|
||||
'ttl': records[0]['ttl'],
|
||||
'values': values
|
||||
}
|
||||
|
||||
# rdata[0]?
|
||||
def _data_for_SSHFP(self, _type, records):
|
||||
values = []
|
||||
algorithm, fp_type, fingerprint = record['rdata'].split(' ', 2)
|
||||
values.append({
|
||||
'algorithm': algorithm,
|
||||
'fingerprint': fingerprint,
|
||||
'fingerprint_type': fp_type
|
||||
})
|
||||
|
||||
return {
|
||||
'type': _type,
|
||||
'ttl': records[0]['ttl'],
|
||||
'values': values
|
||||
}
|
||||
|
||||
def _data_for_TXT(self, _type, records):
|
||||
values = []
|
||||
for r in records:
|
||||
for content in r['rdata']:
|
||||
values.append(content.replace(';', '\\;'))
|
||||
|
||||
return {
|
||||
'ttl': records[0]['ttl'],
|
||||
'type': _type,
|
||||
'values': values
|
||||
# 'values': [r['rdata'][0].replace(';', '\\;') for r in records]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
def _test(self, zone) :
|
||||
|
||||
zone_name = zone.name[:len(zone.name)-1]
|
||||
|
||||
record_name = "octo.basir-test.com"
|
||||
record_type = "A"
|
||||
params = {
|
||||
"name": "octo.basir-test.com",
|
||||
"type": "A",
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"10.0.0.2",
|
||||
"10.0.0.3"
|
||||
]
|
||||
}
|
||||
repl_params = {
|
||||
"name": "octo.basir-test.com",
|
||||
"type": "A",
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"99.99.99.99",
|
||||
"10.0.0.3",
|
||||
"1.2.3.4"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# print("\n\nRunning test: record get..........\n")
|
||||
# self._test_record_get(zone_name, "test.basir-test.com", record_type)
|
||||
# print("\n\nRunning test: record create..........\n")
|
||||
# self._test_record_create(zone_name, record_name, record_type, params)
|
||||
# print("\n\nRunning test: record replace..........\n")
|
||||
# self._test_record_replace(zone_name, record_name, record_type, repl_params)
|
||||
# print("\n\nRunning test: record delete..........\n")
|
||||
# self._test_record_delete(zone_name, record_name, record_type)
|
||||
|
||||
# print("\n\nRunning test: zones get..........\n")
|
||||
# self._test_zones_get()
|
||||
|
||||
print("\n\nRunning test: zone recordset get..........\n")
|
||||
self._test_zones_recordset_get(zone_name)
|
||||
|
||||
# print("\n\nRunning test: Master Zone File get..........\n")
|
||||
# self._test_master_zone_file_get(zone_name)
|
||||
|
||||
return
|
||||
|
||||
def _test_record_get(self, zone_name, record_name, record_type):
|
||||
try:
|
||||
get = self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print ("record get test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("record get test result: ")
|
||||
print(json.dumps(get.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
|
||||
def _test_record_delete(self, zone_name, record_name, record_type):
|
||||
|
||||
try:
|
||||
delete = self._dns_client.record_delete(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("delete failed")
|
||||
print(e.message)
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("get on record failed as expected, since record was succesfully deleted")
|
||||
print ("(Probably Ignore):", e.message)
|
||||
print ("delete status:", delete.status_code)
|
||||
else:
|
||||
print("unexpected condition in test delete")
|
||||
|
||||
return
|
||||
|
||||
def _test_record_create(self, zone_name, record_name, record_type, params):
|
||||
|
||||
try:
|
||||
create = self._dns_client.record_create(zone_name, record_name, record_type, params)
|
||||
except AkamaiClientException as e:
|
||||
print ("create unsuccessful, presumably because it already exists")
|
||||
print ("(Probably Ignore)", e.message)
|
||||
else:
|
||||
print("initial create of", create.json().get("name"), "succesful: ", create.status_code)
|
||||
|
||||
return
|
||||
|
||||
def _test_record_replace(self, zone_name, record_name, record_type, params):
|
||||
|
||||
## create record to be replaced, if it doesn't already exist
|
||||
try:
|
||||
old_params = {
|
||||
"name": record_name,
|
||||
"type": record_type,
|
||||
"ttl": 300,
|
||||
"rdata": [
|
||||
"10.0.0.2",
|
||||
"10.0.0.3"
|
||||
]
|
||||
}
|
||||
create = self._dns_client.record_create(zone_name, record_name, record_type, old_params)
|
||||
except AkamaiClientException as e:
|
||||
print ("initial create unsuccessful, presumably because it already exists")
|
||||
print ("(Probably Ignore)", e.message)
|
||||
else:
|
||||
print("initial create of record to be replaced", create.json().get("name"), "succesful: ", create.status_code)
|
||||
|
||||
|
||||
## test replace
|
||||
try:
|
||||
replace = self._dns_client.record_replace(zone_name, record_name, record_type, params)
|
||||
except AkamaiClientException as e:
|
||||
print("replace failed")
|
||||
print(e.message)
|
||||
return
|
||||
else:
|
||||
try:
|
||||
record = self._dns_client.record_get(zone_name, record_name, record_type)
|
||||
except AkamaiClientException as e:
|
||||
print("retrieval in replacement failed")
|
||||
print(e.message)
|
||||
else:
|
||||
new_data = record.json()
|
||||
|
||||
if (new_data != params):
|
||||
print("replace failed, records don't match")
|
||||
print("current data:")
|
||||
print(new_data)
|
||||
print("expected data:")
|
||||
print(params)
|
||||
|
||||
else:
|
||||
print("replace succesful")
|
||||
print("replace status:", replace.status_code)
|
||||
|
||||
def _test_zones_get(self):
|
||||
try:
|
||||
zonesList = self._dns_client.zones_get()
|
||||
except AkamaiClientException as e:
|
||||
print ("zones get test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("zones list: ")
|
||||
print(json.dumps(zonesList.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
|
||||
def _test_zones_recordset_get(self, zone_name):
|
||||
try:
|
||||
zoneRecordset = self._dns_client.zone_recordset_get(zone_name)
|
||||
except AkamaiClientException as e:
|
||||
print("zone recordset retrieval test failed")
|
||||
print (e.message)
|
||||
else:
|
||||
print("zone recordset: ")
|
||||
print(json.dumps(zoneRecordset.json(), indent=4, separators=(',', ': ')))
|
||||
return
|
||||
|
||||
def _test_master_zone_file_get(self, zone_name):
|
||||
try:
|
||||
mzf = self._dns_client.master_zone_file_get(zone_name)
|
||||
|
||||
except AkamaiClientException as e:
|
||||
print("MZF retrieval test failed")
|
||||
print (e.message)
|
||||
|
||||
else:
|
||||
print("Master Zone File:")
|
||||
print(json.dumps(mzf.json(), indent=4, separators=(',', ': ')))
|
||||
|
||||
return
|
||||
|
Reference in New Issue
Block a user