1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-02-10 13:57:36 +03:00

Finished metepools admin part

This commit is contained in:
Adolfo Gómez García 2018-10-03 11:08:24 +02:00
parent f995903056
commit 7d5ce53317
11 changed files with 150 additions and 109 deletions

View File

@ -52,7 +52,7 @@ from uds.REST.model import ModelHandler
from uds.REST import RequestError, ResponseError
from uds.core.ui.UserInterface import gui
from .user_services import Groups
from .access_calendars import AccessCalendars
from uds.REST.methods.op_calendars import AccessCalendars
from .meta_service_pools import MetaServicesPool
import six
@ -73,7 +73,7 @@ class MetaPools(ModelHandler):
}
save_fields = ['name', 'short_name', 'comments', 'tags',
'image_id', 'servicesPoolGroup_id', 'visible']
'image_id', 'servicesPoolGroup_id', 'visible', 'policy']
remove_fields = []
@ -119,6 +119,7 @@ class MetaPools(ModelHandler):
'user_services_count': userServicesCount,
'user_services_in_preparation': userServicesInPreparation,
'visible': item.visible,
'policy': item.policy,
'fallbackAccess': item.fallbackAccess,
'permission': permissions.getEffectivePermission(self._user, item),
}
@ -131,6 +132,13 @@ class MetaPools(ModelHandler):
g = self.addDefaultFields([], ['name', 'short_name', 'comments', 'tags'])
for f in [{
'name': 'policy',
'values': [gui.choiceItem(k, str(v)) for k, v in MetaPool.TYPES.items()],
'label': ugettext('Policy'),
'tooltip': ugettext('Service pool policy'),
'type': gui.InputField.CHOICE_TYPE,
'order': 100,
}, {
'name': 'image_id',
'values': [gui.choiceImage(-1, '--------', DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in Image.objects.all()]),
'label': ugettext('Associated Image'),
@ -150,9 +158,9 @@ class MetaPools(ModelHandler):
'name': 'visible',
'value': True,
'label': ugettext('Visible'),
'tooltip': ugettext('If active, transport will be visible for users'),
'tooltip': ugettext('If active, metapool will be visible for users'),
'type': gui.InputField.CHECKBOX_TYPE,
'order': 107,
'order': 123,
'tab': ugettext('Display'),
}]:
self.addField(g, f)

View File

