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

* Added support for "reset" services that support it.

Right now, we will test on enterprise this feature.
This commit is contained in:
Adolfo Gómez García 2018-03-14 08:03:23 +01:00
parent ee72b65534
commit 92de41d410
14 changed files with 132 additions and 18 deletions

View File

@ -62,6 +62,7 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
@staticmethod
def serviceInfo(item):
info = item.getType()
return {
'icon': info.icon().replace('\n', ''),
'needs_publication': info.publicationType is not None,
@ -74,6 +75,7 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
'allowedProtocols': info.allowedProtocols,
'servicesTypeProvided': info.servicesTypeProvided,
'must_assign_manually': info.mustAssignManually,
'can_reset': info.canReset,
}
@staticmethod

View File

@ -72,7 +72,8 @@ class ServicesPools(ModelHandler):
save_fields = ['name', 'short_name', 'comments', 'tags', 'service_id',
'osmanager_id', 'image_id', 'servicesPoolGroup_id', 'initial_srvs',
'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports',
'allow_users_remove', 'ignores_unused']
'allow_users_remove', 'allow_users_reset', 'ignores_unused']
remove_fields = ['osmanager_id', 'service_id']
table_title = _('Service Pools')
@ -134,6 +135,7 @@ class ServicesPools(ModelHandler):
'restrained': item.isRestrained(),
'show_transports': item.show_transports,
'allow_users_remove': item.allow_users_remove,
'allow_users_reset': item.allow_users_reset,
'ignores_unused': item.ignores_unused,
'fallbackAccess': item.fallbackAccess,
'permission': permissions.getEffectivePermission(self._user, item),
@ -186,13 +188,21 @@ class ServicesPools(ModelHandler):
'type': gui.InputField.CHECKBOX_TYPE,
'order': 111,
'tab': ugettext('Advanced'),
}, {
'name': 'allow_users_reset',
'value': False,
'label': ugettext('Allow reset by users'),
'tooltip': ugettext('If active, the user will be allowed to reset the service'),
'type': gui.InputField.CHECKBOX_TYPE,
'order': 112,
'tab': ugettext('Advanced'),
}, {
'name': 'ignores_unused',
'value': False,
'label': ugettext('Ignores unused'),
'tooltip': ugettext('If the option is enabled, UDS will not attempt to detect and remove the user services assigned but not in use.'),
'type': gui.InputField.CHECKBOX_TYPE,
'order': 112,
'order': 113,
'tab': ugettext('Advanced'),
}, {
'name': 'image_id',

View File

@ -51,7 +51,7 @@ import requests
import json
import logging
__updated__ = '2018-03-02'
__updated__ = '2018-03-14'
logger = logging.getLogger(__name__)
traceLogger = logging.getLogger('traceLog')
@ -360,6 +360,20 @@ class UserServiceManager(object):
UserServiceOpChecker.makeUnique(uService, ui, state)
return False
def reset(self, uService):
UserService.objects.update()
uService = UserService.objects.get(id=uService.id)
if uService.deployed_service.service.getType().canReset is False:
return
logger.debug('Reseting'.format(uService))
ui = uService.getInstance()
try:
ui.reset()
except Exception:
logger.exception('Reseting service')
def notifyPreconnect(self, uService, userName, protocol):
url = uService.getCommsUrl()
if url is None:

View File

@ -36,7 +36,7 @@ from uds.core import Environmentable
from uds.core import Serializable
from uds.core.util.State import State
__updated__ = '2017-09-29'
__updated__ = '2018-03-14'
class UserDeployment(Environmentable, Serializable):
@ -574,6 +574,13 @@ class UserDeployment(Environmentable, Serializable):
'''
raise Exception('cancel method for class {0} not provided!'.format(self.__class__.__name__))
def reset(self):
'''
This method is invoked for "reset" an user service
This method is not intended to be a task right now, it's more like the
'''
raise Exception('reset method for class {0} not provided!'.format(self.__class__.__name__))
def __str__(self):
'''
Mainly used for debugging purposses

View File

@ -37,7 +37,7 @@ from uds.core import Module
from uds.core.transports import protocols
from . import types
__updated__ = '2016-03-09'
__updated__ = '2018-03-14'
class Service(Module):
@ -167,14 +167,14 @@ class Service(Module):
# : Default behavior is False (and most common), but some services may need to respawn a new "copy" on every launch
spawnsNew = False
# : If the service allows "reset", here we will announce it
# : Defaults to False
canReset = False
# : 'kind' of services that this service provides:
# : For example, VDI, VAPP, ...
servicesTypeProvided = types.ALL
# : If the service can provide any other option on release appart of "delete" & "keep assigned"
# : Defaults to None (no any other options are provided)
actionsOnRelease = None
def __init__(self, environment, parent, values=None):
'''
Do not forget to invoke this in your derived class using "super(self.__class__, self).__init__(environment, parent, values)".

View File

@ -39,7 +39,7 @@ import logging
logger = logging.getLogger(__name__)
__updated__ = '2016-04-25'
__updated__ = '2018-03-14'
class ServiceProvider(Module):
@ -120,7 +120,6 @@ class ServiceProvider(Module):
# : Note: this variable can be either a fixed value (integer, string) or a Gui text field (with a .value)
ignoreLimits = None
@classmethod
def getServicesTypes(cls):
'''

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2018-03-14 06:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('uds', '0026_auto_20180302_0525'),
]
operations = [
migrations.AddField(
model_name='deployedservice',
name='allow_users_reset',
field=models.BooleanField(default=False),
),
]

