From 17ec42fca5a58390296fe32bb46b5540ca0bca10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Wed, 24 Sep 2014 13:57:14 +0200 Subject: [PATCH] Starting again with actor over REST and fixed a few Xen "typos" --- server/src/uds/REST/methods/actor.py | 81 ++++++++++--------- .../uds/services/Xen/xen_client/__init__.py | 56 +++++++------ server/src/uds/xmlrpc/actor/__init__.py | 2 +- 3 files changed, 73 insertions(+), 66 deletions(-) diff --git a/server/src/uds/REST/methods/actor.py b/server/src/uds/REST/methods/actor.py index 236690fa..8fa77682 100644 --- a/server/src/uds/REST/methods/actor.py +++ b/server/src/uds/REST/methods/actor.py @@ -38,11 +38,15 @@ from uds.core.util import Config from uds.core.util.State import State from uds.core.util import log from uds.core.managers import cryptoManager -from uds.REST import Handler, AccessDenied, RequestError +from uds.REST import Handler +from uds.REST import AccessDenied +from uds.REST import RequestError from uds.models import UserService import datetime +import six +import simplejson as json import logging @@ -52,7 +56,7 @@ logger = logging.getLogger(__name__) # Actor key, configurable in Security Section of administration interface actorKey = Config.Config.section(Config.SECURITY_SECTION).value('actorKey', cryptoManager().uuid(datetime.datetime.now()).replace('-', ''), - type=Config.Config.NUMERIC_FIELD) + type=Config.Config.TEXT_FIELD) actorKey.get() @@ -64,23 +68,17 @@ class Actor(Handler): authenticated = False # Actor requests are not authenticated def test(self): + ''' + Executes and returns the test + ''' return {'result': _('Correct'), 'date': datetime.datetime.now()} - def getClientIdAndMessage(self): - - # Now we will process .../clientIds/message - if len(self._args) < 3: - raise RequestError('Invalid arguments provided') - - clientIds, message = self._args[1].split(',')[:5], self._args[2] - - return clientIds, message - - def validateRequest(self): + def validateRequestKey(self): # Ensures that key is first parameter - # Here, path will be .../actor/KEY/... (probably /rest/actor/KEY/...) - if self._args[0] != actorKey.get(True): - raise AccessDenied('Invalid actor key') + # Here, path will be .../actor/ACTION/KEY (probably /rest/actor/KEY/...) + if self._params.get('key') != actorKey.get(True): + return {'result': _('Invalid key'), 'date': datetime.datetime.now()} + return None def processRequest(self, clientIds, message, data): logger.debug("Called message for id_ {0}, message \"{1}\" and data \"{2}\"".format(clientIds, message, data)) @@ -105,35 +103,46 @@ class Actor(Handler): logger.debug("Returning {0}".format(res)) return res + def getUserServiceByIds(self): + ''' + This will get the client from the IDs passed from parameters + ''' + logger.debug('Getting User services from ids: {}'.format(self._params.get('id'))) + + try: + clientIds = self._params.get('id').split(',')[:5] + except Exception: + raise RequestError('Invalid request: (no id found)') + + services = UserService.objects.filter(unique_id__in=clientIds, state__in=[State.USABLE, State.PREPARING]) + if services.count() == 0: + return None + + return services[0] + def get(self): ''' Processes get requests ''' logger.debug("Actor args for GET: {0}".format(self._args)) - self.validateRequest() # Wil raise an access denied exception if not valid + # if path is .../test (/rest/actor/[test|init]?key=.....) + if self._args[0] in ('test', 'init'): + v = self.validateRequestKey() + if v is not None: + return v + if self._args[0] == 'test': + return self.test() - # if path is .../test (/rest/actor/KEY/test) - if self._args[1] == 'test': - return self.test() - - clientIds, message = self.getClientIdAndMessage() - - try: - data = self._args[3] - except Exception: - data = '' - - return self.processRequest(clientIds, message, data) + # Returns UID of selected Machine + service = self.getUserServiceByIds() + if service is None: + return "" + else: + return service.uuid def post(self): ''' Processes post requests ''' - self.validateRequest() # Wil raise an access denied exception if not valid - - clientIds, message = self.getClientIdAndMessage() - - data = self._params[0] - - return self.processRequest(clientIds, message, data) + raise RequestError('Invalid method invoked') diff --git a/server/src/uds/services/Xen/xen_client/__init__.py b/server/src/uds/services/Xen/xen_client/__init__.py index ae08cbac..e51408ff 100644 --- a/server/src/uds/services/Xen/xen_client/__init__.py +++ b/server/src/uds/services/Xen/xen_client/__init__.py @@ -49,7 +49,8 @@ class XenFailure(XenAPI.Failure, XenFault): exHandleInvalid = 'HANDLE_INVALID' exHostIsSlave = 'HOST_IS_SLAVE' - def __init__(self, details=[]): + def __init__(self, details=None): + details = [] if details is None else details super(XenFailure, self).__init__(details) def isHandleInvalid(self): @@ -75,7 +76,7 @@ class XenFailure(XenAPI.Failure, XenFault): err = errList.get(self.details[0], 'Error {0}') return err.format(*self.details) - except: + except Exception: return 'Unknown exception: {0}'.format(self.details) def __unicode__(self): @@ -83,9 +84,8 @@ class XenFailure(XenAPI.Failure, XenFault): class XenException(XenFault): - def __init__(self, message): - Exception.__init__(self, message) + XenFault.__init__(self, message) logger.debug('Exception create: {0}'.format(message)) @@ -106,37 +106,38 @@ class XenServer(object): self._loggedIn = False self._username = username self._password = password - self._poolName = '' + self._session = None + self._poolName = self._apiVersion = '' @staticmethod def toMb(number): return int(number) / (1024 * 1024) - def __checkLogin(self): + def checkLogin(self): if self._loggedIn is False: self.login() return self._loggedIn - def __getXenapiProperty(self, prop): - if self.__checkLogin() is False: - raise "Can't log in" + def getXenapiProperty(self, prop): + if self.checkLogin() is False: + raise Exception("Can't log in") return getattr(self._session.xenapi, prop) # Properties to fast access XenApi classes - Async = property(lambda self: self.__getXenapiProperty('Async')) - task = property(lambda self: self.__getXenapiProperty('task')) - VM = property(lambda self: self.__getXenapiProperty('VM')) - SR = property(lambda self: self.__getXenapiProperty('SR')) - pool = property(lambda self: self.__getXenapiProperty('pool')) - host = property(lambda self: self.__getXenapiProperty('host')) - network = property(lambda self: self.__getXenapiProperty('network')) - VIF = property(lambda self: self.__getXenapiProperty('VIF')) # Virtual Interface - VDI = property(lambda self: self.__getXenapiProperty('VDI')) # Virtual Disk Image - VBD = property(lambda self: self.__getXenapiProperty('VBD')) # Virtual Block Device + Async = property(lambda self: self.getXenapiProperty('Async')) + task = property(lambda self: self.getXenapiProperty('task')) + VM = property(lambda self: self.getXenapiProperty('VM')) + SR = property(lambda self: self.getXenapiProperty('SR')) + pool = property(lambda self: self.getXenapiProperty('pool')) + host = property(lambda self: self.getXenapiProperty('host')) + network = property(lambda self: self.getXenapiProperty('network')) + VIF = property(lambda self: self.getXenapiProperty('VIF')) # Virtual Interface + VDI = property(lambda self: self.getXenapiProperty('VDI')) # Virtual Disk Image + VBD = property(lambda self: self.getXenapiProperty('VBD')) # Virtual Block Device # Properties to access private vars - poolName = property(lambda self: self.__checkLogin() and self._poolName) - hasPool = property(lambda self: self.__checkLogin() and self._poolName != '') + poolName = property(lambda self: self.checkLogin() and self._poolName) + hasPool = property(lambda self: self.checkLogin() and self._poolName != '') def getPoolName(self): pool = self.pool.get_all()[0] @@ -224,7 +225,7 @@ class XenServer(object): # Only valid SR shared, non iso name_label = self.SR.get_name_label(srId) if self.SR.get_content_type(srId) == 'iso' or \ - self.SR.get_shared(srId) == False or \ + self.SR.get_shared(srId) is False or \ name_label == '': continue @@ -300,7 +301,7 @@ class XenServer(object): def startVM(self, vmId, async=True): vmState = self.getVMPowerState(vmId) if vmState == XenPowerState.running: - return None # Already powered on + return None # Already powered on if async: return self.Async.VM.start(vmId, False, False) return self.VM.start(vmId, False, False) @@ -308,7 +309,7 @@ class XenServer(object): def stopVM(self, vmId, async=True): vmState = self.getVMPowerState(vmId) if vmState in (XenPowerState.suspended, XenPowerState.halted): - return None # Already powered off + return None # Already powered off if async: return self.Async.VM.hard_shutdown(vmId) return self.VM.hard_shutdown(vmId) @@ -388,7 +389,6 @@ class XenServer(object): Mac address should be in the range 02:xx:xx:xx:xx (recommended, but not a "have to") ''' - pass mac = kwargs.get('mac', None) memory = kwargs.get('memory', None) @@ -423,7 +423,7 @@ class XenServer(object): tags = self.VM.get_tags(vmId) try: del tags[tags.index(TAG_TEMPLATE)] - except: + except Exception: pass tags.append(TAG_MACHINE) self.VM.set_tags(vmId, tags) @@ -432,7 +432,6 @@ class XenServer(object): return self.Async.VM.provision(vmId) return self.VM.provision(vmId) - def convertToTemplate(self, vmId, shadowMultiplier=4): try: operations = self.VM.get_allowed_operations(vmId) @@ -453,7 +452,7 @@ class XenServer(object): # Set multiplier try: self.VM.set_HVM_shadow_multiplier(vmId, float(shadowMultiplier)) - except: + except Exception: # Can't set shadowMultiplier, nothing happens pass # TODO: Log this? except XenAPI.Failure as e: @@ -467,4 +466,3 @@ class XenServer(object): After cloning template, we must deploy the VM so it's a full usable VM ''' return self.cloneVM(templateId, targetName) - diff --git a/server/src/uds/xmlrpc/actor/__init__.py b/server/src/uds/xmlrpc/actor/__init__.py index bf7eee4c..1cdfdb93 100644 --- a/server/src/uds/xmlrpc/actor/__init__.py +++ b/server/src/uds/xmlrpc/actor/__init__.py @@ -1,3 +1,3 @@ ''' -This module is responsible of the communication betwen actors and OS Managers +This module is responsible of the communication between actors and OS Managers ''' \ No newline at end of file