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

Updating user interface, and more refactor

This commit is contained in:
Adolfo Gómez García 2024-01-17 20:00:22 +01:00
parent cc89e7f5db
commit 98d0306846
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
36 changed files with 342 additions and 224 deletions

View File

@ -232,7 +232,7 @@ class OAuth2Authenticator(auths.Authenticator):
if self.publicKey.value.strip() == '':
return []
return [cert.public_key() for cert in fields.get_vertificates_from_field(self.publicKey)]
return [cert.public_key() for cert in fields.get_certificates_from_field(self.publicKey)]
def _code_verifier_and_challenge(self) -> tuple[str, str]:
"""Generate a code verifier and a code challenge for PKCE

View File

@ -113,13 +113,13 @@ class ServiceProvider(module.Module):
# : Default is return the GlobalConfig value of GlobalConfig.MAX_PREPARING_SERVICES
# : Note: this variable can be either a fixed value (integer, string) or a Gui text field (with a .value property)
# : Note: This cannot be renamed with out a "migration", because it's used at database
max_preparing_services: typing.Optional[typing.Union[int, gui.InputField]] = None
max_preparing_services: typing.Optional[typing.Union[int, gui.NumericField]] = None
# : This defines the maximum number of concurrent services that should be in state "removing" for this provider
# : Default is return the GlobalConfig value of GlobalConfig.MAX_REMOVING_SERVICES
# : Note: this variable can be either a fixed value (integer, string) or a Gui text field (with a .value property)
# : Note: This cannot be renamed with out a "migration", because it's used at database
max_removing_services: typing.Optional[typing.Union[int, gui.InputField]] = None
max_removing_services: typing.Optional[typing.Union[int, gui.NumericField]] = None
# : This defines if the limits (max.. vars) should be taken into accout or simply ignored
# : Default is return the GlobalConfig value of GlobalConfig.IGNORE_LIMITS
@ -197,22 +197,22 @@ class ServiceProvider(module.Module):
if val is None:
val = self.max_preparing_services = consts.system.DEFAULT_MAX_PREPARING_SERVICES
if isinstance(val, gui.InputField):
retVal = int(val.value)
if isinstance(val, gui.NumericField):
ret_val = val.as_int()
else:
retVal = val
return retVal if retVal > 0 else 1
ret_val = val
return max(ret_val, 1) # Ensure that is at least 1
def get_max_removing_services(self) -> int:
val = self.max_removing_services
if val is None:
val = self.max_removing_services = 15
if isinstance(val, gui.InputField):
retVal = int(val.value)
if isinstance(val, gui.NumericField):
ret_val = val.as_int()
else:
retVal = val
return retVal if retVal > 0 else 1
ret_val = val
return max(ret_val, 1)
def get_ignore_limits(self) -> bool:
val = self.ignore_limits

View File

@ -125,7 +125,7 @@ class FieldInfo:
tooltip: str
order: int
type: FieldType
stored_field_name: typing.Optional[str] = None
old_field_name: typing.Optional[str] = None
readonly: typing.Optional[bool] = None
value: typing.Union[collections.abc.Callable[[], typing.Any], typing.Any] = None
default: typing.Optional[typing.Union[collections.abc.Callable[[], str], str]] = None

View File

@ -279,13 +279,13 @@ class gui:
_fields_info: types.ui.FieldInfo
def __init__(
self, label: str, type: types.ui.FieldType, stored_field_name: typing.Optional[str], **kwargs
self, label: str, type: types.ui.FieldType, old_field_name: typing.Optional[str], **kwargs
) -> None:
default = kwargs.get('default')
# Length is not used on some kinds of fields, but present in all anyway
# This property only affects in "modify" operations
self._fields_info = types.ui.FieldInfo(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
order=kwargs.get('order') or 0,
label=label,
tooltip=kwargs.get('tooltip') or '',
@ -321,11 +321,11 @@ class gui:
def is_serializable(self) -> bool:
return True
def stored_field_name(self) -> typing.Optional[str]:
def old_field_name(self) -> typing.Optional[str]:
"""
Returns the name of the field
"""
return self._fields_info.stored_field_name
return self._fields_info.old_field_name
@property
def value(self) -> typing.Any:
@ -360,7 +360,7 @@ class gui:
alter original values.
"""
data = typing.cast(dict, self._fields_info.as_dict())
for i in ('value', 'stored_field_name'):
for i in ('value', 'old_field_name'):
if i in data:
del data[i] # We don't want to send some values on gui_description
data['label'] = gettext(data['label']) if data['label'] else ''
@ -466,10 +466,10 @@ class gui:
value: typing.Optional[str] = None,
pattern: typing.Union[str, types.ui.FieldPatternType] = types.ui.FieldPatternType.NONE,
lines: int = 0,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
length=length,
readonly=readonly,
@ -573,7 +573,7 @@ class gui:
dict[str, str],
None,
] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
label=label,
@ -585,7 +585,7 @@ class gui:
tab=tab,
default=default,
value=value,
stored_field_name=stored_field_name,
old_field_name=old_field_name,
)
# Update parent type
self.type = types.ui.FieldType.TEXT_AUTOCOMPLETE
@ -635,10 +635,10 @@ class gui:
value: typing.Optional[int] = None,
min_value: typing.Optional[int] = None,
max_value: typing.Optional[int] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
length=length,
readonly=readonly,
@ -686,10 +686,10 @@ class gui:
typing.Union[collections.abc.Callable[[], datetime.date], datetime.date]
] = None,
value: typing.Optional[typing.Union[str, datetime.date]] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
length=length,
readonly=readonly,
@ -774,10 +774,10 @@ class gui:
tab: typing.Optional[typing.Union[str, types.ui.Tab]] = None,
default: typing.Union[collections.abc.Callable[[], str], str] = '',
value: typing.Optional[str] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
):
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
length=length,
readonly=readonly,
@ -838,10 +838,10 @@ class gui:
default: typing.Any = None, # May be also callable
value: typing.Any = None,
serializable: bool = False,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
order=order,
default=default,
@ -892,10 +892,10 @@ class gui:
tab: typing.Optional[typing.Union[str, types.ui.Tab]] = None,
default: typing.Union[collections.abc.Callable[[], bool], bool] = False,
value: typing.Optional[bool] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
):
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
readonly=readonly,
order=order,
@ -1034,10 +1034,10 @@ class gui:
tab: typing.Optional[typing.Union[str, types.ui.Tab]] = None,
default: typing.Union[collections.abc.Callable[[], str], str, None] = None,
value: typing.Optional[str] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
readonly=readonly,
order=order,
@ -1087,10 +1087,10 @@ class gui:
tab: typing.Optional[typing.Union[str, types.ui.Tab]] = None,
default: typing.Union[collections.abc.Callable[[], str], str, None] = None,
value: typing.Optional[str] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
):
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
readonly=readonly,
order=order,
@ -1166,10 +1166,10 @@ class gui:
collections.abc.Callable[[], str], collections.abc.Callable[[], list[str]], list[str], str, None
] = None,
value: typing.Optional[collections.abc.Iterable[str]] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
):
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
readonly=readonly,
order=order,
@ -1235,10 +1235,10 @@ class gui:
collections.abc.Callable[[], str], collections.abc.Callable[[], list[str]], list[str], str, None
] = None,
value: typing.Optional[collections.abc.Iterable[str]] = None,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
stored_field_name=stored_field_name,
old_field_name=old_field_name,
label=label,
readonly=readonly,
order=order,
@ -1269,10 +1269,10 @@ class gui:
self,
label: str,
default: str,
stored_field_name: typing.Optional[str] = None,
old_field_name: typing.Optional[str] = None,
) -> None:
super().__init__(
label=label, default=default, type=types.ui.FieldType.INFO, stored_field_name=stored_field_name
label=label, default=default, type=types.ui.FieldType.INFO, old_field_name=old_field_name
)
@ -1457,8 +1457,10 @@ class UserInterface(metaclass=UserInterfaceAbstract):
types.ui.FieldType.INFO: lambda x: None,
}
# Any unexpected type will raise an exception
# Note that currently, we will store old field name on db
# to allow "backwards" migration if needed, but will be removed on a future version
arr = [
(field.stored_field_name() or field_name, field.type.name, fw_converters[field.type](field))
(field.old_field_name() or field_name, field.type.name, fw_converters[field.type](field))
for field_name, field in self._gui.items()
if fw_converters[field.type](field) is not None
]
@ -1489,7 +1491,7 @@ class UserInterface(metaclass=UserInterfaceAbstract):
if not values.startswith(SERIALIZATION_HEADER):
# Unserialize with old method
self.deserialize_old_fields(values)
self.deserialize_from_old_format(values)
return
# For future use, right now we only have one version
@ -1504,7 +1506,7 @@ class UserInterface(metaclass=UserInterfaceAbstract):
arr = _unserialize(values)
# Dict of translations from stored_field_name to field_name
# Dict of translations from old_field_name to field_name
field_names_translations: dict[str, str] = self._get_fieldname_translations()
# Set all values to defaults ones
@ -1539,7 +1541,7 @@ class UserInterface(metaclass=UserInterfaceAbstract):
if fld_name in field_names_translations:
fld_name = field_names_translations[
fld_name
] # Convert stored_field_name to field_name if needed
] # Convert old field name to new one if needed
if fld_name not in self._gui:
logger.warning('Field %s not found in form', fld_name)
continue
@ -1552,7 +1554,7 @@ class UserInterface(metaclass=UserInterfaceAbstract):
continue
self._gui[fld_name].value = converters[field_type](fld_value)
def deserialize_old_fields(self, values: bytes) -> None:
def deserialize_from_old_format(self, values: bytes) -> None:
"""
This method deserializes the values previously obtained using
:py:meth:`serializeForm`, and stores
@ -1645,12 +1647,12 @@ class UserInterface(metaclass=UserInterfaceAbstract):
return found_errors
def _get_fieldname_translations(self) -> dict[str, str]:
# Dict of translations from stored_field_name to field_name
# Dict of translations from old_field_name to field_name
field_names_translations: dict[str, str] = {}
for fld_name, fld in self._gui.items():
fld_stored_field_name = fld.stored_field_name()
if fld_stored_field_name and fld_stored_field_name != fld_name:
field_names_translations[fld_stored_field_name] = fld_name
fld_old_field_name = fld.old_field_name()
if fld_old_field_name and fld_old_field_name != fld_name:
field_names_translations[fld_old_field_name] = fld_name
return field_names_translations

View File

@ -83,7 +83,7 @@ def tunnel_field() -> ui.gui.ChoiceField:
required=True,
choices=functools.partial(_server_group_values, [types.servers.ServerType.TUNNEL]),
tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnel',
old_field_name='tunnel',
)
@ -117,7 +117,7 @@ def server_group_field(
_server_group_values, valid_types, subtype
), # So it gets evaluated at runtime
tab=tab,
stored_field_name='serverGroup',
old_field_name='serverGroup',
)
@ -143,12 +143,12 @@ def tunnel_ticket_validity_field() -> ui.gui.NumericField:
required=True,
min_value=60,
tab=types.ui.Tab.ADVANCED,
stored_field_name='ticketValidity',
old_field_name='ticketValidity',
)
# Tunnel wait time (for uds client related tunnels)
def tunnel_wait_time(order: int = 2) -> ui.gui.NumericField:
def tunnel_wait_time_field(order: int = 2) -> ui.gui.NumericField:
return ui.gui.NumericField(
length=3,
label=_('Tunnel wait time'),
@ -159,12 +159,12 @@ def tunnel_wait_time(order: int = 2) -> ui.gui.NumericField:
tooltip=_('Maximum time, in seconds, to wait before disable new connections on client tunnel listener'),
required=True,
tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnelWait',
old_field_name='tunnelWait',
)
# Get certificates from field
def get_vertificates_from_field(
def get_certificates_from_field(
field: ui.gui.TextField, field_value: typing.Optional[str] = None
) -> list['Certificate']:
# Get certificates in self.publicKey.value, encoded as PEM
@ -188,28 +188,149 @@ def get_vertificates_from_field(
return certs
# For services
# Timeout
def timeout_field(
default: int = 3,
order: typing.Optional[int] = None, tab: 'types.ui.Tab|str|None' = None, old_field_name: typing.Optional[str] = None
) -> ui.gui.NumericField:
return ui.gui.NumericField(
length=3,
label=_('Timeout'),
default=default,
order=order or 90,
tooltip=_('Timeout in seconds for connections to server'),
required=True,
min_value=1,
tab=tab or types.ui.Tab.ADVANCED,
old_field_name=old_field_name,
)
def get_basename_field(order: typing.Optional[int] = None) -> ui.gui.TextField:
# Basename field
def basename_field(order: typing.Optional[int] = None, tab: 'types.ui.Tab|str|None' = None) -> ui.gui.TextField:
return ui.gui.TextField(
label=_('Base Name'),
order=order or 32,
tooltip=_('Base name for clones from this service'),
tab=_('Service'),
tab=tab,
required=True,
stored_field_name='baseName',
old_field_name='baseName',
)
def get_lenname_field(order: typing.Optional[int] = None) -> ui.gui.NumericField:
# Length of name field
def lenname_field(
order: typing.Optional[int] = None, tab: 'types.ui.Tab|str|None' = None
) -> ui.gui.NumericField:
return ui.gui.NumericField(
length=1,
label=_('Name Length'),
default=3,
order=order or 33,
tooltip=_('Size of numeric part for the names of these services'),
tab=_('Service'),
tooltip=_('Size of numeric part for the names derived from this service'),
tab=tab,
required=True,
stored_field_name='lenName',
old_field_name='lenName',
)
# Max preparing services field
def max_preparing_services_field(
order: typing.Optional[int] = None, tab: typing.Optional[types.ui.Tab] = None
) -> ui.gui.NumericField:
# Advanced tab
return ui.gui.NumericField(
length=3,
label=_('Creation concurrency'),
default=30,
min_value=1,
max_value=65536,
order=order or 50,
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=tab or types.ui.Tab.ADVANCED,
old_field_name='maxPreparingServices',
)
def max_removing_services_field(
order: typing.Optional[int] = None, tab: 'types.ui.Tab|str|None' = None
) -> ui.gui.NumericField:
return ui.gui.NumericField(
length=3,
label=_('Removal concurrency'),
default=15,
min_value=1,
max_value=65536,
order=order or 51,
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=tab or types.ui.Tab.ADVANCED,
old_field_name='maxRemovingServices',
)
def remove_duplicates_field(
order: typing.Optional[int] = None, tab: 'types.ui.Tab|str|None' = None
) -> ui.gui.CheckBoxField:
return ui.gui.CheckBoxField(
label=_('Remove found duplicates'),
default=True,
order=order or 102,
tooltip=_('If active, found duplicates vApps for this service will be removed'),
tab=tab or types.ui.Tab.ADVANCED,
old_field_name='removeDuplicates',
)
def soft_shutdown_field(
order: typing.Optional[int] = None,
tab: 'types.ui.Tab|str|None' = None,
old_field_name: typing.Optional[str] = None,
) -> ui.gui.CheckBoxField:
return ui.gui.CheckBoxField(
label=_('Try SOFT Shutdown first'),
default=False,
order=order or 103,
tooltip=_(
'If active, UDS will try to shutdown (soft) the machine using Nutanix ACPI. Will delay 30 seconds the power off of hanged machines.'
),
tab=tab or types.ui.Tab.ADVANCED,
old_field_name=old_field_name,
)
def keep_on_access_error_field(
order: typing.Optional[int] = None,
tab: 'types.ui.Tab|str|None' = None,
old_field_name: typing.Optional[str] = None,
) -> ui.gui.CheckBoxField:
return ui.gui.CheckBoxField(
label=_('Keep on error'),
value=False,
order=order or 104,
tooltip=_('If active, access errors found on machine will not be considered errors.'),
tab=tab or types.ui.Tab.ADVANCED,
old_field_name=old_field_name,
)
def macs_range_field(
default: str,
order: typing.Optional[int] = None,
tab: 'types.ui.Tab|str|None' = None,
readonly: bool = False,
) -> ui.gui.TextField:
return ui.gui.TextField(
length=36,
label=_('Macs range'),
default=default,
order=order or 91,
readonly=readonly,
tooltip=_('Range of valid macs for created machines. Must be in the range {default}').format(
default=default
),
required=True,
tab=tab or types.ui.Tab.ADVANCED,
old_field_name='macsRange',
)

View File

@ -43,11 +43,11 @@ class UniqueGIDGenerator(UniqueIDGenerator):
def __init__(self, owner, baseName=None):
super().__init__('id', owner, baseName)
def __toName(self, seq: int) -> str:
def _to_name(self, seq: int) -> str:
if seq == -1:
raise KeyError('No more GIDS available.')
return f'{self._baseName}{seq:08d}'
return f'{self._base_name}{seq:08d}'
# return "%s%0*d" % (self._baseName, 8, seq)
def get(self, rangeStart: int = 0, rangeEnd: int = MAX_SEQ) -> str: # type: ignore
return self.__toName(super().get())
return self._to_name(super().get())

View File

@ -54,21 +54,19 @@ class CreateNewIdException(Exception):
class UniqueIDGenerator:
__slots__ = ('_owner', '_baseName')
__slots__ = ('_owner', '_base_name')
# owner is the owner of the UniqueID
_owner: str
# base name for filtering unique ids. (I.e. "mac", "ip", "ipv6" ....)
_baseName: str
_base_name: str
def __init__(
self, type_name: str, owner: str, baseName: typing.Optional[str] = None
):
def __init__(self, type_name: str, owner: str, baseName: typing.Optional[str] = None):
self._owner = owner + type_name
self._baseName = 'uds' if baseName is None else baseName
self._base_name = 'uds' if baseName is None else baseName
def setBaseName(self, newBaseName: str):
self._baseName = newBaseName
self._base_name = newBaseName
def __filter(
self, rangeStart: int, rangeEnd: int = MAX_SEQ, forUpdate: bool = False
@ -76,9 +74,7 @@ class UniqueIDGenerator:
# Order is defined on UniqueId model, and is '-seq' by default (so this gets items in sequence order)
# if not for update, do not use the clause :)
obj = UniqueId.objects.select_for_update() if forUpdate else UniqueId.objects
return obj.filter(
basename=self._baseName, seq__gte=rangeStart, seq__lte=rangeEnd
)
return obj.filter(basename=self._base_name, seq__gte=rangeStart, seq__lte=rangeEnd)
def get(self, rangeStart: int = 0, rangeEnd: int = MAX_SEQ) -> int:
"""
@ -127,7 +123,7 @@ class UniqueIDGenerator:
# will get an "duplicate key error",
UniqueId.objects.create(
owner=self._owner,
basename=self._baseName,
basename=self._base_name,
seq=seq,
assigned=True,
stamp=stamp,
@ -150,13 +146,13 @@ class UniqueIDGenerator:
def transfer(self, seq: int, toUidGen: 'UniqueIDGenerator') -> bool:
self.__filter(0, forUpdate=True).filter(owner=self._owner, seq=seq).update(
owner=toUidGen._owner, # pylint: disable=protected-access
basename=toUidGen._baseName, # pylint: disable=protected-access
basename=toUidGen._base_name, # pylint: disable=protected-access
stamp=sql_stamp_seconds(),
)
return True
def free(self, seq) -> None:
logger.debug('Freeing seq %s from %s (%s)', seq, self._owner, self._baseName)
logger.debug('Freeing seq %s from %s (%s)', seq, self._owner, self._base_name)
with transaction.atomic():
flt = (
self.__filter(0, forUpdate=True)
@ -164,9 +160,9 @@ class UniqueIDGenerator:
.update(owner='', assigned=False, stamp=sql_stamp_seconds())
)
if flt > 0:
self.__purge()
self._purge()
def __purge(self) -> None:
def _purge(self) -> None:
logger.debug('Purging UniqueID database')
try:
last: UniqueId = self.__filter(0, forUpdate=False).filter(assigned=True)[0] # type: ignore # Slicing is not supported by pylance right now
@ -176,21 +172,17 @@ class UniqueIDGenerator:
# logger.exception('Error here')
seq = 0
with transaction.atomic():
self.__filter(
seq
).delete() # Clean ups all unassigned after last assigned in this range
self.__filter(seq).delete() # Clean ups all unassigned after last assigned in this range
def release(self) -> None:
UniqueId.objects.select_for_update().filter(owner=self._owner).update(
assigned=False, owner='', stamp=sql_stamp_seconds()
) # @UndefinedVariable
self.__purge()
)
self._purge()
def releaseOlderThan(self, stamp=None) -> None:
def release_older_than(self, stamp: typing.Optional[int] = None) -> None:
stamp = sql_stamp_seconds() if stamp is None else stamp
UniqueId.objects.select_for_update().filter(
owner=self._owner, stamp__lt=stamp
).update(
UniqueId.objects.select_for_update().filter(owner=self._owner, stamp__lt=stamp).update(
assigned=False, owner='', stamp=stamp
) # @UndefinedVariable
self.__purge()
)
self._purge()