View File

@ -62,7 +62,7 @@ import logging
import pickle
import six
__updated__ = '2017-11-29'
__updated__ = '2018-03-14'
logger = logging.getLogger(__name__)
@ -83,8 +83,12 @@ class DeployedService(UUIDModel, TaggingMixin):
state = models.CharField(max_length=1, default=states.servicePool.ACTIVE, db_index=True)
state_date = models.DateTimeField(default=NEVER)
show_transports = models.BooleanField(default=True)
allow_users_remove = models.BooleanField(default=False)
allow_users_reset = models.BooleanField(default=False)
ignores_unused = models.BooleanField(default=False)
image = models.ForeignKey(Image, null=True, blank=True, related_name='deployedServices', on_delete=models.SET_NULL)
servicesPoolGroup = models.ForeignKey(ServicesPoolGroup, null=True, blank=True, related_name='servicesPools', on_delete=models.SET_NULL)

View File

@ -72,6 +72,7 @@ gui.servicesPools.link = (event) ->
serviceChangedFnc = (formId) ->
$fld = $(formId + " [name=\"service_id\"]")
$osmFld = $(formId + " [name=\"osmanager_id\"]")
$canResetFld = $(formId + " [name=\"allow_users_reset\"]")
selectors = []
$.each [
"initial_srvs"
@ -89,6 +90,13 @@ gui.servicesPools.link = (event) ->
unless $fld.val() is -1
api.providers.service $fld.val(), (data) ->
gui.doLog "Onchange", data
if $canResetFld.bootstrapSwitch("readonly") == data.info.can_reset
gui.doLog('reset doent not match field')
$canResetFld.bootstrapSwitch "toggleReadonly", true
if data.info.can_reset is false
gui.doLog($canResetFld.bootstrapSwitch("readonly"), data.info.can_reset)
if data.info.needs_manager is false
$osmFld.prop "disabled", "disabled"
else

View File

@ -50,6 +50,9 @@
{% if ser.allow_users_remove %}
<span data-href="{% url 'Releaser' idService=ser.id %}" class="release fa fa-trash"> </span>
{% endif %}
{% if ser.allow_users_reset %}
<span data-href="{% url 'Reseter' idService=ser.id %}" class="reseter fa fa-refresh"> </span>
{% endif %}
</span>
{% endif %}
</div>
@ -284,6 +287,10 @@
span.gear > span.release {
cursor: cell;
}
span.gear > span.reseter {
cursor: cell;
}
</style>
{% endblock %}
@ -377,6 +384,26 @@
return false;
});
$('div.service:not(.maintenance, .notaccesible) > span.gear > span.release').on("click", function (event) {
event.stopPropagation();
event.preventDefault();
if ( confirm("{%trans 'Are you sure that you want to release this service. Its current content will be lost!' %}") ) {
window.location.href = $(this).attr('data-href');
}
return false;
});
$('div.service:not(.maintenance, .notaccesible) > span.gear > span.reseter').on("click", function (event) {
event.stopPropagation();
event.preventDefault();
if ( confirm("{%trans 'Are you sure that you want to reset this service. USE WITH CAUTION!' %}") ) {
window.location.href = $(this).attr('data-href');
}
return false;
});
$(".maintenance").click( function(event) {
$('#maintenance-dialog').modal({
keyboard: false

View File

@ -69,8 +69,9 @@ urlpatterns = patterns(
# Client access enabler
url(r'^enable/(?P<idService>.+)/(?P<idTransport>.+)$', 'web.views.clientEnabler', name='ClientAccessEnabler'),
# Releaser
# Releaser & reset
url(r'^release/(?P<idService>.+)$', 'web.views.release', name='Releaser'),
url(r'^reset/(?P<idService>.+)$', 'web.views.reset', name='Reseter'),
# Custom authentication callback
(r'^auth/(?P<authName>.+)', 'web.views.authCallback'),

View File

@ -35,7 +35,7 @@ import logging
from .login import login, logout, customAuth
from .index import index, about
from .prefs import prefs
from .service import transportOwnLink, transportIcon, clientEnabler, serviceImage, release
from .service import transportOwnLink, transportIcon, clientEnabler, serviceImage, release, reset
from .auth import authCallback, authInfo, ticketAuth
from .download import download
from .client_download import client_downloads, plugin_detection
@ -44,6 +44,6 @@ from ..errors import error
from .images import image
from .file_storage import file_storage
__updated__ = '2017-10-26'
__updated__ = '2018-03-14'
logger = logging.getLogger(__name__)

View File

@ -52,7 +52,7 @@ import logging
logger = logging.getLogger(__name__)
__updated__ = '2017-11-10'
__updated__ = '2018-03-14'
def about(request):
@ -141,6 +141,7 @@ def index(request):
'imageId': imageId,
'show_transports': servicePool.show_transports,
'allow_users_remove': servicePool.allow_users_remove,
'allow_users_reset': servicePool.allow_users_reset,
'maintenance': servicePool.isInMaintenance(),
'not_accesible': not servicePool.isAccessAllowed(),
'in_use': svr.in_use,
@ -200,6 +201,7 @@ def index(request):
'imageId': imageId,
'show_transports': svr.show_transports,
'allow_users_remove': svr.allow_users_remove,
'allow_users_reset': svr.allow_users_reset,
'maintenance': svr.isInMaintenance(),
'not_accesible': not svr.isAccessAllowed(),
'in_use': in_use,

View File

@ -56,7 +56,7 @@ import logging
logger = logging.getLogger(__name__)
__updated__ = '2017-11-16'
__updated__ = '2018-03-14'
@webLoginRequired(admin=False)
@ -159,7 +159,7 @@ def clientEnabler(request, idService, idTransport):
def release(request, idService):
logger.debug('ID Service: {}'.format(idService))
userService = userServiceManager().locateUserService(request.user, idService, create=False)
logger.debug('UserSrvice: >{}<'.format(userService))
logger.debug('UserService: >{}<'.format(userService))
if userService is not None and userService.deployed_service.allow_users_remove:
log.doLog(
userService.deployed_service,
@ -172,3 +172,23 @@ def release(request, idService):
return HttpResponseRedirect(reverse('Index'))
@webLoginRequired(admin=False)
@never_cache
def reset(request, idService):
logger.debug('ID Service: {}'.format(idService))
userService = userServiceManager().locateUserService(request.user, idService, create=False)
logger.debug('UserService: >{}<'.format(userService))
if (userService is not None and userService.deployed_service.allow_users_reset
and userService.deployed_service.service.getType().canReset):
log.doLog(
userService.deployed_service,
log.INFO,
"Reseting User Service {} as requested by {} from {}".format(userService.friendly_name, request.user.pretty_name, request.ip),
log.WEB
)
# userServiceManager().requestLogoff(userService)
userServiceManager().reset(userService)
return HttpResponseRedirect(reverse('Index'))