1
0
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:
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__)
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

View File

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

View File

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