Source code for slam_domain.views

"""
This module provide different view to manage domain. To avoid shadow name declaration, we use those
following nomenclature
 - *_view: a function that manage the web interface (per example domains_view manage web interface
 of domains, ...)
 - domain: a specific domain (per example example.com)
 - domains: a list of domain
 - entry: a name associated with a domain that represent a entry in DNS
 - entries: a list of entry

 - rest_api: a boolean which say if REST API is used. If not, HTML rendering will be used
 - options: a generic structure that represent arguments we send/receive to/from function
 - result: a temporary structure that represent the output of the view
 - result_*: a temporary structure that represent a part of the output (per example result_entries)
 - uri_*: input retrieve from URI structure itselfmkdir -p /opt/slam
"""
import logging
import json

from datetime import datetime

from django.shortcuts import render
from django.http import JsonResponse, QueryDict
from django.contrib.auth.decorators import login_required

from slam_domain.models import Domain, DomainEntry

LOGGER = logging.getLogger('api')


[docs]@login_required def domains_view(request): """ This function manage interaction between user and SLAM for all domains management. URI is represented by https://slam.example.com/domains :param request: full HTTP request from user """ result = Domain.search() if request.headers['Accept'] == 'application/json' or \ request.GET.get('format') == 'json': return JsonResponse(result, safe=False) return render(request, 'domains/index.html', dict())
[docs]@login_required def domain_view(request, uri_domain): """ This function manage interaction between user and SLAM for a specific domain management. URI is represented by https://slam.example.com/domains/example.com :param request: full HTTP request from user :param uri_domain: the name of domain from URI (per example example.com is our URI) """ if request.method == 'GET' and request.headers['Accept'] != 'application/json': return render(request, 'domains/domain.html', dict()) if request.method == 'GET': # If we just want to retrieve (GET) information for the domain. We're looking for # domain and all entries associated to it. result = Domain.get(uri_domain) elif request.method == 'POST': # If we want to create (POST) a new domain. We retrieve optional information and create # a new object. options = dict() for args in request.POST: # We don't care about the saintly of options as Domain.create take care of it. options[args] = request.POST.get(args) LOGGER.info('{}: {} created domain {} with options {}'.format( datetime.now(), request.user, uri_domain, json.dumps(options))) result = Domain.create(name=uri_domain, args=options) elif request.method == 'PUT': # If we want to update (PUT) a existing domain. We retrieve all mutable value and change it. raw_data = request.body data = QueryDict(raw_data) options = dict() for args in data: # We don't care about the saintly of options as Domain.update take care of it. options[args] = data.get(args) LOGGER.info('{}: {} updated domain {} with options {}'.format( datetime.now(), request.user, uri_domain, json.dumps(options))) result = Domain.update(uri_domain, args=options) elif request.method == 'DELETE': # If we want to delete (DELETE) a existing domain, we just do it. LOGGER.info('{}: {} deleted domain {}'.format( datetime.now(), request.user, uri_domain)) result = Domain.remove(uri_domain) else: # We just support GET / POST / PUT / DELETE HTTP method. If anything else arrived, we # just drop it result = { 'domain': uri_domain, 'status': 'failed', 'message': '{} method is not supported'.format(request.method) } return JsonResponse(result)
[docs]@login_required def entry_view(request, uri_domain, uri_entry): """ This function manage interaction between user and SLAM for a specific domain management. URI is represented by https://slam.example.com/domains/example.com/www if we want to represent www.example.com :param request: full HTTP request from user :param uri_domain: the name of domain from URI (per example example.com in our URI) :param uri_entry: the entry name in a domain (per example www.example.com in our URI) """ if request.method == 'GET': # If we want a list of entries, we need to retrieve domain and list all entries associated # with it. result = DomainEntry.get(name=uri_entry, domain=uri_domain) elif request.method == 'POST': # If we want to create a new entry, we need to retrieve the domain and add the entry on # this domain. options = { 'name': uri_entry, 'domain': uri_domain, } if request.POST.get('ns_type') is not None: options['ns_type'] = request.POST.get('ns_type') if request.POST.get('sub_entry_name') is not None: options['sub_entry'] = { 'name': request.POST.get('sub_entry_name'), 'domain': request.POST.get('sub_entry_domain'), 'type': request.POST.get('sub_entry_type') } LOGGER.info('{}: {} created domain record {} with options {}'.format( datetime.now(), request.user, '{}.{}'.format(uri_entry, uri_domain), json.dumps(options) )) result = DomainEntry.create(**options) elif request.method == 'DELETE': # If we want to remove a specific entry, we must retrieve the entry associated with the # right domain and delete it. raw_data = request.body data = QueryDict(raw_data) LOGGER.info('{}: {} deleted domain record {}'.format( datetime.now(), request.user, '{}.{}'.format(uri_entry, uri_domain), )) if data.get('type') is not None: result = DomainEntry.remove(uri_entry, uri_domain, ns_type=data.get('type')) else: result = DomainEntry.remove(uri_entry, uri_domain) elif request.method == 'PUT': raw_data = request.body data = QueryDict(raw_data) options = { 'name': uri_entry, 'domain': uri_domain, } if data.get('type') is not None: options['ns_type'] = data.get('type') if data.get('sub_entry_name') is not None: options['sub_entry'] = { 'name': data.get('sub_entry_name'), 'domain': data.get('sub_entry_domain') } LOGGER.info('{}: {} updated domain record {} with options {}'.format( datetime.now(), request.user, '{}.{}'.format(uri_entry, uri_domain), json.dumps(options) )) result = DomainEntry.update(**options) else: # We just support GET / POST / PUT / DELETE HTTP method. If anything else arrived, we # just drop it. result = { 'entry': '{}.{}'.format(uri_entry, uri_domain), 'status': 'failed', 'message': '{} method is not supported'.format(request.method) } return JsonResponse(result)