View File

@ -44,10 +44,10 @@ class UniqueMacGenerator(UniqueIDGenerator):
def __init__(self, owner: str) -> None:
super().__init__('mac', owner, '\tmac')
def __toInt(self, mac: str) -> int:
def _to_int(self, mac: str) -> int:
return int(mac.replace(':', ''), 16)
def __toMac(self, seq: int) -> str:
def _to_mac_addr(self, seq: int) -> str:
if seq == -1: # No mor macs available
return '00:00:00:00:00:00'
return re.sub(r"(..)", r"\1:", f'{seq:012X}')[:-1]
@ -55,12 +55,12 @@ class UniqueMacGenerator(UniqueIDGenerator):
# noinspection PyMethodOverriding
def get(self, macRange: str) -> str: # type: ignore # pylint: disable=arguments-differ
firstMac, lastMac = macRange.split('-')
return self.__toMac(super().get(self.__toInt(firstMac), self.__toInt(lastMac)))
return self._to_mac_addr(super().get(self._to_int(firstMac), self._to_int(lastMac)))
def transfer(self, mac: str, toUMgen: 'UniqueMacGenerator'): # type: ignore # pylint: disable=arguments-renamed
super().transfer(self.__toInt(mac), toUMgen)
super().transfer(self._to_int(mac), toUMgen)
def free(self, mac: str) -> None: # type: ignore # pylint: disable=arguments-renamed
super().free(self.__toInt(mac))
super().free(self._to_int(mac))
# Release is inherited, no mod needed

View File

@ -44,7 +44,7 @@ class UniqueNameGenerator(UniqueIDGenerator):
def __init__(self, owner):
super().__init__('name', owner)
def __toName(self, seq: int, length: int) -> str:
def _to_name(self, seq: int, length: int) -> str:
"""Converts a sequence number to a name
Args:
@ -56,18 +56,18 @@ class UniqueNameGenerator(UniqueIDGenerator):
"""
if seq == -1:
raise KeyError('No more names available. Please, increase service digits.')
return f'{self._baseName}{seq:0{length}d}'
return f'{self._base_name}{seq:0{length}d}'
def get(self, baseName: str, length: int = 5) -> str: # type: ignore # pylint: disable=arguments-differ,arguments-renamed
self.setBaseName(baseName)
minVal = 0
maxVal = 10**length - 1
return self.__toName(super().get(minVal, maxVal), length)
return self._to_name(super().get(minVal, maxVal), length)
def transfer(self, baseName: str, name: str, toUNGen: 'UniqueNameGenerator') -> None: # type: ignore # pylint: disable=arguments-differ
self.setBaseName(baseName)
super().transfer(int(name[len(self._baseName) :]), toUNGen)
super().transfer(int(name[len(self._base_name) :]), toUNGen)
def free(self, baseName: str, name: str) -> None: # type: ignore # pylint: disable=arguments-differ
self.setBaseName(baseName)
super().free(int(name[len(self._baseName) :]))
super().free(int(name[len(self._base_name) :]))

