Skip to content

Commit

Permalink
Merge pull request #2300 from szok/dns-create-records
Browse files Browse the repository at this point in the history
Create new DNS records
  • Loading branch information
szok committed Mar 17, 2016
2 parents abf5e11 + 5b584cd commit ac23590
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 61 deletions.
168 changes: 124 additions & 44 deletions src/ralph/dns/dnsaas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import requests
from django.conf import settings
from django.utils.lru_cache import lru_cache

from ralph.dns.forms import RecordType

Expand All @@ -22,6 +23,15 @@ def __init__(self, headers=None):
self.session.headers.update(_headers)

def get_api_result(self, url):
"""
Returns 'results' from DNSAAS API.
Args:
url: Url to API
Returns:
list of records
"""
request = self.session.get(url)
json_data = request.json()
api_results = json_data.get('results', [])
Expand All @@ -34,13 +44,14 @@ def get_dns_records(self, ipaddresses):
"""Gets DNS Records for `ipaddresses` by API call"""
dns_records = []
ipaddresses = [('ip', i) for i in ipaddresses]
url = '{}/{}/?{}'.format(
url = urljoin(
settings.DNSAAS_URL,
'api/records',
urlencode([
('limit', 100),
('offset', 0)
] + ipaddresses)
'api/records/?{}'.format(
urlencode([
('limit', 100),
('offset', 0)
] + ipaddresses)
)
)
api_results = self.get_api_result(url)
ptr_list = set(
Expand All @@ -53,46 +64,115 @@ def get_dns_records(self, ipaddresses):
'name': item['name'],
'type': RecordType.from_name(item['type'].lower()).id,
'content': item['content'],
'ptr': item['name'] in ptr_list
'ptr': item['name'] in ptr_list,
'owner': settings.DNSAAS_OWNER
})
return dns_records

def update_dns_records(self, records):
error = False
for item in records:
url = urljoin(
settings.DNSAAS_URL, 'api/records/{}/'.format(item['pk'])
def update_dns_records(self, record):
"""
Update DNS Record in DNSAAS
Args:
record: record cleaned data
Returns:
True or False if an error from api
"""
url = urljoin(
settings.DNSAAS_URL, 'api/records/{}/'.format(record['pk'])
)
data = {
'name': record['name'],
'type': RecordType.raw_from_id(int(record['type'])),
'content': record['content'],
'auto_ptr': (
settings.DNSAAS_AUTO_PTR_ALWAYS if record['ptr'] and
record['type'] == str(RecordType.a.id)
else settings.DNSAAS_AUTO_PTR_NEVER
),
'owner': settings.DNSAAS_OWNER
}
request = self.session.patch(url, data=data)
if request.status_code != 200:
return False
return True

@lru_cache()
def get_domain(self, record):
"""
Return domain URL base on record name.
Args:
record: Cleaned data from formset
Return:
Domain URL from API or False if not exists
"""
domain_name = record['name'].split('.', 1)
url = urljoin(
settings.DNSAAS_URL, 'api/domains/?'.format(
urlencode([('name', domain_name[-1])])
)
data = {
'name': item['name'],
'type': RecordType.raw_from_id(int(item['type'])),
'content': item['content'],
'auto_ptr': (
settings.DNSAAS_AUTO_PTR_ALWAYS if item['ptr'] and
item['type'] == RecordType.a.id
else settings.DNSAAS_AUTO_PTR_NEVER
)
}
request = self.session.patch(url, data=data)
if request.status_code != 200:
logger.error(
'Error from DNS API {}: {}'.format(url, request.json())
)
error = True

return error

def delete_dns_records(self, record_ids):
error = False
for record_id in record_ids:
url = urljoin(
settings.DNSAAS_URL, 'api/records/{}/'.format(record_id)
)
result = self.get_api_result(url)
if result:
return result[0]['url']

return False

def create_dns_records(self, record):
"""
Create new DNS record.
Args:
records: Record cleaned data
Returns:
True or False if an error from api
"""

url = urljoin(settings.DNSAAS_URL, 'api/records/')
domain = self.get_domain(record)
if not domain:
logger.error(
'Domain not found for record {}'.format(record)
)
request = self.session.delete(url)
if request.status_code != 204:
error = True
logger.error(
'Error from DNS API {}: {}'.format(url, request.json())
)

return error
return False

data = {
'name': record['name'],
'type': RecordType.raw_from_id(int(record['type'])),
'content': record['content'],
'auto_ptr': (
settings.DNSAAS_AUTO_PTR_ALWAYS if record['ptr'] and
record['type'] == RecordType.a.id
else settings.DNSAAS_AUTO_PTR_NEVER
),
'domain': domain,
'owner': settings.DNSAAS_OWNER
}
request = self.session.post(url, data=data)
if request.status_code != 201:
return False

return True

def delete_dns_records(self, record_id):
"""
Delete rcords in DNSAAS
Args:
record_ids: ID's to delete
Returns:
True or False if an error from api
"""
url = urljoin(
settings.DNSAAS_URL, 'api/records/{}/'.format(record_id)
)
request = self.session.delete(url)
if request.status_code != 204:
return False

return True
23 changes: 6 additions & 17 deletions src/ralph/dns/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# -*- coding: utf-8 -*-
import logging

from django.contrib import messages
from django.forms import BaseFormSet, formset_factory
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _

from ralph.admin.views.extra import RalphDetailView
from ralph.dns.dnsaas import DNSaaS
Expand Down Expand Up @@ -46,23 +44,14 @@ def get(self, request, *args, **kwargs):
def post(self, request, *args, **kwargs):
formset = self.get_formset()
if formset.is_valid():
to_delete = []
to_update = []
for form in formset.forms:
for i, form in enumerate(formset.forms):
if form.cleaned_data.get('DELETE'):
to_delete.append(form.cleaned_data['pk'])
self.dnsaas.delete_dns_records(form.cleaned_data['pk'])
elif form.has_changed():
to_update.append(form.cleaned_data)

if to_delete and self.dnsaas.delete_dns_records(to_delete):
messages.error(
request, _('An error occurred while deleting a record')
)
if to_update and self.dnsaas.update_dns_records(to_update):
messages.error(
request, _('An error occurred while updating a record')
)

if form.cleaned_data['pk']:
self.dnsaas.update_dns_records(form.cleaned_data)
else:
self.dnsaas.create_dns_records(form.cleaned_data)
return HttpResponseRedirect('.')

kwargs['formset'] = formset
Expand Down
2 changes: 2 additions & 0 deletions src/ralph/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ def os_env_true(var, default=''):
DNSAAS_TOKEN = os.environ.get('DNSAAS_TOKEN', '')
DNSAAS_AUTO_PTR_ALWAYS = os.environ.get('DNSAAS_AUTO_PTR_ALWAYS', 2)
DNSAAS_AUTO_PTR_NEVER = os.environ.get('DNSAAS_AUTO_PTR_NEVER', 1)
DNSAAS_OWNER = os.environ.get('DNSAAS_OWNER', 'ralph')

if ENABLE_DNSAAS_INTEGRATION:
INSTALLED_APPS += (
'ralph.dns',
Expand Down

0 comments on commit ac23590

Please sign in to comment.