1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-18 06:03:54 +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:
Adolfo Gómez 2012-11-15 08:56:59 +00:00
parent 85dd9b0537
commit 0bb26cfae1
4 changed files with 257 additions and 52 deletions

View 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

View File

@ -42,6 +42,8 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from Helpers import oVirtHelpers
class OVirtLinkedService(Service): class OVirtLinkedService(Service):
''' '''
oVirt Linked clones service. This is based on creating a template from selected vm, and then use it to 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) #: Types of deploys (services in cache and/or assigned to users)
deployedType = OVirtLinkedDeployment deployedType = OVirtLinkedDeployment
# Now the form part, this service will have only two "dummy" fields # Now the form part
# If we don't indicate an order, the output order of fields will be machine = gui.ChoiceField(label=translatable("Base Machine"), order = 1, tooltip = _('Service base machine'), required = True)
# "random" 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)
ov = gui.HiddenField()
ev = gui.HiddenField() # We need to keep the env so we can instantiate the Provider
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
)
def initialize(self, values): def initialize(self, values):
''' '''
@ -116,40 +122,27 @@ class OVirtLinkedService(Service):
Note that we check them throught FROM variables, that already has been Note that we check them throught FROM variables, that already has been
initialized by __init__ method of base class, before invoking this. 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 values is not None:
if self.colour.value == 'nonsense': length = int(self.lenName.value)
raise Service.ValidationException('The selected colour is invalid!!!') 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():
# Services itself are non testeable right now, so we don't even have raise Service.ValidationException(_('The machine name can\'t be only numbers'))
# to provide one!!!
# Congratulations!!!, the needed part of your first simple service is done! machines = self.parent().getMachines()
# Now you can go to administration panel, and check it vals = []
# for m in machines:
# From now onwards, we implement our own methods, that will be used by, vals.append( gui.choiceItem( m['id'], m['name'] ))
# for example, services derived from this provider self.machine.setValues(vals)
def getColour(self): clusters = self.parent().getClusters()
''' vals = []
Simply returns colour, for deployed user services. 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

View File

@ -118,9 +118,120 @@ class Provider(ServiceProvider):
self._api = None self._api = None
def testConnection(self): 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 @staticmethod
def test(env, data): def test(env, data):

View File

@ -92,7 +92,6 @@ class Client(object):
get data from cache and, if valid, return this. get data from cache and, if valid, return this.
Returns Returns
An array of dictionaries, containing: An array of dictionaries, containing:
'name' 'name'
'id' 'id'
@ -124,6 +123,60 @@ class Client(object):
finally: finally:
lock.release() 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): def getClusterInfo(self, clusterId, force = False):
''' '''
Obtains the cluster info Obtains the cluster info
@ -138,7 +191,6 @@ class Client(object):
A dictionary with following values A dictionary with following values
'name' 'name'
'id' 'id'
'description'
'datacenter_id' 'datacenter_id'
''' '''
clKey = self.__getKey('o-cluster'+clusterId) clKey = self.__getKey('o-cluster'+clusterId)
@ -154,7 +206,12 @@ class Client(object):
c = api.clusters.get(id=clusterId) 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) self._cache.put(clKey, res, Client.CACHE_TIME_HIGH)
return res return res
finally: finally: