mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-10 01:17:59 +03:00
* Added service known IP to services list
* Optimized service retrieval for dashboard * Added group regex expressions * Added pool in maintenance mode for pools list * Upgraded visibility of "warned" pools (couoling them) * Improved base service list on new pool (added provider in front of service)
This commit is contained in:
parent
9a529b8f5b
commit
70fc09b21a
@ -103,7 +103,7 @@ class ServicesPools(ModelHandler):
|
||||
'id': item.uuid,
|
||||
'name': item.name,
|
||||
'comments': item.comments,
|
||||
'state': item.state,
|
||||
'state': item.state if item.service.provider.maintenance_mode is False else State.MAINTENANCE,
|
||||
'thumb': item.image.thumb64 if item.image is not None else DEFAULT_THUMB_BASE64,
|
||||
'service_id': item.service.uuid,
|
||||
'restrained': item.isRestrained(),
|
||||
@ -121,7 +121,7 @@ class ServicesPools(ModelHandler):
|
||||
|
||||
for f in [{
|
||||
'name': 'service_id',
|
||||
'values': [gui.choiceItem(-1, '')] + [gui.choiceItem(v.uuid, v.name) for v in Service.objects.all()],
|
||||
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.provider.name + '\\' + v.name) for v in Service.objects.all()]),
|
||||
'label': ugettext('Base service'),
|
||||
'tooltip': ugettext('Service used as base of this service pool'),
|
||||
'type': gui.InputField.CHOICE_TYPE,
|
||||
@ -129,7 +129,7 @@ class ServicesPools(ModelHandler):
|
||||
'order': 100, # Ensueres is At end
|
||||
}, {
|
||||
'name': 'osmanager_id',
|
||||
'values': [gui.choiceItem(-1, '')] + [gui.choiceItem(v.uuid, v.name) for v in OSManager.objects.all()],
|
||||
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.name) for v in OSManager.objects.all()]),
|
||||
'label': ugettext('OS Manager'),
|
||||
'tooltip': ugettext('OS Manager used as base of this service pool'),
|
||||
'type': gui.InputField.CHOICE_TYPE,
|
||||
@ -137,7 +137,7 @@ class ServicesPools(ModelHandler):
|
||||
'order': 101,
|
||||
}, {
|
||||
'name': 'image_id',
|
||||
'values': [gui.choiceItem(-1, '')] + [gui.choiceItem(v.uuid, v.name) for v in Image.objects.all()],
|
||||
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.name) for v in Image.objects.all()]),
|
||||
'label': ugettext('Associated Image'),
|
||||
'tooltip': ugettext('Image assocciated with this service'),
|
||||
'type': gui.InputField.CHOICE_TYPE,
|
||||
|
@ -50,6 +50,7 @@ class AssignedService(DetailHandler):
|
||||
|
||||
@staticmethod
|
||||
def itemToDict(item, is_cache=False):
|
||||
props = item.getProperties()
|
||||
val = {
|
||||
'id': item.uuid,
|
||||
'id_deployed_service': item.deployed_service.uuid,
|
||||
@ -60,7 +61,8 @@ class AssignedService(DetailHandler):
|
||||
'state_date': item.state_date,
|
||||
'creation_date': item.creation_date,
|
||||
'revision': item.publication and item.publication.revision or '',
|
||||
'actor_version': item.getProperty('actor_version', _('unknown')),
|
||||
'ip': props.get('ip', _('unknown')),
|
||||
'actor_version': props.get('actor_version', _('unknown')),
|
||||
}
|
||||
|
||||
if is_cache:
|
||||
@ -79,7 +81,8 @@ class AssignedService(DetailHandler):
|
||||
# Extract provider
|
||||
try:
|
||||
if item is None:
|
||||
return [AssignedService.itemToDict(k) for k in parent.assignedUserServices().all()]
|
||||
return [AssignedService.itemToDict(k) for k in parent.assignedUserServices().all()
|
||||
.prefetch_related('properties').prefetch_related('deployed_service').prefetch_related('publication')]
|
||||
else:
|
||||
return parent.assignedUserServices().get(uuid=item)
|
||||
except Exception:
|
||||
@ -94,6 +97,7 @@ class AssignedService(DetailHandler):
|
||||
{'creation_date': {'title': _('Creation date'), 'type': 'datetime'}},
|
||||
{'revision': {'title': _('Revision')}},
|
||||
{'unique_id': {'title': 'Unique ID'}},
|
||||
{'ip': {'title': _('IP')}},
|
||||
{'friendly_name': {'title': _('Friendly name')}},
|
||||
{'state': {'title': _('State')}},
|
||||
{'state_date': {'title': _('State date'), 'type': 'datetime'}},
|
||||
@ -136,7 +140,8 @@ class CachedService(AssignedService):
|
||||
# Extract provider
|
||||
try:
|
||||
if item is None:
|
||||
return [AssignedService.itemToDict(k, True) for k in parent.cachedUserServices().all()]
|
||||
return [AssignedService.itemToDict(k, True) for k in parent.cachedUserServices().all()
|
||||
.prefetch_related('properties').prefetch_related('deployed_service').prefetch_related('publication')]
|
||||
else:
|
||||
k = parent.cachedUserServices().get(uuid=item)
|
||||
return AssignedService.itemToDict(k, True)
|
||||
@ -152,6 +157,7 @@ class CachedService(AssignedService):
|
||||
{'creation_date': {'title': _('Creation date'), 'type': 'datetime'}},
|
||||
{'revision': {'title': _('Revision')}},
|
||||
{'unique_id': {'title': 'Unique ID'}},
|
||||
{'ip': {'title': _('IP')}},
|
||||
{'friendly_name': {'title': _('Friendly name')}},
|
||||
{'state': {'title': _('State'), 'type': 'dict', 'dict': State.dictionary()}},
|
||||
{'cache_level': {'title': _('Cache level')}},
|
||||
|
@ -173,7 +173,7 @@ class Groups(DetailHandler):
|
||||
multi = False
|
||||
if item is None:
|
||||
multi = True
|
||||
q = parent.groups.all()
|
||||
q = parent.groups.all().order_by('name')
|
||||
else:
|
||||
q = parent.groups.filter(uuid=item)
|
||||
res = []
|
||||
|
@ -38,7 +38,7 @@ from uds.core.util.stats.events import addEvent, ET_LOGIN, ET_LOGOUT
|
||||
from uds.core.util import log
|
||||
from uds.core import Module
|
||||
|
||||
__updated__ = '2015-01-21'
|
||||
__updated__ = '2015-01-26'
|
||||
|
||||
STORAGE_KEY = 'osmk'
|
||||
|
||||
@ -159,6 +159,9 @@ class OSManager(Module):
|
||||
'''
|
||||
pass
|
||||
|
||||
def logKnownIp(self, userService, ip):
|
||||
userService.logIP(ip)
|
||||
|
||||
def loggedIn(self, userService, userName=None, save=True):
|
||||
'''
|
||||
This method:
|
||||
|
@ -121,6 +121,10 @@ class gui(object):
|
||||
'''
|
||||
return {'id': str(id_), 'text': str(text)}
|
||||
|
||||
@staticmethod
|
||||
def sortedChoices(choices):
|
||||
return sorted(choices, key=lambda item: item['text'].lower())
|
||||
|
||||
@staticmethod
|
||||
def strToBool(str_):
|
||||
'''
|
||||
|
@ -57,6 +57,7 @@ class State(object):
|
||||
USABLE = 'U'
|
||||
RUNNING = 'W'
|
||||
FOR_EXECUTE = 'X'
|
||||
MAINTENANCE = 'Y' # "Visual" state, no element will be in fact in maintenance, but used to show "Services Pools" for which a Provider is in maintenance
|
||||
|
||||
string = {
|
||||
ACTIVE: _('Active'),
|
||||
@ -74,7 +75,8 @@ class State(object):
|
||||
RUNNING: _('Running'),
|
||||
FINISHED: _('Finished'),
|
||||
FOR_EXECUTE: _('Waiting execution'),
|
||||
BALANCING: _('Balancing')
|
||||
BALANCING: _('Balancing'),
|
||||
MAINTENANCE: _('In maintenance')
|
||||
}
|
||||
|
||||
# States that are merely for "information" to the user. They don't contain any usable instance
|
||||
@ -144,10 +146,7 @@ class State(object):
|
||||
|
||||
@staticmethod
|
||||
def toString(state):
|
||||
try:
|
||||
return State.string[state]
|
||||
except Exception:
|
||||
return ''
|
||||
return State.string.get(state, '')
|
||||
|
||||
@staticmethod
|
||||
def dictionary():
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__updated__ = '2014-12-20'
|
||||
__updated__ = '2015-01-26'
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__updated__ = '2014-12-05'
|
||||
__updated__ = '2015-01-26'
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
@ -420,6 +420,16 @@ class UserService(UUIDModel):
|
||||
except Exception:
|
||||
return default
|
||||
|
||||
def getProperties(self):
|
||||
'''
|
||||
Retrieves all properties as a dictionary
|
||||
The number of properties per item is expected to be "relatively small" (no more than 5 items?)
|
||||
'''
|
||||
dct = {}
|
||||
for v in self.properties.all():
|
||||
dct[v.name] = v.value
|
||||
return dct
|
||||
|
||||
def setProperty(self, propName, propValue):
|
||||
prop, _ = self.properties.get_or_create(name=propName)
|
||||
prop.value = propValue if propValue is not None else ''
|
||||
@ -431,6 +441,12 @@ class UserService(UUIDModel):
|
||||
def getCommsUrl(self):
|
||||
return self.getProperty('comms_url', None)
|
||||
|
||||
def logIP(self, ip=None):
|
||||
self.setProperty('ip', ip)
|
||||
|
||||
def getLoggedIP(self):
|
||||
return self.getProperty('ip', '0.0.0.0')
|
||||
|
||||
def __str__(self):
|
||||
return "User service {0}, cache_level {1}, user {2}, name {3}, state {4}:{5}".format(self.id, self.cache_level, self.user, self.friendly_name,
|
||||
State.toString(self.state), State.toString(self.os_state))
|
||||
|
@ -95,15 +95,22 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
def infoValue(self, service):
|
||||
return 'rename\r' + self.getName(service)
|
||||
|
||||
def notifyIp(self, uid, si, data):
|
||||
def notifyIp(self, uid, service, data):
|
||||
si = service.getInstance()
|
||||
|
||||
ip = ''
|
||||
# Notifies IP to deployed
|
||||
pairs = data.split(',')
|
||||
for p in pairs:
|
||||
key, val = p.split('=')
|
||||
if key.lower() == uid.lower():
|
||||
si.setIp(val)
|
||||
ip = val
|
||||
break
|
||||
|
||||
self.logKnownIp(service, ip)
|
||||
service.updateData(si)
|
||||
|
||||
def doLog(self, service, data, origin=log.OSMANAGER):
|
||||
# Stores a log associated with this service
|
||||
try:
|
||||
@ -151,15 +158,11 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
elif msg == "ip":
|
||||
# This ocurss on main loop inside machine, so service is usable
|
||||
state = State.USABLE
|
||||
si = service.getInstance()
|
||||
self.notifyIp(service.unique_id, si, data)
|
||||
service.updateData(si)
|
||||
self.notifyIp(service.unique_id, service, data)
|
||||
elif msg == "ready":
|
||||
state = State.USABLE
|
||||
si = service.getInstance()
|
||||
notifyReady = True
|
||||
self.notifyIp(service.unique_id, si, data)
|
||||
service.updateData(si)
|
||||
self.notifyIp(service.unique_id, service, data)
|
||||
|
||||
service.setOsState(state)
|
||||
|
||||
|
@ -98,15 +98,22 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
def infoValue(self, service):
|
||||
return 'rename\r' + self.getName(service)
|
||||
|
||||
def notifyIp(self, uid, si, data):
|
||||
def notifyIp(self, uid, service, data):
|
||||
si = service.getInstance()
|
||||
|
||||
ip = ''
|
||||
# Notifies IP to deployed
|
||||
pairs = data.split(',')
|
||||
for p in pairs:
|
||||
key, val = p.split('=')
|
||||
if key.lower() == uid.lower():
|
||||
si.setIp(val)
|
||||
ip = val
|
||||
break
|
||||
|
||||
self.logKnownIp(service, ip)
|
||||
service.updateData(si)
|
||||
|
||||
def doLog(self, service, data, origin=log.OSMANAGER):
|
||||
# Stores a log associated with this service
|
||||
try:
|
||||
@ -157,15 +164,11 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
elif msg == "ip":
|
||||
# This ocurss on main loop inside machine, so service is usable
|
||||
state = State.USABLE
|
||||
si = service.getInstance()
|
||||
self.notifyIp(service.unique_id, si, data)
|
||||
service.updateData(si)
|
||||
self.notifyIp(service.unique_id, service, data)
|
||||
elif msg == "ready":
|
||||
state = State.USABLE
|
||||
si = service.getInstance()
|
||||
notifyReady = True
|
||||
self.notifyIp(service.unique_id, si, data)
|
||||
service.updateData(si)
|
||||
self.notifyIp(service.unique_id, service, data)
|
||||
|
||||
service.setOsState(state)
|
||||
|
||||
|
@ -87,16 +87,28 @@ body {
|
||||
}
|
||||
|
||||
/* States */
|
||||
tr.row-state-A, tr.row-state-F, tr.row-state-U, tr.row-state-W {
|
||||
color: black;
|
||||
|
||||
|
||||
/*
|
||||
This states displays as default
|
||||
tr.row-state-A > td, tr.row-state-F > td, tr.row-state-U > td, tr.row-state-W > td {
|
||||
}
|
||||
*/
|
||||
|
||||
tr.row-state-B:nth-child(2n) > td, tr.row-state-C:nth-child(2n) > td, tr.row-state-E:nth-child(2n) > td, tr.row-state-Y:nth-child(2n) > td {
|
||||
color: #FF6600 !important;
|
||||
}
|
||||
|
||||
tr.row-state-B, tr.row-state-C, tr.row-state-E {
|
||||
color: red;
|
||||
tr.row-state-B:nth-child(2n+1) > td, tr.row-state-C:nth-child(2n+1) > td, tr.row-state-E:nth-child(2n+1) > td, tr.row-state-Y:nth-child(2n+1) > td {
|
||||
color: #FF6600 !important;
|
||||
}
|
||||
|
||||
tr.row-state-M, tr.row-state-R, tr.row-state-I, tr.row-state-S {
|
||||
color: #858585;
|
||||
tr.row-state-M:nth-child(2n+1) > td, tr.row-state-R:nth-child(2n+1) > td, tr.row-state-I:nth-child(2n+1) > td, tr.row-state-S > td:nth-child(2n+1) {
|
||||
color: #9A9A9A !important;
|
||||
}
|
||||
|
||||
tr.row-state-M:nth-child(2n) > td, tr.row-state-R:nth-child(2n) > td, tr.row-state-I:nth-child(2n) > td, tr.row-state-S > td:nth-child(2n) {
|
||||
color: #858585 !important;
|
||||
}
|
||||
|
||||
/* Logs */
|
||||
|
@ -222,6 +222,8 @@ gui.servicesPools.link = (event) ->
|
||||
onNew: (value, table, refreshFnc) ->
|
||||
api.templates.get "pool_add_group", (tmpl) ->
|
||||
api.authenticators.overview (data) ->
|
||||
# Sorts groups, expression means that "if a > b returns 1, if b > a returns -1, else returns 0"
|
||||
|
||||
modalId = gui.launchModal(gettext("Add group"), api.templates.evaluate(tmpl,
|
||||
auths: data
|
||||
))
|
||||
@ -230,6 +232,7 @@ gui.servicesPools.link = (event) ->
|
||||
api.authenticators.detail(auth, "groups").overview (data) ->
|
||||
$select = $(modalId + " #id_group_select")
|
||||
$select.empty()
|
||||
# Sorts groups, expression means that "if a > b returns 1, if b > a returns -1, else returns 0"
|
||||
$.each data, (undefined_, value) ->
|
||||
$select.append "<option value=\"" + value.id + "\">" + value.name + "</option>"
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user