daemon: added type hinting throughout all services and made small tweaks/fixes that were ran across
This commit is contained in:
parent
250bc6e1f5
commit
cd74a44558
11 changed files with 560 additions and 636 deletions
|
@ -1,12 +1,13 @@
|
|||
"""
|
||||
utility.py: defines miscellaneous utility services.
|
||||
"""
|
||||
import os
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import netaddr
|
||||
|
||||
from core import constants, utils
|
||||
from core.errors import CoreCommandError
|
||||
from core.nodes.base import CoreNode
|
||||
from core.services.coreservices import CoreService, ServiceMode
|
||||
|
||||
|
||||
|
@ -15,32 +16,25 @@ class UtilService(CoreService):
|
|||
Parent class for utility services.
|
||||
"""
|
||||
|
||||
name = None
|
||||
group = "Utility"
|
||||
dirs = ()
|
||||
configs = ()
|
||||
startup = ()
|
||||
shutdown = ()
|
||||
name: Optional[str] = None
|
||||
group: str = "Utility"
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
class IPForwardService(UtilService):
|
||||
name = "IPForward"
|
||||
configs = ("ipforward.sh",)
|
||||
startup = ("sh ipforward.sh",)
|
||||
name: str = "IPForward"
|
||||
configs: Tuple[str, ...] = ("ipforward.sh",)
|
||||
startup: Tuple[str, ...] = ("sh ipforward.sh",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
if os.uname()[0] == "Linux":
|
||||
return cls.generateconfiglinux(node, filename)
|
||||
else:
|
||||
raise Exception("unknown platform")
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
return cls.generateconfiglinux(node, filename)
|
||||
|
||||
@classmethod
|
||||
def generateconfiglinux(cls, node, filename):
|
||||
def generateconfiglinux(cls, node: CoreNode, filename: str) -> str:
|
||||
cfg = """\
|
||||
#!/bin/sh
|
||||
# auto-generated by IPForward service (utility.py)
|
||||
|
@ -70,12 +64,12 @@ class IPForwardService(UtilService):
|
|||
|
||||
|
||||
class DefaultRouteService(UtilService):
|
||||
name = "DefaultRoute"
|
||||
configs = ("defaultroute.sh",)
|
||||
startup = ("sh defaultroute.sh",)
|
||||
name: str = "DefaultRoute"
|
||||
configs: Tuple[str, ...] = ("defaultroute.sh",)
|
||||
startup: Tuple[str, ...] = ("sh defaultroute.sh",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
routes = []
|
||||
ifaces = node.get_ifaces()
|
||||
if ifaces:
|
||||
|
@ -93,22 +87,18 @@ class DefaultRouteService(UtilService):
|
|||
|
||||
|
||||
class DefaultMulticastRouteService(UtilService):
|
||||
name = "DefaultMulticastRoute"
|
||||
configs = ("defaultmroute.sh",)
|
||||
startup = ("sh defaultmroute.sh",)
|
||||
name: str = "DefaultMulticastRoute"
|
||||
configs: Tuple[str, ...] = ("defaultmroute.sh",)
|
||||
startup: Tuple[str, ...] = ("sh defaultmroute.sh",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
cfg = "#!/bin/sh\n"
|
||||
cfg += "# auto-generated by DefaultMulticastRoute service (utility.py)\n"
|
||||
cfg += "# the first interface is chosen below; please change it "
|
||||
cfg += "as needed\n"
|
||||
|
||||
for iface in node.get_ifaces(control=False):
|
||||
if os.uname()[0] == "Linux":
|
||||
rtcmd = "ip route add 224.0.0.0/4 dev"
|
||||
else:
|
||||
raise Exception("unknown platform")
|
||||
rtcmd = "ip route add 224.0.0.0/4 dev"
|
||||
cfg += "%s %s\n" % (rtcmd, iface.name)
|
||||
cfg += "\n"
|
||||
break
|
||||
|
@ -116,13 +106,13 @@ class DefaultMulticastRouteService(UtilService):
|
|||
|
||||
|
||||
class StaticRouteService(UtilService):
|
||||
name = "StaticRoute"
|
||||
configs = ("staticroute.sh",)
|
||||
startup = ("sh staticroute.sh",)
|
||||
custom_needed = True
|
||||
name: str = "StaticRoute"
|
||||
configs: Tuple[str, ...] = ("staticroute.sh",)
|
||||
startup: Tuple[str, ...] = ("sh staticroute.sh",)
|
||||
custom_needed: bool = True
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
cfg = "#!/bin/sh\n"
|
||||
cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n"
|
||||
cfg += "# NOTE: this service must be customized to be of any use\n"
|
||||
|
@ -133,7 +123,7 @@ class StaticRouteService(UtilService):
|
|||
return cfg
|
||||
|
||||
@staticmethod
|
||||
def routestr(x):
|
||||
def routestr(x: str) -> str:
|
||||
addr = x.split("/")[0]
|
||||
if netaddr.valid_ipv6(addr):
|
||||
dst = "3ffe:4::/64"
|
||||
|
@ -143,24 +133,20 @@ class StaticRouteService(UtilService):
|
|||
if net[-2] == net[1]:
|
||||
return ""
|
||||
else:
|
||||
if os.uname()[0] == "Linux":
|
||||
rtcmd = "#/sbin/ip route add %s via" % dst
|
||||
else:
|
||||
raise Exception("unknown platform")
|
||||
rtcmd = "#/sbin/ip route add %s via" % dst
|
||||
return "%s %s" % (rtcmd, net[1])
|
||||
|
||||
|
||||
class SshService(UtilService):
|
||||
name = "SSH"
|
||||
configs = ("startsshd.sh", "/etc/ssh/sshd_config")
|
||||
dirs = ("/etc/ssh", "/var/run/sshd")
|
||||
startup = ("sh startsshd.sh",)
|
||||
shutdown = ("killall sshd",)
|
||||
validate = ()
|
||||
validation_mode = ServiceMode.BLOCKING
|
||||
name: str = "SSH"
|
||||
configs: Tuple[str, ...] = ("startsshd.sh", "/etc/ssh/sshd_config")
|
||||
dirs: Tuple[str, ...] = ("/etc/ssh", "/var/run/sshd")
|
||||
startup: Tuple[str, ...] = ("sh startsshd.sh",)
|
||||
shutdown: Tuple[str, ...] = ("killall sshd",)
|
||||
validation_mode: ServiceMode = ServiceMode.BLOCKING
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Use a startup script for launching sshd in order to wait for host
|
||||
key generation.
|
||||
|
@ -228,15 +214,15 @@ UseDNS no
|
|||
|
||||
|
||||
class DhcpService(UtilService):
|
||||
name = "DHCP"
|
||||
configs = ("/etc/dhcp/dhcpd.conf",)
|
||||
dirs = ("/etc/dhcp", "/var/lib/dhcp")
|
||||
startup = ("touch /var/lib/dhcp/dhcpd.leases", "dhcpd")
|
||||
shutdown = ("killall dhcpd",)
|
||||
validate = ("pidof dhcpd",)
|
||||
name: str = "DHCP"
|
||||
configs: Tuple[str, ...] = ("/etc/dhcp/dhcpd.conf",)
|
||||
dirs: Tuple[str, ...] = ("/etc/dhcp", "/var/lib/dhcp")
|
||||
startup: Tuple[str, ...] = ("touch /var/lib/dhcp/dhcpd.leases", "dhcpd")
|
||||
shutdown: Tuple[str, ...] = ("killall dhcpd",)
|
||||
validate: Tuple[str, ...] = ("pidof dhcpd",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate a dhcpd config file using the network address of
|
||||
each interface.
|
||||
|
@ -261,7 +247,7 @@ ddns-update-style none;
|
|||
return cfg
|
||||
|
||||
@staticmethod
|
||||
def subnetentry(x):
|
||||
def subnetentry(x: str) -> str:
|
||||
"""
|
||||
Generate a subnet declaration block given an IPv4 prefix string
|
||||
for inclusion in the dhcpd3 config file.
|
||||
|
@ -297,14 +283,14 @@ class DhcpClientService(UtilService):
|
|||
Use a DHCP client for all interfaces for addressing.
|
||||
"""
|
||||
|
||||
name = "DHCPClient"
|
||||
configs = ("startdhcpclient.sh",)
|
||||
startup = ("sh startdhcpclient.sh",)
|
||||
shutdown = ("killall dhclient",)
|
||||
validate = ("pidof dhclient",)
|
||||
name: str = "DHCPClient"
|
||||
configs: Tuple[str, ...] = ("startdhcpclient.sh",)
|
||||
startup: Tuple[str, ...] = ("sh startdhcpclient.sh",)
|
||||
shutdown: Tuple[str, ...] = ("killall dhclient",)
|
||||
validate: Tuple[str, ...] = ("pidof dhclient",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate a script to invoke dhclient on all interfaces.
|
||||
"""
|
||||
|
@ -313,7 +299,6 @@ class DhcpClientService(UtilService):
|
|||
cfg += "# uncomment this mkdir line and symlink line to enable client-"
|
||||
cfg += "side DNS\n# resolution based on the DHCP server response.\n"
|
||||
cfg += "#mkdir -p /var/run/resolvconf/interface\n"
|
||||
|
||||
for iface in node.get_ifaces(control=False):
|
||||
cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % iface.name
|
||||
cfg += " /var/run/resolvconf/resolv.conf\n"
|
||||
|
@ -327,15 +312,15 @@ class FtpService(UtilService):
|
|||
Start a vsftpd server.
|
||||
"""
|
||||
|
||||
name = "FTP"
|
||||
configs = ("vsftpd.conf",)
|
||||
dirs = ("/var/run/vsftpd/empty", "/var/ftp")
|
||||
startup = ("vsftpd ./vsftpd.conf",)
|
||||
shutdown = ("killall vsftpd",)
|
||||
validate = ("pidof vsftpd",)
|
||||
name: str = "FTP"
|
||||
configs: Tuple[str, ...] = ("vsftpd.conf",)
|
||||
dirs: Tuple[str, ...] = ("/var/run/vsftpd/empty", "/var/ftp")
|
||||
startup: Tuple[str, ...] = ("vsftpd ./vsftpd.conf",)
|
||||
shutdown: Tuple[str, ...] = ("killall vsftpd",)
|
||||
validate: Tuple[str, ...] = ("pidof vsftpd",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate a vsftpd.conf configuration file.
|
||||
"""
|
||||
|
@ -360,13 +345,13 @@ class HttpService(UtilService):
|
|||
Start an apache server.
|
||||
"""
|
||||
|
||||
name = "HTTP"
|
||||
configs = (
|
||||
name: str = "HTTP"
|
||||
configs: Tuple[str, ...] = (
|
||||
"/etc/apache2/apache2.conf",
|
||||
"/etc/apache2/envvars",
|
||||
"/var/www/index.html",
|
||||
)
|
||||
dirs = (
|
||||
dirs: Tuple[str, ...] = (
|
||||
"/etc/apache2",
|
||||
"/var/run/apache2",
|
||||
"/var/log/apache2",
|
||||
|
@ -374,14 +359,14 @@ class HttpService(UtilService):
|
|||
"/var/lock/apache2",
|
||||
"/var/www",
|
||||
)
|
||||
startup = ("chown www-data /var/lock/apache2", "apache2ctl start")
|
||||
shutdown = ("apache2ctl stop",)
|
||||
validate = ("pidof apache2",)
|
||||
|
||||
APACHEVER22, APACHEVER24 = (22, 24)
|
||||
startup: Tuple[str, ...] = ("chown www-data /var/lock/apache2", "apache2ctl start")
|
||||
shutdown: Tuple[str, ...] = ("apache2ctl stop",)
|
||||
validate: Tuple[str, ...] = ("pidof apache2",)
|
||||
APACHEVER22: int = 22
|
||||
APACHEVER24: int = 24
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate an apache2.conf configuration file.
|
||||
"""
|
||||
|
@ -395,7 +380,7 @@ class HttpService(UtilService):
|
|||
return ""
|
||||
|
||||
@classmethod
|
||||
def detectversionfromcmd(cls):
|
||||
def detectversionfromcmd(cls) -> int:
|
||||
"""
|
||||
Detect the apache2 version using the 'a2query' command.
|
||||
"""
|
||||
|
@ -405,14 +390,12 @@ class HttpService(UtilService):
|
|||
except CoreCommandError as e:
|
||||
status = e.returncode
|
||||
result = e.stderr
|
||||
|
||||
if status == 0 and result[:3] == "2.4":
|
||||
return cls.APACHEVER24
|
||||
|
||||
return cls.APACHEVER22
|
||||
|
||||
@classmethod
|
||||
def generateapache2conf(cls, node, filename):
|
||||
def generateapache2conf(cls, node: CoreNode, filename: str) -> str:
|
||||
lockstr = {
|
||||
cls.APACHEVER22: "LockFile ${APACHE_LOCK_DIR}/accept.lock\n",
|
||||
cls.APACHEVER24: "Mutex file:${APACHE_LOCK_DIR} default\n",
|
||||
|
@ -421,22 +404,18 @@ class HttpService(UtilService):
|
|||
cls.APACHEVER22: "",
|
||||
cls.APACHEVER24: "LoadModule mpm_worker_module /usr/lib/apache2/modules/mod_mpm_worker.so\n",
|
||||
}
|
||||
|
||||
permstr = {
|
||||
cls.APACHEVER22: " Order allow,deny\n Deny from all\n Satisfy all\n",
|
||||
cls.APACHEVER24: " Require all denied\n",
|
||||
}
|
||||
|
||||
authstr = {
|
||||
cls.APACHEVER22: "LoadModule authz_default_module /usr/lib/apache2/modules/mod_authz_default.so\n",
|
||||
cls.APACHEVER24: "LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so\n",
|
||||
}
|
||||
|
||||
permstr2 = {
|
||||
cls.APACHEVER22: "\t\tOrder allow,deny\n\t\tallow from all\n",
|
||||
cls.APACHEVER24: "\t\tRequire all granted\n",
|
||||
}
|
||||
|
||||
version = cls.detectversionfromcmd()
|
||||
cfg = "# apache2.conf generated by utility.py:HttpService\n"
|
||||
cfg += lockstr[version]
|
||||
|
@ -552,7 +531,7 @@ TraceEnable Off
|
|||
return cfg
|
||||
|
||||
@classmethod
|
||||
def generateenvvars(cls, node, filename):
|
||||
def generateenvvars(cls, node: CoreNode, filename: str) -> str:
|
||||
return """\
|
||||
# this file is used by apache2ctl - generated by utility.py:HttpService
|
||||
# these settings come from a default Ubuntu apache2 installation
|
||||
|
@ -567,7 +546,7 @@ export LANG
|
|||
"""
|
||||
|
||||
@classmethod
|
||||
def generatehtml(cls, node, filename):
|
||||
def generatehtml(cls, node: CoreNode, filename: str) -> str:
|
||||
body = (
|
||||
"""\
|
||||
<!-- generated by utility.py:HttpService -->
|
||||
|
@ -587,16 +566,15 @@ class PcapService(UtilService):
|
|||
Pcap service for logging packets.
|
||||
"""
|
||||
|
||||
name = "pcap"
|
||||
configs = ("pcap.sh",)
|
||||
dirs = ()
|
||||
startup = ("sh pcap.sh start",)
|
||||
shutdown = ("sh pcap.sh stop",)
|
||||
validate = ("pidof tcpdump",)
|
||||
meta = "logs network traffic to pcap packet capture files"
|
||||
name: str = "pcap"
|
||||
configs: Tuple[str, ...] = ("pcap.sh",)
|
||||
startup: Tuple[str, ...] = ("sh pcap.sh start",)
|
||||
shutdown: Tuple[str, ...] = ("sh pcap.sh stop",)
|
||||
validate: Tuple[str, ...] = ("pidof tcpdump",)
|
||||
meta: str = "logs network traffic to pcap packet capture files"
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate a startpcap.sh traffic logging script.
|
||||
"""
|
||||
|
@ -630,15 +608,17 @@ fi;
|
|||
|
||||
|
||||
class RadvdService(UtilService):
|
||||
name = "radvd"
|
||||
configs = ("/etc/radvd/radvd.conf",)
|
||||
dirs = ("/etc/radvd",)
|
||||
startup = ("radvd -C /etc/radvd/radvd.conf -m logfile -l /var/log/radvd.log",)
|
||||
shutdown = ("pkill radvd",)
|
||||
validate = ("pidof radvd",)
|
||||
name: str = "radvd"
|
||||
configs: Tuple[str, ...] = ("/etc/radvd/radvd.conf",)
|
||||
dirs: Tuple[str, ...] = ("/etc/radvd",)
|
||||
startup: Tuple[str, ...] = (
|
||||
"radvd -C /etc/radvd/radvd.conf -m logfile -l /var/log/radvd.log",
|
||||
)
|
||||
shutdown: Tuple[str, ...] = ("pkill radvd",)
|
||||
validate: Tuple[str, ...] = ("pidof radvd",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
"""
|
||||
Generate a RADVD router advertisement daemon config file
|
||||
using the network address of each interface.
|
||||
|
@ -678,7 +658,7 @@ interface %s
|
|||
return cfg
|
||||
|
||||
@staticmethod
|
||||
def subnetentry(x):
|
||||
def subnetentry(x: str) -> str:
|
||||
"""
|
||||
Generate a subnet declaration block given an IPv6 prefix string
|
||||
for inclusion in the RADVD config file.
|
||||
|
@ -695,14 +675,14 @@ class AtdService(UtilService):
|
|||
Atd service for scheduling at jobs
|
||||
"""
|
||||
|
||||
name = "atd"
|
||||
configs = ("startatd.sh",)
|
||||
dirs = ("/var/spool/cron/atjobs", "/var/spool/cron/atspool")
|
||||
startup = ("sh startatd.sh",)
|
||||
shutdown = ("pkill atd",)
|
||||
name: str = "atd"
|
||||
configs: Tuple[str, ...] = ("startatd.sh",)
|
||||
dirs: Tuple[str, ...] = ("/var/spool/cron/atjobs", "/var/spool/cron/atspool")
|
||||
startup: Tuple[str, ...] = ("sh startatd.sh",)
|
||||
shutdown: Tuple[str, ...] = ("pkill atd",)
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
def generate_config(cls, node: CoreNode, filename: str) -> str:
|
||||
return """
|
||||
#!/bin/sh
|
||||
echo 00001 > /var/spool/cron/atjobs/.SEQ
|
||||
|
@ -717,5 +697,5 @@ class UserDefinedService(UtilService):
|
|||
Dummy service allowing customization of anything.
|
||||
"""
|
||||
|
||||
name = "UserDefined"
|
||||
meta = "Customize this service to do anything upon startup."
|
||||
name: str = "UserDefined"
|
||||
meta: str = "Customize this service to do anything upon startup."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue