Skip to content

Commit

Permalink
Release version: 0.1.50
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien Delle Cave committed Jan 19, 2022
1 parent 6a2ce5c commit 11c0830
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 114 deletions.
38 changes: 37 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
nsaproxy (0.1.50) unstable; urgency=medium

* Release version: 0.1.50

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Wed, 19 Jan 2022 12:31:08 +0100

nsaproxy (0.1.49) unstable; urgency=medium

* Release version: 0.1.49

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Tue, 18 Jan 2022 13:41:07 +0100

nsaproxy (0.1.48) unstable; urgency=medium

* Release version: 0.1.48

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Tue, 18 Jan 2022 13:25:17 +0100

nsaproxy (0.1.47) unstable; urgency=medium

* Release version: 0.1.47

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Tue, 18 Jan 2022 13:19:17 +0100

nsaproxy (0.1.46) unstable; urgency=medium

* Release version: 0.1.46

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Tue, 18 Jan 2022 11:23:54 +0100

nsaproxy (0.1.45) unstable; urgency=medium

* Release version: 0.1.45

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Sat, 15 Jan 2022 09:30:18 +0100

nsaproxy (0.1.44) unstable; urgency=medium

* Release version: 0.1.44
Expand All @@ -6,7 +42,7 @@ nsaproxy (0.1.44) unstable; urgency=medium

nsaproxy (0.1.43) unstable; urgency=medium

* Release version: 0.1.43
* Release version: 0.1.43

-- Adrien DELLE CAVE (Decryptus) <adrien.delle.cave@commandersact.com> Sun, 09 Jan 2022 00:59:24 +0100

Expand Down
2 changes: 1 addition & 1 deletion RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.44
0.1.50
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.44
0.1.50
4 changes: 2 additions & 2 deletions bin/nsaproxy
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2021 fjord-technologies
# Copyright (C) 2018-2022 fjord-technologies
# SPDX-License-Identifier: GPL-3.0-or-later
"""nsaproxy"""

__version__ = '0.1.44'
__version__ = '0.1.50'

# TODO: load Python logging configuration (using standard logging.config)

Expand Down
4 changes: 2 additions & 2 deletions debian/copyright
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ Upstream-Name: nsaproxy
Upstream-Contact: Adrien Delle Cave

Files: *
Copyright: 2018-2021 fjord-technologies
Copyright: 2018-2022 fjord-technologies
License: GPL-3

Files: debian/*
Copyright: 2018-2021 Adrien Delle Cave
Copyright: 2018-2022 Adrien Delle Cave
License: GPL-3

License: GPL-3
Expand Down
26 changes: 2 additions & 24 deletions etc/nsaproxy/nsaproxy.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ general:
pdns:
api_uri: 'http://localhost:8081'
credentials: file:///etc/nsaproxy/credentials.yml
import_modules:
- modules/api.yml
#dns:
# domains:
# default:
Expand Down Expand Up @@ -42,27 +44,3 @@ plugins:
r53:
enabled: true
credentials: file:///etc/nsaproxy/credentials.yml
modules:
pdns:
routes:
api_endpoint_get:
handler: 'api_endpoint_get'
regexp: '^api/v1/servers/(?P<server_id>[^\/]+)/(?P<endpoint>[^\/]+)(?:/(?P<id>[a-zA-Z0-9\.\-]+)(?:/(?P<command>check|export))?)?$'
op: 'GET'
safe_init: true
api_endpoint_put:
handler: 'api_endpoint_put'
regexp: '^api/v1/servers/(?P<server_id>[^\/]+)/(?P<endpoint>[^\/]+)/(?P<id>[a-zA-Z0-9\.\-]+)(?:/(?P<command>axfr-retrieve|notify|rectify))?$'
op: 'PUT'
api_endpoint_post:
handler: 'api_endpoint_post'
regexp: '^api/v1/servers/(?P<server_id>[^\/]+)/(?P<endpoint>[^\/]+)$'
op: 'POST'
api_endpoint_patch:
handler: 'api_endpoint_patch'
regexp: '^api/v1/servers/(?P<server_id>[^\/]+)/(?P<endpoint>[^\/]+)/(?P<id>[a-zA-Z0-9\.\-]+)$'
op: 'PATCH'
api_endpoint_delete:
handler: 'api_endpoint_delete'
regexp: '^api/v1/servers/(?P<server_id>[^\/]+)/(?P<endpoint>[^\/]+)/(?P<id>[a-zA-Z0-9\.\-]+)$'
op: 'DELETE'
117 changes: 91 additions & 26 deletions nsaproxy/modules/pdns.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import logging
import time
import uuid
import requests

from copy import deepcopy

from six import itervalues
import requests

from six import itervalues, string_types

from dwho.classes.modules import DWhoModuleBase, MODULES
from sonicprobe import helpers
Expand All @@ -25,21 +26,20 @@
LOG = logging.getLogger('nsaproxy.modules.pdns')


def validate_params(params):
if not isinstance(params, (list, dict)):
def validate_domain(domain, mask = network.MASK_DOMAIN):
if not isinstance(domain, string_types) \
or not domain \
or domain[-1] != '.':
return False

if not params:
return True
return network.valid_host(domain[0:-1], mask)

return params

def validate_name(ip_addr):
def validate_ipaddr(ip_addr):
return network.valid_host(ip_addr, network.MASK_IPV4_DOTDEC | network.MASK_IPV6)


xys.add_callback('pdns.validate_params', validate_params)
xys.add_callback('pdns.validate_nameservers', network.valid_host)
xys.add_callback('pdns.domain', validate_domain)
xys.add_callback('pdns.ipaddr', validate_ipaddr)


class PDNSModule(DWhoModuleBase):
Expand Down Expand Up @@ -99,6 +99,13 @@ def _add_rrset(self, zone, domain_name, xtype, content, ttl = DEFAULT_TTL):
'changetype': 'REPLACE',
'records': [self._add_record(content)]})

@staticmethod
def _replace_vars(key, xvars):
if '%(' in key and ')s' in key:
return key % xvars

return key

def _append_rrsets(self, zone, domain_name, rrsets):
r = False

Expand All @@ -125,17 +132,25 @@ def _append_rrsets(self, zone, domain_name, rrsets):
else:
rrset['name'] = "%s.%s." % (name.rstrip('.'), domain_name)

rrset['ttl'] = int(rrset.get('ttl', DEFAULT_TTL))
xvars = {'name': name,
'domain_name': domain_name}

rrset['name'] = self._replace_vars(rrset['name'], xvars)
rrset['ttl'] = int(rrset.get('ttl', DEFAULT_TTL))
rrset['changetype'] = 'REPLACE'

if rrset.get('records'):
for record in rrset['records']:
record['content'] = self._replace_vars(record.get('content') or '',
xvars)
record['disabled'] = bool(record.get('disabled') or False)

if rrset.get('comments'):
for comment in rrset['comments']:
comment['account'] = comment.get('account') or ''
comment['content'] = self._replace_vars(comment.get('content') or '',
xvars)
comment['account'] = self._replace_vars(comment.get('account') or '',
xvars)

zone['rrsets'].append(deepcopy(rrset))
r = True
Expand Down Expand Up @@ -169,8 +184,8 @@ def _do_request(self, method, path, params, payload, headers):
json = payload,
headers = h)

def _do_response(self, request, params = None, args = None):
r = self._do_request(request.get_method(), request.get_path(), params, args, request.get_headers())
def _do_response(self, request, params = None, args = None, method = None):
r = self._do_request(method or request.get_method(), request.get_path(), params, args, request.get_headers())
if not r.text:
return HttpResponseJson(r.status_code)

Expand Down Expand Up @@ -293,10 +308,10 @@ def api_endpoint_put(self, request):
""")

ENDPOINT_POST_PSCHEMA = xys.load("""
nameservers?: [ !!str ]
masters?: [ !!str ]
kind?: !~~enum(native,master,slave)
name?: !!str
nameservers?: [ !~~callback(pdns.domain) ]
masters?: [ !~~callback(pdns.ipaddr) ]
kind?: !~~ienum(native,master,primary,slave,secondary)
name?: !~~callback(pdns.domain)
account?: !!str
soa_edit_api?: !~~enum(DEFAULT,INCREASE,INCEPTION-INCREMENT,EPOCH,INCEPTION-EPOCH)
""")
Expand All @@ -320,7 +335,7 @@ def api_endpoint_post(self, request):
raise HttpReqErrJson(415, "invalid arguments for command payload parameters")

if not self.LOCK.acquire_write(self.lock_timeout):
raise HttpReqErrJson(503, "unable to take LOCK for reading after %s seconds" % self.lock_timeout)
raise HttpReqErrJson(503, "unable to take LOCK for writing after %s seconds" % self.lock_timeout)

try:
if params.get('endpoint') != 'zones':
Expand Down Expand Up @@ -391,10 +406,10 @@ def api_endpoint_post(self, request):
""")

ENDPOINT_PATCH_PSCHEMA = xys.load("""
nameservers?: [ !!str ]
masters?: [ !!str ]
kind?: !~~enum(native,master,slave)
name?: !!str
nameservers?: [ !~~callback(pdns.domain) ]
masters?: [ !~~callback(pdns.ipaddr) ]
kind?: !~~ienum(native,primary,secondary,master,slave)
name?: !~~callback(pdns.domain)
soa_edit_api?: !~~enum(INCEPTION-INCREMENT,EPOCH,INCEPTION-EPOCH)
rrsets?: !~~seqlen(0,9999)
- comments?:
Expand Down Expand Up @@ -429,7 +444,7 @@ def api_endpoint_patch(self, request):
raise HttpReqErrJson(415, "invalid arguments for command payload parameters")

if not self.LOCK.acquire_write(self.lock_timeout):
raise HttpReqErrJson(503, "unable to take LOCK for reading after %s seconds" % self.lock_timeout)
raise HttpReqErrJson(503, "unable to take LOCK for writing after %s seconds" % self.lock_timeout)

try:
if params.get('endpoint') != 'zones':
Expand Down Expand Up @@ -474,7 +489,7 @@ def api_endpoint_delete(self, request):
raise HttpReqErrJson(415, "invalid arguments for command for query parameters")

if not self.LOCK.acquire_write(self.lock_timeout):
raise HttpReqErrJson(503, "unable to take LOCK for reading after %s seconds" % self.lock_timeout)
raise HttpReqErrJson(503, "unable to take LOCK for writing after %s seconds" % self.lock_timeout)

try:
if params.get('endpoint') != 'zones':
Expand All @@ -497,6 +512,56 @@ def api_endpoint_delete(self, request):
self.LOCK.release()


ENDPOINT_VALIDATE_QSCHEMA = xys.load("""
server_id: !!str
endpoint: !!str
id: !~~callback(pdns.domain)
""")
def api_endpoint_validate(self, request):
params = request.query_params()

self._check_api_key(request)

if not isinstance(params, dict):
raise HttpReqErrJson(400, "invalid arguments type for query parameters")

if not xys.validate(params, self.ENDPOINT_VALIDATE_QSCHEMA):
raise HttpReqErrJson(415, "invalid arguments for command for query parameters")

if not self.LOCK.acquire_read(self.lock_timeout):
raise HttpReqErrJson(503, "unable to take LOCK for reading after %s seconds" % self.lock_timeout)

try:
domain = params.pop('id').lower()

r = self._do_response(request, method = 'GET')
if not r:
raise HttpReqErrJson(500, "unable to fetch domains list")

data = r.get_data()
if not data:
raise HttpReqErrJson(500, "unable to fetch domains list")

data = json.loads(data)
if not isinstance(data, list):
raise HttpReqErrJson(500, "unable to fetch domains list")

if not data:
return True

for x in data:
if x['name'] == domain:
raise HttpReqErrJson(409, "domain %r already exists" % domain)

return True
except HttpReqErrJson as e:
raise
except Exception as e:
LOG.exception("%r", e)
finally:
self.LOCK.release()


if __name__ != "__main__":
def _start():
MODULES.register(PDNSModule())
Expand Down

0 comments on commit 11c0830

Please sign in to comment.