1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-26 10:03:50 +03:00

Fixing up new servers model

This commit is contained in:
Adolfo Gómez García 2023-11-17 03:23:43 +01:00
parent f3ddb68381
commit 8def04ccd7
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
12 changed files with 59 additions and 49 deletions

View File

@ -91,7 +91,7 @@ def logOperation(
username = handler.request.user.pretty_name if handler.request.user else 'Unknown'
doLog(
None,
None, # > None Objects goes to SYSLOG (global log)
level=level,
message=f'{handler.request.ip} [{username}]: [{handler.request.method}/{response_code}] {path}'[
:4096

View File

@ -35,6 +35,7 @@ import typing
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from traitlets import default
from uds.core import messaging, types
from uds.core.environment import Environment
@ -60,6 +61,7 @@ class Notifiers(ModelHandler):
'comments',
'level',
'tags',
'enabled',
]
table_title = typing.cast(str, _('Notifiers'))
@ -67,6 +69,7 @@ class Notifiers(ModelHandler):
{'name': {'title': _('Name'), 'visible': True, 'type': 'iconType'}},
{'type_name': {'title': _('Type')}},
{'level': {'title': _('Level')}},
{'enabled': {'title': _('Enabled')}},
{'comments': {'title': _('Comments')}},
{'tags': {'title': _('tags'), 'visible': False}},
]
@ -94,6 +97,14 @@ class Notifiers(ModelHandler):
'tooltip': gettext('Level of notifications'),
'type': types.ui.FieldType.CHOICE,
'order': 102,
},
{
'name': 'enabled',
'label': gettext('Enabled'),
'tooltip': gettext('If checked, this notifier will be used'),
'type': types.ui.FieldType.CHECKBOX,
'order': 103,
'default': True,
}
]:
self.addField(localGui, field)
@ -106,7 +117,8 @@ class Notifiers(ModelHandler):
return {
'id': item.uuid,
'name': item.name,
'level': item.level,
'level': str(item.level),
'enabled': item.enabled,
'tags': [tag.tag for tag in item.tags.all()],
'comments': item.comments,
'type': type_.type(),

View File

@ -37,7 +37,7 @@ import typing
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from uds.core import consts, transports, types
from uds.core import consts, transports, types, ui
from uds.core.environment import Environment
from uds.core.util import ensure, permissions
from uds.models import Network, ServicePool, Transport
@ -100,17 +100,14 @@ class Transports(ModelHandler):
'name': 'allowed_oss',
'value': [],
'choices': sorted(
[
{'id': x.name, 'text': x.name}
for x in consts.os.KNOWN_OS_LIST
],
[ui.gui.choiceItem(x.name, x.name) for x in consts.os.KNOWN_OS_LIST],
key=lambda x: x['text'].lower(),
),
'label': gettext('Allowed Devices'),
'tooltip': gettext(
'If empty, any kind of device compatible with this transport will be allowed. Else, only devices compatible with selected values will be allowed'
),
'type': 'multichoice',
'type': types.ui.FieldType.MULTICHOICE,
'tab': types.ui.Tab.ADVANCED,
'order': 102,
},
@ -121,13 +118,15 @@ class Transports(ModelHandler):
'name': 'pools',
'value': [],
'choices': [
{'id': x.uuid, 'text': x.name}
for x in ServicePool.objects.filter(service__isnull=False).order_by('name').prefetch_related('service')
if transportType.protocol in x.service.getType().allowedProtocols
ui.gui.choiceItem(x.uuid, x.name)
for x in ServicePool.objects.filter(service__isnull=False)
.order_by('name')
.prefetch_related('service')
if transportType.protocol in x.service.getType().allowedProtocols
],
'label': gettext('Service Pools'),
'tooltip': gettext('Currently assigned services pools'),
'type': 'multichoice',
'type': types.ui.FieldType.MULTICHOICE,
'order': 103,
},
)
@ -138,10 +137,8 @@ class Transports(ModelHandler):
'length': 32,
'value': '',
'label': gettext('Label'),
'tooltip': gettext(
'Metapool transport label (only used on metapool transports grouping)'
),
'type': 'text',
'tooltip': gettext('Metapool transport label (only used on metapool transports grouping)'),
'type': types.ui.FieldType.TEXT,
'order': 201,
'tab': types.ui.Tab.ADVANCED,
},
@ -152,7 +149,7 @@ class Transports(ModelHandler):
def item_as_dict(self, item: 'Model') -> typing.Dict[str, typing.Any]:
item = ensure.is_instance(item, Transport)
type_ = item.getType()
pools = [{'id': x.uuid} for x in item.deployedServices.all()]
pools = list(item.deployedServices.all().values_list('uuid', flat=True))
return {
'id': item.uuid,
'name': item.name,
@ -161,10 +158,8 @@ class Transports(ModelHandler):
'priority': item.priority,
'label': item.label,
'net_filtering': item.net_filtering,
'networks': [{'id': n.uuid} for n in item.networks.all()],
'allowed_oss': [{'id': x} for x in item.allowed_oss.split(',')]
if item.allowed_oss != ''
else [],
'networks': list(item.networks.all().values_list('uuid', flat=True)),
'allowed_oss': [x for x in item.allowed_oss.split(',')] if item.allowed_oss != '' else [],
'pools': pools,
'pools_count': len(pools),
'deployed_count': item.deployedServices.count(),
@ -180,9 +175,7 @@ class Transports(ModelHandler):
fields['label'] = fields['label'].strip().replace(' ', '-')
# And ensure small_name chars are valid [ a-zA-Z0-9:-]+
if fields['label'] and not re.match(r'^[a-zA-Z0-9:-]+$', fields['label']):
raise self.invalidRequestException(
gettext('Label must contain only letters, numbers, ":" and "-"')
)
raise self.invalidRequestException(gettext('Label must contain only letters, numbers, ":" and "-"'))
def afterSave(self, item: 'Model') -> None:
item = ensure.is_instance(item, Transport)

View File

@ -457,14 +457,15 @@ class ServerManager(metaclass=singleton.Singleton):
Returns:
List of servers sorted by usage
"""
now = model_utils.getSqlDatetime()
fltrs = serverGroup.servers.filter(maintenance_mode=False)
fltrs = fltrs.filter(Q(locked_until=None) | Q(locked_until__lte=now)) # Only unlocked servers
if excludeServersUUids:
fltrs = fltrs.exclude(uuid__in=excludeServersUUids)
# Get the stats for all servers, but in parallel
serverStats = self.getServerStats(fltrs)
with transaction.atomic():
now = model_utils.getSqlDatetime()
fltrs = serverGroup.servers.filter(maintenance_mode=False)
fltrs = fltrs.filter(Q(locked_until=None) | Q(locked_until__lte=now)) # Only unlocked servers
if excludeServersUUids:
fltrs = fltrs.exclude(uuid__in=excludeServersUUids)
# Get the stats for all servers, but in parallel
serverStats = self.getServerStats(fltrs)
# Sort by weight, lower first (lower is better)
return [s[1] for s in sorted(serverStats, key=lambda x: x[0].weight() if x[0] else 999999999)]

View File

@ -61,13 +61,13 @@ def _requestActor(
url = userService.getCommsUrl()
if not url:
# logger.warning('No notification is made because agent does not supports notifications: %s', userService.friendly_name)
raise exceptions.NoActorComms(f'No notification urls for {userService.friendly_name}')
raise exceptions.actor.NoActorComms(f'No notification urls for {userService.friendly_name}')
minVersion = minVersion or '3.5.0'
version = userService.properties.get('actor_version', '0.0.0')
if '-' in version or version < minVersion:
logger.warning('Pool %s has old actors (%s)', userService.deployed_service.name, version)
raise exceptions.OldActorVersion(
raise exceptions.actor.OldActorVersion(
f'Old actor version {version} for {userService.friendly_name}'.format(
version, userService.friendly_name
)
@ -155,7 +155,7 @@ def checkUuid(userService: 'UserService') -> bool:
uuid,
)
return False
except exceptions.NoActorComms:
except exceptions.actor.NoActorComms:
pass
return True # Actor does not supports checking
@ -172,7 +172,7 @@ def requestScreenshot(userService: 'UserService') -> bytes:
png = _requestActor(
userService, 'screenshot', minVersion='3.0.0'
) # First valid version with screenshot is 3.0
except exceptions.NoActorComms:
except exceptions.actor.NoActorComms:
png = None
return base64.b64decode(png or emptyPng)
@ -187,7 +187,7 @@ def sendScript(userService: 'UserService', script: str, forUser: bool = False) -
if forUser:
data['user'] = forUser
_requestActor(userService, 'script', data=data)
except exceptions.NoActorComms:
except exceptions.actor.NoActorComms:
pass
@ -197,7 +197,7 @@ def requestLogoff(userService: 'UserService') -> None:
"""
try:
_requestActor(userService, 'logout', data={})
except exceptions.NoActorComms:
except exceptions.actor.NoActorComms:
pass
@ -207,5 +207,5 @@ def sendMessage(userService: 'UserService', message: str) -> None:
"""
try:
_requestActor(userService, 'message', data={'message': message})
except exceptions.NoActorComms:
except exceptions.actor.NoActorComms:
pass

View File

@ -69,7 +69,7 @@ class MessageProcessorThread(BaseThread):
or time.time() - self._cached_stamp > CACHE_TIMEOUT
):
self._cached_providers = [
(p.level, p.getInstance()) for p in Notifier.objects.all()
(p.level, p.getInstance()) for p in Notifier.objects.filter(enabled=True)
]
self._cached_stamp = time.time()
return self._cached_providers

View File

@ -73,7 +73,7 @@ class Cache:
] = _basic_deserialize
def __init__(self, owner: typing.Union[str, bytes]):
self._owner = owner.decode('utf-8') if isinstance(owner, bytes) else owner
self._owner = typing.cast(str, owner.decode('utf-8') if isinstance(owner, bytes) else owner)
self._bowner = self._owner.encode('utf8')
def __getKey(self, key: typing.Union[str, bytes]) -> str:

View File

@ -45,7 +45,7 @@ _saveLater: typing.List[typing.Tuple['Config.Value', typing.Any]] = []
_getLater: typing.List['Config.Value'] = []
# For custom params (for choices mainly)
_configParams = {}
_configParams: typing.Dict[str, typing.Any] = {}
# Pair of section/value removed from current UDS version
# Note: As of version 4.0, all previous REMOVED values has been moved to migration script 0043

View File

@ -56,6 +56,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
Sample of transports are RDP, Spice, Web file uploader, etc...
"""
# Constants for net_filter
NO_FILTERING = 'n'
ALLOW = 'a'
@ -89,9 +90,7 @@ class Transport(ManagedObjectModel, TaggingMixin):
ordering = ('name',)
app_label = 'uds'
def getInstance(
self, values: typing.Optional[typing.Dict[str, str]] = None
) -> 'transports.Transport':
def getInstance(self, values: typing.Optional[typing.Dict[str, str]] = None) -> 'transports.Transport':
return typing.cast('transports.Transport', super().getInstance(values=values))
def getType(self) -> typing.Type['transports.Transport']:
@ -127,11 +126,16 @@ class Transport(ManagedObjectModel, TaggingMixin):
:note: Ip addresses has been only tested with IPv4 addresses
"""
# Avoid circular import
from uds.models import Network # pylint: disable=import-outside-toplevel
if self.net_filtering == Transport.NO_FILTERING:
return True
ip, version = net.ipToLong(ipStr)
# Allow
exists = self.networks.filter(start__lte=Network.hexlify(ip), end__gte=Network.hexlify(ip), version=version).exists()
exists = self.networks.filter(
start__lte=Network.hexlify(ip), end__gte=Network.hexlify(ip), version=version
).exists()
if self.net_filtering == Transport.ALLOW:
return exists
# Deny, must not be in any network

File diff suppressed because one or more lines are too long

View File

@ -102,6 +102,6 @@
</svg>
</div>
</uds-root>
<script src="/uds/res/admin/runtime.js?stamp=1699891841" type="module"></script><script src="/uds/res/admin/polyfills.js?stamp=1699891841" type="module"></script><script src="/uds/res/admin/main.js?stamp=1699891841" type="module"></script></body>
<script src="/uds/res/admin/runtime.js?stamp=1700178945" type="module"></script><script src="/uds/res/admin/polyfills.js?stamp=1700178945" type="module"></script><script src="/uds/res/admin/main.js?stamp=1700178945" type="module"></script></body>
</html>

View File

@ -1 +1 @@
hPF/H21BzZ0VU9HjimiOa1go9TJVsqmKsgGqB4V4X3cjB6G3NkSa1O45ub3gf+gOriElibPRbXzet4zma4qnBACLzAZQjmmxDRK9gC7eN6p0z0TKg18U6/hKf5gs6ICjQZyONg2gvBBrYUz7JhYoefq9SZRAna7373N0minKoJoBPLB+ylkemBNhKcsN5bRQlEGU03mLREGk/h642qN6ebQhIzY+JMo3c9CwtRS6SCiLhiaYkPFxdEX9e7AGSpTgGSFh4+Mc3QEge4sOquWszX4ocJJc23SHl5GdZSfhn3Bst5lLKILVUT5w7zaZOqa/xx/HjpCmxROJKm/bkR+HK8VMRh4N5c5yvavXid0IwgN8Uc+SOIUh4+wxbOyJI3ySS/77gUI/1TDw+r/gRkSUPwcRSFKuyQMN2yR6yr2BgOXlGmlNwZ/MzsDIIwgGeMlkKZZzLI64aj9VG2QsWHrlw2HWuFfBGGIX4T49p0tvdRm5o1jg/cdsLsHC8of5Vn4wgwyZwlScndDLcBJq76v4wnWUMg4IQpeOoI/PEbgeUfZDuntSt/ZT5icB78nN07hUo56d5Z5q1ktuWEHJSWCVSg59KGOcvaaPub50+anm6Uzac5rynZ0/gqA8Y0IV3dgRalBMZCiCy89lHW1YyO52A4DBka6hG4gKt5VUs+eT+vI=
mzEKyhRHnv5zWHZvuCfZrW6pq0V9NNTVfLrLmuP649dw5+Llpl80QL6F84vzaCuiTGebBrObT9cTO+JKi3gIlmgSfLVHSkOFaLOfX/IVzsQclcP7zn5B6dYwUPgBhrMN1CyvHP0hqvjXQkVgLxI3OFR/wSZ7VllyFBAnD4/EawUa2CIXRTnnCUBr4K5YFiV3esQu8sOCVYYMONwk4FAJUdt1UDfjGKQo15x9Y8S96tuBpVwQOGvF+ioEndQTUSC1GBlmPT6IgffJhI6Tm0xOji8QIdvUcJ/8ipK7qaWFplcJ7Sc/uKSgvcM7P2r6D45TmqbmGYhQgdMnQd7HmRaDi25gEnFckTCAzdEHiy8iibMATs0zqGS07h85vtlkllsi2xFF12ZcRR5AAIjSKmo5CDApjdQegVcHJgwYV8XjZRDyc2kBWvywbN7zob/rDuF5ncvFLwDDLFV6EZ1a15dEP/L6rR2NI1lGDdAqWwQmm0c28dfM3jv3GvyGOwTqJjmXgUrlSIBpM6EkdRMz8yIzdhJAhUxrwxVMi6qi+pWkWbtM9BXqgBgLqfaF5c8cGPup2uUvwvarexgrON28zsqwVvIHo2dqrrRWzjIrZzZpXAvteVLw9SFRlTVi3ilqHF7Zs9pQ7lp/D83SuI7+CWDu4co+3PX2Y9HYT2JfrlYnEjY=