1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-22 13:34:04 +03:00

more linting and refactoring uds.core.managers to remove functions

This commit is contained in:
Adolfo Gómez García 2023-04-19 16:20:30 +02:00
parent cfab4fd29b
commit 60fd7edc7b
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
29 changed files with 354 additions and 307 deletions

View File

@ -51,7 +51,9 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
AUTH_TOKEN_HEADER: typing.Final[str] = 'HTTP_X_AUTH_TOKEN' # nosec: this is not a password
AUTH_TOKEN_HEADER: typing.Final[
str
] = 'HTTP_X_AUTH_TOKEN' # nosec: this is not a password
class Handler:
@ -102,9 +104,8 @@ class Handler:
method: str,
params: typing.MutableMapping[str, typing.Any],
*args: str,
**kwargs
**kwargs,
):
logger.debug(
'Data: %s %s %s', self.__class__, self.needs_admin, self.authenticated
)
@ -151,7 +152,6 @@ class Handler:
else:
self._user = User() # Empty user for non authenticated handlers
def headers(self) -> typing.Dict[str, str]:
"""
Returns the headers of the REST request (all)
@ -183,6 +183,27 @@ class Handler:
except Exception: # nosec: intentionally ingoring exception
pass # If not found, just ignore it
@property
def request(self) -> 'ExtendedHttpRequestWithUser':
"""
Returns the request object
"""
return self._request
@property
def params(self) -> typing.Any:
"""
Returns the params object
"""
return self._params
@property
def args(self) -> typing.Tuple[str, ...]:
"""
Returns the args object
"""
return self._args
# Auth related
def getAuthToken(self) -> typing.Optional[str]:
"""
@ -215,7 +236,9 @@ class Handler:
staff_member = True # Make admins also staff members :-)
# crypt password and convert to base64
passwd = codecs.encode(cryptoManager().symCrypt(password, scrambler), 'base64').decode()
passwd = codecs.encode(
cryptoManager().symCrypt(password, scrambler), 'base64'
).decode()
session['REST'] = {
'auth': id_auth,

View File

@ -64,13 +64,13 @@ class ActorTokens(ModelHandler):
def item_as_dict(self, item: ActorToken) -> typing.Dict[str, typing.Any]:
return {
'id': item.token,
'name': _('Token isued by {} from {}').format(
'name': str(_('Token isued by {} from {}')).format(
item.username, item.hostname or item.ip
),
'stamp': item.stamp,
'username': item.username,
'ip': item.ip,
'host': '{} - {}'.format(item.ip, item.mac),
'host': f'{item.ip} - {item.mac}',
'hostname': item.hostname,
'pre_command': item.pre_command,
'post_command': item.post_command,
@ -92,6 +92,6 @@ class ActorTokens(ModelHandler):
try:
self.model.objects.get(token=self._args[0]).delete()
except self.model.DoesNotExist:
raise NotFound('Element do not exists')
raise NotFound('Element do not exists') from None
return OK

View File

@ -44,7 +44,8 @@ from uds.models import (
)
# from uds.core import VERSION
from uds.core.managers import userServiceManager, cryptoManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core import osmanagers
from uds.core.util import log, security
from uds.core.util.state import State
@ -107,7 +108,7 @@ def clearIfSuccess(func: typing.Callable) -> typing.Callable:
result = func(
*args, **kwargs
) # If raises any exception, it will be raised and we will not clear the counter
clearFailedIp(_self._request)
clearFailedIp(_self._request) # pylint: disable=protected-access
return result
return wrapper
@ -357,7 +358,7 @@ class Initialize(ActorV3Action):
if service and not alias_token: # Is a service managed by UDS
# Create a new alias for it, and save
alias_token = (
cryptoManager().randomString(40)
CryptoManager().randomString(40)
) # fix alias with new token
service.aliases.create(alias=alias_token)
@ -366,7 +367,7 @@ class Initialize(ActorV3Action):
userService.uuid, userService.unique_id, osData, alias_token
)
except (ActorToken.DoesNotExist, Service.DoesNotExist):
raise BlockAccess()
raise BlockAccess() from None
class BaseReadyChange(ActorV3Action):
@ -415,7 +416,7 @@ class BaseReadyChange(ActorV3Action):
if osManager:
osManager.toReady(userService)
userServiceManager().notifyReadyFromOsManager(userService, '')
UserServiceManager().notifyReadyFromOsManager(userService, '')
# Generates a certificate and send it to client.
privateKey, cert, password = security.selfSignedCert(self._params['ip'])

View File

@ -154,7 +154,7 @@ class Authenticators(ModelHandler):
raise Exception() # Not found
except Exception as e:
logger.info('Type not found: %s', e)
raise NotFound('type not found')
raise NotFound('type not found') from e
def item_as_dict(self, item: Authenticator) -> typing.Dict[str, typing.Any]:
type_ = item.getType()
@ -214,7 +214,6 @@ class Authenticators(ModelHandler):
if type_ == 'user':
return list(auth.searchUsers(term))[:limit]
else:
return list(auth.searchGroups(term))[:limit]
except Exception as e:
logger.exception('Too many results: %s', e)
@ -222,11 +221,9 @@ class Authenticators(ModelHandler):
# self.invalidResponseException('{}'.format(e))
def test(self, type_: str):
from uds.core.environment import Environment
authType = auths.factory().lookup(type_)
if not authType:
raise self.invalidRequestException('Invalid type: {}'.format(type_))
raise self.invalidRequestException(f'Invalid type: {type_}')
dct = self._params.copy()
dct['_request'] = self._request

View File

@ -39,7 +39,8 @@ from uds.REST import RequestError
from uds.models import TicketStore
from uds.models import User
from uds.web.util import errors
from uds.core.managers import cryptoManager, userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.util.config import GlobalConfig
from uds.core.services.exceptions import ServiceNotReadyError
from uds.core import VERSION as UDS_VERSION, REQUIRED_CLIENT_VERSION
@ -140,7 +141,7 @@ class Client(Handler):
userServiceInstance,
transport,
transportInstance,
) = userServiceManager().getService(
) = UserServiceManager().getService(
self._request.user,
self._request.os,
self._request.ip,
@ -156,7 +157,7 @@ class Client(Handler):
transport,
transportInstance,
)
password = cryptoManager().symDecrpyt(data['password'], scrambler)
password = CryptoManager().symDecrpyt(data['password'], scrambler)
# userService.setConnectionSource(srcIp, hostname) # Store where we are accessing from so we can notify Service
if not ip:

View File

@ -37,8 +37,8 @@ from uds.core.util.request import ExtendedHttpRequestWithUser
from uds.REST import Handler
from uds.REST import RequestError
from uds.core.managers import userServiceManager
from uds.core.managers import cryptoManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import ServiceNotReadyError
from uds.core.util.rest.tools import match
from uds.web.util import errors, services
@ -103,7 +103,7 @@ class Connection(Handler):
_, # iads,
_, #trans,
itrans,
) = userServiceManager().getService( # pylint: disable=unused-variable
) = UserServiceManager().getService( # pylint: disable=unused-variable
self._user,
self._request.os,
self._request.ip,
@ -132,7 +132,7 @@ class Connection(Handler):
def script(self, idService: str, idTransport: str, scrambler: str, hostname: str) -> typing.Dict[str, typing.Any]:
try:
res = userServiceManager().getService(
res = UserServiceManager().getService(
self._user, self._request.os, self._request.ip, idService, idTransport
)
logger.debug('Res: %s', res)
@ -143,7 +143,7 @@ class Connection(Handler):
transport,
transportInstance,
) = res # pylint: disable=unused-variable
password = cryptoManager().symDecrpyt(self.getValue('password'), scrambler)
password = CryptoManager().symDecrpyt(self.getValue('password'), scrambler)
userService.setConnectionSource(
self._request.ip, hostname

View File

@ -63,7 +63,7 @@ from uds.models.calendar_action import (
CALENDAR_ACTION_REMOVE_STUCK_USERSERVICES,
)
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.ui.images import DEFAULT_THUMB_BASE64
from uds.core.util.state import State
from uds.core.util.model import processUuid
@ -225,8 +225,8 @@ class ServicesPools(ModelHandler):
state = item.state
if item.isInMaintenance():
state = State.MAINTENANCE
# This needs a lot of queries, and really does not shows anything important i think...
# elif userServiceManager().canInitiateServiceFromDeployedService(item) is False:
# This needs a lot of queries, and really does not apport anything important to the report
# elif UserServiceManager().canInitiateServiceFromDeployedService(item) is False:
# state = State.SLOWED_DOWN
val = {
'id': item.uuid,
@ -506,16 +506,17 @@ class ServicesPools(ModelHandler):
return g
def beforeSave(
self, fields: typing.Dict[str, typing.Any]
) -> None: # pylint: disable=too-many-branches,too-many-statements
# pylint: disable=too-many-statements
def beforeSave(self, fields: typing.Dict[str, typing.Any]) -> None:
# logger.debug(self._params)
try:
try:
service = Service.objects.get(uuid=processUuid(fields['service_id']))
fields['service_id'] = service.id
except:
raise RequestError(gettext('Base service does not exist anymore'))
except Exception:
raise RequestError(
gettext('Base service does not exist anymore')
) from None
try:
serviceType = service.getType()
@ -551,7 +552,9 @@ class ServicesPools(ModelHandler):
):
fields[k] = 0
else: # uses cache, adjust values
fields['max_srvs'] = int(fields['max_srvs']) or 1 # ensure max_srvs is at least 1
fields['max_srvs'] = (
int(fields['max_srvs']) or 1
) # ensure max_srvs is at least 1
fields['initial_srvs'] = int(fields['initial_srvs'])
fields['cache_l1_srvs'] = int(fields['cache_l1_srvs'])
@ -565,10 +568,10 @@ class ServicesPools(ModelHandler):
fields['cache_l1_srvs'] = min(
fields['cache_l1_srvs'], serviceType.maxDeployed
)
except Exception:
raise RequestError(gettext('This service requires an OS Manager'))
except Exception as e:
raise RequestError(
gettext('This service requires an OS Manager')
) from e
# If max < initial or cache_1 or cache_l2
fields['max_srvs'] = max(
@ -618,14 +621,14 @@ class ServicesPools(ModelHandler):
except (RequestError, ResponseError):
raise
except Exception as e:
raise RequestError(str(e))
raise RequestError(str(e)) from e
def afterSave(self, item: ServicePool) -> None:
if self._params.get('publish_on_save', False) is True:
try:
item.publish()
except Exception as e:
logger.error('Could not publish service pool %s: %s',item.name, e)
logger.error('Could not publish service pool %s: %s', item.name, e)
def deleteItem(self, item: ServicePool) -> None:
try:
@ -679,7 +682,7 @@ class ServicesPools(ModelHandler):
CALENDAR_ACTION_DEL_ALL_TRANSPORTS,
CALENDAR_ACTION_ADD_GROUP,
CALENDAR_ACTION_DEL_GROUP,
CALENDAR_ACTION_DEL_ALL_GROUPS
CALENDAR_ACTION_DEL_ALL_GROUPS,
)
# Advanced actions
@ -699,7 +702,7 @@ class ServicesPools(ModelHandler):
return self.invalidRequestException('Invalid parameters')
logger.debug('Creating from assignable: %s', self._params)
userServiceManager().createFromAssignable(
UserServiceManager().createFromAssignable(
item,
User.objects.get(uuid=processUuid(self._params['user_id'])),
self._params['assignable_id'],

View File

@ -58,7 +58,7 @@ class TunnelTokens(ModelHandler):
def item_as_dict(self, item: TunnelToken) -> typing.Dict[str, typing.Any]:
return {
'id': item.token,
'name': _('Token isued by {} from {}').format(item.username, item.ip),
'name': str(_('Token isued by {} from {}')).format(item.username, item.ip),
'stamp': item.stamp,
'username': item.username,
'ip': item.ip,
@ -80,6 +80,6 @@ class TunnelTokens(ModelHandler):
try:
self.model.objects.get(token=self._args[0]).delete()
except self.model.DoesNotExist:
raise NotFound('Element do not exists')
raise NotFound('Element do not exists') from None
return OK

View File

@ -39,7 +39,7 @@ from uds import models
from uds.core.util.state import State
from uds.core.util.model import processUuid
from uds.core.util import log, permissions
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.REST.model import DetailHandler
from uds.REST import ResponseError
@ -125,9 +125,9 @@ class AssignedService(DetailHandler):
return AssignedService.itemToDict(
parent.assignedUserServices().get(processUuid(uuid=processUuid(item)))
)
except Exception:
except Exception as e:
logger.exception('getItems')
raise self.invalidItemException()
raise self.invalidItemException() from e
def getTitle(self, parent: models.ServicePool) -> str:
return _('Assigned services')
@ -164,8 +164,8 @@ class AssignedService(DetailHandler):
)
logger.debug('Getting logs for %s', userService)
return log.getLogs(userService)
except Exception:
raise self.invalidItemException()
except Exception as e:
raise self.invalidItemException() from e
# This is also used by CachedService, so we use "userServices" directly and is valid for both
def deleteItem(self, parent: models.ServicePool, item: str) -> None:
@ -173,20 +173,14 @@ class AssignedService(DetailHandler):
userService: models.UserService = parent.userServices.get(
uuid=processUuid(item)
)
except Exception:
except Exception as e:
logger.exception('deleteItem')
raise self.invalidItemException()
raise self.invalidItemException() from e
if userService.user:
logStr = 'Deleted assigned service {} to user {} by {}'.format(
userService.friendly_name,
userService.user.pretty_name,
self._user.pretty_name,
)
logStr = f'Deleted assigned service {userService.friendly_name} to user {userService.user.pretty_name} by {self._user.pretty_name}'
else:
logStr = 'Deleted cached service {} by {}'.format(
userService.friendly_name, self._user.pretty_name
)
logStr = f'Deleted cached service {userService.friendly_name} by {self._user.pretty_name}'
if userService.state in (State.USABLE, State.REMOVING):
userService.remove()
@ -207,9 +201,7 @@ class AssignedService(DetailHandler):
userService = parent.userServices.get(uuid=processUuid(item))
user = models.User.objects.get(uuid=processUuid(fields['user_id']))
logStr = 'Changing ownership of service from {} to {} by {}'.format(
userService.user, user.pretty_name, self._user.pretty_name
)
logStr = f'Changed ownership of service {userService.friendly_name} from {userService.user} to {user.pretty_name} by {self._user.pretty_name}'
# If there is another service that has this same owner, raise an exception
if (
@ -220,9 +212,7 @@ class AssignedService(DetailHandler):
> 0
):
raise self.invalidResponseException(
'There is already another user service assigned to {}'.format(
user.pretty_name
)
f'There is already another user service assigned to {user.pretty_name}'
)
userService.user = user # type: ignore
@ -233,7 +223,7 @@ class AssignedService(DetailHandler):
def reset(self, parent: 'models.ServicePool', item: str) -> typing.Any:
userService = parent.userServices.get(uuid=processUuid(item))
userServiceManager().reset(userService)
UserServiceManager().reset(userService)
class CachedService(AssignedService):
@ -259,9 +249,9 @@ class CachedService(AssignedService):
uuid=processUuid(item)
)
return AssignedService.itemToDict(cachedService, True)
except Exception:
except Exception as e:
logger.exception('getItems')
raise self.invalidItemException()
raise self.invalidItemException() from e
def getTitle(self, parent: models.ServicePool) -> str:
return _('Cached services')
@ -290,7 +280,7 @@ class CachedService(AssignedService):
logger.debug('Getting logs for %s', item)
return log.getLogs(userService)
except Exception:
raise self.invalidItemException()
raise self.invalidItemException() from None
class Groups(DetailHandler):
@ -351,7 +341,7 @@ class Groups(DetailHandler):
log.doLog(
parent,
log.INFO,
"Added group {} by {}".format(group.pretty_name, self._user.pretty_name),
f'Added group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN,
)
@ -361,7 +351,7 @@ class Groups(DetailHandler):
log.doLog(
parent,
log.INFO,
"Removed group {} by {}".format(group.pretty_name, self._user.pretty_name),
f'Removed group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN,
)
@ -410,7 +400,7 @@ class Transports(DetailHandler):
log.doLog(
parent,
log.INFO,
"Added transport {} by {}".format(transport.name, self._user.pretty_name),
f'Added transport {transport.name} by {self._user.pretty_name}',
log.ADMIN,
)
@ -422,7 +412,7 @@ class Transports(DetailHandler):
log.doLog(
parent,
log.INFO,
"Removed transport {} by {}".format(transport.name, self._user.pretty_name),
f'Removed transport {transport.name} by {self._user.pretty_name}',
log.ADMIN,
)
@ -458,9 +448,7 @@ class Publications(DetailHandler):
log.doLog(
parent,
log.INFO,
"Initated publication v{} by {}".format(
parent.current_pub_revision, self._user.pretty_name
),
f'Initiated publication v{parent.current_pub_revision} by {self._user.pretty_name}',
log.ADMIN,
)
@ -486,14 +474,12 @@ class Publications(DetailHandler):
ds = models.ServicePoolPublication.objects.get(uuid=processUuid(uuid))
ds.cancel()
except Exception as e:
raise ResponseError("{}".format(e))
raise ResponseError(str(e)) from e
log.doLog(
parent,
log.INFO,
"Canceled publication v{} by {}".format(
parent.current_pub_revision, self._user.pretty_name
),
f'Canceled publication v{parent.current_pub_revision} by {self._user.pretty_name}',
log.ADMIN,
)

View File

@ -77,7 +77,6 @@ def getPoolsForGroups(groups):
class Users(DetailHandler):
custom_methods = ['servicesPools', 'userServices', 'cleanRelated']
def getItems(self, parent: Authenticator, item: typing.Optional[str]):
@ -120,7 +119,6 @@ class Users(DetailHandler):
or _('User')
)
return values
else:
u = parent.users.get(uuid=processUuid(item))
res = model_to_dict(
u,
@ -146,9 +144,9 @@ class Users(DetailHandler):
res['groups'] = [g.dbGroup().uuid for g in usr.groups()]
logger.debug('Item: %s', res)
return res
except Exception:
except Exception as e:
logger.exception('En users')
raise self.invalidItemException()
raise self.invalidItemException() from e
def getTitle(self, parent):
try:
@ -191,7 +189,7 @@ class Users(DetailHandler):
try:
user = parent.users.get(uuid=processUuid(item))
except Exception:
raise self.invalidItemException()
raise self.invalidItemException() from None
return log.getLogs(user)
@ -247,18 +245,18 @@ class Users(DetailHandler):
if g.is_meta is False
)
except User.DoesNotExist:
raise self.invalidItemException()
raise self.invalidItemException() from None
except IntegrityError: # Duplicate key probably
raise RequestError(_('User already exists (duplicate key error)'))
raise RequestError(_('User already exists (duplicate key error)')) from None
except AuthenticatorException as e:
raise RequestError(str(e))
raise RequestError(str(e)) from e
except ValidationError as e:
raise RequestError(str(e.message))
raise RequestError(str(e.message)) from e
except RequestError:
raise
except Exception:
except Exception as e:
logger.exception('Saving user')
raise self.invalidRequestException()
raise self.invalidRequestException() from e
return self.getItems(parent, user.uuid)
@ -266,9 +264,12 @@ class Users(DetailHandler):
try:
user = parent.users.get(uuid=processUuid(item))
if not self._user.is_admin and (user.is_admin or user.staff_member):
logger.warn('Removal of user {} denied due to insufficients rights')
logger.warning(
'Removal of user %s denied due to insufficients rights',
user.pretty_name,
)
raise self.invalidItemException(
'Removal of user {} denied due to insufficients rights'
f'Removal of user {user.pretty_name} denied due to insufficients rights'
)
assignedUserService: 'UserService'
@ -285,9 +286,9 @@ class Users(DetailHandler):
logger.exception('Saving user on removing error')
user.delete()
except Exception:
except Exception as e:
logger.exception('Removing user')
raise self.invalidItemException()
raise self.invalidItemException() from e
return 'deleted'
@ -334,7 +335,6 @@ class Users(DetailHandler):
class Groups(DetailHandler):
custom_methods = ['servicesPools', 'users']
def getItems(self, parent: Authenticator, item: typing.Optional[str]):
@ -364,14 +364,14 @@ class Groups(DetailHandler):
if multi:
return res
if not i:
raise # Invalid item
raise Exception('Item not found')
# Add pools field if 1 item only
result = res[0]
result['pools'] = [v.uuid for v in getPoolsForGroups([i])]
return result
except Exception:
except Exception as e:
logger.exception('REST groups')
raise self.invalidItemException()
raise self.invalidItemException() from e
def getTitle(self, parent: Authenticator) -> str:
try:
@ -409,12 +409,12 @@ class Groups(DetailHandler):
}
types = [
{
'name': tDct[t]['name'],
'type': t,
'description': tDct[t]['description'],
'name': v['name'],
'type': k,
'description': v['description'],
'icon': '',
}
for t in tDct
for k, v in tDct.items()
]
if forType is None:
@ -423,7 +423,7 @@ class Groups(DetailHandler):
try:
return next(filter(lambda x: x['type'] == forType, types))
except Exception:
raise self.invalidRequestException()
raise self.invalidRequestException() from None
def saveItem(self, parent: Authenticator, item: typing.Optional[str]) -> None:
group = None # Avoid warning on reference before assignment
@ -467,7 +467,11 @@ class Groups(DetailHandler):
if is_meta:
# Do not allow to add meta groups to meta groups
group.groups.set(i for i in parent.groups.filter(uuid__in=self._params['groups']) if i.is_meta is False)
group.groups.set(
i
for i in parent.groups.filter(uuid__in=self._params['groups'])
if i.is_meta is False
)
if pools:
# Update pools
@ -475,16 +479,16 @@ class Groups(DetailHandler):
group.save()
except Group.DoesNotExist:
raise self.invalidItemException()
raise self.invalidItemException() from None
except IntegrityError: # Duplicate key probably
raise RequestError(_('User already exists (duplicate key error)'))
raise RequestError(_('User already exists (duplicate key error)')) from None
except AuthenticatorException as e:
raise RequestError(str(e))
raise RequestError(str(e)) from e
except RequestError:
raise
except Exception:
except Exception as e:
logger.exception('Saving group')
raise self.invalidRequestException()
raise self.invalidRequestException() from e
def deleteItem(self, parent: Authenticator, item: str) -> None:
try:
@ -492,7 +496,7 @@ class Groups(DetailHandler):
group.delete()
except Exception:
raise self.invalidItemException()
raise self.invalidItemException() from None
def servicesPools(
self, parent: Authenticator, item: str
@ -532,11 +536,10 @@ class Groups(DetailHandler):
'last_access': user.last_access,
}
res: typing.List[typing.Mapping[str, typing.Any]] = []
if group.is_meta:
# Get all users for everygroup and
groups = getGroupsFromMeta((group,))
tmpSet = None
tmpSet: typing.Optional[typing.Set] = None
for g in groups:
gSet = set((i for i in g.users.all()))
if tmpSet is None:
@ -549,12 +552,9 @@ class Groups(DetailHandler):
if not tmpSet:
break # If already empty, stop
users = list(tmpSet) if tmpSet else list()
users = list(tmpSet or {}) if tmpSet else []
tmpSet = None
else:
users = group.users.all()
for i in users:
res.append(info(i))
return res
return [info(i) for i in users]

View File

@ -31,56 +31,23 @@
"""
import traceback
import logging
import enum
import typing
from uds import models
from uds.core.util.config import GlobalConfig
from uds.core.util import singleton
from uds.models.util import getSqlDatetime
from uds.models.log import Log
from .objects import MODEL_TO_TYPE, LogObjectType
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from django.db.models import Model
from uds import models
logger = logging.getLogger(__name__)
class LogObjectType(enum.IntEnum):
USERSERVICE = 0
PUBLICATION = 1
SERVICEPOOL = 2
SERVICE = 3
PROVIDER = 4
USER = 5
GROUP = 6
AUTHENTICATOR = 7
METAPOOL = 8
SYSLOG = 9
def get_max_elements(self) -> int:
"""
if True, this type of log will be limited by number of log entries
"""
if self == LogObjectType.SYSLOG:
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt()
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
# Dict for translations
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {
models.UserService: LogObjectType.USERSERVICE,
models.ServicePoolPublication: LogObjectType.PUBLICATION,
models.ServicePool: LogObjectType.SERVICEPOOL,
models.Service: LogObjectType.SERVICE,
models.Provider: LogObjectType.PROVIDER,
models.User: LogObjectType.USER,
models.Group: LogObjectType.GROUP,
models.Authenticator: LogObjectType.AUTHENTICATOR,
models.MetaPool: LogObjectType.METAPOOL,
}
class LogManager(metaclass=singleton.Singleton):
"""
@ -109,7 +76,7 @@ class LogManager(metaclass=singleton.Singleton):
# Ensure message fits on space
message = str(message)[:255]
qs = models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
# First, ensure we do not have more than requested logs, and we can put one more log item
max_elements = owner_type.get_max_elements()
current_elements = qs.count()
@ -120,7 +87,7 @@ class LogManager(metaclass=singleton.Singleton):
x.delete()
if avoidDuplicates:
lg: typing.Optional[models.Log] = models.Log.objects.filter(
lg: typing.Optional['Log'] = Log.objects.filter(
owner_id=owner_id, owner_type=owner_type.value
).last()
if lg and lg.data == message:
@ -129,10 +96,10 @@ class LogManager(metaclass=singleton.Singleton):
# now, we add new log
try:
models.Log.objects.create(
Log.objects.create(
owner_type=owner_type.value,
owner_id=owner_id,
created=models.getSqlDatetime(),
created=getSqlDatetime(),
source=source,
level=level,
data=message,
@ -147,7 +114,7 @@ class LogManager(metaclass=singleton.Singleton):
"""
Get all logs associated with an user service, ordered by date
"""
qs = models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type.value)
return [
{'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data}
for x in reversed(qs.order_by('-created', '-id')[:limit]) # type: ignore # Slicing is not supported by pylance right now
@ -157,7 +124,7 @@ class LogManager(metaclass=singleton.Singleton):
"""
Clears ALL logs related to user service
"""
models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete()
Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete()
def doLog(
self,
@ -199,7 +166,7 @@ class LogManager(metaclass=singleton.Singleton):
)
def getLogs(
self, wichObject: typing.Optional['Model'], limit: int
self, wichObject: typing.Optional['Model'], limit: int = -1
) -> typing.List[typing.Dict]:
"""
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
@ -213,7 +180,7 @@ class LogManager(metaclass=singleton.Singleton):
logger.debug('Getting log: %s -> %s', wichObject, owner_type)
if owner_type: # 0 is valid owner type
return self.__getLogs(owner_type, getattr(wichObject, 'id', -1), limit)
return self.__getLogs(owner_type, getattr(wichObject, 'id', -1), limit if limit != -1 else owner_type.get_max_elements())
logger.debug(
'Requested getLogs for a type of object not covered: %s', wichObject

View File

@ -0,0 +1,14 @@
import logging
import logging.handlers
class UDSLog(logging.handlers.RotatingFileHandler):
"""
Custom log handler that will log to database before calling to RotatingFileHandler
"""
def emit(self, record: logging.LogRecord) -> None:
# Currently, simply call to parent
msg = self.format(record) # pylint: disable=unused-variable
# TODO: Log message on database and continue as a RotatingFileHandler
return super().emit(record)

View File

@ -0,0 +1,45 @@
import typing
import enum
from uds import models
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from django.db.models import Model
class LogObjectType(enum.IntEnum):
USERSERVICE = 0
PUBLICATION = 1
SERVICEPOOL = 2
SERVICE = 3
PROVIDER = 4
USER = 5
GROUP = 6
AUTHENTICATOR = 7
METAPOOL = 8
SYSLOG = 9
def get_max_elements(self) -> int:
"""
if True, this type of log will be limited by number of log entries
"""
from uds.core.util.config import GlobalConfig # pylint: disable=import-outside-toplevel
if self == LogObjectType.SYSLOG:
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt()
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
# Dict for translations
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {
models.UserService: LogObjectType.USERSERVICE,
models.ServicePoolPublication: LogObjectType.PUBLICATION,
models.ServicePool: LogObjectType.SERVICEPOOL,
models.Service: LogObjectType.SERVICE,
models.Provider: LogObjectType.PROVIDER,
models.User: LogObjectType.USER,
models.Group: LogObjectType.GROUP,
models.Authenticator: LogObjectType.AUTHENTICATOR,
models.MetaPool: LogObjectType.METAPOOL,
}

View File

@ -34,8 +34,6 @@ import logging
import logging.handlers
import typing
from uds.core.managers import logManager
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from django.db.models import Model
@ -149,8 +147,11 @@ def doLog(
source: str = UNKNOWN,
avoidDuplicates: bool = True,
) -> None:
# pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
logger.debug('%s %s %s', wichObject, level, message)
logManager().doLog(wichObject, level, message, source, avoidDuplicates)
LogManager().doLog(wichObject, level, message, source, avoidDuplicates)
def getLogs(
@ -159,21 +160,34 @@ def getLogs(
"""
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
"""
# pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
from uds.core.util.config import GlobalConfig
if limit is None:
limit = GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
return logManager().getLogs(wichObject, limit)
return LogManager().getLogs(wichObject, limit)
def clearLogs(wichObject: 'Model') -> None:
"""
Clears the logs associated with the object using the logManager
"""
return logManager().clearLogs(wichObject)
# pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager
return LogManager().clearLogs(wichObject)
class UDSLogHandler(logging.handlers.RotatingFileHandler):
"""
Custom log handler that will log to database before calling to RotatingFileHandler
"""
def emit(self, record: logging.LogRecord) -> None:
# Currently, simply call to parent
msg = self.format(record) # pylint: disable=unused-variable
# TODO: Log message on database and continue as a RotatingFileHandler
return super().emit(record)

View File

@ -36,7 +36,7 @@ from django.db import transaction
from django.db.models import Q
from uds.core.util.config import GlobalConfig
from uds.core.util.state import State
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.services.exceptions import MaxServicesReachedError
from uds.models import ServicePool, ServicePoolPublication, UserService
from uds.core import services
@ -122,7 +122,7 @@ class ServiceCacheUpdater(Job):
inCacheL1: int = (
servicePool.cachedUserServices()
.filter(
userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L1_CACHE
)
)
@ -132,7 +132,7 @@ class ServiceCacheUpdater(Job):
inCacheL2: int = (
servicePool.cachedUserServices()
.filter(
userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE
)
)
@ -140,7 +140,7 @@ class ServiceCacheUpdater(Job):
)
inAssigned: int = (
servicePool.assignedUserServices()
.filter(userServiceManager().getStateFilter(servicePool.service)) # type: ignore
.filter(UserServiceManager().getStateFilter(servicePool.service)) # type: ignore
.count()
)
# if we bypasses max cache, we will reduce it in first place. This is so because this will free resources on service provider
@ -179,7 +179,7 @@ class ServiceCacheUpdater(Job):
continue
# If this service don't allows more starting user services, continue
if not userServiceManager().canGrowServicePool(servicePool):
if not UserServiceManager().canGrowServicePool(servicePool):
logger.debug(
'This pool cannot grow rithg now: %s',
servicePool,
@ -231,7 +231,7 @@ class ServiceCacheUpdater(Job):
servicePool.cachedUserServices()
.select_for_update()
.filter(
userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE
)
)
@ -252,7 +252,7 @@ class ServiceCacheUpdater(Job):
return
try:
# This has a velid publication, or it will not be here
userServiceManager().createCacheFor(
UserServiceManager().createCacheFor(
typing.cast(ServicePoolPublication, servicePool.activePublication()),
services.UserDeployment.L1_CACHE,
)
@ -288,7 +288,7 @@ class ServiceCacheUpdater(Job):
logger.debug("Growing L2 cache creating a new service for %s", servicePool.name)
try:
# This has a velid publication, or it will not be here
userServiceManager().createCacheFor(
UserServiceManager().createCacheFor(
typing.cast(ServicePoolPublication, servicePool.activePublication()),
services.UserDeployment.L2_CACHE,
)
@ -312,7 +312,7 @@ class ServiceCacheUpdater(Job):
cacheItems: typing.List[UserService] = list(
servicePool.cachedUserServices()
.filter(
userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L1_CACHE
)
)
@ -359,7 +359,7 @@ class ServiceCacheUpdater(Job):
cacheItems = (
servicePool.cachedUserServices()
.filter(
userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
servicePool, services.UserDeployment.L2_CACHE
)
)

View File

@ -34,7 +34,7 @@ import logging
import typing
from django.db import transaction
from uds.core import managers
from uds.core.managers.user_service import UserServiceManager
from uds.core.util.config import GlobalConfig
from uds.models import UserService, getSqlDatetime
from uds.core.util.state import State
@ -77,7 +77,7 @@ class UserServiceRemover(Job):
# USER_SERVICE_REMOVAL_LIMIT is the maximum number of items to remove at once
# This configuration value is cached at startup, so it is not updated until next reload
removeAtOnce: int = GlobalConfig.USER_SERVICE_CLEAN_NUMBER.getInt()
manager = managers.userServiceManager()
manager = UserServiceManager()
with transaction.atomic():
removeFrom = getSqlDatetime() - timedelta(

View File

@ -43,7 +43,7 @@ from django.db import models
from uds.core.util import calendar
from uds.core.util import log
from uds.core.util import state
from uds.core import managers
from uds.core.managers.user_service import UserServiceManager
from uds.core import services
from .calendar import Calendar
@ -375,7 +375,7 @@ class CalendarAction(UUIDModel):
def clear_cache() -> None:
# 4.- Remove all cache_l1_srvs
for i in self.service_pool.cachedUserServices().filter(
managers.userServiceManager().getCacheStateFilter(
UserServiceManager().getCacheStateFilter(
self.service_pool,
services.UserDeployment.L1_CACHE
if self.action == CALENDAR_ACTION_CLEAN_CACHE_L1['id']

View File

@ -33,8 +33,6 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com
import logging
from django.db import models
from uds.core.util.log import logStrFromLevel
logger = logging.getLogger(__name__)
@ -75,6 +73,9 @@ class Log(models.Model):
@property
def level_str(self) -> str:
# pylint: disable=import-outside-toplevel
from uds.core.util.log import logStrFromLevel
return logStrFromLevel(self.level)
def __str__(self) -> str:

View File

@ -448,7 +448,7 @@ class UserService(UUIDModel):
:note: If the state is Fase (set to not in use), a check for removal of this deployed service is launched.
"""
# pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
self.in_use = inUse
self.in_use_date = getSqlDatetime()
@ -462,7 +462,7 @@ class UserService(UUIDModel):
if not inUse: # Service released, check y we should mark it for removal
# If our publication is not current, mark this for removal
userServiceManager().checkForRemoval(self)
UserServiceManager().checkForRemoval(self)
def startUsageAccounting(self) -> None:
# 1.- If do not have any account associated, do nothing
@ -526,10 +526,10 @@ class UserService(UUIDModel):
Returns if this service is ready (not preparing or marked for removal)
"""
# pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
# Call to isReady of the instance
return userServiceManager().isReady(self)
return UserServiceManager().isReady(self)
def isInMaintenance(self) -> bool:
return self.deployed_service.isInMaintenance()
@ -551,9 +551,9 @@ class UserService(UUIDModel):
Asks the UserServiceManager to cancel the current operation of this user deployed service.
"""
# pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
userServiceManager().cancel(self)
UserServiceManager().cancel(self)
def removeOrCancel(self) -> None:
"""
@ -578,9 +578,9 @@ class UserService(UUIDModel):
cacheLevel: New cache level to put object in
"""
# pylint: disable=import-outside-toplevel
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
userServiceManager().moveToLevel(self, cacheLevel)
UserServiceManager().moveToLevel(self, cacheLevel)
def getProperty(
self, propName: str, default: typing.Optional[str] = None

View File

@ -40,7 +40,6 @@ from uds.core.ui import gui
from uds.core import osmanagers
from uds.core.util.state import State
from uds.core.util import log
from uds.core.managers import userServiceManager
if typing.TYPE_CHECKING:
from uds.models.user_service import UserService

View File

@ -40,7 +40,6 @@ from uds.core.ui import gui
from uds.core import osmanagers
from uds.core.util.state import State
from uds.core.util import log
from uds.core.managers import userServiceManager
if typing.TYPE_CHECKING:
from uds.models.user_service import UserService

View File

@ -16,7 +16,6 @@ from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core import osmanagers, exceptions
from uds.core.services import types as serviceTypes
from uds.core.ui import gui
from uds.core.managers import userServiceManager
from uds.core.util.state import State
from uds.core.util import log
from uds.models import TicketStore

View File

@ -35,7 +35,7 @@ import logging
import typing
from uds.core import services
from uds.core import managers
from uds.core.managers.user_service import UserServiceManager
from uds.core.util.state import State
from uds.core.util import log
@ -135,7 +135,9 @@ class OVirtLinkedDeployment(services.UserDeployment):
self._mac = vals[3].decode('utf8')
self._vmid = vals[4].decode('utf8')
self._reason = vals[5].decode('utf8')
self._queue = pickle.loads(vals[6]) # nosec: not insecure, we are loading our own data
self._queue = pickle.loads(
vals[6]
) # nosec: not insecure, we are loading our own data
def getName(self) -> str:
if self._name == '':
@ -216,7 +218,7 @@ class OVirtLinkedDeployment(services.UserDeployment):
self.cache.put('ready', '1')
except Exception as e:
self.doLog(log.ERROR, 'Error on setReady: {}'.format(e))
self.doLog(log.ERROR, f'Error on setReady: {e}')
# Treat as operation done, maybe the machine is ready and we can continue
return State.FINISHED
@ -233,19 +235,22 @@ class OVirtLinkedDeployment(services.UserDeployment):
) -> typing.Optional[typing.MutableMapping[str, typing.Any]]:
return self.service().getConsoleConnection(self._vmid)
def desktopLogin(self, username: str, password: str, domain: str = '') -> None:
script = '''import sys
def desktopLogin(
self,
username: str,
password: str,
domain: str = '', # pylint: disable=unused-argument
) -> None:
script = f'''import sys
if sys.platform == 'win32':
from uds import operations
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True)
'''.format(
username=username, password=password
)
'''
# Post script to service
# operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
dbService = self.dbservice()
if dbService:
managers.userServiceManager().sendScript(dbService, script)
UserServiceManager().sendScript(dbService, script)
def notifyReadyFromOsManager(self, data: typing.Any) -> str:
# Here we will check for suspending the VM (when full ready)
@ -273,7 +278,6 @@ if sys.platform == 'win32':
return self.__executeQueue()
def __initQueueForDeploy(self, forLevel2: bool = False) -> None:
if forLevel2 is False:
self._queue = [opCreate, opChangeMac, opStart, opFinish]
else:
@ -322,9 +326,6 @@ if sys.platform == 'win32':
def __pushFrontOp(self, op: int):
self._queue.insert(0, op)
def __pushBackOp(self, op: int):
self._queue.append(op)
def __error(self, reason: typing.Union[str, Exception]) -> str:
"""
Internal method to set object as error state
@ -369,7 +370,7 @@ if sys.platform == 'win32':
if execFnc is None:
return self.__error(
'Unknown operation found at execution queue ({0})'.format(op)
f'Unknown operation found at execution queue ({op})'
)
execFnc()
@ -446,7 +447,7 @@ if sys.platform == 'win32':
if state in UP_STATES: # Already started, return
return State.RUNNING
if state != 'down' and state != 'suspended':
if state not in ('down', 'suspended'):
self.__pushFrontOp(
opRetry
) # Will call "check Retry", that will finish inmediatly and again call this one
@ -466,7 +467,7 @@ if sys.platform == 'win32':
if state == 'down': # Already stoped, return
return State.RUNNING
if state != 'up' and state != 'suspended':
if state not in ('up', 'suspended'):
self.__pushFrontOp(
opRetry
) # Will call "check Retry", that will finish inmediatly and again call this one
@ -576,7 +577,7 @@ if sys.platform == 'win32':
if chkFnc is None:
return self.__error(
'Unknown operation found at check queue ({0})'.format(op)
f'Unknown operation found at check queue ({op})'
)
state = chkFnc()
@ -629,7 +630,7 @@ if sys.platform == 'win32':
if op == opError:
return self.__error('Machine is already in error state!')
if op == opFinish or op == opWait:
if op in (opFinish, opWait):
self._queue = [opStop, opRemove, opFinish]
return self.__executeQueue()

View File

@ -35,7 +35,7 @@ import logging
import typing
from uds.core import services
from uds.core import managers
from uds.core.managers.user_service import UserServiceManager
from uds.core.util.state import State
from uds.core.util import log
from uds.models import getSqlDatetimeAsUnix
@ -186,7 +186,7 @@ class ProxmoxDeployment(services.UserDeployment):
except client.ProxmoxConnectionError:
raise # If connection fails, let it fail on parent
except Exception as e:
return self.__error('Machine not found: {}'.format(e))
return self.__error(f'Machine not found: {e}')
if vmInfo.status == 'stopped':
self._queue = [opStart, opFinish]
@ -210,20 +210,23 @@ class ProxmoxDeployment(services.UserDeployment):
) -> typing.Optional[typing.MutableMapping[str, typing.Any]]:
return self.service().getConsoleConnection(self._vmid)
def desktopLogin(self, username: str, password: str, domain: str = '') -> None:
script = '''import sys
def desktopLogin(
self,
username: str,
password: str,
domain: str = '', # pylint: disable=unused-argument
) -> None:
script = f'''import sys
if sys.platform == 'win32':
from uds import operations
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", struct.pack('!IsIs', 1, '{username}'.encode('utf8'), 2, '{password}'.encode('utf8')), True)
'''.format(
username=username, password=password
)
'''
# Post script to service
# operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
dbService = self.dbservice()
if dbService:
try:
managers.userServiceManager().sendScript(dbService, script)
UserServiceManager().sendScript(dbService, script)
except Exception as e:
logger.info('Exception sending loggin to %s: %s', dbService, e)
@ -253,7 +256,6 @@ if sys.platform == 'win32':
return self.__executeQueue()
def __initQueueForDeploy(self, forLevel2: bool = False) -> None:
if forLevel2 is False:
self._queue = [opCreate, opGetMac, opStart, opFinish]
else:
@ -282,9 +284,6 @@ if sys.platform == 'win32':
def __pushFrontOp(self, op: int):
self._queue.insert(0, op)
def __pushBackOp(self, op: int):
self._queue.append(op)
def __retryLater(self) -> str:
self.__pushFrontOp(opRetry)
return State.RUNNING
@ -334,7 +333,7 @@ if sys.platform == 'win32':
if execFnc is None:
return self.__error(
'Unknown operation found at execution queue ({0})'.format(op)
f'Unknown operation found at execution queue ({op})'
)
execFnc()
@ -387,14 +386,13 @@ if sys.platform == 'win32':
"""
try:
vmInfo = self.service().getMachineInfo(int(self._vmid))
except Exception:
raise Exception('Machine not found on remove machine')
except Exception as e:
raise Exception('Machine not found on remove machine') from e
if vmInfo.status != 'stopped':
logger.debug('Info status: %s', vmInfo)
self._queue = [opStop, opRemove, opFinish]
return self.__executeQueue()
else:
self.__setTask(self.service().removeMachine(int(self._vmid)))
return State.RUNNING
@ -404,8 +402,8 @@ if sys.platform == 'win32':
vmInfo = self.service().getMachineInfo(int(self._vmid))
except client.ProxmoxConnectionError:
return self.__retryLater()
except Exception:
raise Exception('Machine not found on start machine')
except Exception as e:
raise Exception('Machine not found on start machine') from e
if vmInfo.status == 'stopped':
self.__setTask(self.service().startMachine(int(self._vmid)))
@ -415,8 +413,8 @@ if sys.platform == 'win32':
def __stopMachine(self) -> str:
try:
vmInfo = self.service().getMachineInfo(int(self._vmid))
except Exception:
raise Exception('Machine not found on stop machine')
except Exception as e:
raise Exception('Machine not found on stop machine') from e
if vmInfo.status != 'stopped':
logger.debug('Stopping machine %s', vmInfo)
@ -429,8 +427,8 @@ if sys.platform == 'win32':
vmInfo = self.service().getMachineInfo(int(self._vmid))
except client.ProxmoxConnectionError:
return State.RUNNING # Try again later
except Exception:
raise Exception('Machine not found on suspend machine')
except Exception as e:
raise Exception('Machine not found on suspend machine') from e
if vmInfo.status != 'stopped':
self.__setTask(self.service().shutdownMachine(int(self._vmid)))
@ -463,7 +461,7 @@ if sys.platform == 'win32':
self.service().setVmMac(int(self._vmid), self.getUniqueId())
except Exception as e:
logger.exception('Setting HA and MAC on proxmox')
raise Exception('Error setting MAC and HA on proxmox: {}'.format(e))
raise Exception(f'Error setting MAC and HA on proxmox: {e}') from e
return State.RUNNING
# Check methods
@ -589,7 +587,7 @@ if sys.platform == 'win32':
if chkFnc is None:
return self.__error(
'Unknown operation found at check queue ({0})'.format(op)
f'Unknown operation found at check queue ({op})'
)
state = chkFnc()
@ -645,7 +643,7 @@ if sys.platform == 'win32':
lst = [] if not self.service().tryGracelyShutdown() else [opGracelyStop]
queue = lst + [opStop, opRemove, opFinish]
if op == opFinish or op == opWait:
if op in (opFinish, opWait):
self._queue[:] = queue
return self.__executeQueue()

View File

@ -200,7 +200,7 @@ class ProxmoxLinkedService(Service): # pylint: disable=too-many-public-methods
self.machine.setValues(
[
gui.choiceItem(
str(m.vmid), '{}\\{} ({})'.format(m.node, m.name or m.vmid, m.vmid)
str(m.vmid), f'{m.node}\\{m.name or m.vmid} ({m.vmid})'
)
for m in self.parent().listMachines()
if m.name and m.name[:3] != 'UDS'

View File

@ -38,7 +38,7 @@ import typing
import paramiko
from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core.managers import userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.user_preferences import CommonPrefs
from uds.core.ui import gui
from uds.core import transports
@ -52,7 +52,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30
SSH_KEY_LENGTH = 1024
SSH_KEY_LENGTH = 2048
class BaseX2GOTransport(transports.Transport):
@ -269,11 +269,11 @@ class BaseX2GOTransport(transports.Transport):
key.write_private_key(privFile)
priv = privFile.getvalue()
pub = key.get_base64() # 'ssh-rsa {} UDS@X2GOCLIENT'.format(key.get_base64())
pub = key.get_base64()
return priv, pub
def getAuthorizeScript(self, user: str, pubKey: str) -> str:
with open(os.path.join(os.path.dirname(__file__), 'scripts/authorize.py')) as f:
with open(os.path.join(os.path.dirname(__file__), 'scripts/authorize.py'), encoding='utf8') as f:
data = f.read()
return data.replace('__USER__', user).replace('__KEY__', pubKey)
@ -283,5 +283,5 @@ class BaseX2GOTransport(transports.Transport):
) -> typing.Tuple[str, str]:
priv, pub = self.genKeyPairForSsh()
authScript = self.getAuthorizeScript(userName, pub)
userServiceManager().sendScript(userService, authScript)
UserServiceManager().sendScript(userService, authScript)
return priv, pub

View File

@ -46,7 +46,8 @@ from uds.models import (
)
from uds.core.util.config import GlobalConfig
from uds.core.util import html
from uds.core.managers import cryptoManager, userServiceManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import (
ServiceNotReadyError,
MaxServicesReachedError,
@ -66,6 +67,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
# pylint: disable=too-many-arguments
def _serviceInfo(
uuid: str,
is_meta: bool,
@ -106,6 +108,7 @@ def _serviceInfo(
}
# pylint: disable=too-many-locals, too-many-branches, too-many-statements
def getServicesData(
request: 'ExtendedHttpRequestWithUser',
) -> typing.Dict[
@ -172,10 +175,11 @@ def getServicesData(
)
def buildMetaTransports(
transports: typing.Iterable[Transport],
isLabel: bool,
transports: typing.Iterable[Transport], isLabel: bool, meta: 'MetaPool'
) -> typing.List[typing.Mapping[str, typing.Any]]:
idd = lambda i: i.uuid if not isLabel else 'LABEL:' + i.label
def idd(i):
return i.uuid if not isLabel else 'LABEL:' + i.label
return [
{
'id': idd(i),
@ -211,7 +215,7 @@ def getServicesData(
inAll = tmpSet
# tmpSet has ALL common transports
metaTransports = buildMetaTransports(
Transport.objects.filter(uuid__in=inAll or []), isLabel=False
Transport.objects.filter(uuid__in=inAll or []), isLabel=False, meta=meta
)
elif meta.transport_grouping == MetaPool.LABEL_TRANSPORT_SELECT:
ltrans: typing.MutableMapping[str, Transport] = {}
@ -231,7 +235,7 @@ def getServicesData(
inAll = tmpSet
# tmpSet has ALL common transports
metaTransports = buildMetaTransports(
(v for k, v in ltrans.items() if k in (inAll or set())), isLabel=True
(v for k, v in ltrans.items() if k in (inAll or set())), isLabel=True, meta=meta
)
else:
for member in meta.members.all():
@ -258,7 +262,7 @@ def getServicesData(
break
# if not in_use and meta.number_in_use: # Only look for assignation on possible used
# assignedUserService = userServiceManager().getExistingAssignationForUser(pool, request.user)
# assignedUserService = UserServiceManager().getExistingAssignationForUser(pool, request.user)
# if assignedUserService:
# in_use = assignedUserService.in_use
@ -332,7 +336,7 @@ def getServicesData(
# Locate if user service has any already assigned user service for this. Use "pre cached" number of assignations in this pool to optimize
in_use = typing.cast(typing.Any, sPool).number_in_use > 0
# if svr.number_in_use: # Anotated value got from getDeployedServicesForGroups(...). If 0, no assignation for this user
# ads = userServiceManager().getExistingAssignationForUser(svr, request.user)
# ads = UserServiceManager().getExistingAssignationForUser(svr, request.user)
# if ads:
# in_use = ads.in_use
@ -366,6 +370,7 @@ def getServicesData(
# if sPool.service.getType().usesCache is False:
# maxDeployed = sPool.service.getInstance().maxDeployed
# pylint: disable=cell-var-from-loop
def datator(x) -> str:
return (
x.replace('{use}', use_percent)
@ -438,11 +443,11 @@ def enableService(
# If meta service, process and rebuild idService & idTransport
try:
res = userServiceManager().getService(
res = UserServiceManager().getService(
request.user, request.os, request.ip, idService, idTransport, doTest=False
)
scrambler = cryptoManager().randomString(32)
password = cryptoManager().symCrypt(webPassword(request), scrambler)
scrambler = CryptoManager().randomString(32)
password = CryptoManager().symCrypt(webPassword(request), scrambler)
userService, trans = res[1], res[3]
@ -470,7 +475,7 @@ def enableService(
# error += ' (code {0:04X})'.format(e.code)
error = gettext(
'Your service is being created, please, wait for a few seconds while we complete it.)'
) + '({}%)'.format(int(e.code * 25))
) + f'({e.code*25}%)'
except MaxServicesReachedError:
logger.info('Number of service reached MAX for service pool "%s"', idService)
error = errors.errorString(errors.MAX_SERVICES_REACHED)

View File

@ -38,7 +38,7 @@ from django.utils.translation import gettext as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt
import uds.web.util.errors as errors
from uds.web.util import errors
from uds.core import auths
from uds.core.auths.auth import (
webLogin,
@ -47,9 +47,9 @@ from uds.core.auths.auth import (
authLogLogin,
getUDSCookie,
)
from uds.core.managers import userServiceManager, cryptoManager
from uds.core.managers.user_service import UserServiceManager
from uds.core.managers.crypto import CryptoManager
from uds.core.services.exceptions import ServiceNotReadyError
from uds.core.util import os_detector as OsDetector
from uds.core.util import html
from uds.core.util.state import State
from uds.core.util.model import processUuid
@ -116,14 +116,14 @@ def authCallback_stage2(
result = authenticateViaCallback(authenticator, params, request)
os = OsDetector.getOsFromUA(request.META['HTTP_USER_AGENT'])
# os = OsDetector.getOsFromUA(request.META['HTTP_USER_AGENT'])
if result.url:
raise auths.exceptions.Redirect(result.url)
if result.user is None:
authLogLogin(
request, authenticator, '{0}'.format(params), 'Invalid at auth callback'
request, authenticator, f'{params}', 'Invalid at auth callback'
)
raise auths.exceptions.InvalidUserException()
@ -222,10 +222,10 @@ def ticketAuth(
auth = data['auth']
realname = data['realname']
poolUuid = data['servicePool']
password = cryptoManager().decrypt(data['password'])
password = CryptoManager().decrypt(data['password'])
except Exception:
logger.error('Ticket stored is not valid')
raise auths.exceptions.InvalidUserException()
raise auths.exceptions.InvalidUserException() from None
auth = Authenticator.objects.get(uuid=auth)
# If user does not exists in DB, create it right now
@ -264,7 +264,7 @@ def ticketAuth(
# Check if servicePool is part of the ticket
if poolUuid:
# Request service, with transport = None so it is automatic
res = userServiceManager().getService(
res = UserServiceManager().getService(
request.user, request.os, request.ip, poolUuid, None, False
)
_, userService, _, transport, _ = res
@ -287,7 +287,7 @@ def ticketAuth(
# Now ensure uds cookie is at response
getUDSCookie(request, response, True)
return response
except ServiceNotReadyError as e:
except ServiceNotReadyError:
return errors.errorView(request, errors.SERVICE_NOT_READY)
except TicketStore.InvalidTicket:
return errors.errorView(request, errors.RELOAD_NOT_SUPPORTED)

View File

@ -32,8 +32,6 @@ import json
import logging
import typing
from django.utils.translation import gettext as _
from django.urls import reverse
from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache
@ -45,7 +43,6 @@ from uds.models import Transport, Image
from uds.core.util import log
from uds.core.services.exceptions import ServiceNotReadyError
from uds.web.util import errors
from uds.web.util import services
# Not imported at runtime, just for type checking
@ -91,10 +88,7 @@ def transportOwnLink(
return HttpResponse(content=json.dumps(response), content_type='application/json')
# Will never reach this
return errors.errorView(request, errors.UNKNOWN_ERROR)
# pylint: disable=unused-argument
@cache_page(3600, key_prefix='img', cache='memory')
def transportIcon(request: 'ExtendedHttpRequest', idTrans: str) -> HttpResponse:
try: