scripts sales

This commit is contained in:
Adrian Amaglio 2022-02-19 17:36:17 +01:00
parent 11eda4fd7c
commit 9662f23d08
2 changed files with 244 additions and 0 deletions

View File

@ -0,0 +1,199 @@
#!/usr/bin/python
import bs4
from lxml import etree
import sys
import random
def extractstring (tree, xpathstr):
"""Dirty helper"""
name = tree.xpath(xpathstr)
return name[0].text if len(name) > 0 else ''
types = {
'Ordinateur': 'Ordinateur',
'Portable': 'Ordinateur',
'Rechner': 'Ordinateur',
'Notebook': 'Ordinateur',
'Routeur': 'Routeur',
'Vermittlungsrechner': 'Routeur',
'Switch': 'Switch',
}
class Knot:
def __init__ (self, ident, typ, name, ips, gw, dns, rip=None, dnsrecords={}):
"""Dirty knot. netmask is fixed to /24"""
self.id = ident
self.typ = types[typ]
self.name = name
self.ips = ips
self.gw = gw
self.dns = dns
self.rip = rip
self.dnsrecords = dnsrecords
def __str__ (self):
return f"{self.typ}:{self.name}:{self.ips}"
def has_gw (self):
return self.gw != ''
class Network:
def __init__ (self, filename):
self.filename = filename
self.knots = {}
self.wires = []
with open(filename, 'r') as f:
soup = bs4.BeautifulSoup(f , 'lxml')
for element in soup.findAll(class_="filius.gui.netzwerksicht.GUIKnotenItem"):
tree = etree.XML(str(element))
ident = element.attrs['id'] if 'id' in element.attrs else random.randint(0,10000)
self.knots[ident] = Knot(
ident,
extractstring(tree, '//*[@property="typ"]/string'),
extractstring(tree, '//*[@property="name"]/string'),
[ip.text for ip in tree.xpath('//*[@property="ip"]/string')],
extractstring(tree, '//*[@property="gateway"]/string'),
extractstring(tree, '//*[@property="dns"]/string'),
extractstring(tree, '//*[@property="ripEnabled"]/boolean') == 'true',
{ s.split(' ')[0].upper():s.split(' ')[-1] for s in (extractstring(tree, '//*[@property="dateiInhalt"]/string') or '').split('\n') if s != ''},
)
for element in soup.findAll(property="kabelpanel"):
tree = etree.XML(str(element))
self.wires.append((
tree.xpath('//*[@property="ziel1"]/object')[0].attrib['idref'],
tree.xpath('//*[@property="ziel2"]/object')[0].attrib['idref'],
))
def same_network (self, ip1, ip2):
return ip1.split('.')[0:2] == ip2.split('.')[0:2]
def ips_of (self, ident):
return self.knots[ident].ips if ident in self.knots else []
def gw_of (self, ident):
return self.knots[ident].gw if ident in self.knots else None
def dns_of (self, ident):
return self.knots[ident].dns if ident in self.knots else None
def ident_of (self, name):
for k in self.knots:
if self.knots[k].name.upper() == name.upper():
return k
return None
def gateway_of (self, ident):
"""Returns gws id of ident"""
for k in self.knots:
if self.knots[ident].gw in self.knots[k].ips:
return k
def ip_duplicates (self):
ips = []
for k in self.knots:
for ip in self.knots[k].ips:
if ip in ips:
return True
else:
ips.append(ip)
return False
def connected_to (self, ident):
"""Returns a list of knot connected to ident"""
return [ w[(i+1)%2] for w in self.wires for i in range(2) if w[i] == ident]
def local_path_exists (self, ident, ip):
"""Test if a local network path exists between ident and ip. Assuming there is no loops on a local network :D"""
visited = []
tovisit = [ident]
while len(tovisit) > 0:
knot = tovisit.pop()
visited.append(knot)
for k in self.connected_to(knot):
if ip in self.knots[k].ips:
return True
elif k not in visited:
tovisit.append(k)
return False
def get_routers (self):
return [ k for k in self.knots if self.knots[k].typ == 'Routeur' ]
def ping (self, knot, dest):
k = self.knots[knot]
# Is the destination on our local network?
for ip in k.ips:
if self.same_network(ip, dest):
return self.local_path_exists(knot, dest)
# Have we got a reachable gw?
if k.has_gw() and self.local_path_exists(knot, k.gw):
return self.local_path_exists(self.gateway_of(knot), dest)
return False
def correction (filename):
"""Returns dict criterion:mark, mark, total"""
res = {}
n = Network(filename)
for num, lettre in enumerate(['D', 'E', 'F']):
num +=1
ident = n.ident_of(lettre)
ips = n.knots[ident].ips if ident is not None else []
res[f'- Lordinateur {lettre} peut pinger ladresse IP 10.1.200.{num}'] = int(n.ping(ident, f'10.1.200.{num}')) if ident is not None else 0
res[f'- Lordinateur {lettre} a une IP valide'] = int(len(ips) == 1 and ips[0].startswith('10.2.200.'))
res['- Il ny a pas dadresses IP en double'] = int(not n.ip_duplicates())
ident = n.ident_of('serveur')
ips = n.knots[ident].ips if ident is not None else []
res[f'- Le serveur a une adresse IP valide'] = int(len(ips) == 1 and not ips[0].startswith('10.1.200.') and not ips[0].startswith('10.2.200.'))
routers = n.get_routers()
ips_routers = n.knots[routers[0]].ips if len(routers) == 1 else []
if ips_routers == []:
print(routers, file=sys.stderr)
for k in n.knots:
print(n.knots[k], file=sys.stderr)
res[f'- Le routeur a ladresse IP 10.1.200.254'] = int('10.1.200.254' in ips_routers)
res[f'- Le routeur a ladresse IP 10.2.200.254'] = int('10.2.200.254' in ips_routers)
ip_router = ''
for ip in ips_routers:
if not ip.startswith('10.2.200.') and not ip.startswith('10.1.200.'):
ip_router = ip
break
res['- Le routeur a une adresse IP vers le serveur'] = int(ip_router != '')
res['- Le routage est activé'] = int(n.knots[routers[0]].rip) if len(routers) == 1 else 0
res['- Le routeur et le serveur ont des adresses IP avec la même partie réseau'] = int(ip_router.startswith('.'.join(ips[0].split('.')[0:2]))) if len(ips) == 1 else 0
for num, lettre in enumerate(['A', 'B', 'C']):
num +=1
ident = n.ident_of(lettre)
res[f'- Lordinateur {lettre} a ladresse IP 10.1.200.{num}'] = int(f'10.1.200.{num}' in n.ips_of(ident))
res[f'- Lordinateur {lettre} a la passerelle 10.1.200.254'] = int('10.1.200.254' == n.gw_of(ident))
res[f'- Lordinateur {lettre} a le serveur DNS configuré'] = int(ips[0] == n.dns_of(ident)) if len(ips) == 1 else 0
found = False
for k in n.knots:
if n.knots[k].dnsrecords != '' and 'A.' in n.knots[k].dnsrecords and n.knots[k].dnsrecords['A.'] == '10.1.200.1':
found = True
break
res[f'- Le nom DNS A se traduit par ladresse IP 10.1.200.1'] = int(found)
return res, sum(res.values()), len(res) # Assuming all questions are worth 1 points
if __name__ == '__main__':
if len(sys.argv) != 2:
print(f'Usage:\n {sys.argv[0]} <konfiguration.xml>')
exit(1)
res, note, total = correction(sys.argv[1])
for line in res:
print(line, '', res[line])
print()
print(f'Total : {note}/{total}')
# TODO critères suivants
# quelques traductions DNS

View File

@ -0,0 +1,45 @@
tmp="$(mktemp)"
. venv/bin/activate
function evaluate () {
t="$(mktemp)"
echo "# TP réseau sur filius"
echo "# Correction $1"
unzip -p "$1" projekt/konfiguration.xml > "$t"
python3 correction.py $t
rm $t
}
# If first arg is a file, then show its details
# Else processe all dir
if [ -f "$1" ] && [ "$1" != "details" ] ; then
file="$1"
evaluate "$file" detail
elif [ -d "$1" ] && [ "$1" != "details" ] ; then
d="$1"
for f in "$d"/* ; do
#evaluate "$f" detail
evaluate "$f" "$1"
done
else
for d in * ; do
if [ ! -d "$d" ] ; then continue ; fi
if [[ "$d" = res_* ]] || [ "$d" = venv ] ; then continue ; fi
echo === $d
resd="res_$d"
mkdir -p "$resd"
rm "$resd"/*
for f in "$d"/*.fls ; do
echo "$f"
evaluate "$f" details > "tmp"
pandoc -f markdown "tmp" -o "$resd/$(basename "${f%.fls}").pdf"
done
done
fi
rm "$tmp"