def users_unregister(self, users): """ Unregister users @type users: list @param users: list of users to unregister """ def on_receive_unregistration(conn, iq): if iq.getType() == "result": for jid in users: self.users.remove({"jid": jid.getStripped(), "type": "human"}) self.entity.log.info("XMPPSERVER: Successfully unregistered user(s).") self.entity.push_change("xmppserver:users", "unregistered") else: self.entity.push_change("xmppserver:users", "unregisterationerror", iq) self.entity.log.error("XMPPSERVER: unable to unregister user. %s" % str(iq)) iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain()) iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#delete-user"}) iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"}) iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin") accountjids_node = iq_command_x.addChild("field", attrs={"var": "accountjids"}) for jid in users: accountjids_node.addChild("value").setData(jid.getStripped()) if jid.getStripped() in self.entities_types_cache: del self.entities_types_cache[jid.getStripped()] if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_unregistration) else: self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_unregistration) self.entity.log.info("XMPPSERVER: Unregistring some users %s" % str(users))
def users_change_password(self, users): """ Change password for users @type users: list @param users: list of users to change password """ def on_receive_password_changed(conn, iq): if iq.getType() == "result": self.entity.log.info("XMPPSERVER: Successfully changed paswword for user(s).") self.entity.push_change("xmppserver:users", "passwordchanged") else: self.entity.push_change("xmppserver:users", "changepassworderror", iq) self.entity.log.error("XMPPSERVER: Unable to change password for user. %s" % str(iq)) server = self.entity.jid.getDomain() for user in users: iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain()) iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#change-user-password"}) iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"}) iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin") iq_command_x.addChild("field", attrs={"var": "accountjid"}).addChild("value").setData(user["jid"]) iq_command_x.addChild("field", attrs={"var": "password"}).addChild("value").setData(user["password"]) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_password_changed) else: self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_password_changed) self.entity.log.info("XMPPSERVER: Changing password for user %s@%s" % (user["jid"], server))
def manage_received_users(conn, iq): items = iq.getTag("query").getTags("item") users = map(lambda x: x.getAttr("jid"), items) def on_receive_vcard(conn, iq): try: entity_type = self._extract_entity_type(iq.getTag("vCard")) self.entities_types_cache[iq.getFrom().getStripped()] = entity_type self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type}) if len(self.users) == total_number_of_users: callback(**args) except Exception as ex: self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex)) for user in users: if not user in self.entities_types_cache: iq_vcard = xmpp.Iq(typ="get", to=user) iq_vcard.addChild("vCard", namespace="vcard-temp") self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user])) self.users.append({"jid": user, "type": self.entities_types_cache[user]}) if len(self.users) == total_number_of_users: callback(**args)
def users_register(self, users): """ Register new users @type users: list @param users: list of users to register """ def on_receive_registration(conn, iq): if iq.getType() == "result": for user in users: entry = {"jid": user["jid"].getStripped(), "type": "human"} if entry not in self.users: self.users.append(entry) self.entities_types_cache[user["jid"].getStripped()] = "human" self.entity.log.info("XMPPSERVER: Successfully registered user(s).") self.entity.push_change("xmppserver:users", "registered") else: self.entity.push_change("xmppserver:users", "registerationerror", iq) self.entity.log.error("XMPPSERVER: Unable to register user. %s" % str(iq)) server = self.entity.jid.getDomain() for user in users: iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain()) iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#add-user"}) iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"}) iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin") iq_command_x.addChild("field", attrs={"var": "accountjid"}).addChild("value").setData(user["jid"]) iq_command_x.addChild("field", attrs={"var": "password"}).addChild("value").setData(user["password"]) iq_command_x.addChild("field", attrs={"var": "password-verify"}).addChild("value").setData(user["password"]) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_registration) else: self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_registration) self.entity.log.info("XMPPSERVER: Registering a new user %s@%s" % (user["jid"], server))
def commit_to_db(self, action, table, callback): """ Sends a command to active central agent for execution @type command: string @param command: the sql command to execute @type table: table @param command: the table of dicts of values associated with the command. """ central_agent_jid = self.central_agent_jid() if central_agent_jid: # send an iq to central agent dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) for entry in table: entryTag = xmpp.Node(tag="entry") for key, value in entry.iteritems(): entryTag.addChild("item", attrs={ "key": key, "value": value }) dbCommand.addChild(node=entryTag) def commit_to_db_callback(conn, resp): if callback: unpacked_entries = self.unpack_entries(resp) callback(unpacked_entries) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=central_agent_jid) iq.getTag("query").addChild(name="archipel", attrs={"action": action}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) self.entity.log.debug("CENTRALDB: commit to db request %s" % iq) xmpp.dispatcher.ID += 1 iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID)) self.entity.xmppclient.SendAndCallForResponse( iq, commit_to_db_callback) else: self.entity.log.warning( "CENTRALDB: cannot commit to db because we have not detected any central agent" )
def on_receive_users(conn, iq): if not iq.getType() == "result": self.entity.log.error("unable to fetch users: %s" % str(iq)) return def manage_received_users(conn, iq): items = iq.getTag("query").getTags("item") users = map(lambda x: x.getAttr("jid"), items) def on_receive_vcard(conn, iq): try: entity_type = self._extract_entity_type(iq.getTag("vCard")) self.entities_types_cache[iq.getFrom().getStripped()] = entity_type self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type}) if len(self.users) == total_number_of_users: callback(**args) except Exception as ex: self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex)) for user in users: if not user in self.entities_types_cache: iq_vcard = xmpp.Iq(typ="get", to=user) iq_vcard.addChild("vCard", namespace="vcard-temp") self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user])) self.users.append({"jid": user, "type": self.entities_types_cache[user]}) if len(self.users) == total_number_of_users: callback(**args) try: items = iq.getTag("query").getTags("item") if items[0].getAttr("node"): for page in range(0, len(items)): iq_page = xmpp.Iq(typ="get", to=iq.getFrom()) iq_page.addChild("query", attrs={"node": iq.getTag("query").getTags("item")[page].getAttr("node")}, namespace="http://jabber.org/protocol/disco#items") if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_page, manage_received_users) else: self.entity.xmppclient.SendAndCallForResponse(iq_page, manage_received_users) else: manage_received_users(conn, iq) except Exception as ex: self.entity.log.error("XMPPSERVER: Unable to manage to get users or their vcards. error is %s" % str(ex))
def read_from_db(self, action, columns, where_statement, callback): """ Send a select statement to central db. @type command: string @param command: the sql command to execute @type columns: string @param columns: the list of database columns to return @type where_statement: string @param where_statement: for database reads, provides "where" constraint """ central_agent_jid = self.central_agent_jid() if central_agent_jid: # send an iq to central agent dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) if where_statement: dbCommand.setAttr("where_statement", where_statement) if columns: dbCommand.setAttr("columns", columns) self.entity.log.debug("CENTRALDB: central agent jid %s" % central_agent_jid) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=central_agent_jid) iq.getTag("query").addChild(name="archipel", attrs={"action": action}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) xmpp.dispatcher.ID += 1 iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID)) def _read_from_db_callback(conn, resp): self.entity.log.debug("CENTRALDB: reply to read statement %s" % resp) unpacked_entries = self.unpack_entries(resp) self.entity.log.debug("CENTRALDB: unpacked reply %s" % unpacked_entries) callback(unpacked_entries) self.entity.xmppclient.SendAndCallForResponse( iq, _read_from_db_callback) else: self.entity.log.warning( "CENTRALDB: cannot read from db because we have not detected any central agent" )
def get_management_capabilities(self, base_reply): """ Build the xmpp management capabilities dictionnary """ reply = base_reply.buildReply("result") def on_receive_info(conn, iq): _users_management_capabilities = {"xmpp": False, "xmlrpc": False} _groups_management_capabilities = {"xmpp": False, "xmlrpc": False} _info_msg="XMPPSERVER - User and SRG Management : " if iq.getType() == "result": _users_management_capabilities["xmpp"] = True _info_msg += "XEP-133 allowed" else: _users_management_capabilities["xmpp"] = False _info_msg += "XEP-133 NOT allowed" # next try to use xmlrpc and mod_admin_extra to manage srg try: answer = self._send_xmlrpc_call("srg_list", {"host": self.xmlrpc_host}) _groups_management_capabilities["xmlrpc"] = True _info_msg += " and SRG allowed through xmlrpc" except Exception as ex: _groups_management_capabilities["xmlrpc"] = False _info_msg += " and SRG NOT allowed through xmlrpc, reason : %s" % str(ex) # now send back the reply _users_node = xmpp.Node("users", attrs={"xmpp":_users_management_capabilities["xmpp"], "xmlrpc":_users_management_capabilities["xmlrpc"]}) _groups_node = xmpp.Node("groups", attrs={"xmpp":_groups_management_capabilities["xmpp"], "xmlrpc":_groups_management_capabilities["xmlrpc"]}) reply.setQueryPayload([_users_node, _groups_node]) self.entity.log.debug(_info_msg) self.entity.xmppclient.send(reply) # use disco#info to see if we can use admin-server command XEP-133 iq = xmpp.Iq(typ="get", to=self.entity.jid.getDomain()) iq.addChild("query", attrs={"node": "http://jabber.org/protocol/admin#get-registered-users-num"}, namespace="http://jabber.org/protocol/disco#info") if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_info) else: self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_info)
def handle_first_keepalive(self, keepalive_jid): """ this is the first keepalive. We query hypervisors that have started somewhere else then we trigger method manage_persistence to start the vms. """ vms_from_local_db = self.entity.get_vms_from_local_db() if len(vms_from_local_db) > 0: dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) for vm in vms_from_local_db: entryTag = xmpp.Node(tag="entry") uuid = xmpp.JID(vm["string_jid"]).getNode() entryTag.addChild("item", attrs={"key": "uuid", "value": uuid}) dbCommand.addChild(node=entryTag) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=keepalive_jid) iq.getTag("query").addChild( name="archipel", attrs={"action": "read_vms_started_elsewhere"}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) xmpp.dispatcher.ID += 1 iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID)) def _read_vms_started_elsewhere_callback(conn, packed_vms): vms_started_elsewhere = self.unpack_entries(packed_vms) self.entity.manage_persistence(vms_from_local_db, vms_started_elsewhere) self.entity.xmppclient.SendAndCallForResponse( iq, _read_vms_started_elsewhere_callback) else: # update status to Online(0) self.entity.manage_persistence([], [])
def handle_first_keepalive(self, keepalive_jid): """ this is the first keepalive. We query hypervisors that have vm entities somewhere else then we trigger method manage_persistence to instantiate vm entities. """ vms_from_local_db = self.entity.get_vms_from_local_db() if len(vms_from_local_db) > 0: dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) for vm in vms_from_local_db: entryTag = xmpp.Node(tag="entry") uuid = xmpp.JID(vm["string_jid"]).getNode() entryTag.addChild("item", attrs={"key": "uuid", "value": uuid}) dbCommand.addChild(node=entryTag) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=keepalive_jid) iq.getTag("query").addChild( name="archipel", attrs={"action": "get_existing_vms_instances"}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) def _get_existing_vms_instances_callback(conn, packed_vms): existing_vms_entities = self.unpack_entries(packed_vms) self.entity.manage_persistence(vms_from_local_db, existing_vms_entities) self.entity.xmppclient.SendAndCallForResponse( iq, _get_existing_vms_instances_callback) else: # update status to Online(0) self.entity.manage_persistence()
def _fetch_users(self, xmppserver, callback, args=None): """ Fetch users and populate the internal list @type xmppserver: String @param xmppserver: the xmpp server to query @type callback: function @param callback: the callback to call when fetching is complete @type args: dict @param args: optional kwards of the callback """ self.users = [] self.need_user_refresh = False def on_receive_users_num(conn, iq): if iq.getType() != "result": self.entity.log.error("unable to get user number: %s" % str(iq)) return total_number_of_users = int(iq.getTag("command").getTag("x").getTags("field")[1].getTag("value").getData()) def on_receive_users(conn, iq): if not iq.getType() == "result": self.entity.log.error("unable to fetch users: %s" % str(iq)) return def manage_received_users(conn, iq): items = iq.getTag("query").getTags("item") users = map(lambda x: x.getAttr("jid"), items) def on_receive_vcard(conn, iq): try: entity_type = self._extract_entity_type(iq.getTag("vCard")) self.entities_types_cache[iq.getFrom().getStripped()] = entity_type self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type}) if len(self.users) == total_number_of_users: callback(**args) except Exception as ex: self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex)) for user in users: if not user in self.entities_types_cache: iq_vcard = xmpp.Iq(typ="get", to=user) iq_vcard.addChild("vCard", namespace="vcard-temp") self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard) else: self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user])) self.users.append({"jid": user, "type": self.entities_types_cache[user]}) if len(self.users) == total_number_of_users: callback(**args) try: items = iq.getTag("query").getTags("item") if items[0].getAttr("node"): for page in range(0, len(items)): iq_page = xmpp.Iq(typ="get", to=iq.getFrom()) iq_page.addChild("query", attrs={"node": iq.getTag("query").getTags("item")[page].getAttr("node")}, namespace="http://jabber.org/protocol/disco#items") if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_page, manage_received_users) else: self.entity.xmppclient.SendAndCallForResponse(iq_page, manage_received_users) else: manage_received_users(conn, iq) except Exception as ex: self.entity.log.error("XMPPSERVER: Unable to manage to get users or their vcards. error is %s" % str(ex)) user_iq = xmpp.Iq(typ="get", to=xmppserver) user_iq.addChild("query", attrs={"node": "all users"}, namespace="http://jabber.org/protocol/disco#items") if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(user_iq, on_receive_users) else: self.entity.xmppclient.SendAndCallForResponse(user_iq, on_receive_users) iq = xmpp.Iq(typ="set", to=xmppserver) iq.addChild("command", attrs={"action": "execute", "node": "http://jabber.org/protocol/admin#get-registered-users-num"}, namespace="http://jabber.org/protocol/commands") if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_users_num) else: self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_users_num)