forked from shaba/openuds
Added config for WOL on UDS
This commit is contained in:
parent
b9ba304493
commit
8c68da806a
@ -30,13 +30,60 @@
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import configparser
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
|
||||
from uds.core import services
|
||||
from uds.core.ui.user_interface import gui
|
||||
from uds.core.util import net
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from uds.core.module import Module
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
VALID_CONFIG_SECTIONS = set(('wol',))
|
||||
|
||||
class PhysicalMachinesProvider(services.ServiceProvider):
|
||||
# No extra data needed
|
||||
config = gui.TextField(
|
||||
length=8192, multiline=6, label=_('Advanced configuration'), order=3,
|
||||
tooltip=_('Advanced configuration data for the provider'),
|
||||
required=True, tab=gui.ADVANCED_TAB
|
||||
)
|
||||
|
||||
def initialize(self, values: 'Module.ValuesType') -> None:
|
||||
if values is None:
|
||||
return
|
||||
|
||||
self.config.value = self.config.value.strip()
|
||||
|
||||
if self.config.value:
|
||||
config = configparser.ConfigParser()
|
||||
try:
|
||||
config.read_string(self.config.value)
|
||||
# Seems a valid configuration file, let's see if all se
|
||||
except Exception as e:
|
||||
raise services.ServiceProvider.ValidationException(_('Invalid advanced configuration: ') + str(e))
|
||||
|
||||
for section in config.sections():
|
||||
if section not in VALID_CONFIG_SECTIONS:
|
||||
raise services.ServiceProvider.ValidationException(_('Invalid section in advanced configuration: ') + section)
|
||||
|
||||
# Sections are valid, check values
|
||||
# wol section
|
||||
for key in config['wol']:
|
||||
try:
|
||||
net.networksFromString(key) # Raises exception if net is invalid
|
||||
except Exception:
|
||||
raise services.ServiceProvider.ValidationException(_('Invalid network in advanced configuration: ') + key)
|
||||
# Now check value is an url
|
||||
if config['wol'][key][:4] != 'http':
|
||||
raise services.ServiceProvider.ValidationException(_('Invalid url in advanced configuration: ') + key)
|
||||
|
||||
|
||||
# What services do we offer?
|
||||
typeName = _('Static IP Machines Provider')
|
||||
@ -48,5 +95,20 @@ class PhysicalMachinesProvider(services.ServiceProvider):
|
||||
from .service_single import IPSingleMachineService
|
||||
offers = [IPMachinesService, IPSingleMachineService]
|
||||
|
||||
def wolURL(self, ip: str):
|
||||
if not self.config.value:
|
||||
return ''
|
||||
|
||||
url = ''
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read_string(self.config.value)
|
||||
for key in config['wol']:
|
||||
if net.ipInNetwork(ip, key):
|
||||
return config['wol'][key]
|
||||
except Exception as e:
|
||||
logger.error('Error parsing advanced configuration: %s', e)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "Physical Machines Provider"
|
||||
|
@ -30,7 +30,7 @@
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import subprocess
|
||||
import requests
|
||||
import logging
|
||||
import typing
|
||||
|
||||
@ -38,19 +38,8 @@ from uds.core import services
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# We have included a "hidden testing" for adding ip+mac as static machines list.
|
||||
# (This is done using IP;MAC as IP on the IP list)
|
||||
# This is a test for WOL, and to be used at your risk.
|
||||
# Example:
|
||||
# WOLAPP = "/usr/sbin/etherwake {MAC} -i eth0 -b"
|
||||
# Remember that you MUST setuid /usr/sbin/etherwake (chmod +s ....) and allow only for uds user,
|
||||
# so it allows uds user to execute "privileged" etherwake program
|
||||
# Note:
|
||||
# {MAC} will be replaced with the MAC if it exists
|
||||
# {IP} will be replaced with the IP of the machine
|
||||
# If empty, no WOL will be tried NEVER, if not empty
|
||||
WOLAPP = ''
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from . import provider
|
||||
|
||||
class IPServiceBase(services.Service):
|
||||
|
||||
@ -65,6 +54,9 @@ class IPServiceBase(services.Service):
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def parent(self) -> 'provider.PhysicalMachinesProvider':
|
||||
return typing.cast('provider.PhysicalMachinesProvider', super().parent())
|
||||
|
||||
def getUnassignedMachine(self) -> typing.Optional[str]:
|
||||
raise NotADirectoryError('getUnassignedMachine')
|
||||
|
||||
@ -72,11 +64,12 @@ class IPServiceBase(services.Service):
|
||||
raise NotADirectoryError('unassignMachine')
|
||||
|
||||
def wakeup(self, ip: str, mac: typing.Optional[str]) -> None:
|
||||
if WOLAPP and mac:
|
||||
cmd = WOLAPP.replace('{MAC}', mac or '').replace('{IP}', ip or '')
|
||||
logger.info('Launching WOL: %s', cmd)
|
||||
try:
|
||||
result = subprocess.run(cmd, shell=True, check=True)
|
||||
# logger.debug('Result: %s', result)
|
||||
except Exception as e:
|
||||
logger.error('Error on WOL: %s', e)
|
||||
if mac:
|
||||
wolurl = self.parent().wolURL(ip).replace('{MAC}', mac or '').replace('{IP}', ip or '')
|
||||
if wolurl:
|
||||
logger.info('Launching WOL: %s', wolurl)
|
||||
try:
|
||||
requests.get(wolurl, verify=False)
|
||||
# logger.debug('Result: %s', result)
|
||||
except Exception as e:
|
||||
logger.error('Error on WOL: %s', e)
|
||||
|
@ -46,7 +46,7 @@ from uds.core.util import config
|
||||
from uds.core.services import types as serviceTypes
|
||||
|
||||
from .deployment import IPMachineDeployed
|
||||
from .service_base import IPServiceBase, WOLAPP
|
||||
from .service_base import IPServiceBase
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
@ -204,7 +204,7 @@ class IPMachinesService(IPServiceBase):
|
||||
continue # The check failed not so long ago, skip it...
|
||||
self.storage.putPickle(theIP, now)
|
||||
# Now, check if it is available on port, if required...
|
||||
if self._port > 0 and not WOLAPP: # If configured WOLAPP, then check port is a nonsense...
|
||||
if self._port > 0 and not self.parent().wolURL(theIP): # If configured WOL, check is a nonsense
|
||||
if (
|
||||
connection.testServer(theIP, self._port, timeOut=0.5)
|
||||
is False
|
||||
|
Loading…
Reference in New Issue
Block a user