View File

@ -103,11 +103,11 @@ def package_relative_file(moduleName: str, fileName: str) -> str:
return fileName
def timestampAsStr(stamp, format_='SHORT_DATETIME_FORMAT'):
def timestamp_as_str(stamp: float, format_: typing.Optional[str]=None):
"""
Converts a timestamp to date string using specified format (DJANGO format such us SHORT_DATETIME_FORMAT..)
"""
format_ = formats.get_format(format_)
format_ = formats.get_format(format_ or 'SHORT_DATETIME_FORMAT')
return filters.date(datetime.datetime.fromtimestamp(stamp), format_)

View File

@ -118,7 +118,7 @@ class EmailNotifier(messaging.Notifier):
tooltip=_('Email address that will be used as sender'),
required=True,
tab=_('Config'),
stored_field_name='fromEmail'
old_field_name='fromEmail'
)
to_email = gui.TextField(
@ -128,7 +128,7 @@ class EmailNotifier(messaging.Notifier):
tooltip=_('Email address that will be used as recipient'),
required=True,
tab=_('Config'),
stored_field_name='toEmail'
old_field_name='toEmail'
)
enable_html = gui.CheckBoxField(
@ -137,7 +137,7 @@ class EmailNotifier(messaging.Notifier):
tooltip=_('Enable HTML in emails'),
default=True,
tab=_('Config'),
stored_field_name='enableHTML'
old_field_name='enableHTML'
)
def initialize(self, values: 'Module.ValuesType' = None):

View File

@ -88,7 +88,7 @@ class TelegramNotifier(messaging.Notifier):
required=True,
default='',
tab=_('Telegram'),
stored_field_name='accessToken',
old_field_name='accessToken',
)
# Secret key used to validate join and subscribe requests
@ -115,7 +115,7 @@ class TelegramNotifier(messaging.Notifier):
min_value=60,
max_value=86400,
tab=_('Telegram'),
stored_field_name='checkDelay',
old_field_name='checkDelay',
)
def initialize(self, values: 'Module.ValuesType' = None):

View File

