Skip to content
Snippets Groups Projects
Commit 1dd4436a authored by Lars Beckers's avatar Lars Beckers
Browse files

improve on pep8 conformance

parent 2e5ef85d
Branches
No related tags found
No related merge requests found
...@@ -7,14 +7,15 @@ import re ...@@ -7,14 +7,15 @@ import re
import sys import sys
from pathlib import Path from pathlib import Path
config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation()) config = configparser.ConfigParser(
interpolation=configparser.ExtendedInterpolation())
try: try:
with open('./sshgen.cfg') as fp: with open('./sshgen.cfg') as fp:
config.read_file(fp) config.read_file(fp)
except Exception: except Exception:
pass pass
if not 'presets' in config: if 'presets' not in config:
config['presets'] = {} config['presets'] = {}
choices = [] choices = []
choice_default = None choice_default = None
...@@ -22,12 +23,16 @@ else: ...@@ -22,12 +23,16 @@ else:
choices = list(config['presets']) choices = list(config['presets'])
choice_default = list(config['presets'].keys())[0] choice_default = list(config['presets'].keys())[0]
parser = argparse.ArgumentParser(description='Generates a SSH config file from some DNS zone(s).') parser = argparse.ArgumentParser(
description='Generates a SSH config file from some DNS zone(s).')
if choices: if choices:
parser.add_argument('--preset', choices=choices, default=choice_default, help='select a configuration preset') parser.add_argument('--preset', choices=choices, default=choice_default,
help='select a configuration preset')
else: else:
parser.add_argument('--preset', action='store', default=choice_default, help='select a configuration preset') parser.add_argument('--preset', action='store', default=choice_default,
parser.add_argument('--cfg', action='store', default='./sshgen.cfg', help='config file') help='select a configuration preset')
parser.add_argument('--cfg', action='store', default='./sshgen.cfg',
help='config file')
args = parser.parse_args() args = parser.parse_args()
preset = args.preset preset = args.preset
...@@ -37,6 +42,7 @@ if args.cfg != './sshgen.cfg': ...@@ -37,6 +42,7 @@ if args.cfg != './sshgen.cfg':
if preset not in list(config['presets']): if preset not in list(config['presets']):
sys.exit('preset not in presets configuration') sys.exit('preset not in presets configuration')
def get_zones(): def get_zones():
all_zones = [] all_zones = []
for x, y in config['zones'].items(): for x, y in config['zones'].items():
...@@ -46,13 +52,16 @@ def get_zones(): ...@@ -46,13 +52,16 @@ def get_zones():
elif p.is_file(): elif p.is_file():
all_zones.append(p) all_zones.append(p)
else: else:
print('incorrectly configured zone {}, skipping'.format(x), file=sys.stderr) print('incorrectly configured zone {}, skipping'.format(x),
file=sys.stderr)
return all_zones return all_zones
def get_zone_file(zone): def get_zone_file(zone):
with open(str(zone), 'r') as fp: with open(str(zone), 'r') as fp:
return '\n'.join(fp.readlines()) return '\n'.join(fp.readlines())
def retrieve_hosts(): def retrieve_hosts():
d = get_zones() d = get_zones()
h = {} h = {}
...@@ -63,21 +72,21 @@ def retrieve_hosts(): ...@@ -63,21 +72,21 @@ def retrieve_hosts():
# TODO AAAA records (and others) # TODO AAAA records (and others)
for (name, ttl, rdata) in z.iterate_rdatas('A'): for (name, ttl, rdata) in z.iterate_rdatas('A'):
l = h.get(name) host = h.get(name)
if l is None: if host is None:
l = [] host = []
h[name] = l h[name] = host
m = i.get(rdata.address) addr = i.get(rdata.address)
if m is None: if addr is None:
m = [] addr = []
i[rdata.address] = m i[rdata.address] = addr
m.append(name) addr.append(name)
for (name, ttl, rdata) in z.iterate_rdatas('CNAME'): for (name, ttl, rdata) in z.iterate_rdatas('CNAME'):
l = h.get(rdata.target) target = h.get(rdata.target)
if l is None: if target is None:
l = [] target = []
h[rdata.target] = l h[rdata.target] = target
l.append(name) target.append(name)
fin = False fin = False
while not fin: while not fin:
...@@ -110,26 +119,37 @@ def retrieve_hosts(): ...@@ -110,26 +119,37 @@ def retrieve_hosts():
return h return h
proxies = {} proxies = {}
strip_domains = [] strip_domains = []
preset_config = [k.strip() for k in config['presets'][preset].split(',')] preset_config = [k.strip() for k in config['presets'][preset].split(',')]
for c in preset_config: for c in preset_config:
if c.startswith('proxies_'): if c.startswith('proxies_'):
proxies.update({re.compile(k.strip()): v for v in config[c] for k in config[c][v].split(',')}) proxies.update({re.compile(k.strip()): v
for v in config[c] for k in config[c][v].split(',')})
elif c.startswith('strip_'): elif c.startswith('strip_'):
strip_domains.extend([re.compile('\.{}\.?'.format(k.strip())) for k in config['strips'][c[len('strip_'):]].split(',')]) strip_options = config['strips'][c[len('strip_'):]]
strip_domains.extend([re.compile(r'\.{}\.?'.format(k.strip()))
for k in strip_options.split(',')])
else: else:
pass pass
exclude_hosts = [re.compile(x.strip()) for x in config['excludes']['hosts'].split(',')] exclude_hosts = [re.compile(x.strip())
exclude_aliases = [re.compile(x.strip()) for x in config['excludes']['aliases'].split(',')] for x in config['excludes']['hosts'].split(',')]
usernames = {re.compile(k.strip()): v for v in config['usernames'] for k in config['usernames'][v].split(',')} exclude_aliases = [re.compile(x.strip())
agents = {re.compile(k.strip()): True for k in config['agents']['enabled'].split(',')} for x in config['excludes']['aliases'].split(',')]
agents.update({re.compile(k.strip()): False for k in config['agents']['disabled'].split(',')}) usernames = {re.compile(k.strip()): v
for v in config['usernames']
for k in config['usernames'][v].split(',')}
agents = {re.compile(k.strip()): True
for k in config['agents']['enabled'].split(',')}
agents.update({re.compile(k.strip()): False
for k in config['agents']['disabled'].split(',')})
h = {} h = {}
h = retrieve_hosts() h = retrieve_hosts()
def modify_list(h): def modify_list(h):
for e in exclude_hosts: for e in exclude_hosts:
h = {l: m for l, m in h.items() if not e.match(str(l))} h = {l: m for l, m in h.items() if not e.match(str(l))}
...@@ -149,20 +169,25 @@ def modify_list(h): ...@@ -149,20 +169,25 @@ def modify_list(h):
h[k].extend([x.strip() for x in av.split(',')]) h[k].extend([x.strip() for x in av.split(',')])
return h return h
h = modify_list(h) h = modify_list(h)
def re_suffix(pattern, text): def re_suffix(pattern, text):
res = pattern.search(text) res = pattern.search(text)
if res and res.span()[1] == len(text) and res.span()[0] != 0: if res and res.span()[1] == len(text) and res.span()[0] != 0:
return text[res.span()[0]:res.span()[1]] return text[res.span()[0]:res.span()[1]]
return None return None
for k in h: for k in h:
c = [str(k)] c = [str(k)]
c.extend([str(k)[:-len(re_suffix(d, str(k)))] for d in strip_domains if re_suffix(d, str(k))]) c.extend([str(k)[:-len(re_suffix(d, str(k)))] for d in strip_domains
if re_suffix(d, str(k))])
c.extend(map(str, h[k])) c.extend(map(str, h[k]))
for j in map(str, h[k]): for j in map(str, h[k]):
c.extend([j[:-len(re_suffix(d, j))] for d in strip_domains if re_suffix(d, j)]) c.extend([j[:-len(re_suffix(d, j))] for d in strip_domains
if re_suffix(d, j)])
c = [x[:-1] if x.endswith('.') else x for x in c] c = [x[:-1] if x.endswith('.') else x for x in c]
print('Host ' + ' '.join(c)) print('Host ' + ' '.join(c))
...@@ -181,4 +206,3 @@ for k in h: ...@@ -181,4 +206,3 @@ for k in h:
print('\tProxyJump ' + proxies[p]) print('\tProxyJump ' + proxies[p])
break break
print('') print('')
...@@ -2,36 +2,42 @@ ...@@ -2,36 +2,42 @@
import requests import requests
import bs4 import bs4
import re
import argparse import argparse
import getpass import getpass
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
parser = argparse.ArgumentParser(description='Downloads a zone file from RWTH DNS-Admin-Portal.') parser = argparse.ArgumentParser(
description='Downloads a zone file from RWTH DNS-Admin-Portal.')
group = parser.add_mutually_exclusive_group(required=True) group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--list', action='store_true', default=False, help='list available zones') group.add_argument('--list', action='store_true', default=False,
help='list available zones')
group.add_argument('--zone', type=int, nargs='+', help='download zone by id') group.add_argument('--zone', type=int, nargs='+', help='download zone by id')
group.add_argument('--domain', nargs='+', help='download zone by name') group.add_argument('--domain', nargs='+', help='download zone by name')
parser.add_argument('--passwordstore', action='store', default=None, help='password store entry used for login to the portal') parser.add_argument('--passwordstore', action='store', default=None,
parser.add_argument('dest', action='store', default='-', help='destination to store downloaded zone(s), - for stdout', nargs='?') help='password store entry used for login to the portal')
parser.add_argument('dest', action='store', default='-', nargs='?',
help='destination for downloaded zone(s), - for stdout')
args = parser.parse_args() args = parser.parse_args()
DNS_ADMIN = 'https://noc-portal.rz.rwth-aachen.de/dnsadmin' NOC_PREFIX = 'https://noc-portal.rz.rwth-aachen.de'
ZONE_FILE = 'https://noc-portal.rz.rwth-aachen.de/dnsadmin/zones/{}-{}/pre_deploy_preview' DNS_ADMIN = NOC_PREFIX + '/dnsadmin'
ZONE_FILE = DNS_ADMIN + '/zones/{}-{}/pre_deploy_preview'
SHIB_PREFIX = 'https://sso.rwth-aachen.de' SHIB_PREFIX = 'https://sso.rwth-aachen.de'
SHIB_AUTH = 'https://sso.rwth-aachen.de/idp/profile/SAML2/Redirect/SSO' SHIB_AUTH = SHIB_PREFIX + '/idp/profile/SAML2/Redirect/SSO'
SHIB_REDIRECT = 'https://noc-portal.rz.rwth-aachen.de/Shibboleth.sso/SAML2/POST' SHIB_REDIRECT = NOC_PREFIX + '/Shibboleth.sso/SAML2/POST'
if args.passwordstore: if args.passwordstore:
prc = subprocess.run(['pass', 'show', args.passwordstore], stdout=subprocess.PIPE, check=True) prc = subprocess.run(['pass', 'show', args.passwordstore],
stdout=subprocess.PIPE, check=True)
USERNAME = prc.stdout.splitlines()[1].strip() USERNAME = prc.stdout.splitlines()[1].strip()
PASSWORD = prc.stdout.splitlines()[0].strip() PASSWORD = prc.stdout.splitlines()[0].strip()
else: else:
USERNAME = input('Username: ') USERNAME = input('Username: ')
PASSWORD = getpass.getpass() PASSWORD = getpass.getpass()
def get_zones(session): def get_zones(session):
r = session.get(DNS_ADMIN) r = session.get(DNS_ADMIN)
if r.url.startswith(SHIB_AUTH): if r.url.startswith(SHIB_AUTH):
...@@ -43,26 +49,33 @@ def get_zones(session): ...@@ -43,26 +49,33 @@ def get_zones(session):
d = {} d = {}
for zone in z.find_all('tr'): for zone in z.find_all('tr'):
a = zone.find('td').find('a') a = zone.find('td').find('a')
#d[int(a['href'].split('/')[-1])] = a.text
d[a.text] = int(a['href'].split('/')[-1].split('-', maxsplit=1)[0]) d[a.text] = int(a['href'].split('/')[-1].split('-', maxsplit=1)[0])
return d return d
def get_zone_file(session, zone): def get_zone_file(session, zone):
r = session.get(ZONE_FILE.format(str(zone[0]), str(zone[1].replace('.', '-')))) r = session.get(ZONE_FILE.format(str(zone[0]),
str(zone[1].replace('.', '-'))))
if r.url.startswith(SHIB_AUTH): if r.url.startswith(SHIB_AUTH):
res, session, r = shib_auth(session, r) res, session, r = shib_auth(session, r)
if not res: if not res:
return '' return ''
b = bs4.BeautifulSoup(r.text, 'lxml') b = bs4.BeautifulSoup(r.text, 'lxml')
t = b.find(id='content-wrapper').find('div', class_='zone-content').text t = b.find(id='content-wrapper').find('div', class_='zone-content').text
return t.replace('<br>', '').replace('\n\n', '\n') # \n return t.replace('<br>', '').replace('\n\n', '\n')
def shib_auth(session, resp, iterations=0): def shib_auth(session, resp, iterations=0):
b = bs4.BeautifulSoup(resp.text, 'lxml') b = bs4.BeautifulSoup(resp.text, 'lxml')
form = b.find('form') form = b.find('form')
data = {} data = {}
if form['name'] == 'loginformular': if form['name'] == 'loginformular':
data={'j_username': USERNAME, 'j_password': PASSWORD, 'donotcache': 'true', '_shib_idp_revokeConsent': 'false', '_eventId_proceed': ''} data = {'j_username': USERNAME,
'j_password': PASSWORD,
'donotcache': 'true',
'_shib_idp_revokeConsent': 'false',
'_eventId_proceed': '',
}
elif form['name'] == 'form1': elif form['name'] == 'form1':
data = {'shib_idp_ls_exception.shib_idp_session_ss': '', data = {'shib_idp_ls_exception.shib_idp_session_ss': '',
'shib_idp_ls_success.shib_idp_session_ss': 'false', 'shib_idp_ls_success.shib_idp_session_ss': 'false',
...@@ -79,7 +92,8 @@ def shib_auth(session, resp, iterations=0): ...@@ -79,7 +92,8 @@ def shib_auth(session, resp, iterations=0):
if not f.startswith(SHIB_AUTH[len(SHIB_PREFIX):]): if not f.startswith(SHIB_AUTH[len(SHIB_PREFIX):]):
relaystate = b.find('input', attrs={'name': 'RelayState'})['value'] relaystate = b.find('input', attrs={'name': 'RelayState'})['value']
samlresponse = b.find('input', attrs={'name': 'SAMLResponse'})['value'] samlresponse = b.find('input', attrs={'name': 'SAMLResponse'})['value']
r = session.post(f, data={'RelayState': relaystate, 'SAMLResponse': samlresponse}) r = session.post(f, data={'RelayState': relaystate,
'SAMLResponse': samlresponse})
return True, session, r return True, session, r
else: else:
if iterations == 0: if iterations == 0:
...@@ -87,6 +101,7 @@ def shib_auth(session, resp, iterations=0): ...@@ -87,6 +101,7 @@ def shib_auth(session, resp, iterations=0):
# authentication failed # authentication failed
return False, session, r return False, session, r
s = requests.session() s = requests.session()
d = get_zones(s) d = get_zones(s)
...@@ -111,7 +126,8 @@ if args.domain: ...@@ -111,7 +126,8 @@ if args.domain:
wanted.append((d[k], k)) wanted.append((d[k], k))
for a in args.domain: for a in args.domain:
if a not in d: if a not in d:
print('Domain {} is not available, skipping'.format(a), file=sys.stderr) print('Domain {} is not available, skipping'.format(a),
file=sys.stderr)
else: else:
zones = [] zones = []
for k in d: for k in d:
...@@ -120,7 +136,8 @@ else: ...@@ -120,7 +136,8 @@ else:
zones.append(d[k]) zones.append(d[k])
for a in args.zone: for a in args.zone:
if a not in zones: if a not in zones:
print('Zone {} is not available, skipping'.format(a), file=sys.stderr) print('Zone {} is not available, skipping'.format(a),
file=sys.stderr)
if fp is None: if fp is None:
for w in wanted: for w in wanted:
...@@ -129,4 +146,3 @@ if fp is None: ...@@ -129,4 +146,3 @@ if fp is None:
else: else:
for w in wanted: for w in wanted:
fp.write(get_zone_file(s, w)) fp.write(get_zone_file(s, w))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment