mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
* Added "Service Pool Group" full logic, so new we can add services pools to groups, so we can visualzize them grouped. (already needs the visualizarion part)
* Finished basic taglist edition (fixed a bug & added the possibility of insert serveral comma separated values at once')
This commit is contained in:
parent
e1b8c43cca
commit
a08fe53383
@ -52,7 +52,7 @@ class Authenticators(ModelHandler):
|
||||
# Custom get method "search" that requires authenticator id
|
||||
custom_methods = [('search', True)]
|
||||
detail = {'users': Users, 'groups': Groups}
|
||||
save_fields = ['name', 'comments', 'priority', 'small_name']
|
||||
save_fields = ['name', 'comments', 'tags', 'priority', 'small_name']
|
||||
|
||||
table_title = _('Current authenticators')
|
||||
table_fields = [
|
||||
@ -80,7 +80,7 @@ class Authenticators(ModelHandler):
|
||||
|
||||
def getGui(self, type_):
|
||||
try:
|
||||
return self.addDefaultFields(auths.factory().lookup(type_).guiDescription(), ['name', 'comments', 'priority', 'small_name'])
|
||||
return self.addDefaultFields(auths.factory().lookup(type_).guiDescription(), ['name', 'comments', 'tags', 'priority', 'small_name'])
|
||||
except:
|
||||
raise NotFound('type not found')
|
||||
|
||||
|
@ -53,7 +53,7 @@ class Calendars(ModelHandler):
|
||||
model = Calendar
|
||||
detail = {'rules': CalendarRules}
|
||||
|
||||
save_fields = ['name', 'comments']
|
||||
save_fields = ['name', 'comments', 'tags']
|
||||
|
||||
table_title = _('Calendars')
|
||||
table_fields = [
|
||||
@ -73,4 +73,4 @@ class Calendars(ModelHandler):
|
||||
}
|
||||
|
||||
def getGui(self, type_):
|
||||
return self.addDefaultFields([], ['name', 'comments'])
|
||||
return self.addDefaultFields([], ['name', 'comments', 'tags'])
|
||||
|
@ -78,7 +78,7 @@ class Images(ModelHandler):
|
||||
'value': '',
|
||||
'label': ugettext('Image'),
|
||||
'tooltip': ugettext('Image object'),
|
||||
'type': gui.InputField.IMAGE_TYPE,
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 100, # At end
|
||||
}
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ class Networks(ModelHandler):
|
||||
Implements specific handling for network related requests using GUI
|
||||
'''
|
||||
model = Network
|
||||
save_fields = ['name', 'net_string']
|
||||
save_fields = ['name', 'net_string', 'tags']
|
||||
|
||||
table_title = _('Current Networks')
|
||||
table_fields = [
|
||||
@ -74,7 +74,7 @@ class Networks(ModelHandler):
|
||||
|
||||
def getGui(self, type_):
|
||||
return self.addField(
|
||||
self.addDefaultFields([], ['name']), {
|
||||
self.addDefaultFields([], ['name', 'tags']), {
|
||||
'name': 'net_string',
|
||||
'value': '',
|
||||
'label': ugettext('Network range'),
|
||||
|
@ -50,7 +50,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class OsManagers(ModelHandler):
|
||||
model = OSManager
|
||||
save_fields = ['name', 'comments']
|
||||
save_fields = ['name', 'comments', 'tags']
|
||||
|
||||
table_title = _('Current OS Managers')
|
||||
table_fields = [
|
||||
@ -89,6 +89,6 @@ class OsManagers(ModelHandler):
|
||||
# Gui related
|
||||
def getGui(self, type_):
|
||||
try:
|
||||
return self.addDefaultFields(factory().lookup(type_).guiDescription(), ['name', 'comments'])
|
||||
return self.addDefaultFields(factory().lookup(type_).guiDescription(), ['name', 'comments', 'tags'])
|
||||
except:
|
||||
raise NotFound('type not found')
|
||||
|
@ -56,7 +56,7 @@ class Providers(ModelHandler):
|
||||
detail = {'services': DetailServices}
|
||||
custom_methods = [('allservices', False), ('service', False), ('maintenance', True)]
|
||||
|
||||
save_fields = ['name', 'comments']
|
||||
save_fields = ['name', 'comments', 'tags']
|
||||
|
||||
table_title = _('Service providers')
|
||||
|
||||
|
@ -35,7 +35,7 @@ from __future__ import unicode_literals
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
||||
from uds.models import Service, UserService
|
||||
from uds.models import Service, UserService, Tag
|
||||
|
||||
from uds.core.services import Service as coreService
|
||||
from uds.core.util import log
|
||||
@ -130,7 +130,9 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
|
||||
# Extract item db fields
|
||||
# We need this fields for all
|
||||
logger.debug('Saving service {0} / {1}'.format(parent, item))
|
||||
fields = self.readFieldsFromParams(['name', 'comments', 'data_type'])
|
||||
fields = self.readFieldsFromParams(['name', 'comments', 'data_type', 'tags'])
|
||||
tags = fields['tags']
|
||||
del fields['tags']
|
||||
service = None
|
||||
try:
|
||||
if item is None: # Create new
|
||||
@ -139,6 +141,8 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
|
||||
service = parent.services.get(uuid=processUuid(item))
|
||||
service.__dict__.update(fields)
|
||||
|
||||
service.tags = [Tag.objects.get_or_create(tag=val)[0] for val in tags]
|
||||
|
||||
service.data = service.getInstance(self._params).serialize()
|
||||
service.save()
|
||||
except Service.DoesNotExist:
|
||||
@ -209,7 +213,7 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
|
||||
parentInstance = parent.getInstance()
|
||||
serviceType = parentInstance.getServiceByType(forType)
|
||||
service = serviceType(Environment.getTempEnv(), parentInstance) # Instantiate it so it has the opportunity to alter gui description based on parent
|
||||
return self.addDefaultFields(service.guiDescription(service), ['name', 'comments'])
|
||||
return self.addDefaultFields(service.guiDescription(service), ['name', 'comments', 'tags'])
|
||||
except Exception as e:
|
||||
logger.exception('getGui')
|
||||
raise ResponseError(unicode(e))
|
||||
|
105
server/src/uds/REST/methods/services_pool_groups.py
Normal file
105
server/src/uds/REST/methods/services_pool_groups.py
Normal file
@ -0,0 +1,105 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@itemor: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext
|
||||
from uds.models import ServicesPoolGroup, Image
|
||||
from uds.core.util.model import processUuid
|
||||
from uds.core.ui.UserInterface import gui
|
||||
from uds.core.ui.images import DEFAULT_THUMB_BASE64
|
||||
|
||||
from uds.REST.model import ModelHandler
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Enclosed methods under /item path
|
||||
|
||||
|
||||
class ServicesPoolGroups(ModelHandler):
|
||||
'''
|
||||
Handles the gallery REST interface
|
||||
'''
|
||||
needs_admin = True
|
||||
|
||||
path = 'gallery'
|
||||
model = ServicesPoolGroup
|
||||
save_fields = ['name', 'comments', 'image_id']
|
||||
|
||||
table_title = _('Services Pool Groups')
|
||||
table_fields = [
|
||||
{'name': {'title': _('Name')}},
|
||||
{'thumb': {'title': _('Image'), 'visible': True, 'type': 'image'}},
|
||||
]
|
||||
|
||||
def beforeSave(self, fields):
|
||||
imgId = fields['image_id']
|
||||
fields['image_id'] = None
|
||||
logger.debug('Image id: {}'.format(imgId))
|
||||
try:
|
||||
if imgId != '-1':
|
||||
image = Image.objects.get(uuid=processUuid(imgId))
|
||||
fields['image_id'] = image.id
|
||||
except Exception:
|
||||
logger.exception('At image recovering')
|
||||
|
||||
# Gui related
|
||||
def getGui(self, type_):
|
||||
g = self.addDefaultFields([], ['name', 'comments'])
|
||||
|
||||
for f in [{
|
||||
'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'),
|
||||
'tooltip': ugettext('Image assocciated with this service'),
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 102,
|
||||
}]:
|
||||
self.addField(g, f)
|
||||
|
||||
return g
|
||||
|
||||
def item_as_dict(self, item):
|
||||
return {
|
||||
'id': item.uuid,
|
||||
'name': item.name,
|
||||
'image_id': item.image.uuid,
|
||||
}
|
||||
|
||||
def item_as_dict_overview(self, item):
|
||||
return {
|
||||
'id': item.uuid,
|
||||
'name': item.name,
|
||||
'thumb': item.image.thumb64,
|
||||
}
|
@ -33,7 +33,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
from uds.models import DeployedService, OSManager, Service, Image
|
||||
from uds.models import DeployedService, OSManager, Service, Image, ServicesPoolGroup
|
||||
from uds.core.ui.images import DEFAULT_THUMB_BASE64
|
||||
from uds.core.util.State import State
|
||||
from uds.core.util.model import processUuid
|
||||
@ -64,7 +64,7 @@ class ServicesPools(ModelHandler):
|
||||
'changelog': Changelog
|
||||
}
|
||||
|
||||
save_fields = ['name', 'comments', 'service_id', 'osmanager_id', 'image_id', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports']
|
||||
save_fields = ['name', 'comments', 'tags', 'service_id', 'osmanager_id', 'image_id', 'servicesPoolGroup_id', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports']
|
||||
remove_fields = ['osmanager_id', 'service_id']
|
||||
|
||||
table_title = _('Service Pools')
|
||||
@ -73,7 +73,7 @@ class ServicesPools(ModelHandler):
|
||||
{'parent': {'title': _('Parent Service')}},
|
||||
{'state': {'title': _('status'), 'type': 'dict', 'dict': State.dictionary()}},
|
||||
{'show_transports': {'title': _('Shows transports'), 'type': 'callback'}},
|
||||
{'comments': {'title': _('Comments')}},
|
||||
{'servicesPoolGroup': {'title': _('Services Pool Group')}},
|
||||
]
|
||||
# Field from where to get "class" and prefix for that class, so this will generate "row-state-A, row-state-X, ....
|
||||
table_row_style = {'field': 'state', 'prefix': 'row-state-'}
|
||||
@ -93,6 +93,8 @@ class ServicesPools(ModelHandler):
|
||||
'service_id': item.service.uuid,
|
||||
'provider_id': item.service.provider.uuid,
|
||||
'image_id': item.image.uuid if item.image is not None else None,
|
||||
'servicesPoolGroup_id': item.servicesPoolGroup.uuid if item.servicesPoolGroup is not None else None,
|
||||
'servicesPoolGroup': item.servicesPoolGroup.name if item.servicesPoolGroup is not None else _('Default'),
|
||||
'initial_srvs': item.initial_srvs,
|
||||
'cache_l1_srvs': item.cache_l1_srvs,
|
||||
'cache_l2_srvs': item.cache_l2_srvs,
|
||||
@ -116,7 +118,7 @@ class ServicesPools(ModelHandler):
|
||||
if Service.objects.count() < 1:
|
||||
raise ResponseError(ugettext('Create at least a service before creating a new service pool'))
|
||||
|
||||
g = self.addDefaultFields([], ['name', 'comments'])
|
||||
g = self.addDefaultFields([], ['name', 'comments', 'tags'])
|
||||
|
||||
for f in [{
|
||||
'name': 'service_id',
|
||||
@ -141,6 +143,13 @@ class ServicesPools(ModelHandler):
|
||||
'tooltip': ugettext('Image assocciated with this service'),
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 102,
|
||||
}, {
|
||||
'name': 'servicesPoolGroup_id',
|
||||
'values': [gui.choiceImage(-1, _('Default'), DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.image.thumb64) for v in ServicesPoolGroup.objects.all()]),
|
||||
'label': ugettext('Pool group'),
|
||||
'tooltip': ugettext('Pool group for this pool (for pool clasify on display)'),
|
||||
'type': gui.InputField.IMAGECHOICE_TYPE,
|
||||
'order': 103,
|
||||
}, {
|
||||
'name': 'initial_srvs',
|
||||
'value': '0',
|
||||
@ -148,7 +157,7 @@ class ServicesPools(ModelHandler):
|
||||
'label': ugettext('Initial available services'),
|
||||
'tooltip': ugettext('Services created initially for this service pool'),
|
||||
'type': gui.InputField.NUMERIC_TYPE,
|
||||
'order': 103,
|
||||
'order': 110,
|
||||
}, {
|
||||
'name': 'cache_l1_srvs',
|
||||
'value': '0',
|
||||
@ -156,7 +165,7 @@ class ServicesPools(ModelHandler):
|
||||
'label': ugettext('Services to keep in cache'),
|
||||
'tooltip': ugettext('Services kept in cache for improved user service assignation'),
|
||||
'type': gui.InputField.NUMERIC_TYPE,
|
||||
'order': 104,
|
||||
'order': 111,
|
||||
}, {
|
||||
'name': 'cache_l2_srvs',
|
||||
'value': '0',
|
||||
@ -164,7 +173,7 @@ class ServicesPools(ModelHandler):
|
||||
'label': ugettext('Services to keep in L2 cache'),
|
||||
'tooltip': ugettext('Services kept in cache of level2 for improved service generation'),
|
||||
'type': gui.InputField.NUMERIC_TYPE,
|
||||
'order': 105,
|
||||
'order': 112,
|
||||
}, {
|
||||
'name': 'max_srvs',
|
||||
'value': '0',
|
||||
@ -172,14 +181,14 @@ class ServicesPools(ModelHandler):
|
||||
'label': ugettext('Maximum number of services to provide'),
|
||||
'tooltip': ugettext('Maximum number of service (assigned and L1 cache) that can be created for this service'),
|
||||
'type': gui.InputField.NUMERIC_TYPE,
|
||||
'order': 106,
|
||||
'order': 113,
|
||||
}, {
|
||||
'name': 'show_transports',
|
||||
'value': True,
|
||||
'label': ugettext('Show transports'),
|
||||
'tooltip': ugettext('If active, alternative transports for user will be shown'),
|
||||
'type': gui.InputField.CHECKBOX_TYPE,
|
||||
'order': 107,
|
||||
'order': 120,
|
||||
}]:
|
||||
self.addField(g, f)
|
||||
|
||||
@ -226,6 +235,17 @@ class ServicesPools(ModelHandler):
|
||||
except Exception:
|
||||
logger.exception('At image recovering')
|
||||
|
||||
# Servicepool Group
|
||||
spgrpId = fields['servicesPoolGroup_id']
|
||||
fields['servicesPoolGroup_id'] = None
|
||||
logger.debug('servicesPoolGroup_id: {}'.format(spgrpId))
|
||||
try:
|
||||
if imgId != '-1':
|
||||
spgrp = ServicesPoolGroup.objects.get(uuid=processUuid(spgrpId))
|
||||
fields['servicesPoolGroup_id'] = spgrp.id
|
||||
except Exception:
|
||||
logger.exception('At service pool group recovering')
|
||||
|
||||
except (RequestError, ResponseError):
|
||||
raise
|
||||
except Exception as e:
|
||||
|
@ -48,7 +48,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Transports(ModelHandler):
|
||||
model = Transport
|
||||
save_fields = ['name', 'comments', 'priority', 'nets_positive']
|
||||
save_fields = ['name', 'comments', 'tags', ' priority', 'nets_positive']
|
||||
|
||||
table_title = _('Current Transports')
|
||||
table_fields = [
|
||||
@ -64,7 +64,7 @@ class Transports(ModelHandler):
|
||||
def getGui(self, type_):
|
||||
try:
|
||||
return self.addField(
|
||||
self.addField(self.addDefaultFields(factory().lookup(type_).guiDescription(), ['name', 'comments', 'priority']), {
|
||||
self.addField(self.addDefaultFields(factory().lookup(type_).guiDescription(), ['name', 'comments', 'tags', 'priority']), {
|
||||
'name': 'nets_positive',
|
||||
'value': True,
|
||||
'label': ugettext('Network access'),
|
||||
|
@ -42,6 +42,8 @@ from uds.REST.handlers import Handler, HandlerError
|
||||
from uds.core.util import log
|
||||
from uds.core.util import permissions
|
||||
from uds.core.util.model import processUuid
|
||||
from uds.models import Tag
|
||||
|
||||
|
||||
import fnmatch
|
||||
import re
|
||||
@ -52,7 +54,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2016-02-10'
|
||||
__updated__ = '2016-02-12'
|
||||
|
||||
|
||||
# a few constants
|
||||
@ -841,6 +843,13 @@ class ModelHandler(BaseModelHandler):
|
||||
args = self.readFieldsFromParams(self.save_fields)
|
||||
logger.debug('Args: {}'.format(args))
|
||||
self.beforeSave(args)
|
||||
# If tags is in save fields, treat it "specially"
|
||||
if 'tags' in self.save_fields:
|
||||
tags = args['tags']
|
||||
del args['tags']
|
||||
else:
|
||||
tags = None
|
||||
|
||||
deleteOnError = False
|
||||
if len(self._args) == 0: # create new
|
||||
item = self.model.objects.create(**args)
|
||||
@ -852,6 +861,12 @@ class ModelHandler(BaseModelHandler):
|
||||
if v in args:
|
||||
del args[v]
|
||||
item.__dict__.update(args) # Update fields from args
|
||||
|
||||
# Now if tags, update them
|
||||
if tags is not None:
|
||||
logger.debug('Updating tags: {}'.format(tags))
|
||||
item.tags = [ Tag.objects.get_or_create(tag=val)[0] for val in tags]
|
||||
|
||||
except self.model.DoesNotExist:
|
||||
raise NotFound('Item not found')
|
||||
except IntegrityError: # Duplicate key probably
|
||||
|
34
server/src/uds/migrations/0020_auto_20160212_0330.py
Normal file
34
server/src/uds/migrations/0020_auto_20160212_0330.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('uds', '0019_auto_20160210_0144'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ServicesPoolGroup',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('uuid', models.CharField(default=None, max_length=50, unique=True, null=True)),
|
||||
('name', models.CharField(default='', max_length=128)),
|
||||
('comments', models.CharField(default='', max_length=256)),
|
||||
('image', models.ForeignKey(related_name='servicesPoolsGrou', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='uds.Image', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'db_table': 'uds__pools_groups',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='deployedservice',
|
||||
name='servicesPoolGroup',
|
||||
field=models.ForeignKey(related_name='servicesPools', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='uds.ServicesPoolGroup', null=True),
|
||||
),
|
||||
]
|
@ -49,6 +49,7 @@ from uds.models.Service import Service
|
||||
from uds.models.Transport import Transport
|
||||
from uds.models.Group import Group
|
||||
from uds.models.Image import Image
|
||||
from uds.models.ServicesPoolGroup import ServicesPoolGroup
|
||||
|
||||
from uds.models.Util import NEVER
|
||||
from uds.models.Util import getSqlDatetime
|
||||
@ -56,7 +57,7 @@ from uds.models.Util import getSqlDatetime
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-02-10'
|
||||
__updated__ = '2016-02-12'
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -78,12 +79,16 @@ class DeployedService(UUIDModel, TaggingMixin):
|
||||
state_date = models.DateTimeField(default=NEVER)
|
||||
show_transports = models.BooleanField(default=True)
|
||||
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)
|
||||
|
||||
initial_srvs = models.PositiveIntegerField(default=0)
|
||||
cache_l1_srvs = models.PositiveIntegerField(default=0)
|
||||
cache_l2_srvs = models.PositiveIntegerField(default=0)
|
||||
max_srvs = models.PositiveIntegerField(default=0)
|
||||
current_pub_revision = models.PositiveIntegerField(default=1)
|
||||
|
||||
|
||||
# Meta service related
|
||||
meta_pools = models.ManyToManyField('self', symmetrical=False)
|
||||
|
||||
|
70
server/src/uds/models/ServicesPoolGroup.py
Normal file
70
server/src/uds/models/ServicesPoolGroup.py
Normal file
@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
.. 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.encoding import python_2_unicode_compatible
|
||||
|
||||
from uds.models.UUIDModel import UUIDModel
|
||||
from uds.models.Image import Image
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-02-12'
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class ServicesPoolGroup(UUIDModel):
|
||||
'''
|
||||
A deployed service is the Service produced element that is assigned finally to an user (i.e. a Virtual Machine, etc..)
|
||||
'''
|
||||
# pylint: disable=model-missing-unicode
|
||||
name = models.CharField(max_length=128, default='')
|
||||
comments = models.CharField(max_length=256, default='')
|
||||
image = models.ForeignKey(Image, null=True, blank=True, related_name='servicesPoolsGrou', on_delete=models.SET_NULL)
|
||||
|
||||
class Meta(UUIDModel.Meta):
|
||||
'''
|
||||
Meta class to declare the name of the table at database
|
||||
'''
|
||||
db_table = 'uds__pools_groups'
|
||||
app_label = 'uds'
|
||||
|
||||
def __str__(self):
|
||||
return u"Service Pool group {0}({1})".format(self.name, self.comments)
|
||||
|
@ -65,6 +65,7 @@ from .Group import Group
|
||||
# Provisioned services
|
||||
from .ServicesPool import DeployedService # Old name, will continue here for a while already
|
||||
from .ServicesPool import ServicePool # New name
|
||||
from .ServicesPoolGroup import ServicesPoolGroup
|
||||
from .ServicesPoolPublication import DeployedServicePublication
|
||||
from .UserService import UserService
|
||||
from .UserServiceProperty import UserServiceProperty
|
||||
@ -101,7 +102,7 @@ from .CalendarRule import CalendarRule
|
||||
# Tagging
|
||||
from .Tag import Tag
|
||||
|
||||
__updated__ = '2016-02-10'
|
||||
__updated__ = '2016-02-12'
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -425,6 +425,7 @@ api.networks = new BasicModelRest("networks")
|
||||
api.servicesPools = new BasicModelRest("servicespools")
|
||||
api.configuration = new BasicModelRest("config")
|
||||
api.gallery = new BasicModelRest("gallery/images")
|
||||
api.sPoolGroups = new BasicModelRest("gallery/servicespoolgroups")
|
||||
api.system = new BasicModelRest("system")
|
||||
api.reports = new BasicModelRest("reports") # Not fully used, but basic usage is common
|
||||
api.calendars = new BasicModelRest("calendars")
|
||||
|
28
server/src/uds/static/adm/js/gui-d-servicespoolsgroup.coffee
Normal file
28
server/src/uds/static/adm/js/gui-d-servicespoolsgroup.coffee
Normal file
@ -0,0 +1,28 @@
|
||||
gui.sPoolGroups = new GuiElement(api.sPoolGroups, "spal")
|
||||
gui.sPoolGroups.link = ->
|
||||
gui.doLog 'Executing pool groups'
|
||||
"use strict"
|
||||
|
||||
if api.config.admin is false
|
||||
return
|
||||
|
||||
api.templates.get "services_pool_groups", (tmpl) ->
|
||||
gui.clearWorkspace()
|
||||
gui.appendToWorkspace api.templates.evaluate(tmpl,
|
||||
sPoolGroups: "sPoolGroups-placeholder"
|
||||
)
|
||||
gui.sPoolGroups.table
|
||||
icon: 'sPoolGroups'
|
||||
container: "sPoolGroups-placeholder"
|
||||
rowSelect: "single"
|
||||
buttons: [
|
||||
"new"
|
||||
"edit"
|
||||
"delete"
|
||||
]
|
||||
onNew: gui.methods.typedNew(gui.sPoolGroups, gettext("New services Services Pool Group"), gettext("Services Services Pool Group creation error"))
|
||||
onEdit: gui.methods.typedEdit(gui.sPoolGroups, gettext("Edit services Services Pool Group"), gettext("Services Provider saving error"))
|
||||
onDelete: gui.methods.del(gui.sPoolGroups, gettext("Delete Services Pool Group"), gettext("Services Pool Group error"))
|
||||
return
|
||||
|
||||
return
|
@ -240,6 +240,11 @@
|
||||
exec: gui.calendars.link
|
||||
cleanup: true
|
||||
}
|
||||
{
|
||||
id: "lnk-spoolsgroup"
|
||||
exec: gui.sPoolGroups.link
|
||||
cleanup: true
|
||||
}
|
||||
]
|
||||
$.each sidebarLinks, (index, value) ->
|
||||
gui.doLog "Adding " + value.id
|
||||
|
@ -121,6 +121,7 @@
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-servicespools.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-config.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-gallery.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-servicespoolsgroup.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-reports.coffee"></script>
|
||||
<script type="text/coffeescript" charset="utf-8" src="{% get_static_prefix %}adm/js/gui-d-calendar.coffee"></script>
|
||||
<!-- base64 encoding -->
|
||||
|
@ -30,6 +30,7 @@
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/tools.png"/> <span class="menu-lnk">{% trans 'Tools' %} <b class="caret"></b></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="lnk-gallery" href="#"><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/gallery.png"/> <span class="menu-lnk">{% trans 'Gallery' %}</span></a></li>
|
||||
<li><a class="lnk-spoolsgroup" href="#"><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/groups.png"/> <span class="menu-lnk">{% trans 'Services Pool Group' %}</span></a></li>
|
||||
<li><a class="lnk-reports" href=""><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/reports.png"/> <span class="menu-lnk">{% trans 'Reports' %}</a></span></li>
|
||||
<li><a class="lnk-configuration" href="#"><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/configuration.png"/> <span class="menu-lnk">{% trans 'Configuration' %}</span></a></li>
|
||||
<li><a class="lnk-clear_cache" href="#"><img class="icon" src="{{ STATIC_URL }}/adm/img/icons/flush-cache.png"/> <span class="menu-lnk">{% trans 'Flush cache' %}</span></a></li>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<span class="label label-success tag tagadder" id="adder{{ id }}">{% endverbatim %}{% trans 'Add Tag...' %}{% verbatim %}</span>
|
||||
{{/ unless }}
|
||||
|
||||
<input id="h{{ id }}" type="hidden" data-uds="list" name="{{ name }}" value="{{ value }}" class="{{ css }}" />
|
||||
<input id="h{{ id }}" type="hidden" data-uds="commaList" name="{{ name }}" value="{{ value }}" class="{{ css }}" />
|
||||
|
||||
{% endverbatim %}
|
||||
{% comment %}<script>/*This is a little trick to make IDE recognize sintax hightlight, will not be show on render :-)*/{% endcomment %}
|
||||
@ -44,7 +44,9 @@
|
||||
// Tagadder never gets destroyed, so we only set the event once
|
||||
$('#adder{{ id }}').on('click', function(){
|
||||
var text = prompt('Enter new tag');
|
||||
addTag(text);
|
||||
$.each( text.split(','), function (idx, value) {
|
||||
addTag(value);
|
||||
});
|
||||
});
|
||||
|
||||
{{/ unless }}
|
||||
|
@ -0,0 +1,28 @@
|
||||
{% load i18n html5 static %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h1>{% trans 'UDS Services Pool Groups' %}</h1>
|
||||
<!-- <ol class="breadcrumb">
|
||||
<li><a class="lnk-dashboard" href="#">Dashboard</a></li>
|
||||
<li>{% trans 'Gallery' %}</li>
|
||||
</ol> -->
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
{% if messages %}
|
||||
<div class="row">
|
||||
<div class="col-md-offset-2 col-md-8">
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% verbatim %}
|
||||
<div class="row">
|
||||
<div id="{{ sPoolGroups }}" class="col-xs-12"></div>
|
||||
</div>
|
||||
{% endverbatim %}
|
Loading…
Reference in New Issue
Block a user