mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-31 17:17:53 +03:00
* Added more methods needed at oVirtClient
* Finished (need testing) oVirtLinkedService, so now we can add new oVirtLinkedServices, but can't publish it :-) * Added helpers methods to allow new oVirtLinkedServices
This commit is contained in:
parent
85dd9b0537
commit
0bb26cfae1
44
server/src/uds/services/OVirt/Helpers.py
Normal file
44
server/src/uds/services/OVirt/Helpers.py
Normal file
@ -0,0 +1,44 @@
|
||||
'''
|
||||
Created on Nov 15, 2012
|
||||
|
||||
@author: dkmaster
|
||||
'''
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class oVirtHelpers(object):
|
||||
|
||||
@staticmethod
|
||||
def getResources(parameters):
|
||||
'''
|
||||
This helper is designed as a callback for machine selector, so we can provide valid clusters and datastores domains based on it
|
||||
'''
|
||||
from OVirtProvider import Provider
|
||||
from uds.core.Environment import Environment
|
||||
logger.debug('Parameters received by getResources Helper: {0}'.format(parameters))
|
||||
env = Environment(parameters['ev'])
|
||||
provider = Provider(env)
|
||||
provider.unserialize(parameters['ov'])
|
||||
|
||||
# Obtains datacenter from cluster
|
||||
ci = provider.getClusterInfo(parameters['cluster'])
|
||||
|
||||
res = []
|
||||
# Get storages for that datacenter
|
||||
for storage in provider.getDatacenterInfo(ci['datacenter_id'])['storage']:
|
||||
if storage['active'] is True and storage['type'] == 'data':
|
||||
space, free = storage['available']/1024/1024/1024, (storage['available']-storage['used'])/1024/1024/1024
|
||||
|
||||
res.append( {'id': storage['id'], 'text': "%s (%4.2f Gb/%4.2f Gb)" % (storage['name'], space, free ) })
|
||||
data = [{
|
||||
'name' : 'datastore', 'values' : res
|
||||
}]
|
||||
|
||||
logger.debug('return data: {0}'.format(data))
|
||||
return data
|
||||
|
||||
|
||||
|
@ -42,6 +42,8 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from Helpers import oVirtHelpers
|
||||
|
||||
class OVirtLinkedService(Service):
|
||||
'''
|
||||
oVirt Linked clones service. This is based on creating a template from selected vm, and then use it to
|
||||
@ -93,21 +95,25 @@ class OVirtLinkedService(Service):
|
||||
#: Types of deploys (services in cache and/or assigned to users)
|
||||
deployedType = OVirtLinkedDeployment
|
||||
|
||||
# Now the form part, this service will have only two "dummy" fields
|
||||
# If we don't indicate an order, the output order of fields will be
|
||||
# "random"
|
||||
# Now the form part
|
||||
machine = gui.ChoiceField(label=translatable("Base Machine"), order = 1, tooltip = _('Service base machine'), required = True)
|
||||
cluster = gui.ChoiceField(label=translatable("Cluster"), order = 2,
|
||||
fills = {
|
||||
'callbackName' : 'ovFillResourcesFromCluster',
|
||||
'function' : oVirtHelpers.getResources,
|
||||
'parameters' : ['cluster', 'ov', 'ev']
|
||||
},
|
||||
tooltip = translatable("Cluster to contain services"), required = True
|
||||
)
|
||||
|
||||
machine = gui.ChoiceField(label = _("Base Machine"), order = 6, tooltip = _('Base machine for this service'), required = True )
|
||||
datastore = gui.ChoiceField(label = translatable("Datastore Domain"), rdonly = False, order = 3,
|
||||
tooltip = translatable('Datastore domain where to publish and put incrementals'), required = True)
|
||||
baseName = gui.TextField(label = translatable('Machine Names'), rdonly = False, order = 4, tooltip = ('Base name for clones from this machine'), required = True)
|
||||
lenName = gui.NumericField(length = 1, label = translatable('Name Length'), defvalue = 3, order = 5,
|
||||
tooltip = translatable('Length of numeric part for the names of this machines (betwen 3 and 6'), required = True)
|
||||
|
||||
|
||||
|
||||
baseName = gui.TextField(order = 3,
|
||||
label = translatable('Services names'),
|
||||
tooltip = translatable('Base name for this user services'),
|
||||
# In this case, the choice can have none value selected by default
|
||||
required = True,
|
||||
defvalue = '' # Default value is the ID of the choicefield
|
||||
)
|
||||
ov = gui.HiddenField()
|
||||
ev = gui.HiddenField() # We need to keep the env so we can instantiate the Provider
|
||||
|
||||
def initialize(self, values):
|
||||
'''
|
||||
@ -116,40 +122,27 @@ class OVirtLinkedService(Service):
|
||||
Note that we check them throught FROM variables, that already has been
|
||||
initialized by __init__ method of base class, before invoking this.
|
||||
'''
|
||||
|
||||
# We don't need to check anything, bat because this is a sample, we do
|
||||
# As in provider, we receive values only at new Service creation,
|
||||
# so we only need to validate params if values is not None
|
||||
if values is not None:
|
||||
if self.colour.value == 'nonsense':
|
||||
raise Service.ValidationException('The selected colour is invalid!!!')
|
||||
|
||||
|
||||
# Services itself are non testeable right now, so we don't even have
|
||||
# to provide one!!!
|
||||
|
||||
length = int(self.lenName.value)
|
||||
if len(self.baseName.value) + length > 15:
|
||||
raise Service.ValidationException(_('The length of basename plus length must not be greater than 15'))
|
||||
if self.baseName.value.isdigit():
|
||||
raise Service.ValidationException(_('The machine name can\'t be only numbers'))
|
||||
|
||||
# Congratulations!!!, the needed part of your first simple service is done!
|
||||
# Now you can go to administration panel, and check it
|
||||
#
|
||||
# From now onwards, we implement our own methods, that will be used by,
|
||||
# for example, services derived from this provider
|
||||
|
||||
def getColour(self):
|
||||
'''
|
||||
Simply returns colour, for deployed user services.
|
||||
machines = self.parent().getMachines()
|
||||
vals = []
|
||||
for m in machines:
|
||||
vals.append( gui.choiceItem( m['id'], m['name'] ))
|
||||
self.machine.setValues(vals)
|
||||
|
||||
clusters = self.parent().getClusters()
|
||||
vals = []
|
||||
for c in clusters:
|
||||
vals.append( gui.choiceItem(c['id'], c['name'] ) )
|
||||
self.cluster.setValues(vals)
|
||||
|
||||
|
||||
def initGui(self):
|
||||
self.ov.value = self.parent().serialize()
|
||||
self.ev.value = self.parent().env().key()
|
||||
|
||||
Remember that choiceField.value returns the id part of the ChoiceItem
|
||||
'''
|
||||
return self.colour.value
|
||||
|
||||
def getPassw(self):
|
||||
'''
|
||||
Simply returns passwd, for deloyed user services
|
||||
'''
|
||||
return self.passw.value
|
||||
|
||||
def getBaseName(self):
|
||||
'''
|
||||
'''
|
||||
return self.baseName.value
|
||||
|
@ -118,9 +118,120 @@ class Provider(ServiceProvider):
|
||||
self._api = None
|
||||
|
||||
def testConnection(self):
|
||||
api = self.__getApi()
|
||||
return api.test()
|
||||
'''
|
||||
Test that conection to oVirt server is fine
|
||||
|
||||
Returns
|
||||
|
||||
True if all went fine, false if id didn't
|
||||
'''
|
||||
|
||||
return self.__getApi().test()
|
||||
|
||||
def getMachines(self, force = False):
|
||||
'''
|
||||
Obtains the list of machines inside oVirt.
|
||||
Machines starting with UDS are filtered out
|
||||
|
||||
Args:
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
An array of dictionaries, containing:
|
||||
'name'
|
||||
'id'
|
||||
'cluster_id'
|
||||
'''
|
||||
|
||||
return self.__getApi().getVms(force)
|
||||
|
||||
def getClusters(self, force = False):
|
||||
'''
|
||||
Obtains the list of clusters inside oVirt.
|
||||
|
||||
Args:
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
Filters out clusters not attached to any datacenter
|
||||
An array of dictionaries, containing:
|
||||
'name'
|
||||
'id'
|
||||
'datacenter_id'
|
||||
'''
|
||||
|
||||
return self.__getApi().getClusters(force)
|
||||
|
||||
def getClusterInfo(self, clusterId, force = False):
|
||||
'''
|
||||
Obtains the cluster info
|
||||
|
||||
Args:
|
||||
datacenterId: Id of the cluster to get information about it
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
|
||||
A dictionary with following values
|
||||
'name'
|
||||
'id'
|
||||
'datacenter_id'
|
||||
'''
|
||||
return self.__getApi().getClusterInfo(clusterId, force)
|
||||
|
||||
def getDatacenterInfo(self, datacenterId, force = False):
|
||||
'''
|
||||
Obtains the datacenter info
|
||||
|
||||
Args:
|
||||
datacenterId: Id of the datacenter to get information about it
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
|
||||
A dictionary with following values
|
||||
'name'
|
||||
'id'
|
||||
'storage_type' -> ('isisi', 'nfs', ....)
|
||||
'storage_format' -> ('v1', v2')
|
||||
'description'
|
||||
'storage' -> array of dictionaries, with:
|
||||
'id' -> Storage id
|
||||
'name' -> Storage name
|
||||
'type' -> Storage type ('data', 'iso')
|
||||
'available' -> Space available, in bytes
|
||||
'used' -> Space used, in bytes
|
||||
'active' -> True or False
|
||||
|
||||
'''
|
||||
return self.__getApi().getDatacenterInfo(datacenterId, force)
|
||||
|
||||
def getStorageInfo(self, storageId, force = False):
|
||||
'''
|
||||
Obtains the datacenter info
|
||||
|
||||
Args:
|
||||
datacenterId: Id of the datacenter to get information about it
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
|
||||
A dictionary with following values
|
||||
'id' -> Storage id
|
||||
'name' -> Storage name
|
||||
'type' -> Storage type ('data', 'iso')
|
||||
'available' -> Space available, in bytes
|
||||
'used' -> Space used, in bytes
|
||||
# 'active' -> True or False --> This is not provided by api?? (api.storagedomains.get)
|
||||
|
||||
'''
|
||||
return self.__getApi().getStorageInfo(storageId, force)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def test(env, data):
|
||||
|
@ -92,7 +92,6 @@ class Client(object):
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
|
||||
An array of dictionaries, containing:
|
||||
'name'
|
||||
'id'
|
||||
@ -124,6 +123,60 @@ class Client(object):
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
def getClusters(self, force = False):
|
||||
'''
|
||||
Obtains the list of clusters inside ovirt
|
||||
|
||||
Args:
|
||||
force: If true, force to update the cache, if false, tries to first
|
||||
get data from cache and, if valid, return this.
|
||||
|
||||
Returns
|
||||
Filters out clusters not attached to any datacenter
|
||||
An array of dictionaries, containing:
|
||||
'name'
|
||||
'id'
|
||||
'datacenter_id'
|
||||
|
||||
'''
|
||||
clsKey = self.__getKey('o-clusters')
|
||||
val = self._cache.get(clsKey)
|
||||
|
||||
if val is not None and force is False:
|
||||
return val
|
||||
|
||||
try:
|
||||
lock.acquire(True)
|
||||
|
||||
api = self.__getApi()
|
||||
|
||||
clusters = api.clusters.list()
|
||||
|
||||
res = []
|
||||
|
||||
for cluster in clusters:
|
||||
dc = cluster.get_data_center()
|
||||
|
||||
if dc is not None:
|
||||
dc = dc.get_id()
|
||||
|
||||
val = { 'name' : cluster.get_name(), 'id' : cluster.get_id(), 'datacenter_id' : dc }
|
||||
|
||||
# Updates cache info for every single cluster
|
||||
clKey = self.__getKey('o-cluster'+cluster.get_id())
|
||||
self._cache.put(clKey, val)
|
||||
|
||||
if dc is not None:
|
||||
res.append(val)
|
||||
|
||||
self._cache.put(clsKey, res, Client.CACHE_TIME_HIGH)
|
||||
|
||||
return res
|
||||
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
|
||||
def getClusterInfo(self, clusterId, force = False):
|
||||
'''
|
||||
Obtains the cluster info
|
||||
@ -138,7 +191,6 @@ class Client(object):
|
||||
A dictionary with following values
|
||||
'name'
|
||||
'id'
|
||||
'description'
|
||||
'datacenter_id'
|
||||
'''
|
||||
clKey = self.__getKey('o-cluster'+clusterId)
|
||||
@ -154,7 +206,12 @@ class Client(object):
|
||||
|
||||
c = api.clusters.get(id=clusterId)
|
||||
|
||||
res = { 'name' : c.get_name(), 'id' : c.get_id(), 'datacenter_id' : c.get_data_center().get_id() }
|
||||
dc = c.get_data_center()
|
||||
|
||||
if dc is not None:
|
||||
dc = dc.get_id()
|
||||
|
||||
res = { 'name' : c.get_name(), 'id' : c.get_id(), 'datacenter_id' : dc }
|
||||
self._cache.put(clKey, res, Client.CACHE_TIME_HIGH)
|
||||
return res
|
||||
finally:
|
||||
|
Loading…
Reference in New Issue
Block a user