mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 23:23:52 +01:00
autoreloaddelay implementiert
Update der IpAclManager-Klasse
This commit is contained in:
@@ -16,17 +16,28 @@ class IpAclManager():
|
||||
|
||||
"""Verwaltung fuer IP Adressen und deren ACL Level."""
|
||||
|
||||
def __init__(self, acl=None, minlevel=0, maxlevel=0):
|
||||
def __init__(self, minlevel, maxlevel, acl=None):
|
||||
"""Init IpAclManager class.
|
||||
@param acl ACL Liste fuer Berechtigungen als <class 'str'>"""
|
||||
if minlevel > maxlevel:
|
||||
raise ValueError("minlevel is smaller than maxlevel")
|
||||
|
||||
@param minlevel Smallest access level (min. 0)
|
||||
@param maxlevel Biggest access level (max. 9)
|
||||
@param acl ACL Liste fuer Berechtigungen als <class 'str'>
|
||||
|
||||
"""
|
||||
if type(minlevel) != int:
|
||||
raise ValueError("parameter minlevel must be <class 'int'>")
|
||||
if type(maxlevel) != int:
|
||||
raise ValueError("parameter maxlevel must be <class 'int'>")
|
||||
if minlevel < 0:
|
||||
raise ValueError("minlevel must be 0 or more")
|
||||
if maxlevel > 9:
|
||||
raise ValueError("maxlevel maximum is 9")
|
||||
if minlevel > maxlevel:
|
||||
raise ValueError("minlevel is smaller than maxlevel")
|
||||
|
||||
self.__dict_acl = {}
|
||||
self.__dict_ips = {}
|
||||
self.__rawacl = ""
|
||||
self.__dict_regex = {}
|
||||
self.__dict_knownips = {}
|
||||
self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \
|
||||
+ str(minlevel) + "-" + str(maxlevel) + "] ?)*"
|
||||
|
||||
@@ -34,10 +45,18 @@ class IpAclManager():
|
||||
if acl is not None:
|
||||
self.__set_acl(acl)
|
||||
|
||||
def __iter__(self):
|
||||
"""Gibt einzelne ACLs als <class 'tuple'> aus."""
|
||||
for aclip in sorted(self.__dict_acl):
|
||||
yield (aclip, self.__dict_acl[aclip])
|
||||
|
||||
def __get_acl(self):
|
||||
"""Getter fuer den rohen ACL-String.
|
||||
return ACLs als <class 'str'>"""
|
||||
return self.__rawacl
|
||||
str_acl = ""
|
||||
for aclip in sorted(self.__dict_acl):
|
||||
str_acl += "{},{} ".format(aclip, self.__dict_acl[aclip])
|
||||
return str_acl.strip()
|
||||
|
||||
def __get_regex_acl(self):
|
||||
"""Gibt formatierten RegEx-String zurueck.
|
||||
@@ -50,32 +69,34 @@ class IpAclManager():
|
||||
if type(value) != str:
|
||||
raise ValueError("parameter acl must be <class 'str'>")
|
||||
|
||||
value = value.strip()
|
||||
if not refullmatch(self.__re_ipacl, value):
|
||||
raise ValueError("acl format ist not okay - 1.2.3.4,0 5.6.7.8,1")
|
||||
|
||||
# Klassenwerte übernehmen
|
||||
self.__dict_acl = {}
|
||||
self.__dict_ips = {}
|
||||
self.__rawacl = value
|
||||
self.__dict_regex = {}
|
||||
self.__dict_knownips = {}
|
||||
|
||||
# Liste neu füllen mit regex Strings
|
||||
for ip_level in value.split():
|
||||
ip, level = ip_level.split(",", 1)
|
||||
ip = ip.replace(".", "\\.").replace("*", "\\d{1,3}")
|
||||
self.__dict_acl[ip] = int(level)
|
||||
self.__dict_regex[ip] = \
|
||||
ip.replace(".", "\\.").replace("*", "\\d{1,3}")
|
||||
|
||||
def get_acllevel(self, ipaddress):
|
||||
"""Prueft IP gegen ACL List und gibt ACL-Wert aus.
|
||||
@param ipaddress zum pruefen
|
||||
@return <class 'int'> ACL Wert oder -1 wenn nicht gefunden"""
|
||||
# Bei bereits aufgelösten IPs direkt ACL auswerten
|
||||
if ipaddress in self.__dict_ips:
|
||||
return self.__dict_ips[ipaddress]
|
||||
if ipaddress in self.__dict_knownips:
|
||||
return self.__dict_knownips[ipaddress]
|
||||
|
||||
for aclip in sorted(self.__dict_acl, reverse=True):
|
||||
if refullmatch(aclip, ipaddress):
|
||||
if refullmatch(self.__dict_regex[aclip], ipaddress):
|
||||
# IP und Level merken
|
||||
self.__dict_ips[ipaddress] = self.__dict_acl[aclip]
|
||||
self.__dict_knownips[ipaddress] = self.__dict_acl[aclip]
|
||||
|
||||
# Level zurückgeben
|
||||
return self.__dict_acl[aclip]
|
||||
@@ -86,10 +107,10 @@ class IpAclManager():
|
||||
"""Laed ACL String und gibt erfolg zurueck.
|
||||
@param str_acl ACL als <class 'str'>
|
||||
@return True, wenn erfolgreich uebernommen"""
|
||||
if refullmatch(self.__re_ipacl, str_acl):
|
||||
self.__set_acl(str_acl)
|
||||
return True
|
||||
return False
|
||||
if not refullmatch(self.__re_ipacl, str_acl):
|
||||
return False
|
||||
self.__set_acl(str_acl)
|
||||
return True
|
||||
|
||||
acl = property(__get_acl, __set_acl)
|
||||
regex_acl = property(__get_regex_acl)
|
||||
|
||||
@@ -39,6 +39,7 @@ class RevPiPlc(Thread):
|
||||
self._procplc = None
|
||||
self._pversion = pversion
|
||||
self.autoreload = False
|
||||
self.autoreloaddelay = 5 * 2
|
||||
self.exitcode = None
|
||||
self.gid = 65534
|
||||
self.uid = 65534
|
||||
@@ -131,44 +132,54 @@ class RevPiPlc(Thread):
|
||||
_setuprt(self._procplc.pid, self._evt_exit)
|
||||
|
||||
# Überwachung starten
|
||||
delaycounter = self.autoreloaddelay
|
||||
while not self._evt_exit.is_set():
|
||||
|
||||
# Auswerten
|
||||
self.exitcode = self._procplc.poll()
|
||||
|
||||
if self.exitcode is not None:
|
||||
if self.exitcode > 0:
|
||||
# PLC Python Programm abgestürzt
|
||||
proginit.logger.error(
|
||||
"plc program crashed - exitcode: {}".format(
|
||||
self.exitcode
|
||||
if delaycounter == self.autoreloaddelay:
|
||||
if self.exitcode > 0:
|
||||
# PLC Python Programm abgestürzt
|
||||
proginit.logger.error(
|
||||
"plc program crashed - exitcode: {}".format(
|
||||
self.exitcode
|
||||
)
|
||||
)
|
||||
)
|
||||
if self.zeroonerror:
|
||||
_zeroprocimg()
|
||||
proginit.logger.warning(
|
||||
"set piControl0 to ZERO after PLC program error")
|
||||
if self.zeroonerror:
|
||||
_zeroprocimg()
|
||||
proginit.logger.warning(
|
||||
"set piControl0 to ZERO after "
|
||||
"PLC program error"
|
||||
)
|
||||
|
||||
else:
|
||||
# PLC Python Programm sauber beendet
|
||||
proginit.logger.info("plc program did a clean exit")
|
||||
if self.zeroonexit:
|
||||
_zeroprocimg()
|
||||
proginit.logger.info(
|
||||
"set piControl0 to ZERO after PLC program returns "
|
||||
"clean exitcode")
|
||||
else:
|
||||
# PLC Python Programm sauber beendet
|
||||
proginit.logger.info("plc program did a clean exit")
|
||||
if self.zeroonexit:
|
||||
_zeroprocimg()
|
||||
proginit.logger.info(
|
||||
"set piControl0 to ZERO after "
|
||||
"PLC program returns clean exitcode"
|
||||
)
|
||||
|
||||
if not self._evt_exit.is_set() and self.autoreload:
|
||||
# Prozess neu starten
|
||||
self._procplc = self._spopen(lst_proc)
|
||||
if self.exitcode == 0:
|
||||
proginit.logger.warning(
|
||||
"restart plc program after clean exit"
|
||||
)
|
||||
if delaycounter > 0:
|
||||
delaycounter -= 1
|
||||
else:
|
||||
proginit.logger.warning(
|
||||
"restart plc program after crash"
|
||||
)
|
||||
delaycounter = self.autoreloaddelay
|
||||
|
||||
# Prozess neu starten
|
||||
self._procplc = self._spopen(lst_proc)
|
||||
if self.exitcode == 0:
|
||||
proginit.logger.warning(
|
||||
"restart plc program after clean exit"
|
||||
)
|
||||
else:
|
||||
proginit.logger.warning(
|
||||
"restart plc program after crash"
|
||||
)
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ from time import asctime
|
||||
from xmlrpc.client import Binary
|
||||
from xrpcserver import SaveXMLRPCServer
|
||||
|
||||
pyloadversion = "0.6.0"
|
||||
pyloadversion = "0.6.1"
|
||||
|
||||
|
||||
class RevPiPyLoad():
|
||||
@@ -305,6 +305,7 @@ class RevPiPyLoad():
|
||||
self.pythonversion
|
||||
)
|
||||
th_plc.autoreload = bool(self.autoreload)
|
||||
th_plc.autoreloaddelay = self.autoreloaddelay
|
||||
th_plc.gid = int(self.plcgid)
|
||||
th_plc.uid = int(self.plcuid)
|
||||
th_plc.rtlevel = int(self.rtlevel)
|
||||
|
||||
@@ -18,7 +18,7 @@ class SaveXMLRPCServer(SimpleXMLRPCServer):
|
||||
|
||||
def __init__(
|
||||
self, addr, logRequests=True, allow_none=False,
|
||||
use_builtin_types=False, ipacl=IpAclManager()):
|
||||
use_builtin_types=False, ipacl=None):
|
||||
"""Init SaveXMLRPCServer class."""
|
||||
proginit.logger.debug("enter SaveXMLRPCServer.__init__()")
|
||||
|
||||
@@ -34,7 +34,10 @@ class SaveXMLRPCServer(SimpleXMLRPCServer):
|
||||
)
|
||||
|
||||
# Klassenvariablen
|
||||
self.aclmgr = ipacl
|
||||
if ipacl is None:
|
||||
self.aclmgr = IpAclManager(0, 0)
|
||||
else:
|
||||
self.aclmgr = ipacl
|
||||
self.funcacls = {}
|
||||
self.requestacl = -1
|
||||
self.tpe = futures.ThreadPoolExecutor(max_workers=1)
|
||||
|
||||
Reference in New Issue
Block a user