@ -162,9 +162,9 @@ class PoolPerformanceReport(StatsReport):
reportData.append(
{
'name': p[1],
'date': utils.timestampAsStr(interval[0], 'SHORT_DATETIME_FORMAT')
'date': utils.timestamp_as_str(interval[0], 'SHORT_DATETIME_FORMAT')
+ ' - '
+ utils.timestampAsStr(interval[1], 'SHORT_DATETIME_FORMAT'),
+ utils.timestamp_as_str(interval[1], 'SHORT_DATETIME_FORMAT'),
'users': len(q),
'accesses': accesses,
}

View File

@ -133,9 +133,9 @@ class StatsReportLogin(StatsReport):
data.append((key, val))
reportData.append(
{
'date': utils.timestampAsStr(interval[0], 'SHORT_DATETIME_FORMAT')
'date': utils.timestamp_as_str(interval[0], 'SHORT_DATETIME_FORMAT')
+ ' - '
+ utils.timestampAsStr(interval[1], 'SHORT_DATETIME_FORMAT'),
+ utils.timestamp_as_str(interval[1], 'SHORT_DATETIME_FORMAT'),
'users': val,
}
)

View File

@ -144,7 +144,7 @@ class OVirtProvider(
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -156,7 +156,7 @@ class OVirtProvider(
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -151,7 +151,7 @@ class OGProvider(ServiceProvider):
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -163,7 +163,7 @@ class OGProvider(ServiceProvider):
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -123,7 +123,7 @@ class OpenNebulaProvider(ServiceProvider): # pylint: disable=too-many-public-me
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -135,7 +135,7 @@ class OpenNebulaProvider(ServiceProvider): # pylint: disable=too-many-public-me
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -153,7 +153,7 @@ class OpenStackProvider(ServiceProvider):
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -165,7 +165,7 @@ class OpenStackProvider(ServiceProvider):
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -169,7 +169,7 @@ class ProviderLegacy(ServiceProvider):
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -181,7 +181,7 @@ class ProviderLegacy(ServiceProvider):
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -143,7 +143,7 @@ class LiveService(services.Service):
tooltip=_('Service availability zones'),
required=True,
readonly=True,
stored_field_name='availabilityZone',
old_field_name='availabilityZone',
)
volume = gui.ChoiceField(
label=_('Volume'),

View File

@ -147,4 +147,4 @@ class ProxmoxVmidReleaser(jobs.Job):
def run(self) -> None:
logger.debug('Proxmox Vmid releader running')
gen = UniqueIDGenerator('vmid', 'proxmox', 'proxmox')
gen.releaseOlderThan(sql_stamp_seconds() - MAX_VMID_LIFE_SECS)
gen.release_older_than(sql_stamp_seconds() - MAX_VMID_LIFE_SECS)

View File

@ -108,7 +108,7 @@ class ProxmoxProvider(
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -120,7 +120,7 @@ class ProxmoxProvider(
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
timeout = gui.NumericField(

View File

@ -134,7 +134,7 @@ class XenProvider(ServiceProvider): # pylint: disable=too-many-public-methods
tooltip=_('Maximum number of concurrently creating VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxPreparingServices',
old_field_name='maxPreparingServices',
)
max_removing_services = gui.NumericField(
length=3,
@ -146,7 +146,7 @@ class XenProvider(ServiceProvider): # pylint: disable=too-many-public-methods
tooltip=_('Maximum number of concurrently removing VMs'),
required=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='maxRemovingServices',
old_field_name='maxRemovingServices',
)
macsRange = gui.TextField(

View File

@ -78,7 +78,7 @@ class HTML5RDPTransport(transports.Transport):
'If checked, UDS will use Glyptodon Enterprise Tunnel for HTML tunneling instead of UDS Tunnel'
),
tab=types.ui.Tab.TUNNEL,
stored_field_name='useGlyptodonTunnel',
old_field_name='useGlyptodonTunnel',
)
force_empty_creds = ui.gui.CheckBoxField(
@ -86,21 +86,21 @@ class HTML5RDPTransport(transports.Transport):
order=3,
tooltip=_('If checked, the credentials used to connect will be emtpy'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='useEmptyCreds',
old_field_name='useEmptyCreds',
)
forced_username = ui.gui.TextField(
label=_('Username'),
order=4,
tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
old_field_name='fixedName',
)
forced_password = ui.gui.PasswordField(
label=_('Password'),
order=5,
tooltip=_('If not empty, this password will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedPassword',
old_field_name='fixedPassword',
)
force_no_domain = ui.gui.CheckBoxField(
label=_('Without Domain'),
@ -109,14 +109,14 @@ class HTML5RDPTransport(transports.Transport):
'If checked, the domain part will always be emptied (to connecto to xrdp for example is needed)'
),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='withoutDomain',
old_field_name='withoutDomain',
)
forced_domain = ui.gui.TextField(
label=_('Domain'),
order=7,
tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedDomain',
old_field_name='fixedDomain',
)
wallpaper = ui.gui.CheckBoxField(
label=_('Show wallpaper'),
@ -125,21 +125,21 @@ class HTML5RDPTransport(transports.Transport):
'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='wallpaper',
old_field_name='wallpaper',
)
allow_destop_composition = ui.gui.CheckBoxField(
label=_('Allow Desk.Comp.'),
order=19,
tooltip=_('If checked, desktop composition will be allowed'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='desktopComp',
old_field_name='desktopComp',
)
smooth = ui.gui.CheckBoxField(
label=_('Font Smoothing'),
order=20,
tooltip=_('If checked, fonts smoothing will be allowed (windows clients only)'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='smooth',
old_field_name='smooth',
)
enable_audio = ui.gui.CheckBoxField(
label=_('Enable Audio'),
@ -147,7 +147,7 @@ class HTML5RDPTransport(transports.Transport):
tooltip=_('If checked, the audio will be redirected to remote session (if client browser supports it)'),
tab=types.ui.Tab.PARAMETERS,
default=True,
stored_field_name='enableAudio',
old_field_name='enableAudio',
)
enable_microphone = ui.gui.CheckBoxField(
label=_('Enable Microphone'),
@ -156,7 +156,7 @@ class HTML5RDPTransport(transports.Transport):
'If checked, the microphone will be redirected to remote session (if client browser supports it)'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableAudioInput',
old_field_name='enableAudioInput',
)
enable_printing = ui.gui.CheckBoxField(
label=_('Enable Printing'),
@ -165,7 +165,7 @@ class HTML5RDPTransport(transports.Transport):
'If checked, the printing will be redirected to remote session (if client browser supports it)'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='enablePrinting',
old_field_name='enablePrinting',
)
enable_file_sharing = ui.gui.ChoiceField(
label=_('File Sharing'),
@ -179,7 +179,7 @@ class HTML5RDPTransport(transports.Transport):
{'id': 'true', 'text': _('Enable file sharing')},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableFileSharing',
old_field_name='enableFileSharing',
)
enable_clipboard = ui.gui.ChoiceField(
label=_('Clipboard'),
@ -193,7 +193,7 @@ class HTML5RDPTransport(transports.Transport):
{'id': 'enabled', 'text': _('Enable clipboard')},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='enableClipboard',
old_field_name='enableClipboard',
)
server_layout = ui.gui.ChoiceField(
@ -224,7 +224,7 @@ class HTML5RDPTransport(transports.Transport):
],
default='-',
tab=types.ui.Tab.PARAMETERS,
stored_field_name='serverLayout',
old_field_name='serverLayout',
)
ticket_validity = fields.tunnel_ticket_validity_field()
@ -247,7 +247,7 @@ class HTML5RDPTransport(transports.Transport):
],
default='true',
tab=types.ui.Tab.ADVANCED,
stored_field_name='forceNewWindow',
old_field_name='forceNewWindow',
)
security = ui.gui.ChoiceField(
@ -277,7 +277,7 @@ class HTML5RDPTransport(transports.Transport):
],
default='any',
tab=types.ui.Tab.ADVANCED,
stored_field_name='security',
old_field_name='security',
)
rdp_port = ui.gui.NumericField(
@ -288,7 +288,7 @@ class HTML5RDPTransport(transports.Transport):
required=True, #: Numeric fields have always a value, so this not really needed
default=3389,
tab=types.ui.Tab.ADVANCED,
stored_field_name='rdpPort',
old_field_name='rdpPort',
)
custom_glyptodon_path = ui.gui.TextField(
@ -301,7 +301,7 @@ class HTML5RDPTransport(transports.Transport):
length=128,
required=False,
tab=types.ui.Tab.ADVANCED,
stored_field_name='customGEPath',
old_field_name='customGEPath',
)
def initialize(self, values: 'Module.ValuesType'):

View File

@ -79,7 +79,7 @@ class HTML5SSHTransport(transports.Transport):
order=20,
tooltip=_('Username for SSH connection authentication.'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='username'
old_field_name='username'
)
# password = gui.PasswordField(
@ -113,7 +113,7 @@ class HTML5SSHTransport(transports.Transport):
'Command to execute on the remote server. If not provided, an interactive shell will be executed.'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshCommand'
old_field_name='sshCommand'
)
enable_file_sharing = HTML5RDPTransport.enable_file_sharing
filesharing_root = gui.TextField(
@ -121,7 +121,7 @@ class HTML5SSHTransport(transports.Transport):
order=32,
tooltip=_('Root path for file sharing. If not provided, root directory will be used.'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='fileSharingRoot'
old_field_name='fileSharingRoot'
)
ssh_port = gui.NumericField(
length=40,
@ -131,14 +131,14 @@ class HTML5SSHTransport(transports.Transport):
tooltip=_('Port of the SSH server.'),
required=True,
tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshPort'
old_field_name='sshPort'
)
ssh_host_key = gui.TextField(
label=_('SSH Host Key'),
order=34,
tooltip=_('Host key of the SSH server. If not provided, no verification of host identity is done.'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='sshHostKey'
old_field_name='sshHostKey'
)
server_keep_alive = gui.NumericField(
length=3,
@ -151,7 +151,7 @@ class HTML5SSHTransport(transports.Transport):
required=True,
min_value=0,
tab=types.ui.Tab.PARAMETERS,
stored_field_name='serverKeepAlive'
old_field_name='serverKeepAlive'
)
ticket_validity = fields.tunnel_ticket_validity_field()

View File

@ -80,14 +80,14 @@ class HTML5VNCTransport(transports.Transport):
order=20,
tooltip=_('Username for VNC connection authentication.'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='username'
old_field_name='username'
)
password = gui.PasswordField(
label=_('Password'),
order=21,
tooltip=_('Password for VNC connection authentication'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='password'
old_field_name='password'
)
vnc_port = gui.NumericField(
@ -98,7 +98,7 @@ class HTML5VNCTransport(transports.Transport):
tooltip=_('Port of the VNC server.'),
required=True,
tab=types.ui.Tab.PARAMETERS,
stored_field_name='vncPort'
old_field_name='vncPort'
)
color_depth = gui.ChoiceField(
@ -115,28 +115,28 @@ class HTML5VNCTransport(transports.Transport):
],
default='-',
tab=types.ui.Tab.PARAMETERS,
stored_field_name='colorDepth'
old_field_name='colorDepth'
)
swap_red_blue = gui.CheckBoxField(
label=_('Swap red/blue'),
order=27,
tooltip=_('Use this if your colours seems incorrect (blue appears red, ..) to swap them.'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='swapRedBlue'
old_field_name='swapRedBlue'
)
cursor = gui.CheckBoxField(
label=_('Remote cursor'),
order=28,
tooltip=_('If set, force to show remote cursor'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='cursor'
old_field_name='cursor'
)
read_only = gui.CheckBoxField(
label=_('Read only'),
order=29,
tooltip=_('If set, the connection will be read only'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='readOnly'
old_field_name='readOnly'
)
ticket_validity = fields.tunnel_ticket_validity_field()

View File

@ -64,21 +64,21 @@ class BaseRDPTransport(transports.Transport):
order=11,
tooltip=_('If checked, the credentials used to connect will be emtpy'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='useEmptyCreds',
old_field_name='useEmptyCreds',
)
forced_username = gui.TextField(
label=_('Username'),
order=12,
tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
old_field_name='fixedName',
)
forced_password = gui.PasswordField(
label=_('Password'),
order=13,
tooltip=_('If not empty, this password will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedPassword',
old_field_name='fixedPassword',
)
force_no_domain = gui.CheckBoxField(
label=_('Without Domain'),
@ -87,14 +87,14 @@ class BaseRDPTransport(transports.Transport):
'If checked, the domain part will always be emptied (to connect to xrdp for example is needed)'
),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='withoutDomain',
old_field_name='withoutDomain',
)
forced_domain = gui.TextField(
label=_('Domain'),
order=15,
tooltip=_('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedDomain',
old_field_name='fixedDomain',
)
allow_smartcards = gui.CheckBoxField(
@ -102,14 +102,14 @@ class BaseRDPTransport(transports.Transport):
order=20,
tooltip=_('If checked, this transport will allow the use of smartcards'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowSmartcards',
old_field_name='allowSmartcards',
)
allow_printers = gui.CheckBoxField(
label=_('Allow Printers'),
order=21,
tooltip=_('If checked, this transport will allow the use of user printers'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowPrinters',
old_field_name='allowPrinters',
)
allow_drives = gui.ChoiceField(
label=_('Local drives policy'),
@ -122,7 +122,7 @@ class BaseRDPTransport(transports.Transport):
{'id': 'true', 'text': 'Allow any drive'},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowDrives',
old_field_name='allowDrives',
)
enforce_drives = gui.TextField(
label=_('Force drives'),
@ -131,7 +131,7 @@ class BaseRDPTransport(transports.Transport):
'Use comma separated values, for example "C:,D:". If drives policy is disallowed, this will be ignored'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='enforceDrives',
old_field_name='enforceDrives',
)
allow_serial_ports = gui.CheckBoxField(
@ -139,7 +139,7 @@ class BaseRDPTransport(transports.Transport):
order=24,
tooltip=_('If checked, this transport will allow the use of user serial ports'),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='allowSerials',
old_field_name='allowSerials',
)
allow_clipboard = gui.CheckBoxField(
label=_('Enable clipboard'),
@ -147,7 +147,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, copy-paste functions will be allowed'),
tab=types.ui.Tab.PARAMETERS,
default=True,
stored_field_name='allowClipboard',
old_field_name='allowClipboard',
)
allow_audio = gui.CheckBoxField(
label=_('Enable sound'),
@ -155,7 +155,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, sound will be redirected.'),
tab=types.ui.Tab.PARAMETERS,
default=True,
stored_field_name='allowAudio',
old_field_name='allowAudio',
)
allow_webcam = gui.CheckBoxField(
label=_('Enable webcam'),
@ -163,7 +163,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, webcam will be redirected (ONLY Windows).'),
tab=types.ui.Tab.PARAMETERS,
default=False,
stored_field_name='allowWebcam',
old_field_name='allowWebcam',
)
allow_usb_redirection = gui.ChoiceField(
label=_('USB redirection'),
@ -180,7 +180,7 @@ class BaseRDPTransport(transports.Transport):
{'id': '{745a17a0-74d3-11d0-b6fe-00a0c90f57da}', 'text': 'HIDs'},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='usbRedirection',
old_field_name='usbRedirection',
)
credssp = gui.CheckBoxField(
@ -189,7 +189,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, will enable Credentials Provider Support)'),
tab=types.ui.Tab.PARAMETERS,
default=True,
stored_field_name='credssp',
old_field_name='credssp',
)
rdp_port = gui.NumericField(
order=30,
@ -199,7 +199,7 @@ class BaseRDPTransport(transports.Transport):
tab=types.ui.Tab.PARAMETERS,
required=True, #: Numeric fields have always a value, so this not really needed
default=3389,
stored_field_name='rdpPort',
old_field_name='rdpPort',
)
screen_size = gui.ChoiceField(
@ -224,7 +224,7 @@ class BaseRDPTransport(transports.Transport):
{'id': '-1x-1', 'text': 'Full screen'},
],
tab=types.ui.Tab.DISPLAY,
stored_field_name='screenSize',
old_field_name='screenSize',
)
color_depth = gui.ChoiceField(
@ -239,7 +239,7 @@ class BaseRDPTransport(transports.Transport):
{'id': '32', 'text': '32'},
],
tab=types.ui.Tab.DISPLAY,
stored_field_name='colorDepth',
old_field_name='colorDepth',
)
wallpaper = gui.CheckBoxField(
@ -249,7 +249,7 @@ class BaseRDPTransport(transports.Transport):
'If checked, the wallpaper and themes will be shown on machine (better user experience, more bandwidth)'
),
tab=types.ui.Tab.DISPLAY,
stored_field_name='wallpaper',
old_field_name='wallpaper',
)
multimon = gui.CheckBoxField(
label=_('Multiple monitors'),
@ -258,14 +258,14 @@ class BaseRDPTransport(transports.Transport):
'If checked, all client monitors will be used for displaying (only works on windows clients)'
),
tab=types.ui.Tab.DISPLAY,
stored_field_name='multimon',
old_field_name='multimon',
)
aero = gui.CheckBoxField(
label=_('Allow Desk.Comp.'),
order=35,
tooltip=_('If checked, desktop composition will be allowed'),
tab=types.ui.Tab.DISPLAY,
stored_field_name='aero',
old_field_name='aero',
)
smooth = gui.CheckBoxField(
label=_('Font Smoothing'),
@ -273,7 +273,7 @@ class BaseRDPTransport(transports.Transport):
order=36,
tooltip=_('If checked, fonts smoothing will be allowed'),
tab=types.ui.Tab.DISPLAY,
stored_field_name='smooth',
old_field_name='smooth',
)
show_connection_bar = gui.CheckBoxField(
label=_('Connection Bar'),
@ -281,7 +281,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, connection bar will be shown (only on Windows clients)'),
tab=types.ui.Tab.DISPLAY,
default=True,
stored_field_name='showConnectionBar',
old_field_name='showConnectionBar',
)
lnx_multimedia = gui.CheckBoxField(
@ -289,14 +289,14 @@ class BaseRDPTransport(transports.Transport):
order=40,
tooltip=_('If checked. Linux client will use multimedia parameter for xfreerdp'),
tab='Linux Client',
stored_field_name='multimedia',
old_field_name='multimedia',
)
lnx_alsa = gui.CheckBoxField(
label=_('Use Alsa'),
order=41,
tooltip=_('If checked, Linux client will try to use ALSA, otherwise Pulse will be used'),
tab='Linux Client',
stored_field_name='alsa',
old_field_name='alsa',
)
lnx_printer_string = gui.TextField(
label=_('Printer string'),
@ -304,7 +304,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If printer is checked, the printer string used with xfreerdp client'),
tab='Linux Client',
length=256,
stored_field_name='printerString',
old_field_name='printerString',
)
lnx_smartcard_string = gui.TextField(
label=_('Smartcard string'),
@ -312,7 +312,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If smartcard is checked, the smartcard string used with xfreerdp client'),
tab='Linux Client',
length=256,
stored_field_name='smartcardString',
old_field_name='smartcardString',
)
lnx_custom_parameters = gui.TextField(
label=_('Custom parameters'),
@ -322,7 +322,7 @@ class BaseRDPTransport(transports.Transport):
),
tab='Linux Client',
length=256,
stored_field_name='customParameters',
old_field_name='customParameters',
)
mac_allow_msrdc = gui.CheckBoxField(
@ -331,7 +331,7 @@ class BaseRDPTransport(transports.Transport):
tooltip=_('If checked, allows use of Microsoft Remote Desktop Client. PASSWORD WILL BE PROMPTED!'),
tab='Mac OS X',
default=False,
stored_field_name='allowMacMSRDC',
old_field_name='allowMacMSRDC',
)
mac_custom_parameters = gui.TextField(
@ -342,7 +342,7 @@ class BaseRDPTransport(transports.Transport):
),
tab='Mac OS X',
length=256,
stored_field_name='customParametersMAC',
old_field_name='customParametersMAC',
)
wnd_custom_parameters = gui.TextField(
@ -352,7 +352,7 @@ class BaseRDPTransport(transports.Transport):
length=4096,
lines=10,
tab='Windows Client',
stored_field_name='customParametersWindows',
old_field_name='customParametersWindows',
)
wnd_optimize_teams = gui.CheckBoxField(
@ -360,7 +360,7 @@ class BaseRDPTransport(transports.Transport):
order=46,
tooltip=_('If checked, Teams will be optimized (only works on Windows clients)'),
tab='Windows Client',
stored_field_name='optimizeTeams',
old_field_name='optimizeTeams',
)
def is_ip_allowed(self, userService: 'models.UserService', ip: str) -> bool:

View File

@ -70,7 +70,7 @@ class TRDPTransport(BaseRDPTransport):
tunnel = fields.tunnel_field()
tunnel_wait = fields.tunnel_wait_time()
tunnel_wait = fields.tunnel_wait_time_field()
verify_certificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'),
@ -78,7 +78,7 @@ class TRDPTransport(BaseRDPTransport):
tooltip=_('If enabled, the certificate of tunnel server will be verified (recommended).'),
default=False,
tab=types.ui.Tab.TUNNEL,
stored_field_name='tunnelVerifyCert',
old_field_name='tunnelVerifyCert',
)
force_empty_creds = BaseRDPTransport.force_empty_creds

View File

@ -63,21 +63,21 @@ class BaseSpiceTransport(transports.Transport):
label=_('Empty credentials'),
tooltip=_('If checked, the credentials used to connect will be emtpy'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='useEmptyCreds',
old_field_name='useEmptyCreds',
)
forced_username = gui.TextField(
order=2,
label=_('Username'),
tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
old_field_name='fixedName',
)
forced_password = gui.PasswordField(
order=3,
label=_('Password'),
tooltip=_('If not empty, this password will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedPassword',
old_field_name='fixedPassword',
)
server_certificate = gui.TextField(
order=4,
@ -88,14 +88,14 @@ class BaseSpiceTransport(transports.Transport):
'Server certificate (public), can be found on your ovirt engine, probably at /etc/pki/ovirt-engine/certs/ca.der (Use the contents of this file).'
),
required=False,
stored_field_name='serverCertificate',
old_field_name='serverCertificate',
)
fullscreen = gui.CheckBoxField(
order=5,
label=_('Fullscreen Mode'),
tooltip=_('If checked, viewer will be shown on fullscreen mode-'),
tab=types.ui.Tab.ADVANCED,
stored_field_name='fullScreen',
old_field_name='fullScreen',
)
allow_smartcards = gui.CheckBoxField(
order=6,
@ -103,7 +103,7 @@ class BaseSpiceTransport(transports.Transport):
tooltip=_('If checked, SPICE protocol will allow smartcard redirection.'),
default=False,
tab=types.ui.Tab.ADVANCED,
stored_field_name='smartCardRedirect',
old_field_name='smartCardRedirect',
)
allow_usb_redirection = gui.CheckBoxField(
order=7,
@ -111,7 +111,7 @@ class BaseSpiceTransport(transports.Transport):
tooltip=_('If checked, USB redirection will be allowed.'),
default=False,
tab=types.ui.Tab.ADVANCED,
stored_field_name='usbShare',
old_field_name='usbShare',
)
allow_usb_redirection_new_plugs = gui.CheckBoxField(
order=8,
@ -119,7 +119,7 @@ class BaseSpiceTransport(transports.Transport):
tooltip=_('Auto-redirect USB devices when plugged in.'),
default=False,
tab=types.ui.Tab.ADVANCED,
stored_field_name='autoNewUsbShare',
old_field_name='autoNewUsbShare',
)
ssl_connection = gui.CheckBoxField(
order=9,
@ -127,7 +127,7 @@ class BaseSpiceTransport(transports.Transport):
tooltip=_('If checked, SPICE protocol will allow SSL connections.'),
default=True,
tab=types.ui.Tab.ADVANCED,
stored_field_name='SSLConnection',
old_field_name='SSLConnection',
)
overrided_proxy = gui.TextField(
@ -139,7 +139,7 @@ class BaseSpiceTransport(transports.Transport):
required=False,
tab=types.ui.Tab.ADVANCED,
pattern=types.ui.FieldPatternType.URL,
stored_field_name='overridedProxy',
old_field_name='overridedProxy',
)
def is_ip_allowed(self, userService: 'models.UserService', ip: str) -> bool:

View File

@ -66,7 +66,7 @@ class TSPICETransport(BaseSpiceTransport):
group = types.transports.Grouping.TUNNELED
tunnel = fields.tunnel_field()
tunnel_wait = fields.tunnel_wait_time()
tunnel_wait = fields.tunnel_wait_time_field()
verify_certificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'),
@ -76,7 +76,7 @@ class TSPICETransport(BaseSpiceTransport):
),
default=False,
tab=types.ui.Tab.TUNNEL,
stored_field_name='verifyCertificate',
old_field_name='verifyCertificate',
)
server_certificate = BaseSpiceTransport.server_certificate

View File

@ -71,7 +71,7 @@ class URLCustomTransport(transports.Transport):
default='https://www.udsenterprise.com',
length=256,
required=True,
stored_field_name='urlPattern', # Allows compat with old versions
old_field_name='urlPattern', # Allows compat with old versions
)
force_new_window = gui.CheckBoxField(
@ -82,7 +82,7 @@ class URLCustomTransport(transports.Transport):
),
default=False,
tab=types.ui.Tab.ADVANCED,
stored_field_name='forceNewWindow', # Allows compat with old versions
old_field_name='forceNewWindow', # Allows compat with old versions
)
def initialize(self, values: 'Module.ValuesType'):

