1
0
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:
Adolfo Gómez García 2015-01-26 09:30:25 +01:00
parent 9a529b8f5b
commit 70fc09b21a
12 changed files with 85 additions and 36 deletions

View File

@ -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,

View File

@ -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')}},

View File

@ -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 = []

View File

@ -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:

View File

@ -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_):
'''

View File

@ -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():

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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