def __init__(self, server, agentId): self.agentId = agentId self.flows = {} self.acl = [] self.auth = TSServerClient.AUTH_NONE self.endpointStr = 'local' JSONTS.__init__(self, server)
def deserialize(self, val): if type(val) != self.objType: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, "Expected %s, got %s" % (self.objType, type(val))) return val
def onAgentRegister(self, client): if client.agentType == 'load': if client.agentUuid in self.loadAgents: raise JSONTS.Error( JSONTS.AE_INVALID_STATE, "Loader agent with uuid '%s' already registered" % client.agentUuid) agentId = client.getId() agent = self.createRemoteAgent(agentId, LoadAgent) agentSet = yield self.dbStore.find( Agent, Agent.uuid == uuid.UUID(client.agentUuid)) agentObj = yield agentSet.one() if agentObj is None: agentObj = yield self.registerNewAgent(client, agent) else: # Update last online timestamp agentObj.lastOnline = datetime.now() yield self.dbStore.add(agentObj) yield self.dbStore.commit() agentInfo = LoadAgentInfo(agent, agentObj) self.loadAgents[client.agentUuid] = agentInfo print "Registered agent %s with uuid '%s'" % (agentObj.hostname, client.agentUuid) reactor.callLater(0.0, self.fetchWorkloadTypes, agent, agentObj) reactor.callLater(0.1, self.resourceManager.registerLoadAgent, agent, agentObj)
def deserialize(self, val): fieldValue = val.get(self.field, TSObject.Undef) if fieldValue is TSObject.Undef: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Missing field "%s" for multiobject' % (self.field)) try: objClass = self.objClassMap[fieldValue] except KeyError: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Invalid field "%s" value "%s" for multiobject: Unknown class' % (self.field, fieldValue)) return objClass.deserialize(val)
def authMasterKey(self, context, masterKey): client = context.client self.logger.info('Authorizing client %s with master key', client) if str(self.server.masterKey) == masterKey: client.authorize(TSServerClient.AUTH_MASTER) return raise JSONTS.Error(JSONTS.AE_INVALID_DATA, 'Master key invalid')
def serialize(self, val): try: objType = self.revClassMap[val.__class__] except KeyError: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Invalid class "%s" for multiobject: Unknown type' % (val.__class__.__name__)) obj = val.serialize() obj[self.field] = objType return obj
def serialize(self): val = {} for fieldName in dir(self.__class__): field = getattr(self, fieldName) fieldClass = getattr(self.__class__, fieldName) if isinstance(fieldClass, TSObject.Type): if isinstance(field, TSObject.Type): if field.optional: # Do not serialize optional values continue else: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Field "%s" for class "%s" is not set' % (fieldName, self.__class__.__name__)) try: val[fieldName] = fieldClass.serialize(field) except Exception, e: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Field "%s" for class "%s" serialization failed: "%s"' % (fieldName, self.__class__.__name__, str(e)))
def deserialize(cls, val): obj = cls() for fieldName in dir(cls): field = getattr(cls, fieldName) if isinstance(field, TSObject.Type): fieldValue = val.get(fieldName, TSObject.Undef) if fieldValue is not TSObject.Undef: fieldDeserVal = field.deserialize(fieldValue) setattr(obj, fieldName, fieldDeserVal) elif not field.optional: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Missing field "%s" for class "%s"' % (fieldName, cls.__name__)) return obj
def processMessage(self, srcClient, message): srcAgentId = srcClient.getId() srcMsgId = message['id'] dstAgentId = message['agentId'] self.doTrace('Process message %s(%d, %d)', srcClient, srcAgentId, srcMsgId) if 'cmd' in message: command = message['cmd'] cmdArgs = message['msg'] if dstAgentId != self.client.getId(): raise JSONTS.Error( JSONTS.AE_INVALID_AGENT, 'Invalid destination agent: ours is %d, received is %d' % (self.client.getId(), dstAgentId)) if type(cmdArgs) != dict: raise JSONTS.Error( JSONTS.AE_MESSAGE_FORMAT, 'Message should be dictionary, not a %s' % type(cmdArgs)) try: method = getattr(self, command) except AttributeError as ae: raise JSONTS.Error(JSONTS.AE_COMMAND_NOT_FOUND, str(ae)) context = CallContext(srcClient, srcMsgId) response = method(context, cmdArgs) if isinstance(response, Deferred): # Add closures callback/errbacks to deferred and return def deferredCallback(response): self.doTrace('Got response (deferred) %s', response) srcClient.sendResponse(srcClient.getId(), srcMsgId, response) def deferredErrback(failure): self.doTrace('Got error (deferred) %s', str(failure)) srcClient.sendError(srcClient.getId(), srcMsgId, failure.getErrorMessage(), JSONTS.AE_INTERNAL_ERROR) response.addCallback(deferredCallback) response.addErrback(deferredErrback) return self.doTrace('Got response %s', response) srcClient.sendResponse(srcClient.getId(), srcMsgId, response) else: # Notify MethodProxy deferred that response arrived call = self.calls[srcMsgId] if 'response' in message: response = message['response'] call.callback(response) elif 'error' in message: error = message['error'] code = message['code'] call.errback((code, error)) del self.calls[srcMsgId]
def __init__(self, factory, agentId): self.agentId = agentId JSONTS.__init__(self, factory)
def _callbackError(self, failure): code, error = failure.value raise JSONTS.Error(code, error)
def processMessage(self, srcClient, message): '''Main method of server that routes messages between agents''' srcAgentId = srcClient.getId() srcMsgId = message['id'] dstAgentId = message['agentId'] dstMsgId = next(self.msgCounter) self.doTrace('Process message %s from %d', message, srcAgentId) try: dstClient = self.clients[dstAgentId] except KeyError: if 'cmd' in message: raise JSONTS.Error(JSONTS.AE_INVALID_AGENT, 'Invalid agent #%d' % dstAgentId) return self.doTrace('Process message %s(%d, %d) -> %s(%d, %d)', srcClient, srcAgentId, srcMsgId, dstClient, dstAgentId, dstMsgId) if 'cmd' in message: command = message['cmd'] flow = Flow(srcAgentId = srcAgentId, dstAgentId = dstAgentId, command = command) # The only way to communicate for unauthorized if srcClient.auth == TSServerClient.AUTH_NONE: for listener in self.listenerFlows: self.doTrace('Checking flow %s against listener rule %s', flow, listener) if listener == flow: dstMsgId = next(self.msgCounter) flowClone = flow.clone(srcMsgId, dstMsgId) dstClient.addFlow(flowClone) message['id'] = dstMsgId message['agentId'] = listener.dstAgentId self.deliverMessage(srcClient, message) else: flow.setMsgIds(srcMsgId, dstMsgId) if not srcClient.checkACL(flow): raise JSONTS.Error(JSONTS.AE_ACCESS_DENIED, 'Access is denied') dstClient.addFlow(flow) message['id'] = dstMsgId self.deliverMessage(srcClient, message) else: flow = srcClient.findFlow(srcAgentId, srcMsgId) if flow is None: return self.doTrace('Found flow %s [%d -> %d]', flow, flow.srcMsgId, flow.dstMsgId) message['id'] = flow.srcMsgId message['agentId'] = flow.srcAgentId self.deliverMessage(srcClient, message)
def deserialize(self, val): if val is not None: raise JSONTS.Error(JSONTS.AE_MESSAGE_FORMAT, "Expected Null, got %s" % type(val))