View File

@ -73,7 +73,7 @@ class BaseX2GOTransport(transports.Transport):
label=_('Username'),
tooltip=_('If not empty, this username will be always used as credential'),
tab=types.ui.Tab.CREDENTIALS,
stored_field_name='fixedName',
old_field_name='fixedName',
)
screen_size = gui.ChoiceField(
@ -90,7 +90,7 @@ class BaseX2GOTransport(transports.Transport):
{'id': CommonPrefs.SZ_FULLSCREEN, 'text': gettext_lazy('Full Screen')},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='screenSize',
old_field_name='screenSize',
)
desktop_type = gui.ChoiceField(
@ -109,7 +109,7 @@ class BaseX2GOTransport(transports.Transport):
{'id': 'UDSVAPP', 'text': 'UDS vAPP'},
],
tab=types.ui.Tab.PARAMETERS,
stored_field_name='desktopType',
old_field_name='desktopType',
)
custom_cmd = gui.TextField(
@ -119,7 +119,7 @@ class BaseX2GOTransport(transports.Transport):
'If UDS vAPP is selected as "Desktop", the FULL PATH of the app to be executed. If UDS vAPP is not selected, this field will be ignored.'
),
tab=types.ui.Tab.PARAMETERS,
stored_field_name='customCmd',
old_field_name='customCmd',
)
sound = gui.CheckBoxField(
@ -163,7 +163,7 @@ class BaseX2GOTransport(transports.Transport):
{'id': 'esd', 'text': 'ESD'},
],
tab=types.ui.Tab.ADVANCED,
stored_field_name='soundType',
old_field_name='soundType',
)
keyboard_layout = gui.TextField(
@ -172,7 +172,7 @@ class BaseX2GOTransport(transports.Transport):
tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
default='',
tab=types.ui.Tab.ADVANCED,
stored_field_name='keyboardLayout',
old_field_name='keyboardLayout',
)
# 'nopack', '8', '64', '256', '512', '4k', '32k', '64k', '256k', '2m', '16m'
# '256-rdp', '256-rdp-compressed', '32k-rdp', '32k-rdp-compressed', '64k-rdp'