@ -61,6 +61,7 @@ class MetaServicesPool(DetailHandler):
def as_dict(item: MetaPoolMember):
return {
'id': item.uuid,
'pool_id': item.pool.uuid,
'name': item.pool.name,
'comments': item.pool.comments,
'priority': item.priority,
@ -95,8 +96,8 @@ class MetaServicesPool(DetailHandler):
# If already exists
uuid = processUuid(item) if item is not None else None
pool = ServicePool.objects.get(uuid=processUuid(self._params['servicePoolId']))
enabled = self._params['enabled'].upper() in ('1', 'TRUE')
pool = ServicePool.objects.get(uuid=processUuid(self._params['pool_id']))
enabled = self._params['enabled'] not in ('false', False, '0', 0)
priority = int(self._params['priority'])
if uuid is not None:
@ -108,7 +109,7 @@ class MetaServicesPool(DetailHandler):
else:
parent.members.create(pool=pool, priority=priority, enabled=enabled)
log.doLog(parent, log.INFO, "Added meta pool member {}/{} by {}".format(pool.name, priority, self._user.pretty_name), log.ADMIN)
log.doLog(parent, log.INFO, (uuid is None and "Added" or "Modified") + " meta pool member {}/{}/{} by {}".format(pool.name, priority, enabled, self._user.pretty_name), log.ADMIN)
return self.success()

View File

@ -52,7 +52,7 @@ from uds.REST.model import ModelHandler
from uds.REST import RequestError, ResponseError
from uds.core.ui.UserInterface import gui
from .user_services import AssignedService, CachedService, Groups, Transports, Publications, Changelog
from uds.REST.methods.access_calendars import AccessCalendars, ActionsCalendars
from .op_calendars import AccessCalendars, ActionsCalendars
from .services import Services
from uds.core.managers import userServiceManager

View File

@ -148,6 +148,7 @@ class LogManager(object):
"""
owner_type = transDict.get(type(wichObject), None)
logger.debug('Getting log: %s -> %s', wichObject, owner_type)
if owner_type is not None:
return self.__getLogs(owner_type, wichObject.id, limit)

View File

@ -1,82 +0,0 @@
# Generated by Django 2.1.1 on 2018-09-28 10:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('uds', '0028_auto_20180316_1001'),
]
operations = [
migrations.CreateModel(
name='CalendarAccessMeta',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.CharField(default=None, max_length=50, null=True, unique=True)),
('access', models.CharField(default='DENY', max_length=8)),
('priority', models.IntegerField(db_index=True, default=0)),
('calendar', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='uds.Calendar')),
],
options={
'db_table': 'uds_cal_maccess',
'ordering': ('priority',),
},
),
migrations.CreateModel(
name='MetaPool',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.CharField(default=None, max_length=50, null=True, unique=True)),
('name', models.CharField(default='', max_length=128)),
('short_name', models.CharField(default='', max_length=32)),
('comments', models.CharField(default='', max_length=256)),
('visible', models.BooleanField(default=True)),
('fallbackAccess', models.CharField(default='ALLOW', max_length=8)),
('accessCalendars', models.ManyToManyField(related_name='accessMeta', through='uds.CalendarAccessMeta', to='uds.Calendar')),
('assignedGroups', models.ManyToManyField(db_table='uds__meta_grps', related_name='metaPools', to='uds.Group')),
('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='metaPools', to='uds.Image')),
],
options={
'abstract': False,
'db_table': 'uds__pool_meta',
},
),
migrations.CreateModel(
name='MetaPoolMember',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.CharField(default=None, max_length=50, null=True, unique=True)),
('priority', models.PositiveIntegerField(default=0)),
('enabled', models.BooleanField(default=True)),
('meta_pool', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metaPool', to='uds.MetaPool')),
('pool', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pool', to='uds.DeployedService')),
],
options={
'abstract': False,
'db_table': 'uds__meta_pool_member',
},
),
migrations.AddField(
model_name='metapool',
name='pools',
field=models.ManyToManyField(related_name='meta', through='uds.MetaPoolMember', to='uds.DeployedService'),
),
migrations.AddField(
model_name='metapool',
name='servicesPoolGroup',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='metaPools', to='uds.ServicesPoolGroup'),
),
migrations.AddField(
model_name='metapool',
name='tags',
field=models.ManyToManyField(to='uds.Tag'),
),
migrations.AddField(
model_name='calendaraccessmeta',
name='meta_pool',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='uds.MetaPool'),
),
]

View File

@ -30,11 +30,9 @@
"""
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
"""
from __future__ import unicode_literals
from django.db import models
from django.db.models import signals
from django.utils.translation import ugettext_noop as _
from uds.core.util import log
from uds.core.util import states
@ -49,15 +47,26 @@ from uds.models.Calendar import Calendar
import logging
__updated__ = '2018-10-01'
__updated__ = '2018-10-03'
logger = logging.getLogger(__name__)
class MetaPool(UUIDModel, TaggingMixin):
"""
A deployed service is the Service produced element that is assigned finally to an user (i.e. a Virtual Machine, etc..)
A meta pool is a pool that has pool members
"""
# Type of pool selection for meta pool
ROUND_ROBIN_POOL = 0
PRIORITY_POOL = 1
MOST_AVAILABLE_BY_NUMBER = 2
TYPES = {
ROUND_ROBIN_POOL: _('Round Robin (distribute among all services)'),
PRIORITY_POOL: _('Priority (lowest priority is first consumed)'),
MOST_AVAILABLE_BY_NUMBER: _('Most available (based on max services value and current used value)'),
}
name = models.CharField(max_length=128, default='')
short_name = models.CharField(max_length=32, default='')
comments = models.CharField(max_length=256, default='')
@ -72,6 +81,9 @@ class MetaPool(UUIDModel, TaggingMixin):
pools = models.ManyToManyField(ServicePool, through='MetapoolMember', related_name='meta')
# Pool selection policy
policy = models.SmallIntegerField(default=0)
class Meta(UUIDModel.Meta):
"""
Meta class to declare the name of the table at database
@ -99,7 +111,9 @@ class MetaPool(UUIDModel, TaggingMixin):
clean(toDelete)
def __str__(self):
return ''
return 'Meta pool: {}, no. pools: {}, visible: {}, policy: {}'.format(
self.name, self.pools.all().count(), self.visible, self.policy
)
# Connects a pre deletion signal

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# Copyright (c) 2012-2018 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -31,8 +31,6 @@
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
"""
from __future__ import unicode_literals
from django.db import models
from uds.models.Util import NEVER_UNIX
@ -40,8 +38,7 @@ from uds.models.Util import getSqlDatetime
import logging
__updated__ = '2016-01-19'
__updated__ = '2018-10-03'
logger = logging.getLogger(__name__)

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# Copyright (c) 2012-2018 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -31,14 +31,12 @@
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
"""
from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
import logging
__updated__ = '2018-01-29'
__updated__ = '2018-10-03'
logger = logging.getLogger(__name__)

View File

@ -1,6 +1,64 @@
# jshint strict: true
gui.metaPools = new GuiElement(api.metaPools, "metapools")
# Method to add/edit pool
newEditMemberPoolModal = (memberPools, refreshFnc, member) ->
gui.doLog('refreshFnc: ', refreshFnc)
if member != null
pool_id = member.pool_id
enabled = member.enabled
priority = member.priority
else
pool_id = null
enabled = true
priority = 1
api.templates.get "meta_add_pool", (tmpl) ->
api.servicesPools.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 service pool"), api.templates.evaluate(tmpl,
pools: data
pool_id: pool_id
enabled: enabled
priority: priority
))
$(modalId + " .button-accept").on "click", (event) ->
pool = $(modalId + " #id_pool_select").val()
enabled = $(modalId + " #id_enabled").is(":checked")
priority = $(modalId + " #id_priority").val()
if member != null # Modify
memberPools.rest.save
id: member.id
pool_id: pool
enabled: enabled
priority: priority
, (data) ->
$(modalId).modal "hide"
refreshFnc()
return
else # Create
memberPools.rest.create
pool_id: pool
enabled: enabled
priority: priority
, (data) ->
$(modalId).modal "hide"
refreshFnc()
return
return
# Makes form "beautyfull" :-)
gui.tools.applyCustoms modalId
return
return
return
# To allow fast admin navigation
gui.metaPools.fastLink = (event, obj) ->
gui.doLog 'FastLink clicked', obj
@ -126,12 +184,12 @@ gui.metaPools.link = (event) ->
#
# * Services pools part
#
servicePool = new GuiElement(api.metaPools.detail(metaPool.id, "pools", { permission: metaPool.permission }), "pools")
memberPools = new GuiElement(api.metaPools.detail(metaPool.id, "pools", { permission: metaPool.permission }), "pools")
# servicePool items table
servicePoolTable = servicePool.table(
memberPoolsTable = memberPools.table(
doNotLoadData: true
icon: 'pool'
icon: 'pools'
container: "meta-service-pools-placeholder"
rowSelect: "multi"
buttons: [
@ -140,8 +198,18 @@ gui.metaPools.link = (event) ->
"delete"
"xls"
]
onNew: (value, table, refreshFnc) ->
gui.doLog('v, t, r', value, table, refreshFnc)
newEditMemberPoolModal(memberPools, refreshFnc, null)
onEdit: (item, event, table, refreshFnc) ->
newEditMemberPoolModal(memberPools, refreshFnc, item)
onDelete: gui.methods.del(memberPools, gettext("Remove member pool"), gettext("Member pool removal error"))
)
prevTables.push servicePoolTable
prevTables.push memberPoolsTable
#
# * Groups part

View File

@ -0,0 +1,36 @@
{% load i18n %}
{% verbatim %}
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="id_priority" class="col-sm-2 control-label">{% endverbatim %}{% trans 'Priority' %}{% verbatim %}</label>
<div class="col-sm-10">
<input type="numeric" class="modal_field_data" id="id_priority" value="{{ priority }}">
</div>
</div>
<div class="form-group">
<label for="id_pool_select" class="col-sm-2 control-label">{% endverbatim %}{% trans 'Service pool' %}{% verbatim %}</label>
<div class="col-sm-10">
<select id="id_pool_select" name="pool" class="selectpicker show-menu-arrow show-tick modal_field_data" data-style="btn-default" data-width="100%">
<option value="-1"></option>
{{# each pools }}
<option value="{{ id }}"{{# ifequals id ../pool_id }} selected{{/ ifequals }}>{{ name }}</option>
{{/ each }}
</select>
</div>
</div>
<div class="form-group">
<label for="id_enabled" class="col-sm-3 control-label">{% endverbatim %}{% trans 'Enabled?' %}{% verbatim %}</label>
<div class="col-sm-9">
<input type="checkbox"
data-on-text="{% endverbatim %}{% trans 'Yes' %}{% verbatim %}"
data-off-text="{% endverbatim %}{% trans 'No' %}{% verbatim %}"
class="modal_field_data"
id="id_enabled"{{# ifequals enabled true }} checked{{/ ifequals }}>
</div>
</div>
</form>
{% endverbatim %}