View File

@ -68,7 +68,7 @@ class TX2GOTransport(BaseX2GOTransport):
group = types.transports.Grouping.TUNNELED
tunnel = fields.tunnel_field()
tunnel_wait = fields.tunnel_wait_time()
tunnel_wait = fields.tunnel_wait_time_field()
verify_certificate = gui.CheckBoxField(
label=_('Force SSL certificate verification'),
@ -76,7 +76,7 @@ class TX2GOTransport(BaseX2GOTransport):
tooltip=_('If enabled, the certificate of tunnel server will be verified (recommended).'),
default=False,
tab=types.ui.Tab.TUNNEL,
stored_field_name='verifyCertificate',
old_field_name='verifyCertificate',
)
fixed_name = BaseX2GOTransport.fixed_name

View File

@ -153,7 +153,7 @@ class UserinterfaceTest(UDSTestCase):
ui = TestingUserInterface()
data = old_serialize_form(ui)
ui2 = TestingUserInterface()
ui2.deserialize_old_fields(data)
ui2.deserialize_from_old_format(data)
self.assertEqual(ui, ui2)
self.ensure_values_fine(ui2)
@ -176,7 +176,7 @@ class UserinterfaceTest(UDSTestCase):
self.assertEqual(ui, ui2)
self.ensure_values_fine(ui2)
def test_stored_field_name(self):
def test_old_field_name(self):
# This test is to ensure that new serialized data can be loaded
# mock logging warning
ui = TestingUserInterfaceFieldNameOrig()
@ -185,6 +185,9 @@ class UserinterfaceTest(UDSTestCase):
ui2.unserialize_fields(data)
self.assertEqual(ui.strField.value, ui2.str_field.value)
# On current version, we allow backwards compatibility, so no warning is issued
# Will be removed on next major version
with mock.patch('logging.Logger.warning') as mock_warning:
data = ui2.serialize_fields() # Should store str_field as strField

View File

@ -94,7 +94,7 @@ class UniqueIdTest(UDSTestCase):
for i in range(NUM):
self.assertEqual(self.uidGen.get(), i + NUM)
self.uidGen.releaseOlderThan(stamp) # Clear ups older than 0 seconds ago
self.uidGen.release_older_than(stamp) # Clear ups older than 0 seconds ago
for i in range(NUM):
self.assertEqual(self.uidGen.get(), i)

View File

@ -58,7 +58,7 @@ class TestingUserInterface(UserInterface):
tooltip='This is a text field',
required=True,
default=typing.cast(str, DEFAULTS['str_field']),
stored_field_name='strField',
old_field_name='strField',
)
str_auto_field = gui.TextAutocompleteField(
label='Text Autocomplete Field',
@ -175,5 +175,5 @@ class TestingUserInterfaceFieldName(UserInterface):
tooltip='This is a text field',
required=True,
default='', # Will be loaded from orig
stored_field_name='strField',
old_field_name='strField',
)